/src/libreoffice/svx/source/dialog/signaturelinehelper.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | */ |
9 | | |
10 | | #include <svx/signaturelinehelper.hxx> |
11 | | |
12 | | #include <com/sun/star/drawing/XShape.hpp> |
13 | | #include <com/sun/star/graphic/GraphicProvider.hpp> |
14 | | #include <com/sun/star/security/DocumentDigitalSignatures.hpp> |
15 | | |
16 | | #include <comphelper/processfactory.hxx> |
17 | | #include <comphelper/propertyvalue.hxx> |
18 | | #include <comphelper/sequenceashashmap.hxx> |
19 | | #include <comphelper/storagehelper.hxx> |
20 | | #include <comphelper/xmlsechelper.hxx> |
21 | | #include <config_folders.h> |
22 | | #include <rtl/bootstrap.hxx> |
23 | | #include <sal/log.hxx> |
24 | | #include <sfx2/docfile.hxx> |
25 | | #include <sfx2/docfilt.hxx> |
26 | | #include <sfx2/objsh.hxx> |
27 | | #include <svx/dialmgr.hxx> |
28 | | #include <svx/strings.hrc> |
29 | | #include <svx/svdmark.hxx> |
30 | | #include <svx/svdview.hxx> |
31 | | #include <tools/stream.hxx> |
32 | | #include <unotools/localedatawrapper.hxx> |
33 | | #include <unotools/streamwrap.hxx> |
34 | | #include <unotools/syslocale.hxx> |
35 | | #include <vcl/weld/weld.hxx> |
36 | | #include <sfx2/digitalsignatures.hxx> |
37 | | #include <sfx2/viewsh.hxx> |
38 | | |
39 | | using namespace com::sun::star; |
40 | | |
41 | | namespace svx::SignatureLineHelper |
42 | | { |
43 | | OUString getSignatureImage(const OUString& rType) |
44 | 0 | { |
45 | 0 | OUString aType = rType; |
46 | 0 | if (aType.isEmpty()) |
47 | 0 | { |
48 | 0 | aType = "signature-line.svg"; |
49 | 0 | } |
50 | 0 | OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/" + aType); |
51 | 0 | rtl::Bootstrap::expandMacros(aPath); |
52 | 0 | SvFileStream aStream(aPath, StreamMode::READ); |
53 | 0 | if (aStream.GetError() != ERRCODE_NONE) |
54 | 0 | { |
55 | 0 | SAL_WARN("cui.dialogs", "failed to open " << aType); |
56 | 0 | } |
57 | | |
58 | 0 | OString const svg = read_uInt8s_ToOString(aStream, aStream.remainingSize()); |
59 | 0 | return OUString::fromUtf8(svg); |
60 | 0 | } |
61 | | |
62 | | uno::Reference<security::XCertificate> |
63 | | getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld::Window* pParent) |
64 | 0 | { |
65 | 0 | if (!pShell) |
66 | 0 | { |
67 | 0 | return {}; |
68 | 0 | } |
69 | | |
70 | 0 | if (!pParent) |
71 | 0 | { |
72 | 0 | return {}; |
73 | 0 | } |
74 | | |
75 | 0 | uno::Reference<security::XDocumentDigitalSignatures> xSigner; |
76 | 0 | if (pShell->GetMedium()->GetFilter()->IsAlienFormat()) |
77 | 0 | { |
78 | 0 | xSigner = security::DocumentDigitalSignatures::createDefault( |
79 | 0 | comphelper::getProcessComponentContext()); |
80 | 0 | } |
81 | 0 | else |
82 | 0 | { |
83 | 0 | OUString const aODFVersion( |
84 | 0 | comphelper::OStorageHelper::GetODFVersionFromStorage(pShell->GetStorage())); |
85 | 0 | xSigner = security::DocumentDigitalSignatures::createWithVersion( |
86 | 0 | comphelper::getProcessComponentContext(), aODFVersion); |
87 | 0 | } |
88 | 0 | xSigner->setParentWindow(pParent->GetXWindow()); |
89 | 0 | OUString aDescription; |
90 | 0 | security::CertificateKind certificateKind = security::CertificateKind_NONE; |
91 | | // When signing ooxml, we only want X.509 certificates |
92 | 0 | if (pShell->GetMedium()->GetFilter()->IsAlienFormat()) |
93 | 0 | { |
94 | 0 | certificateKind = security::CertificateKind_X509; |
95 | 0 | } |
96 | 0 | auto xModelSigner = dynamic_cast<sfx2::DigitalSignatures*>(xSigner.get()); |
97 | 0 | assert(xModelSigner); |
98 | 0 | uno::Reference<security::XCertificate> xSignCertificate |
99 | 0 | = xModelSigner->SelectSigningCertificateWithType(pViewShell, certificateKind, aDescription); |
100 | 0 | return xSignCertificate; |
101 | 0 | } |
102 | | |
103 | | OUString getSignerName(const svl::crypto::CertificateOrName& rCertificateOrName) |
104 | 0 | { |
105 | 0 | if (rCertificateOrName.m_xCertificate.is()) |
106 | 0 | { |
107 | 0 | return comphelper::xmlsec::GetContentPart( |
108 | 0 | rCertificateOrName.m_xCertificate->getSubjectName(), |
109 | 0 | rCertificateOrName.m_xCertificate->getCertificateKind()); |
110 | 0 | } |
111 | | |
112 | 0 | return rCertificateOrName.m_aName; |
113 | 0 | } |
114 | | |
115 | | OUString getLocalizedDate() |
116 | 0 | { |
117 | 0 | const SvtSysLocale aSysLocale; |
118 | 0 | const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); |
119 | 0 | Date aDateTime(Date::SYSTEM); |
120 | 0 | return rLocaleData.getDate(aDateTime); |
121 | 0 | } |
122 | | |
123 | | uno::Reference<graphic::XGraphic> importSVG(std::u16string_view rSVG) |
124 | 0 | { |
125 | 0 | SvMemoryStream aSvgStream(4096, 4096); |
126 | 0 | aSvgStream.WriteOString(OUStringToOString(rSVG, RTL_TEXTENCODING_UTF8)); |
127 | 0 | uno::Reference<io::XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream)); |
128 | 0 | const uno::Reference<uno::XComponentContext>& xContext( |
129 | 0 | comphelper::getProcessComponentContext()); |
130 | 0 | uno::Reference<graphic::XGraphicProvider> xProvider |
131 | 0 | = graphic::GraphicProvider::create(xContext); |
132 | |
|
133 | 0 | uno::Sequence<beans::PropertyValue> aMediaProperties{ comphelper::makePropertyValue( |
134 | 0 | u"InputStream"_ustr, xInputStream) }; |
135 | 0 | uno::Reference<graphic::XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties)); |
136 | 0 | return xGraphic; |
137 | 0 | } |
138 | | |
139 | | void setShapeCertificate(SfxViewShell* pViewShell, |
140 | | const svl::crypto::CertificateOrName& rCertificateOrName) |
141 | 0 | { |
142 | 0 | const SdrView* pView = pViewShell->GetDrawView(); |
143 | 0 | const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); |
144 | 0 | if (rMarkList.GetMarkCount() < 1) |
145 | 0 | { |
146 | 0 | return; |
147 | 0 | } |
148 | | |
149 | 0 | const SdrMark* pMark = rMarkList.GetMark(0); |
150 | 0 | SdrObject* pSignatureLine = pMark->GetMarkedSdrObj(); |
151 | 0 | if (!pSignatureLine) |
152 | 0 | { |
153 | 0 | return; |
154 | 0 | } |
155 | | |
156 | | // Remember the selected certificate. |
157 | 0 | uno::Reference<drawing::XShape> xShape = pSignatureLine->getUnoShape(); |
158 | 0 | uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); |
159 | 0 | pViewShell->SetSignPDFCertificate(rCertificateOrName); |
160 | | |
161 | | // Read svg and replace placeholder texts. |
162 | 0 | OUString aSvgImage( |
163 | 0 | svx::SignatureLineHelper::getSignatureImage(u"signature-line-draw.svg"_ustr)); |
164 | 0 | aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", SvxResId(RID_SVXSTR_SIGNATURELINE_DSIGNED_BY)); |
165 | 0 | OUString aSignerName = svx::SignatureLineHelper::getSignerName(rCertificateOrName); |
166 | 0 | aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", aSignerName); |
167 | 0 | OUString aDate = svx::SignatureLineHelper::getLocalizedDate(); |
168 | 0 | aDate = SvxResId(RID_SVXSTR_SIGNATURELINE_DATE).replaceFirst("%1", aDate); |
169 | 0 | aSvgImage = aSvgImage.replaceAll("[DATE]", aDate); |
170 | |
|
171 | 0 | uno::Reference<graphic::XGraphic> xGraphic = svx::SignatureLineHelper::importSVG(aSvgImage); |
172 | 0 | xShapeProps->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic)); |
173 | 0 | } |
174 | | } |
175 | | |
176 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |