cui/source/dialogs/SignSignatureLineDialog.cxx | 8 + desktop/source/lib/init.cxx | 7 - include/sfx2/objsh.hxx | 6 - include/sfx2/viewsh.hxx | 11 +- include/svl/cryptosign.hxx | 16 +++ include/svx/signaturelinehelper.hxx | 9 - sd/qa/unit/tiledrendering/data/empty.pdf |binary sd/qa/unit/tiledrendering/tiledrendering2.cxx | 56 +++++++++++ sd/sdi/_drvwsh.sdi | 1 sd/source/ui/func/fuconrec.cxx | 18 ++- sd/source/ui/func/fusel.cxx | 4 sd/source/ui/view/drviewse.cxx | 17 ++- sfx2/qa/cppunit/doc.cxx | 10 + sfx2/source/doc/objserv.cxx | 75 +------------- sfx2/source/view/viewfrm.cxx | 5 sfx2/source/view/viewimp.hxx | 3 sfx2/source/view/viewsh.cxx | 86 ++++++++++++++++- svl/source/crypto/cryptosign.cxx | 5 svx/qa/unit/data/empty.pdf |binary svx/qa/unit/svdraw.cxx | 85 ++++++++++++++++ svx/sdi/svx.sdi | 2 svx/source/dialog/signaturelinehelper.cxx | 25 ++-- svx/source/svdraw/svddrgv.cxx | 12 ++ svx/source/svdraw/svdedtv1.cxx | 4 svx/source/svdraw/svdmrkv.cxx | 12 ++ vcl/qa/cppunit/filter/ipdf/ipdf.cxx | 5 xmlsecurity/qa/unit/signing/signing.cxx | 5 xmlsecurity/source/dialogs/certificatechooser.cxx | 5 xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 2 xmlsecurity/source/helper/pdfsignaturehelper.cxx | 16 --- 30 files changed, 372 insertions(+), 138 deletions(-)
New commits: commit 3225bdeb523ab5c69448f7d32321e938208b0b21 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jan 16 08:58:27 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 12 10:43:33 2025 +0100 cool#10630 doc electronic sign: move signature line tracking to the view No functional changes intended: - Replace SfxObjectShell::GetSignPDFCertificate() and SfxObjectShell::ResetSignPDFCertificate() with SfxViewShell::SetSignPDFCertificate() and SfxViewShell::GetSignPDFCertificate(), because information about shape selection belongs to the view. - Change svx::SignatureLineHelper::setShapeCertificate() to use SfxViewShell::SetSignPDFCertificate() to avoid duplication. - Change GetSignatureLineShape() in xmlsecurity/ to use SfxViewShell::GetSignPDFCertificate(), again to avoid duplication. With this, all setters/getters of the inserted signature line go via SfxViewShell and the amount of getCurrentSelection() calls on the model is reduced. Change-Id: I021bc41262b2a16d1014fbf1431a0eb6e1e86c73 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180355 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 9fc11e799571..b686c2379e78 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5174,8 +5174,7 @@ static bool isCommandAllowed(OUString& command) { if (pViewShell && command == u".uno:TransformDialog"_ustr) { // If the just added signature line shape is selected, allow moving it. - SfxObjectShell* pDocShell = pViewShell->GetObjectShell(); - bRet = pDocShell->GetSignPDFCertificate().Is(); + bRet = pViewShell->GetSignPDFCertificate().Is(); } return bRet; } diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index d97ce8e13a38..1c9281b49b87 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -813,11 +813,6 @@ public: /// Is this read-only object shell opened via .uno:SignPDF? bool IsSignPDF() const; - /// Gets the certificate that is already picked by the user but not yet used for signing. - svl::crypto::CertificateOrName GetSignPDFCertificate() const; - - void ResetSignPDFCertificate(); - /// Gets grab-bagged password info to unprotect change tracking with verification css::uno::Sequence< css::beans::PropertyValue > GetDocumentProtectionFromGrabBag() const; diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index 9d64937d6dc5..ad988db09b4c 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -499,6 +499,12 @@ public: int getA11yCaretPosition() const; void SetSigningCertificate(const svl::crypto::CertificateOrName& rCertificateOrName); svl::crypto::CertificateOrName GetSigningCertificate() const; + + // These are used for visual signing: SetSignPDFCertificate() is called when the signature + // line is inserted, and GetSignPDFCertificate() is used by the signing code to get the already + // selected certificate. + void SetSignPDFCertificate(const svl::crypto::CertificateOrName& rCertificateOrName); + svl::crypto::CertificateOrName GetSignPDFCertificate() const; }; #endif // INCLUDED_SFX2_VIEWSH_HXX diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx index 25a4428ce1ad..89740a042540 100644 --- a/include/svl/cryptosign.hxx +++ b/include/svl/cryptosign.hxx @@ -129,7 +129,7 @@ public: OUString m_aName; /// Returns if a certificate or a name is set. - bool Is(); + bool Is() const; }; } diff --git a/include/svx/signaturelinehelper.hxx b/include/svx/signaturelinehelper.hxx index 6f17f3726dd2..e17d4ce148e6 100644 --- a/include/svx/signaturelinehelper.hxx +++ b/include/svx/signaturelinehelper.hxx @@ -61,7 +61,7 @@ SVX_DLLPUBLIC css::uno::Reference<css::graphic::XGraphic> importSVG(std::u16stri /** * Sets xCertificate as the signing certificate of the selected shape on pView. */ -SVX_DLLPUBLIC void setShapeCertificate(const SdrView* pView, +SVX_DLLPUBLIC void setShapeCertificate(SfxViewShell* pViewShell, const svl::crypto::CertificateOrName& rCertificateOrName); } diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx index 2e4e7a9cfcb2..af031550258f 100644 --- a/sd/source/ui/func/fuconrec.cxx +++ b/sd/source/ui/func/fuconrec.cxx @@ -512,7 +512,8 @@ void FuConstructRectangle::Deactivate() return; } - svl::crypto::CertificateOrName aCertificateOrName = mpViewShell->GetViewShell()->GetSigningCertificate(); + SfxViewShell* pViewShell = mpViewShell->GetViewShell(); + svl::crypto::CertificateOrName aCertificateOrName = pViewShell->GetSigningCertificate(); if (aCertificateOrName.m_aName.isEmpty()) { aCertificateOrName.m_xCertificate = svx::SignatureLineHelper::getSignatureCertificate( @@ -524,7 +525,7 @@ void FuConstructRectangle::Deactivate() } } - svx::SignatureLineHelper::setShapeCertificate(mpView, aCertificateOrName); + svx::SignatureLineHelper::setShapeCertificate(pViewShell, aCertificateOrName); // Update infobar to offer "finish signing". SfxViewFrame* pFrame = mpViewShell->GetViewFrame(); diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx index 8624c784fca5..bb6abf7dd8a3 100644 --- a/sd/source/ui/func/fusel.cxx +++ b/sd/source/ui/func/fusel.cxx @@ -205,7 +205,8 @@ bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt) bTextEdit = true; bool bPreventModify = mpDocSh->IsReadOnly(); - if (bPreventModify && mpDocSh->GetSignPDFCertificate().Is()) + SfxViewShell* pViewShell = mpViewShell->GetViewShell(); + if (bPreventModify && pViewShell && pViewShell->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow moving / resizing it. bPreventModify = false; diff --git a/sfx2/qa/cppunit/doc.cxx b/sfx2/qa/cppunit/doc.cxx index 2f9d79068d07..5b541fd28461 100644 --- a/sfx2/qa/cppunit/doc.cxx +++ b/sfx2/qa/cppunit/doc.cxx @@ -22,6 +22,7 @@ #include <comphelper/propertysequence.hxx> #include <comphelper/sequence.hxx> #include <svl/cryptosign.hxx> +#include <sfx2/viewsh.hxx> using namespace com::sun::star; @@ -53,14 +54,14 @@ CPPUNIT_TEST_FIXTURE(Test, testNoGrabBagShape) xController->select(aShape); // See if it has a signing certificate associated. - auto pBaseModel = dynamic_cast<SfxBaseModel*>(xModel.get()); - CPPUNIT_ASSERT(pBaseModel); - SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + SfxViewShell* pViewShell + = SfxViewShell::Get(uno::Reference<frame::XController>(xController, uno::UNO_QUERY)); + CPPUNIT_ASSERT(pViewShell); // Without the accompanying fix in place, this test would have failed with: // An uncaught exception of type com.sun.star.beans.UnknownPropertyException // which was not caught later, resulting in a crash. - pObjectShell->GetSignPDFCertificate(); + pViewShell->GetSignPDFCertificate(); } CPPUNIT_TEST_FIXTURE(Test, testTempFilePath) diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 3ba266116ba7..54c759c99eae 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -430,74 +430,6 @@ bool SfxObjectShell::IsSignPDF() const return false; } -namespace -{ -uno::Reference<beans::XPropertySet> GetSelectedShapeOfModel(const uno::Reference<frame::XModel>& xModel) -{ - if (!xModel.is()) - { - return uno::Reference<beans::XPropertySet>(); - } - - uno::Reference<drawing::XShapes> xShapes(xModel->getCurrentSelection(), uno::UNO_QUERY); - if (!xShapes.is() || xShapes->getCount() < 1) - { - return uno::Reference<beans::XPropertySet>(); - } - - uno::Reference<beans::XPropertySet> xShapeProps(xShapes->getByIndex(0), uno::UNO_QUERY); - return xShapeProps; -} -} - -svl::crypto::CertificateOrName SfxObjectShell::GetSignPDFCertificate() const -{ - uno::Reference<beans::XPropertySet> xShapeProps = GetSelectedShapeOfModel(GetBaseModel()); - if (!xShapeProps.is() || !xShapeProps->getPropertySetInfo()->hasPropertyByName(u"InteropGrabBag"_ustr)) - { - return {}; - } - - comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue(u"InteropGrabBag"_ustr)); - auto it = aMap.find(u"SignatureCertificate"_ustr); - if (it == aMap.end()) - { - return {}; - } - - svl::crypto::CertificateOrName aCertificateOrName; - if (it->second.has<uno::Reference<security::XCertificate>>()) - { - it->second >>= aCertificateOrName.m_xCertificate; - } - else - { - it->second >>= aCertificateOrName.m_aName; - } - return aCertificateOrName; -} - -void SfxObjectShell::ResetSignPDFCertificate() -{ - uno::Reference<beans::XPropertySet> xShapeProps = GetSelectedShapeOfModel(GetBaseModel()); - if (!xShapeProps->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) - { - return; - } - - comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue("InteropGrabBag")); - auto it = aMap.find("SignatureCertificate"); - if (it == aMap.end()) - { - return; - } - - aMap.erase(it); - xShapeProps->setPropertyValue("InteropGrabBag", uno::Any(aMap.getAsConstPropertyValueList())); - // The shape's property is now reset, so the doc model is no longer modified. - SetModified(false); -} - static void sendErrorToLOK(const ErrCodeMsg& error) { if (error.GetCode().GetClass() == ErrCodeClass::NONE) @@ -616,7 +548,9 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) if (SID_SIGNATURE == nId) { - uno::Reference<security::XCertificate> xCertificate = GetSignPDFCertificate().m_xCertificate; + SfxViewFrame* pFrame = GetFrame(); + SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; + uno::Reference<security::XCertificate> xCertificate = pViewShell ? pViewShell->GetSignPDFCertificate().m_xCertificate : nullptr; if (xCertificate.is()) { @@ -627,9 +561,9 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) // Reset the picked certificate for PDF signing, then recheck signatures to show how // the PDF actually looks like after signing. Also change the "finish signing" on // the infobar back to "sign document". - if (SfxViewFrame* pFrame = GetFrame()) + if (pViewShell) { - ResetSignPDFCertificate(); + pViewShell->SetSignPDFCertificate({}); RecheckSignature(false); pFrame->RemoveInfoBar(u"readonly"); pFrame->AppendReadOnlyInfobar(); @@ -676,8 +610,6 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) return; } - SfxViewFrame* pFrame = GetFrame(); - SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; if (pViewShell) { svl::crypto::CertificateOrName aCertificateOrName; diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 2a32b003d2b9..791996653298 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -1275,8 +1275,8 @@ void SfxViewFrame::AppendReadOnlyInfobar() bool bSignWithCert = false; if (bSignPDF) { - SfxObjectShell* pObjectShell = GetObjectShell(); - uno::Reference<security::XCertificate> xCertificate = pObjectShell->GetSignPDFCertificate().m_xCertificate; + SfxViewShell* pViewShell = GetViewShell(); + uno::Reference<security::XCertificate> xCertificate = pViewShell->GetSignPDFCertificate().m_xCertificate; bSignWithCert = xCertificate.is(); } diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index e42a69ea27aa..10dcb366eefc 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -47,6 +47,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/view/XRenderable.hpp> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> @@ -2817,6 +2818,83 @@ svl::crypto::CertificateOrName SfxViewShell::GetSigningCertificate() const return pImpl->m_aSigningCertificate; } +namespace +{ +uno::Reference<beans::XPropertySet> +GetSelectedShapeOfView(const uno::Reference<frame::XController>& xController) +{ + uno::Reference<view::XSelectionSupplier> xSelectionSupplier(xController, uno::UNO_QUERY); + uno::Reference<drawing::XShapes> xShapes(xSelectionSupplier->getSelection(), uno::UNO_QUERY); + if (!xShapes.is() || xShapes->getCount() != 1) + { + return {}; + } + + return uno::Reference<beans::XPropertySet>(xShapes->getByIndex(0), uno::UNO_QUERY); +} +} + +void SfxViewShell::SetSignPDFCertificate(const svl::crypto::CertificateOrName& rCertificateOrName) +{ + uno::Reference<beans::XPropertySet> xShape = GetSelectedShapeOfView(GetController()); + if (!xShape.is() || !xShape->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) + { + return; + } + + comphelper::SequenceAsHashMap aMap(xShape->getPropertyValue("InteropGrabBag")); + + auto it = aMap.find("SignatureCertificate"); + if (rCertificateOrName.Is()) + { + if (rCertificateOrName.m_xCertificate.is()) + { + aMap["SignatureCertificate"] <<= rCertificateOrName.m_xCertificate; + } + else + { + aMap["SignatureCertificate"] <<= rCertificateOrName.m_aName; + } + } + else if (it != aMap.end()) + { + aMap.erase(it); + } + xShape->setPropertyValue("InteropGrabBag", uno::Any(aMap.getAsConstPropertyValueList())); + if (!rCertificateOrName.Is()) + { + // The shape's property is now reset, so the doc model is no longer modified. + GetObjectShell()->SetModified(false); + } +} + +svl::crypto::CertificateOrName SfxViewShell::GetSignPDFCertificate() const +{ + uno::Reference<beans::XPropertySet> xShape = GetSelectedShapeOfView(GetController()); + if (!xShape.is() || !xShape->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) + { + return {}; + } + + comphelper::SequenceAsHashMap aMap(xShape->getPropertyValue("InteropGrabBag")); + auto it = aMap.find("SignatureCertificate"); + if (it == aMap.end()) + { + return {}; + } + + svl::crypto::CertificateOrName aCertificateOrName; + if (it->second.has<uno::Reference<security::XCertificate>>()) + { + it->second >>= aCertificateOrName.m_xCertificate; + } + else + { + it->second >>= aCertificateOrName.m_aName; + } + return aCertificateOrName; +} + bool SfxViewShell::PrepareClose ( bool bUI // TRUE: Allow Dialog and so on, FALSE: silent-mode diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 377214a05da2..f053d25134e5 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -2404,7 +2404,7 @@ void Signing::appendHex(sal_Int8 nInt, OStringBuffer& rBuffer) rBuffer.append( pHexDigits[ nInt & 15 ] ); } -bool CertificateOrName::Is() +bool CertificateOrName::Is() const { return m_xCertificate.is() || !m_aName.isEmpty(); } diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index e2c6b58a9dac..b3262e588e94 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -862,10 +862,11 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testVisualSignResize) { return; } - SdrView* pView = SfxViewShell::Current()->GetDrawView(); + SfxViewShell* pViewShell + = SfxViewShell::Get(uno::Reference<frame::XController>(xController, uno::UNO_QUERY)); svl::crypto::CertificateOrName aCertificateOrName; aCertificateOrName.m_xCertificate = xCert; - svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); + svx::SignatureLineHelper::setShapeCertificate(pViewShell, aCertificateOrName); pObjectShell->SetModified(false); // When resizing the shape by moving the bottom right (last) handle towards top right: diff --git a/svx/source/dialog/signaturelinehelper.cxx b/svx/source/dialog/signaturelinehelper.cxx index d8a41e8d3cc7..d4f286995f2b 100644 --- a/svx/source/dialog/signaturelinehelper.cxx +++ b/svx/source/dialog/signaturelinehelper.cxx @@ -34,6 +34,7 @@ #include <unotools/syslocale.hxx> #include <vcl/weld.hxx> #include <sfx2/digitalsignatures.hxx> +#include <sfx2/viewsh.hxx> using namespace com::sun::star; @@ -135,9 +136,10 @@ uno::Reference<graphic::XGraphic> importSVG(std::u16string_view rSVG) return xGraphic; } -void setShapeCertificate(const SdrView* pView, +void setShapeCertificate(SfxViewShell* pViewShell, const svl::crypto::CertificateOrName& rCertificateOrName) { + const SdrView* pView = pViewShell->GetDrawView(); const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); if (rMarkList.GetMarkCount() < 1) { @@ -154,16 +156,7 @@ void setShapeCertificate(const SdrView* pView, // Remember the selected certificate. uno::Reference<drawing::XShape> xShape = pSignatureLine->getUnoShape(); uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); - comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue(u"InteropGrabBag"_ustr)); - if (rCertificateOrName.m_xCertificate.is()) - { - aMap[u"SignatureCertificate"_ustr] <<= rCertificateOrName.m_xCertificate; - } - else - { - aMap[u"SignatureCertificate"_ustr] <<= rCertificateOrName.m_aName; - } - xShapeProps->setPropertyValue("InteropGrabBag", uno::Any(aMap.getAsConstPropertyValueList())); + pViewShell->SetSignPDFCertificate(rCertificateOrName); // Read svg and replace placeholder texts. OUString aSvgImage( diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index 02cfc5ee38c8..645cb8fd2bef 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -415,8 +415,7 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl { bool bResizeAllowed = IsResizeAllowed(true); SfxViewShell* pViewShell = GetSfxViewShell(); - SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (!bResizeAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().Is()) + if (!bResizeAllowed && pViewShell && pViewShell->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow resizing it. bResizeAllowed = true; diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index 2e7cbe6c5c7d..d35ace8a11bc 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -1829,8 +1829,7 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr, bool addPageMargin // change position bool bMoveAllowed = m_bMoveAllowed; SfxViewShell* pViewShell = GetSfxViewShell(); - SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (!bMoveAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().Is()) + if (!bMoveAllowed && pViewShell && pViewShell->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow moving it. bMoveAllowed = true; diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index c4f096dd04a8..0e24fe898e3f 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -1116,7 +1116,7 @@ void SdrMarkView::SetMarkHandlesForLOKit(tools::Rectangle const & rRect, const S else { SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (pObjectShell && pObjectShell->IsSignPDF() && pObjectShell->GetSignPDFCertificate().Is()) + if (pObjectShell && pObjectShell->IsSignPDF() && pViewShell && pViewShell->GetSignPDFCertificate().Is()) { // Expose the info that this is the special signature widget that is OK to // move/resize. diff --git a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx index 9964ec88dfb2..243687dad00b 100644 --- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx +++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx @@ -102,10 +102,9 @@ CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testPDFAddVisibleSignatureLastPage) } SfxViewShell* pCurrent = SfxViewShell::Current(); CPPUNIT_ASSERT(pCurrent); - SdrView* pView = pCurrent->GetDrawView(); svl::crypto::CertificateOrName aCertificateOrName; aCertificateOrName.m_xCertificate = xCert; - svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); + svx::SignatureLineHelper::setShapeCertificate(pCurrent, aCertificateOrName); // the document is modified now, but Sign function can't show SaveAs dialog // in unit test, so just clear the modified diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index 82a7d2a1ae73..bb2c4d5df992 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -773,10 +773,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testPDFAddVisibleSignature) } SfxViewShell* pCurrent = SfxViewShell::Current(); CPPUNIT_ASSERT(pCurrent); - SdrView* pView = pCurrent->GetDrawView(); svl::crypto::CertificateOrName aCertificateOrName; aCertificateOrName.m_xCertificate = xCert; - svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); + svx::SignatureLineHelper::setShapeCertificate(pCurrent, aCertificateOrName); // the document is modified now, but Sign function can't show SaveAs dialog // in unit test, so just clear the modified diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx index 79ee45c0e3c3..8d316bcffd91 100644 --- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx +++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx @@ -33,6 +33,7 @@ #include <vcl/checksum.hxx> #include <svl/cryptosign.hxx> #include <vcl/filter/PDFiumLibrary.hxx> +#include <sfx2/viewsh.hxx> using namespace ::com::sun::star; @@ -70,21 +71,14 @@ void GetSignatureLineShape(const uno::Reference<frame::XModel>& xModel, sal_Int3 return; } - uno::Reference<drawing::XShapes> xShapes(xModel->getCurrentSelection(), uno::UNO_QUERY); - if (!xShapes.is() || xShapes->getCount() < 1) - { - return; - } - - uno::Reference<beans::XPropertySet> xShapeProps(xShapes->getByIndex(0), uno::UNO_QUERY); - if (!xShapeProps.is()) + SfxViewShell* pViewShell = SfxViewShell::Get(xModel->getCurrentController()); + if (!pViewShell || !pViewShell->GetSignPDFCertificate().Is()) { return; } - comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue(u"InteropGrabBag"_ustr)); - auto it = aMap.find(u"SignatureCertificate"_ustr); - if (it == aMap.end()) + uno::Reference<drawing::XShapes> xShapes(xModel->getCurrentSelection(), uno::UNO_QUERY); + if (!xShapes.is() || xShapes->getCount() < 1) { return; } commit 7f791b643244a34d6fcaf44b420ebfc0af91ada7 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jan 15 09:32:30 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 12 10:43:33 2025 +0100 cool#10630 doc electronic sign: fix no graphic selection for the signature line Insert a signature line in "extern" mode, the shape gets selected but there is no graphic selection at a LOK API level. This is because GetSignPDFCertificate() returned an XCertificate, which is empty in the external signing case, so we can't differentiate between no signing and external signing. Fix this by changing the return type to svl::crypto::CertificateOrName, this way SdrMarkView::SetMarkHandlesForLOKit() can annotate the signature line correctly even in the external signing case. The tracking of the signature line selection is still in the model (not in the view), that's not yet fixed here. Change-Id: I4ef9c1fa0a88af0c0fcd55156b973a3705f985c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180296 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index f6fd9ca3fb9d..9fc11e799571 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5175,7 +5175,7 @@ static bool isCommandAllowed(OUString& command) { { // If the just added signature line shape is selected, allow moving it. SfxObjectShell* pDocShell = pViewShell->GetObjectShell(); - bRet = pDocShell->GetSignPDFCertificate().is(); + bRet = pDocShell->GetSignPDFCertificate().Is(); } return bRet; } diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index 83e0fac51af8..d97ce8e13a38 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -111,6 +111,7 @@ namespace com::sun::star::security { struct DocumentSignatureInformation; } namespace com::sun::star::task { class XInteractionHandler; } namespace com::sun::star::lang { class XComponent; } namespace com::sun::star::text { class XTextRange; } +namespace svl::crypto { class CertificateOrName; } #define SFX_TITLE_TITLE 0 #define SFX_TITLE_FILENAME 1 @@ -813,7 +814,7 @@ public: bool IsSignPDF() const; /// Gets the certificate that is already picked by the user but not yet used for signing. - css::uno::Reference<css::security::XCertificate> GetSignPDFCertificate() const; + svl::crypto::CertificateOrName GetSignPDFCertificate() const; void ResetSignPDFCertificate(); diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx index 291201cd394a..25a4428ce1ad 100644 --- a/include/svl/cryptosign.hxx +++ b/include/svl/cryptosign.hxx @@ -127,6 +127,9 @@ public: /// Otherwise we don't have a certificate but have a name to be featured on the visual /// signature. OUString m_aName; + + /// Returns if a certificate or a name is set. + bool Is(); }; } diff --git a/sd/qa/unit/tiledrendering/tiledrendering2.cxx b/sd/qa/unit/tiledrendering/tiledrendering2.cxx index bf9f7db738a4..5b56c5033966 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering2.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering2.cxx @@ -47,9 +47,11 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testInsertSignatureLineExternal) uno::Sequence<beans::PropertyValue> aArgs = { comphelper::makePropertyValue("ReadOnly", true) }; loadWithParams(createFileURL(u"empty.pdf"), aArgs); SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + pImpressDocument->initializeForTiledRendering({}); sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell(); sd::View* pView = pViewShell->GetView(); pView->SetAuthor("myauthor"); + ViewCallback aView; // When insrerting a signature line for electronic (extrenal) signing: aArgs = { @@ -66,6 +68,28 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testInsertSignatureLineExternal) aMarkedObjects[0]->GetGrabBagItem(aAny); comphelper::SequenceAsHashMap aMap(aAny); CPPUNIT_ASSERT(aMap.contains("SignatureCertificate")); + // Also verify that this is exposed at a LOK level: + OString aShapeSelection = "[" + aView.m_ShapeSelection + "]"; + const char* pShapeSelectionStr = aShapeSelection.getStr(); + std::stringstream aStream(pShapeSelectionStr); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + int nCount = 0; + bool bSignature = false; + for (const auto& i : aTree) + { + ++nCount; + if (nCount <= 5) + { + // x, y, w, h, part + continue; + } + boost::property_tree::ptree aProps = i.second; + // Without the accompanying fix in place, this test would have failed with: + // - No such node (isSignature) + bSignature = aProps.get<bool>("isSignature"); + } + CPPUNIT_ASSERT(bSignature); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx index aa43a76ee91b..8624c784fca5 100644 --- a/sd/source/ui/func/fusel.cxx +++ b/sd/source/ui/func/fusel.cxx @@ -61,6 +61,7 @@ #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <comphelper/lok.hxx> +#include <svl/cryptosign.hxx> using namespace ::com::sun::star; @@ -204,7 +205,7 @@ bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt) bTextEdit = true; bool bPreventModify = mpDocSh->IsReadOnly(); - if (bPreventModify && mpDocSh->GetSignPDFCertificate().is()) + if (bPreventModify && mpDocSh->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow moving / resizing it. bPreventModify = false; diff --git a/sfx2/qa/cppunit/doc.cxx b/sfx2/qa/cppunit/doc.cxx index b16c078ef412..2f9d79068d07 100644 --- a/sfx2/qa/cppunit/doc.cxx +++ b/sfx2/qa/cppunit/doc.cxx @@ -21,6 +21,7 @@ #include <comphelper/sequenceashashmap.hxx> #include <comphelper/propertysequence.hxx> #include <comphelper/sequence.hxx> +#include <svl/cryptosign.hxx> using namespace com::sun::star; diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 6741e09623c2..3ba266116ba7 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -450,22 +450,31 @@ uno::Reference<beans::XPropertySet> GetSelectedShapeOfModel(const uno::Reference } } -uno::Reference<security::XCertificate> SfxObjectShell::GetSignPDFCertificate() const +svl::crypto::CertificateOrName SfxObjectShell::GetSignPDFCertificate() const { uno::Reference<beans::XPropertySet> xShapeProps = GetSelectedShapeOfModel(GetBaseModel()); if (!xShapeProps.is() || !xShapeProps->getPropertySetInfo()->hasPropertyByName(u"InteropGrabBag"_ustr)) { - return uno::Reference<security::XCertificate>(); + return {}; } comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue(u"InteropGrabBag"_ustr)); auto it = aMap.find(u"SignatureCertificate"_ustr); if (it == aMap.end()) { - return uno::Reference<security::XCertificate>(); + return {}; } - return uno::Reference<security::XCertificate>(it->second, uno::UNO_QUERY); + svl::crypto::CertificateOrName aCertificateOrName; + if (it->second.has<uno::Reference<security::XCertificate>>()) + { + it->second >>= aCertificateOrName.m_xCertificate; + } + else + { + it->second >>= aCertificateOrName.m_aName; + } + return aCertificateOrName; } void SfxObjectShell::ResetSignPDFCertificate() @@ -607,7 +616,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) if (SID_SIGNATURE == nId) { - uno::Reference<security::XCertificate> xCertificate = GetSignPDFCertificate(); + uno::Reference<security::XCertificate> xCertificate = GetSignPDFCertificate().m_xCertificate; if (xCertificate.is()) { diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index e70cceeffe70..2a32b003d2b9 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -132,6 +132,7 @@ #include "impviewframe.hxx" #include <vcl/commandinfoprovider.hxx> #include <vcl/svapp.hxx> +#include <svl/cryptosign.hxx> #define ShellClass_SfxViewFrame #include <sfxslots.hxx> @@ -1275,7 +1276,7 @@ void SfxViewFrame::AppendReadOnlyInfobar() if (bSignPDF) { SfxObjectShell* pObjectShell = GetObjectShell(); - uno::Reference<security::XCertificate> xCertificate = pObjectShell->GetSignPDFCertificate(); + uno::Reference<security::XCertificate> xCertificate = pObjectShell->GetSignPDFCertificate().m_xCertificate; bSignWithCert = xCertificate.is(); } diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 6a5f08077765..377214a05da2 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -2403,6 +2403,11 @@ void Signing::appendHex(sal_Int8 nInt, OStringBuffer& rBuffer) rBuffer.append( pHexDigits[ (nInt >> 4) & 15 ] ); rBuffer.append( pHexDigits[ nInt & 15 ] ); } + +bool CertificateOrName::Is() +{ + return m_xCertificate.is() || !m_aName.isEmpty(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index 9b05f0206539..02cfc5ee38c8 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -40,6 +40,7 @@ #include <officecfg/Office/Common.hxx> #include <sfx2/objsh.hxx> #include <sfx2/viewsh.hxx> +#include <svl/cryptosign.hxx> using namespace sdr; @@ -415,7 +416,7 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl bool bResizeAllowed = IsResizeAllowed(true); SfxViewShell* pViewShell = GetSfxViewShell(); SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (!bResizeAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().is()) + if (!bResizeAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow resizing it. bResizeAllowed = true; diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index 00034815fb7b..2e7cbe6c5c7d 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -70,6 +70,7 @@ #include <comphelper/lok.hxx> #include <osl/diagnose.h> #include <sfx2/objsh.hxx> +#include <svl/cryptosign.hxx> // EditView @@ -1829,7 +1830,7 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr, bool addPageMargin bool bMoveAllowed = m_bMoveAllowed; SfxViewShell* pViewShell = GetSfxViewShell(); SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (!bMoveAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().is()) + if (!bMoveAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().Is()) { // If the just added signature line shape is selected, allow moving it. bMoveAllowed = true; diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index 8ba5583853a1..c4f096dd04a8 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -65,6 +65,7 @@ #include <svtools/optionsdrawinglayer.hxx> #include <drawinglayer/processor2d/textextractor2d.hxx> +#include <svl/cryptosign.hxx> #include <array> @@ -1115,7 +1116,7 @@ void SdrMarkView::SetMarkHandlesForLOKit(tools::Rectangle const & rRect, const S else { SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; - if (pObjectShell && pObjectShell->IsSignPDF() && pObjectShell->GetSignPDFCertificate().is()) + if (pObjectShell && pObjectShell->IsSignPDF() && pObjectShell->GetSignPDFCertificate().Is()) { // Expose the info that this is the special signature widget that is OK to // move/resize. commit 00d0ab590fb38bcb1425bd7e601b202b41ffdae1 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Jan 13 11:18:12 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 12 10:43:33 2025 +0100 cool#10630 doc electronic sign: fix insertion of the signature line Have electronic signing configured in the LOK client, try to insert a signature line, you'll get a certificate picker, while we don't have a cert during esign. What's in fact needed for creating the signature line is just a name (previously extracted from the certificate), we can survive the lack of actual certificate. Fix the problem by adding a new External parameter to .uno:InsertSignatureLine to hint that the certificate chooser should not be opened, instead the editor name (used for comments already) should be used. Add a new CertificateOrName in svl/ and use that in all places where previously we wanted a certificate but in fact it's enough to have a certificate or a name to create the signature line. The name on the signature line is just visual feedback, the actual name on the crypto signature is still not based on untrusted used input. Change-Id: Ib7008112a8e28a9e7d9649745e6021dd6b6b9c39 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180193 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/cui/source/dialogs/SignSignatureLineDialog.cxx b/cui/source/dialogs/SignSignatureLineDialog.cxx index a1cf837c107c..cb6a7191c436 100644 --- a/cui/source/dialogs/SignSignatureLineDialog.cxx +++ b/cui/source/dialogs/SignSignatureLineDialog.cxx @@ -163,8 +163,10 @@ IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, weld::Button&, void) if (xSignCertificate.is()) { m_xSelectedCertifate = xSignCertificate; + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = xSignCertificate; m_xBtnChooseCertificate->set_label( - svx::SignatureLineHelper::getSignerName(xSignCertificate)); + svx::SignatureLineHelper::getSignerName(aCertificateOrName)); } ValidateFields(); } @@ -210,9 +212,11 @@ css::uno::Reference<css::graphic::XGraphic> SignSignatureLineDialog::getSignedGr aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(m_aSuggestedSignerName)); aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(m_aSuggestedSignerTitle)); + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = m_xSelectedCertifate; OUString aIssuerLine = CuiResId(RID_CUISTR_SIGNATURELINE_SIGNED_BY) - .replaceFirst("%1", svx::SignatureLineHelper::getSignerName(m_xSelectedCertifate)); + .replaceFirst("%1", svx::SignatureLineHelper::getSignerName(aCertificateOrName)); aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", getCDataString(aIssuerLine)); if (bValid) aSvgImage = aSvgImage.replaceAll("[INVALID_SIGNATURE]", ""); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 14f260a0e52e..f6fd9ca3fb9d 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -4513,7 +4513,9 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis, uno::Reference<security::XCertificate> xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); if (SfxViewShell* pViewShell = SfxViewShell::Current()) { - pViewShell->SetSigningCertificate(xCertificate); + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = xCertificate; + pViewShell->SetSigningCertificate(aCertificateOrName); } } diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index bfd43c67101e..9d64937d6dc5 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -76,6 +76,7 @@ namespace com::sun::star::view { class XRenderable; } namespace com::sun::star::security { class XCertificate; } namespace tools { class Rectangle; } namespace svtools { enum ColorConfigEntry : int; } +namespace svl::crypto { class CertificateOrName; } enum class SfxPrinterChangeFlags { @@ -496,8 +497,8 @@ public: OUString getA11yFocusedParagraph() const; int getA11yCaretPosition() const; - void SetSigningCertificate(const css::uno::Reference<css::security::XCertificate>& xCertificate); - const css::uno::Reference<css::security::XCertificate> & GetSigningCertificate() const; + void SetSigningCertificate(const svl::crypto::CertificateOrName& rCertificateOrName); + svl::crypto::CertificateOrName GetSigningCertificate() const; }; #endif // INCLUDED_SFX2_VIEWSH_HXX diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx index 8c8e48f0da54..291201cd394a 100644 --- a/include/svl/cryptosign.hxx +++ b/include/svl/cryptosign.hxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#pragma once + #include <sal/types.h> #include <utility> @@ -116,6 +118,17 @@ public: std::vector<unsigned char> m_aSignatureValue; }; +/// Used for visual signing: an XCertificate or a signer name. +class SVL_DLLPUBLIC CertificateOrName +{ +public: + /// If set, the certificate used for signing. + css::uno::Reference<css::security::XCertificate> m_xCertificate; + /// Otherwise we don't have a certificate but have a name to be featured on the visual + /// signature. + OUString m_aName; +}; + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/svx/signaturelinehelper.hxx b/include/svx/signaturelinehelper.hxx index e8105a37bd7f..6f17f3726dd2 100644 --- a/include/svx/signaturelinehelper.hxx +++ b/include/svx/signaturelinehelper.hxx @@ -16,6 +16,7 @@ #include <rtl/ustring.hxx> #include <svx/svxdllapi.h> +#include <svl/cryptosign.hxx> #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/security/XCertificate.hpp> @@ -45,8 +46,7 @@ getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld:: /** * Get a signer name out of a certificate. */ -SVX_DLLPUBLIC OUString -getSignerName(const css::uno::Reference<css::security::XCertificate>& xCertificate); +SVX_DLLPUBLIC OUString getSignerName(const svl::crypto::CertificateOrName& rCertificateOrName); /** * Gets a localized date string. @@ -61,9 +61,8 @@ SVX_DLLPUBLIC css::uno::Reference<css::graphic::XGraphic> importSVG(std::u16stri /** * Sets xCertificate as the signing certificate of the selected shape on pView. */ -SVX_DLLPUBLIC void -setShapeCertificate(const SdrView* pView, - const css::uno::Reference<css::security::XCertificate>& xCertificate); +SVX_DLLPUBLIC void setShapeCertificate(const SdrView* pView, + const svl::crypto::CertificateOrName& rCertificateOrName); } #endif diff --git a/sd/qa/unit/tiledrendering/data/empty.pdf b/sd/qa/unit/tiledrendering/data/empty.pdf new file mode 100644 index 000000000000..d6142103184b Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/empty.pdf differ diff --git a/sd/qa/unit/tiledrendering/tiledrendering2.cxx b/sd/qa/unit/tiledrendering/tiledrendering2.cxx index 28860a293b41..bf9f7db738a4 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering2.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering2.cxx @@ -11,6 +11,11 @@ #include <sfx2/sidebar/Sidebar.hxx> #include <vcl/scheduler.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/sequenceashashmap.hxx> + +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSidebarSwitchDeck) { @@ -36,6 +41,33 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSidebarSwitchDeck) CPPUNIT_ASSERT(it != aView.m_aStateChanges.end()); } +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testInsertSignatureLineExternal) +{ + // Given a PDF to be signed: + uno::Sequence<beans::PropertyValue> aArgs = { comphelper::makePropertyValue("ReadOnly", true) }; + loadWithParams(createFileURL(u"empty.pdf"), aArgs); + SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell(); + sd::View* pView = pViewShell->GetView(); + pView->SetAuthor("myauthor"); + + // When insrerting a signature line for electronic (extrenal) signing: + aArgs = { + comphelper::makePropertyValue("External", true), + }; + // Without the accompanying fix in place, this test would hang here in the certificate chooser + // dialog. + dispatchCommand(mxComponent, ".uno:InsertSignatureLine", aArgs); + + // Then make sure the shape is marked as a signature line: + std::vector<SdrObject*> aMarkedObjects = pView->GetMarkedObjects(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMarkedObjects.size()); + uno::Any aAny; + aMarkedObjects[0]->GetGrabBagItem(aAny); + comphelper::SequenceAsHashMap aMap(aAny); + CPPUNIT_ASSERT(aMap.contains("SignatureCertificate")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx index 5cbdb1e82596..2e4e7a9cfcb2 100644 --- a/sd/source/ui/func/fuconrec.cxx +++ b/sd/source/ui/func/fuconrec.cxx @@ -512,16 +512,19 @@ void FuConstructRectangle::Deactivate() return; } - uno::Reference<security::XCertificate> xCertificate - = svx::SignatureLineHelper::getSignatureCertificate(mpViewShell->GetObjectShell(), - mpViewShell->GetViewShell(), - mpViewShell->GetFrameWeld()); - if (!xCertificate.is()) + svl::crypto::CertificateOrName aCertificateOrName = mpViewShell->GetViewShell()->GetSigningCertificate(); + if (aCertificateOrName.m_aName.isEmpty()) { - return; + aCertificateOrName.m_xCertificate = svx::SignatureLineHelper::getSignatureCertificate( + mpViewShell->GetObjectShell(), mpViewShell->GetViewShell(), + mpViewShell->GetFrameWeld()); + if (!aCertificateOrName.m_xCertificate.is()) + { + return; + } } - svx::SignatureLineHelper::setShapeCertificate(mpView, xCertificate); + svx::SignatureLineHelper::setShapeCertificate(mpView, aCertificateOrName); // Update infobar to offer "finish signing". SfxViewFrame* pFrame = mpViewShell->GetViewFrame(); diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx index ea2f65a01c00..f9466b51a3d1 100644 --- a/sd/source/ui/view/drviewse.cxx +++ b/sd/source/ui/view/drviewse.cxx @@ -61,6 +61,7 @@ #include <sfx2/docfile.hxx> #include <sfx2/notebookbar/SfxNotebookBar.hxx> #include <osl/diagnose.h> +#include <svl/cryptosign.hxx> #include <DrawViewShell.hxx> #include <slideshow.hxx> @@ -471,18 +472,28 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq) { aSignatureKey = pSignatureKey->GetValue().toUtf8(); } + bool bExternal = false; + const SfxBoolItem* pExternal = rReq.GetArg<SfxBoolItem>(FN_PARAM_3); + if (pExternal) + { + bExternal = pExternal->GetValue(); + } SfxViewFrame* pFrame = GetFrame(); SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; if (pViewShell) { - uno::Reference<security::XCertificate> xSigningCertificate; + svl::crypto::CertificateOrName aCertificateOrName; if (!aSignatureCert.empty() && !aSignatureKey.empty()) { - xSigningCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); + aCertificateOrName.m_xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); + } + else if (bExternal) + { + aCertificateOrName.m_aName = mpDrawView->GetAuthor(); } // Always set the signing certificate, to clear data from a previous dispatch. - pViewShell->SetSigningCertificate(xSigningCertificate); + pViewShell->SetSigningCertificate(aCertificateOrName); } } diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index c18da34283ef..6741e09623c2 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -671,13 +671,13 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; if (pViewShell) { - uno::Reference<security::XCertificate> xSigningCertificate; + svl::crypto::CertificateOrName aCertificateOrName; if (!aSignatureCert.empty() && !aSignatureKey.empty()) { - xSigningCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); + aCertificateOrName.m_xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); } // Always set the signing certificate, to clear data from a previous dispatch. - pViewShell->SetSigningCertificate(xSigningCertificate); + pViewShell->SetSigningCertificate(aCertificateOrName); } // Async, all code before return has to go into the callback. diff --git a/sfx2/source/view/viewimp.hxx b/sfx2/source/view/viewimp.hxx index 1dc24eec7a82..83279ae84cee 100644 --- a/sfx2/source/view/viewimp.hxx +++ b/sfx2/source/view/viewimp.hxx @@ -28,6 +28,7 @@ #include <svtools/acceleratorexecute.hxx> #include <rtl/ref.hxx> #include <vcl/print.hxx> +#include <svl/cryptosign.hxx> #include <chrono> #include <vector> @@ -59,7 +60,7 @@ struct SfxViewShell_Impl static sal_uInt32 m_nLastViewShellId; const ViewShellId m_nViewShellId; const ViewShellDocId m_nDocId; - css::uno::Reference<css::security::XCertificate> m_xSigningCertificate; + svl::crypto::CertificateOrName m_aSigningCertificate; explicit SfxViewShell_Impl(SfxViewShellFlags const nFlags, ViewShellDocId nDocId); ~SfxViewShell_Impl(); diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index d743cd5ddd02..e42a69ea27aa 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -2807,14 +2807,14 @@ int SfxViewShell::getA11yCaretPosition() const return rDocFocusListener.getCaretPosition(); } -void SfxViewShell::SetSigningCertificate(const uno::Reference<security::XCertificate>& xCertificate) +void SfxViewShell::SetSigningCertificate(const svl::crypto::CertificateOrName& rCertificate) { - pImpl->m_xSigningCertificate = xCertificate; + pImpl->m_aSigningCertificate = rCertificate; } -const uno::Reference<security::XCertificate> & SfxViewShell::GetSigningCertificate() const +svl::crypto::CertificateOrName SfxViewShell::GetSigningCertificate() const { - return pImpl->m_xSigningCertificate; + return pImpl->m_aSigningCertificate; } bool SfxViewShell::PrepareClose diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index 6cf4c6bc10f3..e2c6b58a9dac 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -863,7 +863,9 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testVisualSignResize) return; } SdrView* pView = SfxViewShell::Current()->GetDrawView(); - svx::SignatureLineHelper::setShapeCertificate(pView, xCert); + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = xCert; + svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); pObjectShell->SetModified(false); // When resizing the shape by moving the bottom right (last) handle towards top right: diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index 449cd55d36d9..edc54923f4d0 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -12416,7 +12416,7 @@ SfxVoidItem AnchorMenu SID_ANCHOR_MENU ] SfxVoidItem InsertSignatureLine SID_INSERT_SIGNATURELINE -(SfxStringItem SignatureCert FN_PARAM_1, SfxStringItem SignatureKey FN_PARAM_2) +(SfxStringItem SignatureCert FN_PARAM_1, SfxStringItem SignatureKey FN_PARAM_2, SfxBoolItem External FN_PARAM_3) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/svx/source/dialog/signaturelinehelper.cxx b/svx/source/dialog/signaturelinehelper.cxx index e079d62d5631..d8a41e8d3cc7 100644 --- a/svx/source/dialog/signaturelinehelper.cxx +++ b/svx/source/dialog/signaturelinehelper.cxx @@ -99,10 +99,16 @@ getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld:: return xSignCertificate; } -OUString getSignerName(const css::uno::Reference<css::security::XCertificate>& xCertificate) +OUString getSignerName(const svl::crypto::CertificateOrName& rCertificateOrName) { - return comphelper::xmlsec::GetContentPart(xCertificate->getSubjectName(), - xCertificate->getCertificateKind()); + if (rCertificateOrName.m_xCertificate.is()) + { + return comphelper::xmlsec::GetContentPart( + rCertificateOrName.m_xCertificate->getSubjectName(), + rCertificateOrName.m_xCertificate->getCertificateKind()); + } + + return rCertificateOrName.m_aName; } OUString getLocalizedDate() @@ -130,7 +136,7 @@ uno::Reference<graphic::XGraphic> importSVG(std::u16string_view rSVG) } void setShapeCertificate(const SdrView* pView, - const css::uno::Reference<css::security::XCertificate>& xCertificate) + const svl::crypto::CertificateOrName& rCertificateOrName) { const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); if (rMarkList.GetMarkCount() < 1) @@ -149,15 +155,21 @@ void setShapeCertificate(const SdrView* pView, uno::Reference<drawing::XShape> xShape = pSignatureLine->getUnoShape(); uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue(u"InteropGrabBag"_ustr)); - aMap[u"SignatureCertificate"_ustr] <<= xCertificate; - xShapeProps->setPropertyValue(u"InteropGrabBag"_ustr, - uno::Any(aMap.getAsConstPropertyValueList())); + if (rCertificateOrName.m_xCertificate.is()) + { + aMap[u"SignatureCertificate"_ustr] <<= rCertificateOrName.m_xCertificate; + } + else + { + aMap[u"SignatureCertificate"_ustr] <<= rCertificateOrName.m_aName; + } + xShapeProps->setPropertyValue("InteropGrabBag", uno::Any(aMap.getAsConstPropertyValueList())); // Read svg and replace placeholder texts. OUString aSvgImage( svx::SignatureLineHelper::getSignatureImage(u"signature-line-draw.svg"_ustr)); aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", SvxResId(RID_SVXSTR_SIGNATURELINE_DSIGNED_BY)); - OUString aSignerName = svx::SignatureLineHelper::getSignerName(xCertificate); + OUString aSignerName = svx::SignatureLineHelper::getSignerName(rCertificateOrName); aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", aSignerName); OUString aDate = svx::SignatureLineHelper::getLocalizedDate(); aDate = SvxResId(RID_SVXSTR_SIGNATURELINE_DATE).replaceFirst("%1", aDate); diff --git a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx index b910f55820f0..9964ec88dfb2 100644 --- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx +++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx @@ -103,7 +103,9 @@ CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testPDFAddVisibleSignatureLastPage) SfxViewShell* pCurrent = SfxViewShell::Current(); CPPUNIT_ASSERT(pCurrent); SdrView* pView = pCurrent->GetDrawView(); - svx::SignatureLineHelper::setShapeCertificate(pView, xCert); + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = xCert; + svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); // the document is modified now, but Sign function can't show SaveAs dialog // in unit test, so just clear the modified diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index 00a835119642..82a7d2a1ae73 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -774,7 +774,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testPDFAddVisibleSignature) SfxViewShell* pCurrent = SfxViewShell::Current(); CPPUNIT_ASSERT(pCurrent); SdrView* pView = pCurrent->GetDrawView(); - svx::SignatureLineHelper::setShapeCertificate(pView, xCert); + svl::crypto::CertificateOrName aCertificateOrName; + aCertificateOrName.m_xCertificate = xCert; + svx::SignatureLineHelper::setShapeCertificate(pView, aCertificateOrName); // the document is modified now, but Sign function can't show SaveAs dialog // in unit test, so just clear the modified diff --git a/xmlsecurity/source/dialogs/certificatechooser.cxx b/xmlsecurity/source/dialogs/certificatechooser.cxx index 89fef57d032d..48dd33533efe 100644 --- a/xmlsecurity/source/dialogs/certificatechooser.cxx +++ b/xmlsecurity/source/dialogs/certificatechooser.cxx @@ -28,6 +28,7 @@ #include <comphelper/xmlsechelper.hxx> #include <comphelper/lok.hxx> #include <sfx2/viewsh.hxx> +#include <svl/cryptosign.hxx> #include <com/sun/star/security/NoPasswordException.hpp> #include <com/sun/star/security/CertificateCharacters.hpp> @@ -227,9 +228,9 @@ void CertificateChooser::ImplInitialize(bool mbSearch) if (comphelper::LibreOfficeKit::isActive()) { // The LOK case takes the signing certificate from the view. - if (m_pViewShell && m_pViewShell->GetSigningCertificate().is()) + if (m_pViewShell && m_pViewShell->GetSigningCertificate().m_xCertificate.is()) { - xCerts = { m_pViewShell->GetSigningCertificate() }; + xCerts = { m_pViewShell->GetSigningCertificate().m_xCertificate }; } } else diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index aa4bfec4664b..6fef34748469 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -264,7 +264,7 @@ DigitalSignaturesDialog::DigitalSignaturesDialog( if (comphelper::LibreOfficeKit::isActive()) { // If the view has a signing certificate, then allow adding a signature. - if (!pViewShell || !pViewShell->GetSigningCertificate().is()) + if (!pViewShell || !pViewShell->GetSigningCertificate().m_xCertificate.is()) { m_xAddBtn->hide(); } commit 1b73db385d90f6a1f5251ebbad989d59b10c36e5 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jan 9 11:52:47 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 12 10:43:33 2025 +0100 cool#10630 lok doc sign: allow setting the size of the Impress sign line Insert a signature line in LOK mode when PEM certs are configured, moving the just inserted shape works (even in the read-only PDF view), but you can't resize the shape. This is because moving goes via .uno:TransformDialog, while resizing uses .uno:MoveShapeHandle. Fix this similar to moving, by allowing the operation when the shape is a just inserted signature line. Allowing the command in read-only mode is meant to be safe, since the command implementation again checks if the resize is allowed, and there we allow this only for signature lines. Also expose the "is signature line" info on the LOK API, so it can show the graphic selection handles conditionally (only when resize will be allowed). Change-Id: Ie85aa1211564758dc24ff83b4241de78a8e69ffc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180065 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sd/sdi/_drvwsh.sdi b/sd/sdi/_drvwsh.sdi index 917d369ac8fc..b0c655176b1b 100644 --- a/sd/sdi/_drvwsh.sdi +++ b/sd/sdi/_drvwsh.sdi @@ -2966,6 +2966,7 @@ interface DrawView SID_MOVE_SHAPE_HANDLE [ ExecMethod = FuTemporary ; + ReadOnlyDoc = TRUE ; ] SID_ATTR_TEXTCOLUMNS_NUMBER [ diff --git a/svx/qa/unit/data/empty.pdf b/svx/qa/unit/data/empty.pdf new file mode 100644 index 000000000000..d6142103184b Binary files /dev/null and b/svx/qa/unit/data/empty.pdf differ diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index 12cdd6093f20..6cf4c6bc10f3 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -17,6 +17,9 @@ #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> #include <com/sun/star/drawing/HomogenMatrix3.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/xml/crypto/SEInitializer.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> #include <extendedprimitive2dxmldump.hxx> #include <rtl/ustring.hxx> @@ -35,6 +38,10 @@ #include <svl/itempool.hxx> #include <svx/svdomedia.hxx> #include <vcl/filter/PDFiumLibrary.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <sfx2/sfxbasemodel.hxx> +#include <svx/signaturelinehelper.hxx> +#include <sfx2/objsh.hxx> #include <sdr/contact/objectcontactofobjlistpainter.hxx> @@ -45,16 +52,35 @@ namespace /// Tests for svx/source/svdraw/ code. class SvdrawTest : public UnoApiXmlTest { +private: + uno::Reference<xml::crypto::XSEInitializer> mxSEInitializer; + uno::Reference<xml::crypto::XXMLSecurityContext> mxSecurityContext; + public: SvdrawTest() : UnoApiXmlTest(u"svx/qa/unit/data/"_ustr) { } + void setUp() override; + uno::Reference<xml::crypto::XXMLSecurityContext>& getSecurityContext() + { + return mxSecurityContext; + } + protected: SdrPage* getFirstDrawPageWithAssert(); }; +void SvdrawTest::setUp() +{ + UnoApiTest::setUp(); + MacrosTest::setUpX509(m_directories, "svx_unit"); + + mxSEInitializer = xml::crypto::SEInitializer::create(m_xContext); + mxSecurityContext = mxSEInitializer->createSecurityContext(OUString()); +} + SdrPage* SvdrawTest::getFirstDrawPageWithAssert() { uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, @@ -800,6 +826,62 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf161724) CPPUNIT_ASSERT_EQUAL(sal_Int16(9901), nBmpWidth); CPPUNIT_ASSERT_EQUAL(sal_Int16(12693), nBmpHeight); } + +CPPUNIT_TEST_FIXTURE(SvdrawTest, testVisualSignResize) +{ + // Given a read-only document with a just inserted signature line: + uno::Sequence<beans::PropertyValue> aArgs = { comphelper::makePropertyValue("ReadOnly", true) }; + loadWithParams(createFileURL(u"empty.pdf"), aArgs); + SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get()); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + CPPUNIT_ASSERT(pObjectShell); + CPPUNIT_ASSERT(pObjectShell->IsReadOnly()); + // Add a signature line to the 2nd page. + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShape( + xFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY); + xShape->setPosition(awt::Point(1000, 1000)); + xShape->setSize(awt::Size(10000, 10000)); + uno::Reference<drawing::XDrawPagesSupplier> xSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getDrawPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPages->getCount()); + + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawView> xController(xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY); + xController->setCurrentPage(xDrawPage); + xDrawPage->add(xShape); + // Select it and assign a certificate. + uno::Reference<view::XSelectionSupplier> xSelectionSupplier(pBaseModel->getCurrentController(), + uno::UNO_QUERY); + xSelectionSupplier->select(uno::Any(xShape)); + auto xEnv = getSecurityContext()->getSecurityEnvironment(); + auto xCert = GetValidCertificate(xEnv->getPersonalCertificates(), xEnv); + if (!xCert) + { + return; + } + SdrView* pView = SfxViewShell::Current()->GetDrawView(); + svx::SignatureLineHelper::setShapeCertificate(pView, xCert); + pObjectShell->SetModified(false); + + // When resizing the shape by moving the bottom right (last) handle towards top right: + aArgs = { + comphelper::makePropertyValue("HandleNum", static_cast<sal_Int32>(7)), + comphelper::makePropertyValue("NewPosX", static_cast<sal_Int32>(1500)), + comphelper::makePropertyValue("NewPosY", static_cast<sal_Int32>(1500)), + }; + dispatchCommand(mxComponent, ".uno:MoveShapeHandle", aArgs); + + // Then make sure the size decreases: + // Without the accompanying fix in place, this test would have failed with: + // - Expected less than: 10000 + // - Actual : 10000 + // i.e. you could not resize even a just inserted signature line in a read-only view. + CPPUNIT_ASSERT_LESS(static_cast<sal_Int32>(10000), xShape->getSize().Width); + CPPUNIT_ASSERT_LESS(static_cast<sal_Int32>(10000), xShape->getSize().Height); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index 051e559c94cd..9b05f0206539 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -38,6 +38,8 @@ #include <unotools/configmgr.hxx> #include <comphelper/lok.hxx> #include <officecfg/Office/Common.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewsh.hxx> using namespace sdr; @@ -410,7 +412,15 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl } else { - if(!IsResizeAllowed(true)) + bool bResizeAllowed = IsResizeAllowed(true); + SfxViewShell* pViewShell = GetSfxViewShell(); + SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; + if (!bResizeAllowed && pObjectShell && pObjectShell->GetSignPDFCertificate().is()) + { + // If the just added signature line shape is selected, allow resizing it. + bResizeAllowed = true; + } + if(!bResizeAllowed) { return false; } diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index 96bd7be18b7b..8ba5583853a1 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -61,6 +61,7 @@ #include <sfx2/lokhelper.hxx> #include <sfx2/lokcomponenthelpers.hxx> #include <sfx2/viewsh.hxx> +#include <sfx2/objsh.hxx> #include <svtools/optionsdrawinglayer.hxx> #include <drawinglayer/processor2d/textextractor2d.hxx> @@ -1111,6 +1112,16 @@ void SdrMarkView::SetMarkHandlesForLOKit(tools::Rectangle const & rRect, const S } } } + else + { + SfxObjectShell* pObjectShell = pViewShell ? pViewShell->GetObjectShell() : nullptr; + if (pObjectShell && pObjectShell->IsSignPDF() && pObjectShell->GetSignPDFCertificate().is()) + { + // Expose the info that this is the special signature widget that is OK to + // move/resize. + aExtraInfo.append(", \"isSignature\": true"); + } + } if (!bTableSelection && !pOtherShell && maHdlList.GetHdlCount()) { boost::property_tree::ptree responseJSON;