cui/source/dialogs/SignSignatureLineDialog.cxx             |    2 
 include/sfx2/digitalsignatures.hxx                         |    8 +++
 include/svx/signaturelinehelper.hxx                        |    3 -
 sd/source/ui/func/fuconrec.cxx                             |    1 
 sd/source/ui/view/drviewse.cxx                             |   31 +++++++++++++
 svx/sdi/svx.sdi                                            |    2 
 svx/source/dialog/signaturelinehelper.cxx                  |    9 ++-
 xmlsecurity/source/component/documentdigitalsignatures.cxx |   29 ++++++++----
 8 files changed, 71 insertions(+), 14 deletions(-)

New commits:
commit 0cc0896b212b0d1fded8d999b980f18f0379e6e0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jan 3 13:44:59 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jan 6 13:02:15 2025 +0100

    cool#10630 lok doc sign: fix Impress sign line when picking a certificate
    
    Once .uno:InsertSignatureLine gets dispatched, a visual signature
    placeholder gets inserted, then a certificate picker shows up, but no
    certificates are visible in the list.
    
    The first problem is that .uno:InsertSignatureLine needs to take sign
    key/cert parameters in DrawViewShell::FuPermanent() (similar to
    .uno:Signature), so it can learn what certificate to use for signing.
    
    The second problem is that once that sign cert is attached to the view,
    the cert chooser for signature lines were not taking the sign cert from
    the view in DocumentDigitalSignatures::chooseCertificatesImpl() -- this
    needs routing the info about the current view from sd/ (where we still
    have that info) to xmlsecurity/.
    
    With this, a LOK client dispatching .uno:InsertSignatureLine with the 2
    new parameters set can insert a signature line, it'll show up, but the
    subsequent .uno:Signature dispatch still needs fixing up. (Currently it
    wants to "save" the modified PDF, while it should just sign.)
    
    Change-Id: Ie536842152ef097aa6959c67916f2beb6d356e4a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179819
    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 a58e9298054d..a1cf837c107c 100644
--- a/cui/source/dialogs/SignSignatureLineDialog.cxx
+++ b/cui/source/dialogs/SignSignatureLineDialog.cxx
@@ -158,7 +158,7 @@ IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, 
weld::Button&, void)
         return;
 
     Reference<XCertificate> xSignCertificate
-        = svx::SignatureLineHelper::getSignatureCertificate(pShell, 
m_xDialog.get());
+        = svx::SignatureLineHelper::getSignatureCertificate(pShell, nullptr, 
m_xDialog.get());
 
     if (xSignCertificate.is())
     {
diff --git a/include/sfx2/digitalsignatures.hxx 
b/include/sfx2/digitalsignatures.hxx
index fe5f2bc97874..7778f5e1fb89 100644
--- a/include/sfx2/digitalsignatures.hxx
+++ b/include/sfx2/digitalsignatures.hxx
@@ -15,6 +15,7 @@
 #include <com/sun/star/frame/XModel.hpp>
 #include <com/sun/star/io/XStream.hpp>
 #include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
 
 #include <sal/types.h>
 
@@ -56,6 +57,13 @@ public:
     SetSignScriptingContent(const css::uno::Reference<css::io::XStream>& 
xScriptingSignStream)
         = 0;
 
+    /// View-aware replacement for selectSigningCertificateWithType().
+    virtual css::uno::Reference<css::security::XCertificate>
+    SelectSigningCertificateWithType(SfxViewShell* pViewShell,
+                                     const css::security::CertificateKind 
certificateKind,
+                                     OUString& rDescription)
+        = 0;
+
 protected:
     ~DigitalSignatures() noexcept = default;
 };
diff --git a/include/svx/signaturelinehelper.hxx 
b/include/svx/signaturelinehelper.hxx
index 9a10a09a29ce..e8105a37bd7f 100644
--- a/include/svx/signaturelinehelper.hxx
+++ b/include/svx/signaturelinehelper.hxx
@@ -26,6 +26,7 @@ class Window;
 }
 class SdrView;
 class SfxObjectShell;
