1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <SignSignatureLineDialog.hxx>
12 #include <sal/log.hxx>
13 #include <sal/types.h>
15 #include <dialmgr.hxx>
16 #include <strings.hrc>
18 #include <comphelper/graphicmimetype.hxx>
19 #include <comphelper/processfactory.hxx>
20 #include <comphelper/propertyvalue.hxx>
21 #include <sfx2/filedlghelper.hxx>
22 #include <sfx2/objsh.hxx>
23 #include <svx/xoutbmp.hxx>
25 #include <vcl/graph.hxx>
26 #include <vcl/weld.hxx>
27 #include <svx/signaturelinehelper.hxx>
28 #include <tools/urlobj.hxx>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/graphic/GraphicProvider.hpp>
32 #include <com/sun/star/graphic/XGraphic.hpp>
33 #include <com/sun/star/graphic/XGraphicProvider.hpp>
34 #include <com/sun/star/security/CertificateKind.hpp>
35 #include <com/sun/star/security/XCertificate.hpp>
36 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
39 using namespace comphelper
;
41 using namespace css::uno
;
42 using namespace css::beans
;
43 using namespace css::frame
;
44 using namespace css::io
;
45 using namespace css::lang
;
46 using namespace css::frame
;
47 using namespace css::text
;
48 using namespace css::graphic
;
49 using namespace css::security
;
50 using namespace css::ui::dialogs
;
52 SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget
* pParent
, Reference
<XModel
> xModel
)
53 : SignatureLineDialogBase(pParent
, std::move(xModel
), "cui/ui/signsignatureline.ui",
54 "SignSignatureLineDialog")
55 , m_xEditName(m_xBuilder
->weld_entry("edit_name"))
56 , m_xEditComment(m_xBuilder
->weld_text_view("edit_comment"))
57 , m_xBtnLoadImage(m_xBuilder
->weld_button("btn_load_image"))
58 , m_xBtnClearImage(m_xBuilder
->weld_button("btn_clear_image"))
59 , m_xBtnChooseCertificate(m_xBuilder
->weld_button("btn_select_certificate"))
60 , m_xBtnSign(m_xBuilder
->weld_button("ok"))
61 , m_xLabelHint(m_xBuilder
->weld_label("label_hint"))
62 , m_xLabelHintText(m_xBuilder
->weld_label("label_hint_text"))
63 , m_xLabelAddComment(m_xBuilder
->weld_label("label_add_comment"))
64 , m_bShowSignDate(false)
66 Reference
<container::XIndexAccess
> xIndexAccess(m_xModel
->getCurrentSelection(),
68 m_xShapeProperties
.set(xIndexAccess
->getByIndex(0), UNO_QUERY_THROW
);
70 bool bIsSignatureLine(false);
71 m_xShapeProperties
->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine
;
72 if (!bIsSignatureLine
)
74 SAL_WARN("cui.dialogs", "No signature line selected!");
78 m_xBtnLoadImage
->connect_clicked(LINK(this, SignSignatureLineDialog
, loadImage
));
79 m_xBtnClearImage
->connect_clicked(LINK(this, SignSignatureLineDialog
, clearImage
));
80 m_xBtnChooseCertificate
->connect_clicked(
81 LINK(this, SignSignatureLineDialog
, chooseCertificate
));
82 m_xEditName
->connect_changed(LINK(this, SignSignatureLineDialog
, entryChanged
));
84 // Read properties from selected signature line
85 m_xShapeProperties
->getPropertyValue("SignatureLineId") >>= m_aSignatureLineId
;
86 m_xShapeProperties
->getPropertyValue("SignatureLineSuggestedSignerName")
87 >>= m_aSuggestedSignerName
;
88 m_xShapeProperties
->getPropertyValue("SignatureLineSuggestedSignerTitle")
89 >>= m_aSuggestedSignerTitle
;
90 OUString aSigningInstructions
;
91 m_xShapeProperties
->getPropertyValue("SignatureLineSigningInstructions")
92 >>= aSigningInstructions
;
93 m_xShapeProperties
->getPropertyValue("SignatureLineShowSignDate") >>= m_bShowSignDate
;
94 bool bCanAddComment(false);
95 m_xShapeProperties
->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment
;
97 if (aSigningInstructions
.isEmpty())
100 m_xLabelHintText
->hide();
104 m_xLabelHintText
->set_label(aSigningInstructions
);
109 m_xEditComment
->set_size_request(m_xEditComment
->get_approximate_digit_width() * 48,
110 m_xEditComment
->get_text_height() * 5);
114 m_xLabelAddComment
->hide();
115 m_xEditComment
->hide();
116 m_xEditComment
->set_size_request(0, 0);
122 IMPL_LINK_NOARG(SignSignatureLineDialog
, loadImage
, weld::Button
&, void)
124 Reference
<XComponentContext
> xContext
= comphelper::getProcessComponentContext();
125 sfx2::FileDialogHelper
aHelper(TemplateDescription::FILEOPEN_PREVIEW
, FileDialogFlags::NONE
,
127 aHelper
.SetContext(sfx2::FileDialogHelper::SignatureLine
);
128 Reference
<XFilePicker3
> xFilePicker
= aHelper
.GetFilePicker();
129 if (!xFilePicker
->execute())
132 Sequence
<OUString
> aSelectedFiles
= xFilePicker
->getSelectedFiles();
133 if (!aSelectedFiles
.hasElements())
136 Reference
<XGraphicProvider
> xProvider
= GraphicProvider::create(xContext
);
137 Sequence
<PropertyValue
> aMediaProperties
{ comphelper::makePropertyValue("URL",
138 aSelectedFiles
[0]) };
139 m_xSignatureImage
= xProvider
->queryGraphic(aMediaProperties
);
140 m_sOriginalImageBtnLabel
= m_xBtnLoadImage
->get_label();
142 INetURLObject
aObj(aSelectedFiles
[0]);
143 m_xBtnLoadImage
->set_label(aObj
.GetLastName());
148 IMPL_LINK_NOARG(SignSignatureLineDialog
, clearImage
, weld::Button
&, void)
150 m_xSignatureImage
.set(nullptr);
151 m_xBtnLoadImage
->set_label(m_sOriginalImageBtnLabel
);
155 IMPL_LINK_NOARG(SignSignatureLineDialog
, chooseCertificate
, weld::Button
&, void)
157 // Document needs to be saved before selecting a certificate
158 SfxObjectShell
* pShell
= SfxObjectShell::Current();
159 if (!pShell
|| !pShell
->PrepareForSigning(m_xDialog
.get()))
162 Reference
<XCertificate
> xSignCertificate
163 = svx::SignatureLineHelper::getSignatureCertificate(pShell
, m_xDialog
.get());
165 if (xSignCertificate
.is())
167 m_xSelectedCertifate
= xSignCertificate
;
168 m_xBtnChooseCertificate
->set_label(
169 svx::SignatureLineHelper::getSignerName(xSignCertificate
));
174 IMPL_LINK_NOARG(SignSignatureLineDialog
, entryChanged
, weld::Entry
&, void) { ValidateFields(); }
176 void SignSignatureLineDialog::ValidateFields()
178 bool bEnableSignBtn
= m_xSelectedCertifate
.is()
179 && (!m_xEditName
->get_text().isEmpty() || m_xSignatureImage
.is());
180 m_xBtnSign
->set_sensitive(bEnableSignBtn
);
182 m_xEditName
->set_sensitive(!m_xSignatureImage
.is());
183 m_xBtnLoadImage
->set_sensitive(m_xEditName
->get_text().isEmpty());
184 m_xBtnClearImage
->set_sensitive(m_xSignatureImage
.is());
187 void SignSignatureLineDialog::Apply()
189 if (!m_xSelectedCertifate
.is())
191 SAL_WARN("cui.dialogs", "No certificate selected!");
195 SfxObjectShell
* pShell
= SfxObjectShell::Current();
198 SAL_WARN("cui.dialogs", "No SfxObjectShell!");
202 Reference
<XGraphic
> xValidGraphic
= getSignedGraphic(true);
203 Reference
<XGraphic
> xInvalidGraphic
= getSignedGraphic(false);
204 pShell
->SignSignatureLine(m_xDialog
.get(), m_aSignatureLineId
, m_xSelectedCertifate
,
205 xValidGraphic
, xInvalidGraphic
, m_xEditComment
->get_text());
208 css::uno::Reference
<css::graphic::XGraphic
> SignSignatureLineDialog::getSignedGraphic(bool bValid
)
210 // Read svg and replace placeholder texts
211 OUString
aSvgImage(svx::SignatureLineHelper::getSignatureImage());
212 aSvgImage
= aSvgImage
.replaceAll("[SIGNER_NAME]", getCDataString(m_aSuggestedSignerName
));
213 aSvgImage
= aSvgImage
.replaceAll("[SIGNER_TITLE]", getCDataString(m_aSuggestedSignerTitle
));
216 = CuiResId(RID_CUISTR_SIGNATURELINE_SIGNED_BY
)
217 .replaceFirst("%1", svx::SignatureLineHelper::getSignerName(m_xSelectedCertifate
));
218 aSvgImage
= aSvgImage
.replaceAll("[SIGNED_BY]", getCDataString(aIssuerLine
));
220 aSvgImage
= aSvgImage
.replaceAll("[INVALID_SIGNATURE]", "");
223 if (m_bShowSignDate
&& bValid
)
225 aDate
= svx::SignatureLineHelper::getLocalizedDate();
227 aSvgImage
= aSvgImage
.replaceAll("[DATE]", aDate
);
229 // Custom signature image
230 if (m_xSignatureImage
.is())
232 OUString aGraphicInBase64
;
233 Graphic
aGraphic(m_xSignatureImage
);
234 if (!XOutBitmap::GraphicToBase64(aGraphic
, aGraphicInBase64
, false))
235 SAL_WARN("cui.dialogs", "Could not convert graphic to base64");
237 OUString aImagePart
= "<image y=\"825\" x=\"1300\" "
238 "xlink:href=\"data:[MIMETYPE];base64,[BASE64_IMG]>\" "
239 "preserveAspectRatio=\"xMidYMid\" height=\"1520\" "
241 aImagePart
= aImagePart
.replaceAll(
242 "[MIMETYPE]", GraphicMimeTypeHelper::GetMimeTypeForXGraphic(m_xSignatureImage
));
243 aImagePart
= aImagePart
.replaceAll("[BASE64_IMG]", aGraphicInBase64
);
244 aSvgImage
= aSvgImage
.replaceAll("[SIGNATURE_IMAGE]", aImagePart
);
246 aSvgImage
= aSvgImage
.replaceAll("[SIGNATURE]", "");
250 aSvgImage
= aSvgImage
.replaceAll("[SIGNATURE_IMAGE]", "");
251 aSvgImage
= aSvgImage
.replaceAll("[SIGNATURE]", getCDataString(m_xEditName
->get_text()));
255 return svx::SignatureLineHelper::importSVG(aSvgImage
);
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */