diff options
-rw-r--r-- | cui/source/dialogs/SignSignatureLineDialog.cxx | 87 | ||||
-rw-r--r-- | cui/source/dialogs/SignatureLineDialogBase.cxx | 3 | ||||
-rw-r--r-- | cui/source/inc/SignSignatureLineDialog.hxx | 6 | ||||
-rw-r--r-- | cui/uiconfig/ui/signsignatureline.ui | 73 | ||||
-rw-r--r-- | solenv/sanitizers/ui/cui.suppr | 1 |
5 files changed, 160 insertions, 10 deletions
diff --git a/cui/source/dialogs/SignSignatureLineDialog.cxx b/cui/source/dialogs/SignSignatureLineDialog.cxx index d35c5db3f98b..d189aabde24e 100644 --- a/cui/source/dialogs/SignSignatureLineDialog.cxx +++ b/cui/source/dialogs/SignSignatureLineDialog.cxx @@ -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)); diff --git a/cui/source/dialogs/SignatureLineDialogBase.cxx b/cui/source/dialogs/SignatureLineDialogBase.cxx index c0e7871e1291..4dadbf68e1b6 100644 --- a/cui/source/dialogs/SignatureLineDialogBase.cxx +++ b/cui/source/dialogs/SignatureLineDialogBase.cxx @@ -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; } diff --git a/cui/source/inc/SignSignatureLineDialog.hxx b/cui/source/inc/SignSignatureLineDialog.hxx index a78124bc2679..a12343c4ecd8 100644 --- a/cui/source/inc/SignSignatureLineDialog.hxx +++ b/cui/source/inc/SignSignatureLineDialog.hxx @@ -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); }; diff --git a/cui/uiconfig/ui/signsignatureline.ui b/cui/uiconfig/ui/signsignatureline.ui index c27f42108370..7e191688d967 100644 --- a/cui/uiconfig/ui/signsignatureline.ui +++ b/cui/uiconfig/ui/signsignatureline.ui @@ -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> diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr index 46597941bb8d..a78c3a762914 100644 --- a/solenv/sanitizers/ui/cui.suppr +++ b/solenv/sanitizers/ui/cui.suppr @@ -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 |