+class SfxViewShell;
 
 namespace svx::SignatureLineHelper
 {
@@ -39,7 +40,7 @@ SVX_DLLPUBLIC OUString getSignatureImage(const OUString& 
rType = OUString());
  * Choose a signature for signature line purposes.
  */
 SVX_DLLPUBLIC css::uno::Reference<css::security::XCertificate>
-getSignatureCertificate(SfxObjectShell* pShell, weld::Window* pParent);
+getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, 
weld::Window* pParent);
 
 /**
  * Get a signer name out of a certificate.
diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx
index 45abc8058d82..5cbdb1e82596 100644
--- a/sd/source/ui/func/fuconrec.cxx
+++ b/sd/source/ui/func/fuconrec.cxx
@@ -514,6 +514,7 @@ void FuConstructRectangle::Deactivate()
 
     uno::Reference<security::XCertificate> xCertificate
         = 
svx::SignatureLineHelper::getSignatureCertificate(mpViewShell->GetObjectShell(),
+                mpViewShell->GetViewShell(),
                 mpViewShell->GetFrameWeld());
     if (!xCertificate.is())
     {
diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx
index 9a7c8df31f7a..ea2f65a01c00 100644
--- a/sd/source/ui/view/drviewse.cxx
+++ b/sd/source/ui/view/drviewse.cxx
@@ -98,6 +98,7 @@
 #include <basegfx/utils/zoomtools.hxx>
 #include <officecfg/Office/Draw.hxx>
 #include <officecfg/Office/Impress.hxx>
+#include <sfx2/lokhelper.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -455,6 +456,36 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq)
         case SID_CONNECTOR_LINES_CIRCLES:
         case SID_INSERT_SIGNATURELINE:
         {
+            if (nSId == SID_INSERT_SIGNATURELINE)
+            {
+                // See if a signing cert is passed as a parameter: if so, 
parse that.
+                std::string aSignatureCert;
+                std::string aSignatureKey;
+                const SfxStringItem* pSignatureCert = 
rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+                if (pSignatureCert)
+                {
+                    aSignatureCert = pSignatureCert->GetValue().toUtf8();
+                }
+                const SfxStringItem* pSignatureKey = 
rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+                if (pSignatureKey)
+                {
+                    aSignatureKey = pSignatureKey->GetValue().toUtf8();
+                }
+
+                SfxViewFrame* pFrame = GetFrame();
+                SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : 
nullptr;
+                if (pViewShell)
+                {
+                    uno::Reference<security::XCertificate> xSigningCertificate;
+                    if (!aSignatureCert.empty() && !aSignatureKey.empty())
+                    {
+                        xSigningCertificate = 
SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey);
+                    }
+                    // Always set the signing certificate, to clear data from 
a previous dispatch.
+                    pViewShell->SetSigningCertificate(xSigningCertificate);
+                }
+            }
+
             bCreateDirectly = comphelper::LibreOfficeKit::isActive();
             bRectangle = true;
             SetCurrentFunction( FuConstructRectangle::Create( this, 
GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) );
diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi
index 70dc6c4423fa..449cd55d36d9 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)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/svx/source/dialog/signaturelinehelper.cxx 
b/svx/source/dialog/signaturelinehelper.cxx
index 52fb02c80e87..e079d62d5631 100644
--- a/svx/source/dialog/signaturelinehelper.cxx
+++ b/svx/source/dialog/signaturelinehelper.cxx
@@ -33,6 +33,7 @@
 #include <unotools/streamwrap.hxx>
 #include <unotools/syslocale.hxx>
 #include <vcl/weld.hxx>
+#include <sfx2/digitalsignatures.hxx>
 
 using namespace com::sun::star;
 
@@ -57,8 +58,8 @@ OUString getSignatureImage(const OUString& rType)
     return OUString::fromUtf8(svg);
 }
 
-uno::Reference<security::XCertificate> getSignatureCertificate(SfxObjectShell* 
pShell,
-                                                               weld::Window* 
pParent)
+uno::Reference<security::XCertificate>
+getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, 
weld::Window* pParent)
 {
     if (!pShell)
     {
@@ -91,8 +92,10 @@ uno::Reference<security::XCertificate> 
getSignatureCertificate(SfxObjectShell* p
     {
         certificateKind = security::CertificateKind_X509;
     }
+    auto xModelSigner = dynamic_cast<sfx2::DigitalSignatures*>(xSigner.get());
+    assert(xModelSigner);
     uno::Reference<security::XCertificate> xSignCertificate
-        = xSigner->selectSigningCertificateWithType(certificateKind, 
aDescription);
+        = xModelSigner->SelectSigningCertificateWithType(pViewShell, 
certificateKind, aDescription);
     return xSignCertificate;
 }
 
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx 
b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 541748fc7c73..6d8291c7bf83 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -99,7 +99,7 @@ private:
                          DocumentSignatureMode eMode);
 
     css::uno::Sequence<css::uno::Reference<css::security::XCertificate>>
-    chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const 
CertificateChooserUserAction eAction,
+    chooseCertificatesImpl(SfxViewShell* pViewShell, std::map<OUString, 
OUString>& rProperties, const CertificateChooserUserAction eAction,
                            const CertificateKind 
certificateKind=CertificateKind_NONE);
 
     bool
@@ -207,6 +207,12 @@ public:
     /// See sfx2::DigitalSignatures::SetSignScriptingContent().
     void SetSignScriptingContent(
         const css::uno::Reference<css::io::XStream>& xScriptingSignStream) 
override;
+
+    /// See sfx2::DigitalSignatures::SelectSigningCertificateWithType().
+    css::uno::Reference<css::security::XCertificate>
+    SelectSigningCertificateWithType(SfxViewShell* pViewShell,
+                                     const css::security::CertificateKind 
certificateKind,
+                                     OUString& rDescription) override;
 };
 
 }
@@ -639,7 +645,8 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
 }
 
 uno::Sequence<Reference<css::security::XCertificate>>
-DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, 
OUString>& rProperties,
+DocumentDigitalSignatures::chooseCertificatesImpl(SfxViewShell* pViewShell,
+                                                  std::map<OUString, 
OUString>& rProperties,
                                                   const 
CertificateChooserUserAction eAction,
                                                   const CertificateKind 
certificateKind)
 {
@@ -654,7 +661,7 @@ 
DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>&
             xSecContexts.push_back(aSignatureManager.getGpgSecurityContext());
     }
 
-    std::shared_ptr<CertificateChooser> aChooser = 
CertificateChooser::getInstance(Application::GetFrameWeld(mxParentWindow), 
nullptr, std::move(xSecContexts), eAction);
+    std::shared_ptr<CertificateChooser> aChooser = 
CertificateChooser::getInstance(Application::GetFrameWeld(mxParentWindow), 
pViewShell, std::move(xSecContexts), eAction);
 
     if (aChooser->run() != RET_OK)
         return { Reference< css::security::XCertificate >(nullptr) };
@@ -674,7 +681,7 @@ Reference< css::security::XCertificate > 
DocumentDigitalSignatures::chooseCertif
 Reference< css::security::XCertificate > 
DocumentDigitalSignatures::chooseSigningCertificate(OUString& rDescription)
 {
     std::map<OUString, OUString> aProperties;
-    Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( 
aProperties, CertificateChooserUserAction::Sign )[0];
+    Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( 
nullptr, aProperties, CertificateChooserUserAction::Sign )[0];
     rDescription = aProperties[u"Description"_ustr];
     return xCert;
 }
@@ -682,7 +689,7 @@ Reference< css::security::XCertificate > 
DocumentDigitalSignatures::chooseSignin
 Reference< css::security::XCertificate > 
DocumentDigitalSignatures::selectSigningCertificate(OUString& rDescription)
 {
     std::map<OUString, OUString> aProperties;
-    Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( 
aProperties, CertificateChooserUserAction::SelectSign )[0];
+    Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( 
nullptr, aProperties, CertificateChooserUserAction::SelectSign )[0];
     rDescription = aProperties[u"Description"_ustr];
     return xCert;
 }
@@ -690,10 +697,16 @@ Reference< css::security::XCertificate > 
DocumentDigitalSignatures::selectSignin
 Reference<css::security::XCertificate>
 DocumentDigitalSignatures::selectSigningCertificateWithType(const 
CertificateKind certificateKind,
                                                             OUString& 
rDescription)
+{
+    return SelectSigningCertificateWithType(nullptr, certificateKind, 
rDescription);
+}
+
+Reference<css::security::XCertificate>
+DocumentDigitalSignatures::SelectSigningCertificateWithType(SfxViewShell* 
pViewShell, const CertificateKind certificateKind, OUString& rDescription)
 {
     std::map<OUString, OUString> aProperties;
     Reference<css::security::XCertificate> xCert
-        = chooseCertificatesImpl(aProperties, 
CertificateChooserUserAction::SelectSign, certificateKind)[0];
+        = chooseCertificatesImpl(pViewShell, aProperties, 
CertificateChooserUserAction::SelectSign, certificateKind)[0];
     rDescription = aProperties[u"Description"_ustr];
     return xCert;
 }
@@ -703,7 +716,7 @@ 
DocumentDigitalSignatures::chooseEncryptionCertificate(const CertificateKind cer
 {
     std::map<OUString, OUString> aProperties;
     uno::Sequence< Reference< css::security::XCertificate > > aCerts=
-        chooseCertificatesImpl( aProperties, 
CertificateChooserUserAction::Encrypt , certificateKind );
+        chooseCertificatesImpl( nullptr, aProperties, 
CertificateChooserUserAction::Encrypt , certificateKind );
     if (aCerts.getLength() == 1 && !aCerts[0].is())
         // our error case contract is: empty sequence, so map that!
         return uno::Sequence< Reference< css::security::XCertificate > >();
@@ -714,7 +727,7 @@ 
DocumentDigitalSignatures::chooseEncryptionCertificate(const CertificateKind cer
 css::uno::Reference< css::security::XCertificate > 
DocumentDigitalSignatures::chooseCertificateWithProps(Sequence<css::beans::PropertyValue>&
 rProperties)
 {
     std::map<OUString, OUString> aProperties;
-    auto xCert = chooseCertificatesImpl( aProperties, 
CertificateChooserUserAction::Sign )[0];
+    auto xCert = chooseCertificatesImpl( nullptr, aProperties, 
CertificateChooserUserAction::Sign )[0];
 
     std::vector<css::beans::PropertyValue> vec;
     vec.reserve(aProperties.size());

Reply via email to