summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cui/source/dialogs/SignSignatureLineDialog.cxx87
-rw-r--r--cui/source/dialogs/SignatureLineDialogBase.cxx3
-rw-r--r--cui/source/inc/SignSignatureLineDialog.hxx6
-rw-r--r--cui/uiconfig/ui/signsignatureline.ui73
-rw-r--r--solenv/sanitizers/ui/cui.suppr1
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