Kaydet (Commit) ba439096 authored tarafından Samuel Mehrbrodt's avatar Samuel Mehrbrodt

tdf#118568 Use custom image for signing signature line

Change-Id: Ib3c4d2301bf5e68b7c02590a8947ea3a502e7087
Reviewed-on: https://gerrit.libreoffice.org/63325
Tested-by: Jenkins
Reviewed-by: 's avatarSamuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
üst bad21966
......@@ -9,22 +9,26 @@
#include <SignSignatureLineDialog.hxx>
#include <sal/types.h>
#include <sal/log.hxx>
#include <sal/types.h>
#include <dialmgr.hxx>
#include <strings.hrc>
#include <comphelper/graphicmimetype.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/xmlsechelper.hxx>
#include <osl/file.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/objsh.hxx>
#include <svx/xoutbmp.hxx>
#include <tools/stream.hxx>
#include <unotools/localedatawrapper.hxx>
#include <unotools/streamwrap.hxx>
#include <utility>
#include <vcl/graph.hxx>
#include <vcl/weld.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/objsh.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/XShape.hpp>
......@@ -40,6 +44,9 @@
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/text/XTextContent.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/ui/dialogs/FilePicker.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
using namespace comphelper;
using namespace css;
......@@ -53,12 +60,15 @@ using namespace css::text;
using namespace css::drawing;
using namespace css::graphic;
using namespace css::security;
using namespace css::ui::dialogs;
SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget* pParent, Reference<XModel> xModel)
: SignatureLineDialogBase(pParent, std::move(xModel), "cui/ui/signsignatureline.ui",
"SignSignatureLineDialog")
, m_xEditName(m_xBuilder->weld_entry("edit_name"))
, m_xEditComment(m_xBuilder->weld_text_view("edit_comment"))
, m_xBtnLoadImage(m_xBuilder->weld_button("btn_load_image"))
, m_xBtnClearImage(m_xBuilder->weld_button("btn_clear_image"))
, m_xBtnChooseCertificate(m_xBuilder->weld_button("btn_select_certificate"))
, m_xBtnSign(m_xBuilder->weld_button("ok"))
, m_xLabelHint(m_xBuilder->weld_label("label_hint"))
......@@ -78,6 +88,8 @@ SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget* pParent, Referenc
return;
}
m_xBtnLoadImage->connect_clicked(LINK(this, SignSignatureLineDialog, loadImage));
m_xBtnClearImage->connect_clicked(LINK(this, SignSignatureLineDialog, clearImage));
m_xBtnChooseCertificate->connect_clicked(
LINK(this, SignSignatureLineDialog, chooseCertificate));
m_xEditName->connect_changed(LINK(this, SignSignatureLineDialog, entryChanged));
......@@ -120,6 +132,38 @@ SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget* pParent, Referenc
ValidateFields();
}
IMPL_LINK_NOARG(SignSignatureLineDialog, loadImage, weld::Button&, void)
{
Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
Reference<XFilePicker3> xFilePicker
= FilePicker::createWithMode(xContext, TemplateDescription::FILEOPEN_PREVIEW);
if (xFilePicker->execute())
{
Sequence<OUString> aSelectedFiles = xFilePicker->getSelectedFiles();
if (aSelectedFiles.getLength() < 1)
return;
Reference<XGraphicProvider> xProvider = GraphicProvider::create(xContext);
Sequence<PropertyValue> aMediaProperties(1);
aMediaProperties[0].Name = "URL";
aMediaProperties[0].Value <<= aSelectedFiles[0];
m_xSignatureImage = xProvider->queryGraphic(aMediaProperties);
m_sOriginalImageBtnLabel = m_xBtnLoadImage->get_label();
INetURLObject aObj(aSelectedFiles[0]);
m_xBtnLoadImage->set_label(aObj.GetLastName());
ValidateFields();
}
}
IMPL_LINK_NOARG(SignSignatureLineDialog, clearImage, weld::Button&, void)
{
m_xSignatureImage.set(nullptr);
m_xBtnLoadImage->set_label(m_sOriginalImageBtnLabel);
ValidateFields();
}
IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, weld::Button&, void)
{
// Document needs to be saved before selecting a certificate
......@@ -150,8 +194,13 @@ IMPL_LINK_NOARG(SignSignatureLineDialog, entryChanged, weld::Entry&, void) { Val
void SignSignatureLineDialog::ValidateFields()
{
bool bEnable = m_xSelectedCertifate.is() && !m_xEditName->get_text().isEmpty();
m_xBtnSign->set_sensitive(bEnable);
bool bEnableSignBtn = m_xSelectedCertifate.is()
&& (!m_xEditName->get_text().isEmpty() || m_xSignatureImage.is());
m_xBtnSign->set_sensitive(bEnableSignBtn);
m_xEditName->set_sensitive(!m_xSignatureImage.is());
m_xBtnLoadImage->set_sensitive(m_xEditName->get_text().isEmpty());
m_xBtnClearImage->set_sensitive(m_xSignatureImage.is());
}
void SignSignatureLineDialog::Apply()
......@@ -177,7 +226,6 @@ SignSignatureLineDialog::getSignedGraphic(bool bValid)
aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(m_aSuggestedSignerName));
aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(m_aSuggestedSignerTitle));
aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", getCDataString(m_xEditName->get_text()));
OUString aIssuerLine
= CuiResId(RID_SVXSTR_SIGNATURELINE_SIGNED_BY)
.replaceFirst("%1", xmlsec::GetContentPart(m_xSelectedCertifate->getSubjectName()));
......@@ -195,6 +243,31 @@ SignSignatureLineDialog::getSignedGraphic(bool bValid)
}
aSvgImage = aSvgImage.replaceAll("[DATE]", aDate);
// Custom signature image
if (m_xSignatureImage.is())
{
OUString aGraphicInBase64;
Graphic aGraphic(m_xSignatureImage);
if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64, false))
SAL_WARN("cui.dialogs", "Could not convert graphic to base64");
OUString aImagePart = "<image y=\"825\" x=\"1300\" "
"xlink:href=\"data:[MIMETYPE];base64,[BASE64_IMG]>\" "
"preserveAspectRatio=\"xMidYMid\" height=\"1520\" "
"width=\"7600\" />";
aImagePart = aImagePart.replaceAll(
"[MIMETYPE]", GraphicMimeTypeHelper::GetMimeTypeForXGraphic(m_xSignatureImage));
aImagePart = aImagePart.replaceAll("[BASE64_IMG]", aGraphicInBase64);
aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", aImagePart);
aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", "");
}
else
{
aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", "");
aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", getCDataString(m_xEditName->get_text()));
}
// Create graphic
SvMemoryStream aSvgStream(4096, 4096);
aSvgStream.WriteOString(OUStringToOString(aSvgImage, RTL_TEXTENCODING_UTF8));
......
......@@ -213,7 +213,8 @@ OUString SignatureLineDialogBase::getSignatureImage()
"XTEXT_EOC</desc><desc id=\"desc550\">512: XTEXT_EOC</desc><desc id=\"desc552\">512: "
"XTEXT_EOW</desc><desc id=\"desc554\">512: XTEXT_EOL</desc><desc id=\"desc556\">512: "
"XTEXT_EOP</desc><desc id=\"desc558\">512: "
"XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g></g></g></g></g></g></svg>");
"XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g></g></g></g></"
"g>[SIGNATURE_IMAGE]</g></svg>");
return svg;
}
......
......@@ -24,6 +24,8 @@ public:
private:
std::unique_ptr<weld::Entry> m_xEditName;
std::unique_ptr<weld::TextView> m_xEditComment;
std::unique_ptr<weld::Button> m_xBtnLoadImage;
std::unique_ptr<weld::Button> m_xBtnClearImage;
std::unique_ptr<weld::Button> m_xBtnChooseCertificate;
std::unique_ptr<weld::Button> m_xBtnSign;
std::unique_ptr<weld::Label> m_xLabelHint;
......@@ -32,15 +34,19 @@ private:
css::uno::Reference<css::beans::XPropertySet> m_xShapeProperties;
css::uno::Reference<css::security::XCertificate> m_xSelectedCertifate;
css::uno::Reference<css::graphic::XGraphic> m_xSignatureImage;
OUString m_aSignatureLineId;
OUString m_aSuggestedSignerName;
OUString m_aSuggestedSignerTitle;
bool m_bShowSignDate;
OUString m_sOriginalImageBtnLabel;
void ValidateFields();
const css::uno::Reference<css::graphic::XGraphic> getSignedGraphic(bool bValid);
virtual void Apply() override;
DECL_LINK(clearImage, weld::Button&, void);
DECL_LINK(loadImage, weld::Button&, void);
DECL_LINK(chooseCertificate, weld::Button&, void);
DECL_LINK(entryChanged, weld::Entry&, void);
};
......
......@@ -142,7 +142,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
......@@ -154,9 +154,78 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_or">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes" context="signsignatureline|label_name" comments="Name of the signer">or</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_load_image">
<property name="label" translatable="yes" context="signsignatureline|btn_load_image">Use Signature Image</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<accessibility>
<relation type="labelled-by" target="label_image_dimensions"/>
</accessibility>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_clear_image">
<property name="label" translatable="yes" context="signsignatureline|btn_clear_image">Clear</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_image_dimensions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_bottom">6</property>
<property name="label" translatable="yes" context="signsignatureline|label_image_dimensions">Best image size: 600 x 100 px</property>
<attributes>
<attribute name="style" value="italic"/>
</attributes>
<accessibility>
<relation type="label-for" target="btn_load_image"/>
</accessibility>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
......@@ -293,9 +362,9 @@
</object>
</child>
<action-widgets>
<action-widget response="-11">help</action-widget>
<action-widget response="-6">cancel</action-widget>
<action-widget response="-5">ok</action-widget>
<action-widget response="-11">help</action-widget>
</action-widgets>
</object>
</interface>
......@@ -421,6 +421,7 @@ cui/uiconfig/ui/select_persona_dialog.ui://GtkButton[@id='result8'] button-no-la
cui/uiconfig/ui/select_persona_dialog.ui://GtkButton[@id='result9'] button-no-label
cui/uiconfig/ui/select_persona_dialog.ui://GtkLabel[@id='progress_label'] orphan-label
cui/uiconfig/ui/signsignatureline.ui://GtkTextView[@id='edit_comment'] duplicate-mnemonic
cui/uiconfig/ui/signsignatureline.ui://GtkLabel[@id='label_or'] orphan-label
cui/uiconfig/ui/specialcharacters.ui://GtkLabel[@id='hexulabel'] orphan-label
cui/uiconfig/ui/specialcharacters.ui://GtkDrawingArea[@id='viewchar2'] no-labelled-by
cui/uiconfig/ui/specialcharacters.ui://GtkDrawingArea[@id='viewchar3'] no-labelled-by
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment