[Libreoffice-commits] core.git: Branch 'private/mmeeks/cp-6.2-bits' - 22 commits - chart2/source cui/source desktop/qa desktop/source filter/source include/LibreOfficeKit include/svx offapi/com sc/source sfx2/source svx/sdi svx/source sw/inc sw/qa sw/source xmlsecurity/inc xmlsecurity/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 5 16:52:36 UTC 2019


Rebased ref, commits from common ancestor:
commit dbc107538979efa3f153a5983ccf137df20464d2
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Mar 12 10:21:36 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:04:00 2019 -0400

    sw HTML export: handle field shadings view option
    
    Regardless of the value of the View -> Field Shadings option, shadings
    were always lost when saving to HTML.
    
    Implement handling of this in the HTML conditionally, so in case that
    UI option is on, then shadings are preserved in the HTML result;
    disabling that option results in the old behavior, though.
    
    Change-Id: I1bd19f4c6e22aff2f84fac25f0a506ad0127cc3c
    Reviewed-on: https://gerrit.libreoffice.org/69081
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 630f3d611221..ed30270f96e5 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -185,11 +185,6 @@ OString lclConvToHex(sal_uInt16 nHex)
     return OString(aNToABuf, 2);
 }
 
-OString lclGetCSS1Color(const Color& rColor)
-{
-    return "#" + lclConvToHex(rColor.GetRed()) + lclConvToHex(rColor.GetGreen()) + lclConvToHex(rColor.GetBlue());
-}
-
 /// Determines if rProperty has to be suppressed due to ReqIF mode.
 bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty)
 {
@@ -207,6 +202,11 @@ bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty)
 }
 }
 
+OString GetCSS1_Color(const Color& rColor)
+{
+    return "#" + lclConvToHex(rColor.GetRed()) + lclConvToHex(rColor.GetGreen()) + lclConvToHex(rColor.GetBlue());
+}
+
 class SwCSS1OutMode
 {
     SwHTMLWriter& rWrt;
@@ -2233,7 +2233,7 @@ void SwHTMLWriter::OutCSS1_FrameFormatBackground( const SwFrameFormat& rFrameFor
                 aColor = pVSh->GetViewOptions()->GetRetoucheColor();
         }
 
-        OutCSS1_PropertyAscii(sCSS1_P_background, lclGetCSS1Color(aColor));
+        OutCSS1_PropertyAscii(sCSS1_P_background, GetCSS1_Color(aColor));
     }
 }
 
@@ -2408,7 +2408,7 @@ static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
     if( COL_AUTO == aColor )
         aColor = COL_BLACK;
 
-    rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_color, lclGetCSS1Color(aColor));
+    rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_color, GetCSS1_Color(aColor));
 
     return rWrt;
 }
@@ -3268,7 +3268,7 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
     {
         if( bColor )
         {
-            OString sTmp(lclGetCSS1Color(aColor));
+            OString sTmp(GetCSS1_Color(aColor));
             sOut += OStringToOUString(sTmp, RTL_TEXTENCODING_ASCII_US);
         }
 
@@ -3383,7 +3383,7 @@ static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt,
     sOut.append(' ');
 
     // and also the color
-    sOut.append(lclGetCSS1Color(pLine->GetColor()));
+    sOut.append(GetCSS1_Color(pLine->GetColor()));
 
     rHTMLWrt.OutCSS1_PropertyAscii(pProperty, sOut.makeStringAndClear());
 }
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index 775fc664ec39..badc1f801df8 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -691,6 +691,8 @@ Writer& OutHTML_NumBulListEnd( SwHTMLWriter& rWrt,
 
 Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt );
 
+OString GetCSS1_Color(const Color& rColor);
+
 #endif // INCLUDED_SW_SOURCE_FILTER_HTML_WRTHTML_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 430778af918608709b0fd12fae6693aec62fbd70
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Aug 3 18:53:15 2019 -0400
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:59 2019 -0400

    Fix certificate test mis-merging.
    
    Change-Id: Iea997c8eab371f278d181de0cc61323a25f0d1ae

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index de11c867412b..9101619f9ef1 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2346,7 +2346,6 @@ void DesktopLOKTest::testInsertCertificate_DER_ODT()
     CPPUNIT_ASSERT_EQUAL(int(1), nState);
 }
 
-
 void DesktopLOKTest::testInsertCertificate_PEM_ODT()
 {
     comphelper::LibreOfficeKit::setActive();
@@ -2370,7 +2369,23 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
     std::vector<unsigned char> aPrivateKey;
 
     {
-        readFileIntoByteVector("rootCA.der", aCertificate);
+        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
 
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
@@ -2391,6 +2406,66 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
     CPPUNIT_ASSERT_EQUAL(int(1), nState);
 }
 
+void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Load the document, save it into a temp file and load that file again
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.docx");
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
+    closeDoc();
+
+    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+    pDocument = new LibLODocument_Impl(mxComponent);
+
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(mxComponent.is());
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    Scheduler::ProcessEventsToIdle();
+
+    std::vector<unsigned char> aCertificate;
+    std::vector<unsigned char> aPrivateKey;
+
+    {
+        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-signing.pem", aCertificate);
+        readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
+
+        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
+                            aCertificate.data(), int(aCertificate.size()),
+                            aPrivateKey.data(), int(aPrivateKey.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
+    CPPUNIT_ASSERT_EQUAL(int(5), nState);
+}
+
 void DesktopLOKTest::testSignDocument_PEM_PDF()
 {
     comphelper::LibreOfficeKit::setActive();
@@ -2575,192 +2650,13 @@ void DesktopLOKTest::testComplexSelection()
     CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument));
 }
 
-void DesktopLOKTest::testInsertCertificate_PEM_ODT()
-{
-    comphelper::LibreOfficeKit::setActive();
-
-    // Load the document, save it into a temp file and load that file again
-    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
-    utl::TempFile aTempFile;
-    aTempFile.EnableKillingFile();
-    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
-    closeDoc();
-
-    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
-    pDocument = new LibLODocument_Impl(mxComponent);
-
-    Scheduler::ProcessEventsToIdle();
-    CPPUNIT_ASSERT(mxComponent.is());
-    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
-    Scheduler::ProcessEventsToIdle();
-
-    std::vector<unsigned char> aCertificate;
-    std::vector<unsigned char> aPrivateKey;
-
-    {
-        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-signing.pem", aCertificate);
-        readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
-
-        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
-                            aCertificate.data(), int(aCertificate.size()),
-                            aPrivateKey.data(), int(aPrivateKey.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
-    CPPUNIT_ASSERT_EQUAL(int(1), nState);
-
-    comphelper::LibreOfficeKit::setActive(false);
-}
-
-void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
-{
-    comphelper::LibreOfficeKit::setActive();
-
-    // Load the document, save it into a temp file and load that file again
-    LibLODocument_Impl* pDocument = loadDoc("blank_text.docx");
-    utl::TempFile aTempFile;
-    aTempFile.EnableKillingFile();
-    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
-    closeDoc();
-
-    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
-    pDocument = new LibLODocument_Impl(mxComponent);
-
-    Scheduler::ProcessEventsToIdle();
-    CPPUNIT_ASSERT(mxComponent.is());
-    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
-    Scheduler::ProcessEventsToIdle();
-
-    std::vector<unsigned char> aCertificate;
-    std::vector<unsigned char> aPrivateKey;
-
-    {
-        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-signing.pem", aCertificate);
-        readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
-
-        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
-                            aCertificate.data(), int(aCertificate.size()),
-                            aPrivateKey.data(), int(aPrivateKey.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
-    CPPUNIT_ASSERT_EQUAL(int(5), nState);
-
-    comphelper::LibreOfficeKit::setActive(false);
-}
+namespace {
 
-void DesktopLOKTest::testSignDocument_PEM_PDF()
+constexpr size_t classOffset(int i)
 {
-    comphelper::LibreOfficeKit::setActive();
-
-    // Load the document, save it into a temp file and load that file again
-    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
-    utl::TempFile aTempFile;
-    aTempFile.EnableKillingFile();
-
-    Scheduler::ProcessEventsToIdle();
-    CPPUNIT_ASSERT(mxComponent.is());
-    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
-    Scheduler::ProcessEventsToIdle();
-
-    std::vector<unsigned char> aCertificate;
-    std::vector<unsigned char> aPrivateKey;
-
-    {
-        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "pdf", nullptr));
-
-    closeDoc();
-
-    Scheduler::ProcessEventsToIdle();
-
-    readFileIntoByteVector("test-cert-signing.pem", aCertificate);
-    readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
-
-    LibLibreOffice_Impl aOffice;
-    bool bResult = aOffice.m_pOfficeClass->signDocument(&aOffice, aTempFile.GetURL().toUtf8().getStr(),
-                                         aCertificate.data(), int(aCertificate.size()),
-                                         aPrivateKey.data(), int(aPrivateKey.size()));
-
-    CPPUNIT_ASSERT(bResult);
-
-    comphelper::LibreOfficeKit::setActive(false);
+    return sizeof(static_cast<struct _LibreOfficeKitClass*>(nullptr)->nSize) + i * sizeof(void*);
 }
 
-namespace {
-
 constexpr size_t documentClassOffset(int i)
 {
     return sizeof(static_cast<struct _LibreOfficeKitDocumentClass*>(nullptr)->nSize) + i * sizeof(void*);
commit bf713a41e07d192d8bc61958771aeefdb0197aee
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sat Jul 20 11:01:38 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:57 2019 -0400

    LOK: Enable embedding images in text/html format output
    
    Change-Id: Ibd8bed796678ee26de2ceb6e434dce24da4eab05

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 6291029237e0..de11c867412b 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2568,7 +2568,7 @@ void DesktopLOKTest::testComplexSelection()
     pText = pDocument->pClass->getTextSelection(pDocument, "text/html", nullptr);
     CPPUNIT_ASSERT(pText != nullptr);
     CPPUNIT_ASSERT(std::string(pText).find(aText.getStr()) != std::string::npos); // Must have the text.
-    // CPPUNIT_ASSERT(std::string(pText).find("<img") != std::string::npos); // Must have the image as well.
+    CPPUNIT_ASSERT(std::string(pText).find("<img") != std::string::npos); // Must have the image as well.
     free(pText);
 
     // We expect this to be complex.
diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx
index f9c621d2f58d..b3d7a40a3d0b 100644
--- a/sw/source/filter/html/wrthtml.cxx
+++ b/sw/source/filter/html/wrthtml.cxx
@@ -89,7 +89,7 @@ using namespace css;
 static sal_Char sIndentTabs[MAX_INDENT_LEVEL+2] =
     "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
 
-SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL )
+SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL, const OUString& rFilterOptions )
     : m_pNumRuleInfo(new SwHTMLNumRuleInfo)
     , m_nHTMLMode(0)
     , m_eCSS1Unit(FieldUnit::NONE)
@@ -161,6 +161,8 @@ SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL )
         mpTempBaseURL->EnableKillingFile();
         SetBaseURL(mpTempBaseURL->GetURL());
     }
+
+    SetupFilterOptions(rFilterOptions);
 }
 
 SwHTMLWriter::~SwHTMLWriter()
@@ -183,21 +185,26 @@ void SwHTMLWriter::SetupFilterOptions(SfxMedium& rMedium)
         return;
 
 
-    OUString sFilterOptions = static_cast<const SfxStringItem*>(pItem)->GetValue();
-    if (sFilterOptions == "SkipImages")
+    const OUString sFilterOptions = static_cast<const SfxStringItem*>(pItem)->GetValue();
+    SetupFilterOptions(sFilterOptions);
+}
+
+void SwHTMLWriter::SetupFilterOptions(const OUString& rFilterOptions)
+{
+    if (rFilterOptions == "SkipImages")
     {
         mbSkipImages = true;
     }
-    else if (sFilterOptions == "SkipHeaderFooter")
+    else if (rFilterOptions == "SkipHeaderFooter")
     {
         mbSkipHeaderFooter = true;
     }
-    else if (sFilterOptions == "EmbedImages" )
+    else if (rFilterOptions == "EmbedImages")
     {
         mbEmbedImages = true;
     }
 
-    uno::Sequence<OUString> aOptionSeq = comphelper::string::convertCommaSeparated(sFilterOptions);
+    uno::Sequence<OUString> aOptionSeq = comphelper::string::convertCommaSeparated(rFilterOptions);
     const OUString aXhtmlNsKey("xhtmlns=");
     for (const auto& rOption : aOptionSeq)
     {
@@ -821,13 +828,6 @@ void SwHTMLWriter::Out_SwDoc( SwPaM* pPam )
                 OutHTML_Section( *this, *rNd.GetSectionNode() );
                 m_nBkmkTabPos = m_bWriteAll ? FindPos_Bkmk( *m_pCurrentPam->GetPoint() ) : -1;
             }
-            else if( rNd.IsGrfNode() )
-            {
-                SwGrfNode* pGrfNd = rNd.GetGrfNode();
-                assert(pGrfNd && !"FIXME: Implement Graphic copy as HTML.");
-                // if (pGrfNd)
-                //     OutHTML_SwGrfNode( *this, *pGrfNd );
-            }
             else if( &rNd == &m_pDoc->GetNodes().GetEndOfContent() )
                 break;
 
@@ -1554,9 +1554,9 @@ HTMLSaveData::~HTMLSaveData()
     }
 }
 
-void GetHTMLWriter( const OUString&, const OUString& rBaseURL, WriterRef& xRet )
+void GetHTMLWriter( const OUString& rFilterOptions, const OUString& rBaseURL, WriterRef& xRet )
 {
-    xRet = new SwHTMLWriter( rBaseURL );
+    xRet = new SwHTMLWriter( rBaseURL, rFilterOptions );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index 329ba4da367a..775fc664ec39 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -268,6 +268,8 @@ class SW_DLLPUBLIC SwHTMLWriter : public Writer
     void AddLinkTarget( const OUString& rURL );
     void CollectLinkTargets();
 
+    void SetupFilterOptions(const OUString& rFilterOptions);
+
 protected:
     ErrCode WriteStream() override;
     void SetupFilterOptions(SfxMedium& rMedium) override;
@@ -402,7 +404,9 @@ public:
     /// Tracks which text portion attributes are currently open: a which id -> open count map.
     std::map<sal_uInt16, int> maStartedAttributes;
 
-    explicit SwHTMLWriter( const OUString& rBaseURL );
+    /// Construct an instance of SwHTMLWriter and optionally give it
+    /// the filter options directly, which can also be set via SetupFilterOptions().
+    explicit SwHTMLWriter( const OUString& rBaseURL, const OUString& rFilterOptions = "" );
     virtual ~SwHTMLWriter() override;
 
     void Out_SwDoc( SwPaM* );       // write the marked range
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index eca952826cc8..ad2433ff6b9e 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -736,8 +736,12 @@ bool SwTransferable::WriteObject( tools::SvRef<SotStorageStream>& xStream,
         break;
 
     case SWTRANSFER_OBJECTTYPE_HTML:
-        GetHTMLWriter( aEmptyOUStr, OUString(), xWrt );
+    {
+        // LOK is interested in getting images embedded for copy/paste support.
+        const OUString aFilterOptions("EmbedImages");
+        GetHTMLWriter( comphelper::LibreOfficeKit::isActive() ? aFilterOptions : OUString(), OUString(), xWrt );
         break;
+    }
 
     case SWTRANSFER_OBJECTTYPE_RTF:
     case SWTRANSFER_OBJECTTYPE_RICHTEXT:
commit 2881222bbdd83e23b06374d94a13ec174a6e75c5
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Mar 12 18:43:43 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:56 2019 -0400

    sw HTML export, field shadings: give text portion background priority
    
    If the user explicitly gives a background color to the field portion,
    then respect that, don't overwrite with the field shading (the UI does
    the same).
    
    Change-Id: I7c35618f82a37ef1dd16c03b82651268767813af
    Reviewed-on: https://gerrit.libreoffice.org/69127
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlexport/data/field-shade.odt b/sw/qa/extras/htmlexport/data/field-shade.odt
new file mode 100644
index 000000000000..2533be68c49e
Binary files /dev/null and b/sw/qa/extras/htmlexport/data/field-shade.odt differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 5ae05a172078..f5a4650cea64 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -674,6 +674,22 @@ DECLARE_HTMLEXPORT_TEST(testNoLangReqIf, "reqif-no-lang.odt")
     assertXPathNoAttribute(pDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:h1", "lang");
 }
 
+DECLARE_HTMLEXPORT_TEST(testFieldShade, "field-shade.odt")
+{
+    htmlDocPtr pDoc = parseHtml(maTempFile);
+    CPPUNIT_ASSERT(pDoc);
+
+    // Without the accompanying fix in place, this test would have failed with 'Expected: 1; Actual:
+    // 0', i.e. shading for the field was lost.
+    assertXPath(pDoc, "/html/body/p[1]/span", "style", "background: #c0c0c0");
+
+    // Check that field shading is written only in case there is no user-defined span background.
+    assertXPath(pDoc, "/html/body/p[2]/span", "style", "background: #ff0000");
+    // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
+    // 1', i.e there was an inner span hiding the wanted background color.
+    assertXPath(pDoc, "/html/body/p[2]/span/span", 0);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index 2edf9a57c5fe..02f8f31ec26b 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1933,6 +1933,7 @@ void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
                 pContext = nullptr; // one time only
             }
             Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+            rHWrt.maStartedAttributes[pPos->GetItem()->Which()]++;
             rHWrt.m_nCSS1Script = nCSS1Script;
         }
     }
@@ -1983,6 +1984,7 @@ void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
             if( !bSkipOut )
             {
                 Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+                rHWrt.maStartedAttributes[pPos->GetItem()->Which()]--;
             }
             RemoveItem_( i );
         }
diff --git a/sw/source/filter/html/htmlfldw.cxx b/sw/source/filter/html/htmlfldw.cxx
index 7100a16b6f28..0ad1b55d5db7 100644
--- a/sw/source/filter/html/htmlfldw.cxx
+++ b/sw/source/filter/html/htmlfldw.cxx
@@ -32,10 +32,12 @@
 #include <fldbas.hxx>
 #include <docufld.hxx>
 #include <flddat.hxx>
+#include <viewopt.hxx>
 #include "htmlfld.hxx"
 #include "wrthtml.hxx"
 #include <rtl/strbuf.hxx>
 #include "css1atr.hxx"
+#include "css1kywd.hxx"
 
 using namespace nsSwDocInfoSubType;
 
@@ -535,8 +537,38 @@ Writer& OutHTML_SwFormatField( Writer& rWrt, const SfxPoolItem& rHt )
         const SwTextField *pTextField = rField.GetTextField();
         OSL_ENSURE( pTextField, "Where is the txt fld?" );
         if( pTextField )
+        {
+            SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
+            bool bFieldShadings = SwViewOption::IsFieldShadings();
+            if (bFieldShadings)
+            {
+                // If there is a text portion background started already, that should have priority.
+                auto it = rHTMLWrt.maStartedAttributes.find(RES_CHRATR_BACKGROUND);
+                if (it != rHTMLWrt.maStartedAttributes.end())
+                    bFieldShadings = it->second <= 0;
+            }
+
+            if (bFieldShadings)
+            {
+                OStringBuffer sOut;
+                sOut.append("<" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span);
+                sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_style "=\"");
+                sOut.append(sCSS1_P_background);
+                sOut.append(": ");
+
+                Color& rColor = SwViewOption::GetFieldShadingsColor();
+                sOut.append(GetCSS1_Color(rColor));
+                sOut.append("\">");
+                rWrt.Strm().WriteCharPtr(sOut.getStr());
+            }
+
             OutHTML_SwField( rWrt, pField, pTextField->GetTextNode(),
                              pTextField->GetStart()  );
+
+            if (bFieldShadings)
+                HTMLOutFuncs::Out_AsciiTag(
+                    rWrt.Strm(), rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span, false);
+        }
     }
     return rWrt;
 }
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index e06c4190aa4d..329ba4da367a 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -22,6 +22,7 @@
 #include <memory>
 #include <vector>
 #include <set>
+#include <map>
 
 #include <com/sun/star/container/XIndexContainer.hpp>
 #include <com/sun/star/form/XForm.hpp>
@@ -398,6 +399,9 @@ public:
     bool m_bParaDotLeaders : 1;       // for TOC dot leaders
     // 25
 
+    /// Tracks which text portion attributes are currently open: a which id -> open count map.
+    std::map<sal_uInt16, int> maStartedAttributes;
+
     explicit SwHTMLWriter( const OUString& rBaseURL );
     virtual ~SwHTMLWriter() override;
 
commit 2ec8c75c1fccd1a4a59cfa14a216da5d0de93e8a
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Dec 31 12:27:39 2018 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:55 2019 -0400

    lok: add signDocument to "Office" iface - to sign not opened docs.
    
    LOKit function "signDocument" can sign document without the need
    to open them. This is useful to sign PDF documents after they are
    created from a currently opened (ODF, DOCX) document.
    
    This adds DocumentDigner to sfx2, which could also be used in
    desktop LibreOffice without opening them and in further tests.
    
    Change-Id: Id6f242e817f594aa672f94f9c6f9b34e4035d46a
    Reviewed-on: https://gerrit.libreoffice.org/65767
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 5fb735838cb8..6291029237e0 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2699,6 +2699,66 @@ void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void DesktopLOKTest::testSignDocument_PEM_PDF()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Load the document, save it into a temp file and load that file again
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(mxComponent.is());
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    Scheduler::ProcessEventsToIdle();
+
+    std::vector<unsigned char> aCertificate;
+    std::vector<unsigned char> aPrivateKey;
+
+    {
+        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "pdf", nullptr));
+
+    closeDoc();
+
+    Scheduler::ProcessEventsToIdle();
+
+    readFileIntoByteVector("test-cert-signing.pem", aCertificate);
+    readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
+
+    LibLibreOffice_Impl aOffice;
+    bool bResult = aOffice.m_pOfficeClass->signDocument(&aOffice, aTempFile.GetURL().toUtf8().getStr(),
+                                         aCertificate.data(), int(aCertificate.size()),
+                                         aPrivateKey.data(), int(aPrivateKey.size()));
+
+    CPPUNIT_ASSERT(bResult);
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 namespace {
 
 constexpr size_t documentClassOffset(int i)
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 55712e87aaea..bce7c5594dca 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -101,6 +101,7 @@
 #include <sfx2/msgpool.hxx>
 #include <sfx2/dispatch.hxx>
 #include <sfx2/lokcharthelper.hxx>
+#include <sfx2/lokhelper.hxx>
 #include <sfx2/DocumentSigner.hxx>
 #include <svx/dialmgr.hxx>
 #include <svx/dialogs.hrc>
commit cd0221e26986cee3909d24510794f2d5bd23233d
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Dec 26 20:46:16 2018 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:54 2019 -0400

    lok: add test signing DOCX -> testInsertCertificate_PEM_DOCX
    
    Change-Id: I1918041793935b012e60fe64073480ed4b9581d5
    Reviewed-on: https://gerrit.libreoffice.org/65630
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/desktop/qa/data/blank_text.docx b/desktop/qa/data/blank_text.docx
new file mode 100644
index 000000000000..028a35b6ca58
Binary files /dev/null and b/desktop/qa/data/blank_text.docx differ
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index b65f81e516c5..5fb735838cb8 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2391,50 +2391,6 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
     CPPUNIT_ASSERT_EQUAL(int(1), nState);
 }
 
-void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
-{
-    comphelper::LibreOfficeKit::setActive();
-
-    // Load the document, save it into a temp file and load that file again
-    LibLODocument_Impl* pDocument = loadDoc("blank_text.docx");
-    utl::TempFile aTempFile;
-    aTempFile.EnableKillingFile();
-    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
-    closeDoc();
-
-    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
-    pDocument = new LibLODocument_Impl(mxComponent);
-
-    Scheduler::ProcessEventsToIdle();
-    CPPUNIT_ASSERT(mxComponent.is());
-    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
-    Scheduler::ProcessEventsToIdle();
-
-    std::vector<unsigned char> aCertificate;
-    std::vector<unsigned char> aPrivateKey;
-
-    {
-        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
-
-        bool bResult = pDocument->m_pDocumentClass->addCertificate(
-                            pDocument, aCertificate.data(), int(aCertificate.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    {
-        readFileIntoByteVector("certificate.der", aCertificate);
-        readFileIntoByteVector("certificatePrivateKey.der", aPrivateKey);
-
-        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
-                            aCertificate.data(), int(aCertificate.size()),
-                            aPrivateKey.data(), int(aPrivateKey.size()));
-        CPPUNIT_ASSERT(bResult);
-    }
-
-    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
-    CPPUNIT_ASSERT_EQUAL(int(5), nState);
-}
-
 void DesktopLOKTest::testSignDocument_PEM_PDF()
 {
     comphelper::LibreOfficeKit::setActive();
@@ -2680,6 +2636,69 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
 
     comphelper::LibreOfficeKit::setActive(false);
 }
+
+void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Load the document, save it into a temp file and load that file again
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.docx");
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
+    closeDoc();
+
+    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+    pDocument = new LibLODocument_Impl(mxComponent);
+
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(mxComponent.is());
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    Scheduler::ProcessEventsToIdle();
+
+    std::vector<unsigned char> aCertificate;
+    std::vector<unsigned char> aPrivateKey;
+
+    {
+        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        readFileIntoByteVector("test-cert-signing.pem", aCertificate);
+        readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
+
+        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
+                            aCertificate.data(), int(aCertificate.size()),
+                            aPrivateKey.data(), int(aPrivateKey.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
+    CPPUNIT_ASSERT_EQUAL(int(5), nState);
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 namespace {
 
 constexpr size_t documentClassOffset(int i)
commit 5ec07d325625dfa6b646d02ebc2c63a8ac5d8f8f
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Dec 26 20:44:57 2018 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:53 2019 -0400

    lok: simplify and cleanup testInsertCertificate_{PEM,DER}_ODT
    
    Change-Id: I61891d1295a342e546cab56ef80315c9f5018f90
    Reviewed-on: https://gerrit.libreoffice.org/65629
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 1c929e23ee64..b65f81e516c5 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -64,6 +64,8 @@ public:
     {
     }
 
+    void readFileIntoByteVector(OUString const & sFilename, std::vector<sal_uInt8> & rByteVector);
+
     virtual void setUp() override
     {
         UnoApiTest::setUp();
@@ -128,7 +130,6 @@ public:
     void testExtractParameter();
     void testGetSignatureState_NonSigned();
     void testGetSignatureState_Signed();
-    void testInsertCertificatePEM();
     void testInsertCertificate_DER_ODT();
     void testInsertCertificate_PEM_ODT();
     void testInsertCertificate_PEM_DOCX();
@@ -181,7 +182,6 @@ public:
     CPPUNIT_TEST(testExtractParameter);
     CPPUNIT_TEST(testGetSignatureState_Signed);
     CPPUNIT_TEST(testGetSignatureState_NonSigned);
-    CPPUNIT_TEST(testInsertCertificatePEM);
     CPPUNIT_TEST(testInsertCertificate_DER_ODT);
     CPPUNIT_TEST(testInsertCertificate_PEM_ODT);
     CPPUNIT_TEST(testInsertCertificate_PEM_DOCX);
@@ -2246,6 +2246,16 @@ void DesktopLOKTest::testExtractParameter()
     CPPUNIT_ASSERT_EQUAL(OUString("Something1,Something2=blah,Something3"), aOptions);
 }
 
+void DesktopLOKTest::readFileIntoByteVector(OUString const & sFilename, std::vector<unsigned char> & rByteVector)
+{
+    rByteVector.clear();
+    OUString aURL;
+    createFileURL(sFilename, aURL);
+    SvFileStream aStream(aURL, StreamMode::READ);
+    rByteVector.resize(aStream.remainingSize());
+    aStream.ReadBytes(rByteVector.data(), aStream.remainingSize());
+}
+
 void DesktopLOKTest::testGetSignatureState_Signed()
 {
     comphelper::LibreOfficeKit::setActive();
@@ -2255,28 +2265,16 @@ void DesktopLOKTest::testGetSignatureState_Signed()
     int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
     CPPUNIT_ASSERT_EQUAL(int(4), nState);
 
+    std::vector<unsigned char> aCertificate;
     {
-        OUString aCertificateURL;
-        createFileURL("rootCA.der", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
+        readFileIntoByteVector("rootCA.der", aCertificate);
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
         CPPUNIT_ASSERT(bResult);
     }
 
     {
-        OUString aCertificateURL;
-        createFileURL("intermediateRootCA.der", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
-
+        readFileIntoByteVector("intermediateRootCA.der", aCertificate);
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
         CPPUNIT_ASSERT(bResult);
@@ -2368,13 +2366,11 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
     pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
     Scheduler::ProcessEventsToIdle();
 
+    std::vector<unsigned char> aCertificate;
+    std::vector<unsigned char> aPrivateKey;
+
     {
-        OUString aCertificateURL;
-        createFileURL("rootCA.der", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+        readFileIntoByteVector("rootCA.der", aCertificate);
 
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
@@ -2426,20 +2422,8 @@ void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
     }
 
     {
-        OUString aCertificateURL;
-        createFileURL("certificate.der", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
-
-        OUString aPrivateKeyURL;
-        createFileURL("certificatePrivateKey.der", aPrivateKeyURL);
-        SvFileStream aPrivateKeyStream(aPrivateKeyURL, StreamMode::READ);
-        std::vector<unsigned char> aPrivateKey;
-        aPrivateKey.resize(aPrivateKeyStream.remainingSize());
-        aPrivateKeyStream.ReadBytes(aPrivateKey.data(), aPrivateKeyStream.remainingSize());
+        readFileIntoByteVector("certificate.der", aCertificate);
+        readFileIntoByteVector("certificatePrivateKey.der", aPrivateKey);
 
         bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
                             aCertificate.data(), int(aCertificate.size()),
@@ -2635,7 +2619,7 @@ void DesktopLOKTest::testComplexSelection()
     CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument));
 }
 
-void DesktopLOKTest::testInsertCertificatePEM()
+void DesktopLOKTest::testInsertCertificate_PEM_ODT()
 {
     comphelper::LibreOfficeKit::setActive();
 
@@ -2654,13 +2638,11 @@ void DesktopLOKTest::testInsertCertificatePEM()
     pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
     Scheduler::ProcessEventsToIdle();
 
+    std::vector<unsigned char> aCertificate;
+    std::vector<unsigned char> aPrivateKey;
+
     {
-        OUString aCertificateURL;
-        createFileURL("test-cert-chain-1.pem", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+        readFileIntoByteVector("test-cert-chain-1.pem", aCertificate);
 
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
@@ -2668,13 +2650,7 @@ void DesktopLOKTest::testInsertCertificatePEM()
     }
 
     {
-        OUString aCertificateURL;
-        createFileURL("test-cert-chain-2.pem", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
+        readFileIntoByteVector("test-cert-chain-2.pem", aCertificate);
 
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
@@ -2682,13 +2658,7 @@ void DesktopLOKTest::testInsertCertificatePEM()
     }
 
     {
-        OUString aCertificateURL;
-        createFileURL("test-cert-chain-3.pem", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
+        readFileIntoByteVector("test-cert-chain-3.pem", aCertificate);
 
         bool bResult = pDocument->m_pDocumentClass->addCertificate(
                             pDocument, aCertificate.data(), int(aCertificate.size()));
@@ -2696,20 +2666,8 @@ void DesktopLOKTest::testInsertCertificatePEM()
     }
 
     {
-        OUString aCertificateURL;
-        createFileURL("test-cert-signing.pem", aCertificateURL);
-        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
-        std::vector<unsigned char> aCertificate;
-        aCertificate.resize(aCertificateStream.remainingSize());
-        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
-
-
-        OUString aPrivateKeyURL;
-        createFileURL("test-PK-signing.pem", aPrivateKeyURL);
-        SvFileStream aPrivateKeyStream(aPrivateKeyURL, StreamMode::READ);
-        std::vector<unsigned char> aPrivateKey;
-        aPrivateKey.resize(aPrivateKeyStream.remainingSize());
-        aPrivateKeyStream.ReadBytes(aPrivateKey.data(), aPrivateKeyStream.remainingSize());
+        readFileIntoByteVector("test-cert-signing.pem", aCertificate);
+        readFileIntoByteVector("test-PK-signing.pem", aPrivateKey);
 
         bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
                             aCertificate.data(), int(aCertificate.size()),
commit 24a61a2388985face5780108df16ed59c5188c59
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Dec 24 15:11:30 2018 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:52 2019 -0400

    Fix signing empty Configurations2/accelerator/current.xml
    
    When determining if a file is an XML file for siging, we need to
    read the manifest file to get an accurate detection. In case when
    we were signing in the GUI the manifest file was read when the
    storage was set. When we didn't sign over the GUI, the manifest
    was never read: the code was only present in the GUI code -
    "documentsignaturesdialog.cxx" so the detection was wrong and
    isXML returned "true" for current.xml.
    With this we move the manifest reading to DigitalSignatureManager,
    where the manifest is read when needed.
    
    Change-Id: If45a32af6410bc5f7c5afdb976b182bd69ab7d6b
    Reviewed-on: https://gerrit.libreoffice.org/65600
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index a20c8bb51533..1c929e23ee64 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2635,7 +2635,6 @@ void DesktopLOKTest::testComplexSelection()
     CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument));
 }
 
-
 void DesktopLOKTest::testInsertCertificatePEM()
 {
     comphelper::LibreOfficeKit::setActive();
@@ -2718,6 +2717,9 @@ void DesktopLOKTest::testInsertCertificatePEM()
         CPPUNIT_ASSERT(bResult);
     }
 
+    int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
+    CPPUNIT_ASSERT_EQUAL(int(1), nState);
+
     comphelper::LibreOfficeKit::setActive(false);
 }
 namespace {
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index d67e08318123..85ad7cb07b1e 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -83,6 +83,8 @@ public:
      * differently when they are signed (c14n transformation)
      */
     bool isXML(const OUString& rURI);
+    bool readManifest();
+
     SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream);
     /// Add a new signature, using xCert as a signing certificate, and rDescription as description.
     bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index d7ea836e2e71..fb39f0f55722 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -36,7 +36,6 @@
 #include <com/sun/star/security/CertificateKind.hpp>
 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
-#include <com/sun/star/packages/manifest/ManifestReader.hpp>
 #include <com/sun/star/system/SystemShellExecute.hpp>
 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
 #include <com/sun/star/system/SystemShellExecuteException.hpp>
@@ -242,26 +241,6 @@ void DigitalSignaturesDialog::SetStorage( const css::uno::Reference < css::embed
 
     maSignatureManager.mxStore = rxStore;
     maSignatureManager.maSignatureHelper.SetStorage( maSignatureManager.mxStore, m_sODFVersion);
-
-    Reference < css::packages::manifest::XManifestReader > xReader =
-        css::packages::manifest::ManifestReader::create(mxCtx);
-
-    uno::Reference<container::XNameAccess> xNameAccess(rxStore, uno::UNO_QUERY);
-    if (!xNameAccess.is())
-        return;
-
-    if (xNameAccess->hasByName("META-INF"))
-    {
-        //Get the manifest.xml
-        Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
-                    "META-INF", css::embed::ElementModes::READ), UNO_QUERY_THROW);
-
-        Reference< css::io::XInputStream > xStream(
-            xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
-            UNO_QUERY_THROW);
-
-        maSignatureManager.m_manifest = xReader->readManifestSequence(xStream);
-    }
 }
 
 void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index c247a40db917..c3641829b4f3 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/packages/manifest/ManifestReader.hpp>
 
 #include <comphelper/base64.hxx>
 #include <comphelper/storagehelper.hxx>
@@ -125,6 +126,40 @@ bool DocumentSignatureManager::IsXAdESRelevant()
 }
 #endif
 
+bool DocumentSignatureManager::readManifest()
+{
+    // Check if manifest was already read
+    if (m_manifest.getLength() > 0)
+        return true;
+
+    if (!mxContext.is())
+        return false;
+
+    if (!mxStore.is())
+        return false;
+
+    uno::Reference<packages::manifest::XManifestReader> xReader
+        = packages::manifest::ManifestReader::create(mxContext);
+
+    uno::Reference<container::XNameAccess> xNameAccess(mxStore, uno::UNO_QUERY);
+    if (!xNameAccess.is())
+        return false;
+
+    if (xNameAccess->hasByName("META-INF"))
+    {
+        //Get the manifest.xml
+        uno::Reference<embed::XStorage> xSubStore(
+            mxStore->openStorageElement("META-INF", embed::ElementModes::READ), UNO_QUERY_THROW);
+
+        uno::Reference<io::XInputStream> xStream(
+            xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
+            UNO_QUERY_THROW);
+
+        m_manifest = xReader->readManifestSequence(xStream);
+    }
+    return true;
+}
+
 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
     We use the manifest to find out if a file is xml and if it is encrypted.
     The parameter is an encoded uri. However, the manifest contains paths. Therefore
@@ -140,27 +175,30 @@ bool DocumentSignatureManager::isXML(const OUString& rURI)
     const OUString sPropMediaType("MediaType");
     const OUString sPropDigest("Digest");
 
-    for (int i = 0; i < m_manifest.getLength(); i++)
+    if (readManifest())
     {
-        const uno::Sequence<beans::PropertyValue>& entry = m_manifest[i];
-        OUString sPath, sMediaType;
-        bool bEncrypted = false;
-        for (int j = 0; j < entry.getLength(); j++)
+        for (int i = 0; i < m_manifest.getLength(); i++)
         {
-            const beans::PropertyValue& prop = entry[j];
-
-            if (prop.Name == sPropFullPath)
-                prop.Value >>= sPath;
-            else if (prop.Name == sPropMediaType)
-                prop.Value >>= sMediaType;
-            else if (prop.Name == sPropDigest)
-                bEncrypted = true;
-        }
-        if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
-        {
-            bIsXML = sMediaType == "text/xml" && !bEncrypted;
-            bPropsAvailable = true;
-            break;
+            const uno::Sequence<beans::PropertyValue>& entry = m_manifest[i];
+            OUString sPath, sMediaType;
+            bool bEncrypted = false;
+            for (int j = 0; j < entry.getLength(); j++)
+            {
+                const beans::PropertyValue& prop = entry[j];
+
+                if (prop.Name == sPropFullPath)
+                    prop.Value >>= sPath;
+                else if (prop.Name == sPropMediaType)
+                    prop.Value >>= sMediaType;
+                else if (prop.Name == sPropDigest)
+                    bEncrypted = true;
+            }
+            if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
+            {
+                bIsXML = sMediaType == "text/xml" && !bEncrypted;
+                bPropsAvailable = true;
+                break;
+            }
         }
     }
     if (!bPropsAvailable)
commit a13047883da3de7f181d8a38b317ff6e05aaeef8
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Nov 29 22:09:07 2018 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:50 2019 -0400

    test signing with certificate chain and private key in PEM format
    
    Change-Id: If3b121e44ceec8be668820a7e8a9e35c15d547ff
    Reviewed-on: https://gerrit.libreoffice.org/64295
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/desktop/qa/data/test-PK-signing.pem b/desktop/qa/data/test-PK-signing.pem
new file mode 100644
index 000000000000..eabbaae18c10
--- /dev/null
+++ b/desktop/qa/data/test-PK-signing.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC/x1dyX2PgJs6o
+e/BcBT5XTJXtipme29mtI/FmTq5vuAFopqvAEg084hNM7Q++wKyKG8F0ABF2pUOY
+vo6Pq6rXQqMbxUaO47NNefh4v/f6hBoMfSYmXtEPji8NjIcIrQ3U8yTWquaHi13h
+coG/cVf16Doem5AxUdQ6a9e/jA1VU2MmSZxthkABKPWdw1pfFJDLWhFrCjhePKrB
+xw2ArmNx66fdzpi5XK0fC2TbHD2NVc8cbYOzF4h3knGZo2sq4/MBevyVhzXZNn2P
+jf3PbOxp1O8CLx86MuDTLDkSVjmP0yXBf6rLFMWtEfv1Jmf3I61meIuOcw6wvXRK
+zPnAKpLRAgMBAAECggEAFQU1JooiGQg9OpEV0ArwbFfZTxy+qH+Rz70oJn3qohWE
+bK4SwTi5TrpmQdZHatxqN7EXIS8out0ebaLlXrCtnG6SEOcsoVjVPGFpb1ggnCAt
+TWp3lgO/3SPz2wOo1rXxKtguaivNR39qc4g+LyJYm9GFHU8RHPbKe6TPvw+2HmtB
+Qr2dfwgN+JJ/lBTIE0lUVuGcBcCRxbM6aG3WVpVrWcsGwRekcuuy9xrv+6fd1p2E
+7zdM0/18+tnCWF9kCO6ot+spKJGTKqiuaKrSB54gFnDEgjQKIW7lUuOcXKI8vOZb
+yO3owLE4mlNbE9sv8gPKoMXf2d6wzMRA6wBdaqOlKQKBgQD1XhyNDTpCoqcO82KY
+YCJOZ6d1jH27XhHplfmrYDlQuWiuJ/b3ckq5Pqw5J5pRO19tvb4RSonYtmOcLajR
+CkQtHapeH8mUzGsE/tgauB4KoZ1sVhzsag0Ill44P5/5oBlzhRrvJ7L80qlHn8xC
+a4Tzk5t0tWbCS6K3/rqvil0hXwKBgQDIFsMoujc8hW5jyC6rO41elWEDVmPs5P+5
+RYxH5+uVeByyz2R86CAFmHUn/1nD47KKouNhwU4Anf5lA8JHh9rNVF07a2dAfH1o
+yfkBGz8d3xb5hq3ahVGg9WyMRyfczGGA19uJrQ19dY4G4B4FPPz0J6oOnNkTFaQ9
+Bks/k/fJzwKBgGSBqVZJzcyPzbh9D6z06/iL0vd+ld4TGWlCKqP9ZVzgpbV431va
+sCsTNf6vbzHJDTzplRqGGtLvWvwVY+pEt0p3tVqa0LqnxUqljSXct0mJi+9dkrlw
+c2hKF8wYm9Hnt6UvJ6pA67tOG1MgbM3kNvCDTRFQYQhDbSLLL/NJzP4nAoGAJqhv
+MFE6FtFY0KJ+kcrBt4J46eIpED32Ql9ziPkABTLdqJZ1PcTDWxFnoUCuoTA+8JYk
+BGEKpwfffLjLMnLHDWC9WpuXqVfkCvjqyRHwkd7mW3Nv54ZWjRidzkR5KSm7tN7/
+pYvvzUuHE0D9y9lKrglzy7r2Hb/SqY+rvi7icvUCgYADV2kkky++OmCVLkEg3WUf
+SJkF6jUAVMqlMdjTbySEfCJbxpVwRAiUWWlDD07c5HCBEASi6/NSn06MDb9Fvxo0
+a3m24Aa2c+K4ENj+bj453gdxhtvpeyfSRK+gBEP64iBG92UFJjcwHz5kFCzppPuP
+p+ZtA6JAnV6QPT1EixAOCA==
+-----END PRIVATE KEY-----
diff --git a/desktop/qa/data/test-cert-chain-1.pem b/desktop/qa/data/test-cert-chain-1.pem
new file mode 100644
index 000000000000..3a3407caf613
--- /dev/null
+++ b/desktop/qa/data/test-cert-chain-1.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID+zCCAuOgAwIBAgIUaS0j9S5ZbREDcPMsLlfFE0+oUE0wDQYJKoZIhvcNAQEL
+BQAwajELMAkGA1UEBhMCQ0gxDDAKBgNVBAgMA1p1ZzEMMAoGA1UEBwwDWnVnMRMw
+EQYDVQQKDApWZXJlaWduIEFHMRUwEwYDVQQLDAxCdXNzaW5lcyBEZXAxEzARBgNV
+BAMMCnZlcmVpZ24tY2EwHhcNMTgxMTI0MDAwMDAwWhcNMjMxMjE4MjM1OTU5WjCB
+jzELMAkGA1UEBhMCQ0gxDDAKBgNVBAgTA1p1ZzEMMAoGA1UEBxMDWnVnMRMwEQYD
+VQQKEwpWZXJlaWduIEFHMRUwEwYDVQQLEwxCdXNpbmVzcyBEZXAxODA2BgNVBAMT
+L2YxZmUxZGJhLWZiMDUtNDk5Ni04Zjk1LWE4MTQyMjE5OGRiOS1zZXJ2ZXJzaWRl
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE7WuIkjvhWceJGwLoYN
+2+huR47jlqqb0ez5VMGuZqK8qn1uf0PB6j/OW9B0cdBs65nBTL2CrkZncKov5g/i
+yZADuiezqBtEUr6J74oRBVPWV+e9iNr3M2FMtG/lkpYDpkvNziibMLE4kyhgbbRd
+Q0OHz55mk4Wn3CYAA/a7zhMgCjvT+wPuLXJjLje+2bB4rMv/USlnTN3DINx4i/Vt
+klNNtK5NSaxlkYf1QuyxXeHEJUufVuFY7sG4xZBhh75yUF7Z7836Oi1++DNeuWc/
+YOmsrfu1lqDfYNjb5IpOMz9x2HtmG6V3ETeKQX8GIs34qhG6zA9Up3JkSQsd9qTP
+1QIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCAbYwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBQlN+K7lesKXsDZYQUu4zkqtNBwrjAaBgNVHREEEzARgg93d3cudmVy
+ZWlnbi5jb20wEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBCwUAA4IBAQAx
+86wXlw779hT3Jad4EfuozQycLw4lXLMiGdHuLdRGNdg6faK2p5qaJXFEd13pE/Qn
+AI2z5SpuYr2G3NYJsT3deXi8Yh58AsBSF5UY61xCgITXOW2NaB2gb6L7sL8Uau8i
+BE5yn0r0V6wD3gxG7yJRNPgH7ksELfN1b++BHdvkcodC1H4vHzl0mAJvYaNlPBhd
+LDnGU3GKhZ1r2pF+eXIW7n3BbAi/a7226Or4eTWEjc0footKJeJLfsG4HOcSj+Bi
+LKAeftebGRRsZzuL6tLTzoSiRsEn6Y6GOdxRM21Uu1rvtWmfDyNRuCcKZU8Secqy
+0s1uSGkNr+6wgcWqA+VQ
+-----END CERTIFICATE-----
diff --git a/desktop/qa/data/test-cert-chain-2.pem b/desktop/qa/data/test-cert-chain-2.pem
new file mode 100644
index 000000000000..a31db3f657ab
--- /dev/null
+++ b/desktop/qa/data/test-cert-chain-2.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEdjCCA16gAwIBAgIEW7HqGDANBgkqhkiG9w0BAQsFADBqMQswCQYDVQQGEwJD
+SDEMMAoGA1UECAwDWnVnMQwwCgYDVQQHDANadWcxEzARBgNVBAoMClZlcmVpZ24g
+QUcxFTATBgNVBAsMDEJ1c3NpbmVzIERlcDETMBEGA1UEAwwKdmVyZWlnbi1jYTAe
+Fw0xODEwMDEwOTM0MTZaFw0xOTEwMDEwOTM0MTZaMGoxCzAJBgNVBAYTAkNIMQww
+CgYDVQQIDANadWcxDDAKBgNVBAcMA1p1ZzETMBEGA1UECgwKVmVyZWlnbiBBRzEV
+MBMGA1UECwwMQnVzc2luZXMgRGVwMRMwEQYDVQQDDAp2ZXJlaWduLWNhMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsfpPjrblQuxrHiSLAAyyDgRd66gY
+PRo7lgKZH5NYcBO9VhJNwnvV+fBIVeJI49b+a12TPHjRzJYrkaBAcUxMM8FkZ01A
+mv6JSG4o2ZXV+GWpnWzEJzt9ZXmNZ1MSUlqIGzVZ/eUlXIj4gy57+SZoJURcQGhs
+jpoRgUpYnFsDJk2x77jiOa5ym/N+8HKsOabASMU6VkbIFvUqf62RXWpnQlOhFjGo
+0jvheRGBWbaYKHM3/d+u78w4tmvHqGVDDbsuOluZ39p2jCic9S7CnDkauZB0Afd/
+xgQ0CglpAgY8g4cfMl2zwRmm616PtutqjcE/NoA2JEVN5vP9QZsuXeRpJwIDAQAB
+o4IBIjCCAR4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwLwYDVR0R
+BCgwJoIPd3d3LnZlcmVpZ24uY29tgRNjb250YWN0QHZlcmVpZ24uY29tMBEGA1Ud
+IAQKMAgwBgYEVR0gADCBlwYDVR0jBIGPMIGMgBQlN+K7lesKXsDZYQUu4zkqtNBw
+rqFupGwwajELMAkGA1UEBhMCQ0gxDDAKBgNVBAgMA1p1ZzEMMAoGA1UEBwwDWnVn
+MRMwEQYDVQQKDApWZXJlaWduIEFHMRUwEwYDVQQLDAxCdXNzaW5lcyBEZXAxEzAR
+BgNVBAMMCnZlcmVpZ24tY2GCBFux6hgwHQYDVR0OBBYEFCU34ruV6wpewNlhBS7j
+OSq00HCuMA0GCSqGSIb3DQEBCwUAA4IBAQCG3tf8/tuCNJXby4B7decDNE6bff40
+1ybO17kzekrKj0IO2TatFIG+UDlxDfm2iydEQVoPuRTAgmJD1aq5g4C0ZLyUqmOg
+75Dve6W9+zzxbdI711WKxH+uSj4mTRkFD4Tb7r3VZ1ZyZYnCOMIGB4/lqUK6Ok3a
+2v8XaFcxHt5XhrQtgqd5bBGokQfwYPNVZW9FwXf/8cd59prEOnqlMbZJ7copgwYO
+97abhpy2FUoRWtvDjDLLfdiFQhVY8meDcS/h5mw2aEugew8hnfSEaD5ZcbOf0ZQe
+MOVxKbIzSeUDAFyRY6BPpGVPuJD6QAXRMW6KIWiGoF1taKp5G/nzbzJC
+-----END CERTIFICATE-----
diff --git a/desktop/qa/data/test-cert-chain-3.pem b/desktop/qa/data/test-cert-chain-3.pem
new file mode 100644
index 000000000000..d02dbe0f6aa1
--- /dev/null
+++ b/desktop/qa/data/test-cert-chain-3.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID5zCCAs+gAwIBAgIU0Ar2t+Zp1ZC0Jx1An2HK+e+ghR0wDQYJKoZIhvcNAQEL
+BQAwgY8xCzAJBgNVBAYTAkNIMQwwCgYDVQQIEwNadWcxDDAKBgNVBAcTA1p1ZzET
+MBEGA1UEChMKVmVyZWlnbiBBRzEVMBMGA1UECxMMQnVzaW5lc3MgRGVwMTgwNgYD
+VQQDEy9mMWZlMWRiYS1mYjA1LTQ5OTYtOGY5NS1hODE0MjIxOThkYjktc2VydmVy
+c2lkZTAeFw0xODExMjMyMzAwMDBaFw0yMzExMjQyMjU5NTlaMIGGMYGDMDYGA1UE
+AxMvZjFmZTFkYmEtZmIwNS00OTk2LThmOTUtYTgxNDIyMTk4ZGI5LXVzZXJkZXZp
+Y2UwCQYDVQQGEwJDSDAKBgNVBAcTA1p1ZzAKBgNVBAgTA1p1ZzARBgNVBAoTClZl
+cmVpZ24gQUcwEwYDVQQLEwxCdXNpbmVzcyBEZXAwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDFQ+2fHCdE9ksa/h0aMK/DHPdq3iGWHx6eFsG3yI7RSU/7
+IA/DPht7A4U/a4qw/8PqT9Df9CvNeURXDmIG1S4ZVn7oTlEua9Da5A+HByA6M4Vk
+4meDo/tY6hE8NZy25Q3l0dZvH34eocRe0xhjGajoUo6vGfzzQ+pQPerM1VivraVf
+EZva4b3rCN7XrZkzkBPjEZijLvlk1wKcG5R1teXlEMHiHKiIeECDXmBD406ngWlt
+KzlH2bXZYkfdBSoYXW2eyM/z0kJcY4M/75re0YGMRUPK6Cp1C4F+jIIv8np09bKS
+6lvr/niemJz0BPXapsLOWXsc0Gg9sPiMpwdNbjflAgMBAAGjQjBAMA4GA1UdDwEB
+/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdM4fK3wQY6/nXpgZL
+5Nl5udSGGjANBgkqhkiG9w0BAQsFAAOCAQEAe/6URI5GLBee3OJo00iHXCYMxOoX
+Bi2V6IC1zS6mQlRYDtzbUQAKJrxRVns2+wjeCqKetqSuZ00hM/ipCrnxwb/X0CKY
+4az9Mf9BycYnkmGNKzzskefIlUciaThdc0Ju6RVlCgFXX8vP9iMO3iQ9ET7JS4jB
+oRNFnMeyy4+HG1RwYivi1YjaPNkp7xd8Lqq56VULGY4dKZUieJceFXtYQZHuVgWo
+woAulOZH0IYqTv16tHxLovWGJaWpoMwgWo/c8sk8CfYF5vv9SMxcFnWwNooCRtWI
+HJzs/1zxXIFy9D49PcH0gwkPM66F8bPS8TMpHcyjRDF/TQFzu1JwVyFY0g==
+-----END CERTIFICATE-----
diff --git a/desktop/qa/data/test-cert-signing.pem b/desktop/qa/data/test-cert-signing.pem
new file mode 100644
index 000000000000..8f5c788b53a5
--- /dev/null
+++ b/desktop/qa/data/test-cert-signing.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID3zCCAsmgAwIBAgIUV/4FfTrYMHCb7AxAeI/zAHowUjQwCwYJKoZIhvcNAQEL
+MIGGMYGDMDYGA1UEAxMvZjFmZTFkYmEtZmIwNS00OTk2LThmOTUtYTgxNDIyMTk4
+ZGI5LXVzZXJkZXZpY2UwCQYDVQQGEwJDSDAKBgNVBAcTA1p1ZzAKBgNVBAgTA1p1
+ZzARBgNVBAoTClZlcmVpZ24gQUcwEwYDVQQLEwxCdXNpbmVzcyBEZXAwHhcNMTgx
+MTIzMjMwMDAwWhcNMjMxMTI0MjI1OTU5WjCBjjGBizA+BgNVBAMTNzNub2JKdk9n
+ZkstZjFmZTFkYmEtZmIwNS00OTk2LThmOTUtYTgxNDIyMTk4ZGI5LW9uZXRpbWUw
+CQYDVQQGEwJDSDAKBgNVBAcTA1p1ZzAKBgNVBAgTA1p1ZzARBgNVBAoTClZlcmVp
+Z24gQUcwEwYDVQQLEwxCdXNpbmVzcyBEZXAwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQC/x1dyX2PgJs6oe/BcBT5XTJXtipme29mtI/FmTq5vuAFopqvA
+Eg084hNM7Q++wKyKG8F0ABF2pUOYvo6Pq6rXQqMbxUaO47NNefh4v/f6hBoMfSYm
+XtEPji8NjIcIrQ3U8yTWquaHi13hcoG/cVf16Doem5AxUdQ6a9e/jA1VU2MmSZxt
+hkABKPWdw1pfFJDLWhFrCjhePKrBxw2ArmNx66fdzpi5XK0fC2TbHD2NVc8cbYOz
+F4h3knGZo2sq4/MBevyVhzXZNn2Pjf3PbOxp1O8CLx86MuDTLDkSVjmP0yXBf6rL
+FMWtEfv1Jmf3I61meIuOcw6wvXRKzPnAKpLRAgMBAAGjPzA9MAwGA1UdEwEB/wQC
+MAAwDgYDVR0PAQH/BAQDAgDwMB0GA1UdDgQWBBSjYCO+w2VQgpdkCvoHgdgZzOPz
+BTALBgkqhkiG9w0BAQsDggEBAD6MAP/l4jkJjIJinJ1uPuA6wOVBff1Beb6JV2jo
+ay1099VkFVHe/tEeyDcx2j+a2CSKsLdOoG/RjcBup3XsumxlqQS6r9GjZLwtNkxI
+nFNLqwv2PbXesSLTR1mjm/6BdcjGEgcxllkST2uYb8DMwbASNQT+rvmGy85b3D4m
+tk3scetFWozkfs+lRUql1dWf2aZTcN+IIZlSpxEZu+w1w8yMoDvVV0pCz49d7WIA
+RIXDE8QJpiAqszuCbqsNdAbr/pAyYzIAIfKKuteWaViesdY26pZfCe2JsfUTDWSi
+PDrFAlkbtB5LGYd4Tfliuvud6I/87GZsuWcCYoS4wXDkRS4=
+-----END CERTIFICATE-----
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 7044fe258113..a20c8bb51533 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -128,6 +128,7 @@ public:
     void testExtractParameter();
     void testGetSignatureState_NonSigned();
     void testGetSignatureState_Signed();
+    void testInsertCertificatePEM();
     void testInsertCertificate_DER_ODT();
     void testInsertCertificate_PEM_ODT();
     void testInsertCertificate_PEM_DOCX();
@@ -180,6 +181,7 @@ public:
     CPPUNIT_TEST(testExtractParameter);
     CPPUNIT_TEST(testGetSignatureState_Signed);
     CPPUNIT_TEST(testGetSignatureState_NonSigned);
+    CPPUNIT_TEST(testInsertCertificatePEM);
     CPPUNIT_TEST(testInsertCertificate_DER_ODT);
     CPPUNIT_TEST(testInsertCertificate_PEM_ODT);
     CPPUNIT_TEST(testInsertCertificate_PEM_DOCX);
@@ -2633,6 +2635,91 @@ void DesktopLOKTest::testComplexSelection()
     CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument));
 }
 
+
+void DesktopLOKTest::testInsertCertificatePEM()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Load the document, save it into a temp file and load that file again
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
+    closeDoc();
+
+    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+    pDocument = new LibLODocument_Impl(mxComponent);
+
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(mxComponent.is());
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    Scheduler::ProcessEventsToIdle();
+
+    {
+        OUString aCertificateURL;
+        createFileURL("test-cert-chain-1.pem", aCertificateURL);
+        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
+        std::vector<unsigned char> aCertificate;
+        aCertificate.resize(aCertificateStream.remainingSize());
+        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        OUString aCertificateURL;
+        createFileURL("test-cert-chain-2.pem", aCertificateURL);
+        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
+        std::vector<unsigned char> aCertificate;
+        aCertificate.resize(aCertificateStream.remainingSize());
+        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        OUString aCertificateURL;
+        createFileURL("test-cert-chain-3.pem", aCertificateURL);
+        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
+        std::vector<unsigned char> aCertificate;
+        aCertificate.resize(aCertificateStream.remainingSize());
+        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+
+
+        bool bResult = pDocument->m_pDocumentClass->addCertificate(
+                            pDocument, aCertificate.data(), int(aCertificate.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    {
+        OUString aCertificateURL;
+        createFileURL("test-cert-signing.pem", aCertificateURL);
+        SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
+        std::vector<unsigned char> aCertificate;
+        aCertificate.resize(aCertificateStream.remainingSize());
+        aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+
+
+        OUString aPrivateKeyURL;
+        createFileURL("test-PK-signing.pem", aPrivateKeyURL);
+        SvFileStream aPrivateKeyStream(aPrivateKeyURL, StreamMode::READ);
+        std::vector<unsigned char> aPrivateKey;
+        aPrivateKey.resize(aPrivateKeyStream.remainingSize());
+        aPrivateKeyStream.ReadBytes(aPrivateKey.data(), aPrivateKeyStream.remainingSize());
+
+        bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument,
+                            aCertificate.data(), int(aCertificate.size()),
+                            aPrivateKey.data(), int(aPrivateKey.size()));
+        CPPUNIT_ASSERT(bResult);
+    }
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
 namespace {
 
 constexpr size_t documentClassOffset(int i)
commit 424956c8cc1810f419ec1618bf3e1e7b6eb4c222
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Jun 28 12:30:40 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:49 2019 -0400

    lok: vital to quote nested JSON inserted into a json property.
    
    Somehow this managed to work fine in most browsers, but when
    the Kit/Poco tried to parse JSON to extract viewID it could explode.
    
    Change-Id: I39d2ecc9ee95b7e6f67a23c8b15f9a1d01769ddc

diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 34ee2dc37289..664b2fb16afa 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -142,11 +142,26 @@ void SfxLokHelper::setViewLanguage(int nId, const OUString& rBcp47LanguageTag)
     }
 }
 
+static OString lcl_escapeQuotes(const OString &rStr)
+{
+    if (rStr.getLength() < 1)
+        return rStr;
+    // FIXME: need an optimized 'escape' method for O[U]String.
+    OStringBuffer aBuf(rStr.getLength() + 8);
+    for (sal_Int32 i = 0; i < rStr.getLength(); ++i)
+    {
+        if (rStr[i] == '"' || rStr[i] == '\\')
+            aBuf.append('\\');
+        aBuf.append(rStr[i]);
+    }
+    return aBuf.makeStringAndClear();
+}
+
 void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload)
 {
     OString aPayload = OString("{ \"viewId\": \"") + OString::number(SfxLokHelper::getView(pThisView)) +
                        "\", \"part\": \"" + OString::number(pThisView->getPart()) +
-                       "\", \"" + rKey + "\": \"" + rPayload + "\" }";
+                       "\", \"" + rKey + "\": \"" + lcl_escapeQuotes(rPayload) + "\" }";
 
     pOtherView->libreOfficeKitViewCallback(nType, aPayload.getStr());
 }
commit 384e0d74d880337006a93565b24a26782f808bc6
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 2 13:13:51 2019 -0400
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:48 2019 -0400

    XTransferable2 - add missing 'since' tag on isComplex.
    
    Change-Id: Ib8165edb4d87fb5bbb115fe26b8dbbe5a70bd59a

diff --git a/offapi/com/sun/star/datatransfer/XTransferable2.idl b/offapi/com/sun/star/datatransfer/XTransferable2.idl
index a6b53f0671e2..9fb99e600177 100644
--- a/offapi/com/sun/star/datatransfer/XTransferable2.idl
+++ b/offapi/com/sun/star/datatransfer/XTransferable2.idl
@@ -34,6 +34,8 @@ interface XTransferable2 : com::sun::star::datatransfer::XTransferable
 
     /**
      * Returns true if the selection contains embedded objects or is a large text blob.
+     *
+     * @since LibreOffice 6.4
      */
     boolean isComplex();
 };
commit 229cd323ce63e4a66ef95559c792540ba8b8107a
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Jul 20 11:15:05 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:47 2019 -0400

    lok: minimal implementation of isComplex for calc for now.
    
    Change-Id: Ic4141d30a0ff48a9ec5ecc8e6119d9d779c4a0fc

diff --git a/sc/source/ui/app/seltrans.cxx b/sc/source/ui/app/seltrans.cxx
index 84a0e6b23778..8ac01ec63197 100644
--- a/sc/source/ui/app/seltrans.cxx
+++ b/sc/source/ui/app/seltrans.cxx
@@ -414,4 +414,16 @@ void ScSelectionTransferObj::ObjectReleased()
     TransferableHelper::ObjectReleased();
 }
 
+sal_Bool SAL_CALL ScSelectionTransferObj::isComplex()
+{
+    switch (eMode)
+    {
+    case SC_SELTRANS_CELL:
+    case SC_SELTRANS_CELLS:
+        return false;
+    default:
+        return true;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 583c89c32823..7d37a9821a14 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -242,6 +242,42 @@ void ScTransferObj::AddSupportedFormats()
     }
 }
 
+static ScRange lcl_reduceBlock(ScDocumentUniquePtr &pDoc, ScRange aReducedBlock, bool bIncludeVisual = false)
+{
+    if ((aReducedBlock.aEnd.Col() == MAXCOL || aReducedBlock.aEnd.Row() == MAXROW) &&
+        aReducedBlock.aStart.Tab() == aReducedBlock.aEnd.Tab())
+    {
+        // Shrink the block here so we don't waste time creating huge
+        // output when whole columns or rows are selected.
+
+        SCCOL nPrintAreaEndCol = 0;
+        SCROW nPrintAreaEndRow = 0;
+        if (bIncludeVisual)
+            pDoc->GetPrintArea( aReducedBlock.aStart.Tab(), nPrintAreaEndCol, nPrintAreaEndRow, true );
+
+        // Shrink the area to allow pasting to external applications.
+        // Shrink to real data area for HTML, RTF and RICHTEXT, but include
+        // all objects and top-left area for BITMAP and PNG.
+        SCCOL nStartCol = aReducedBlock.aStart.Col();
+        SCROW nStartRow = aReducedBlock.aStart.Row();
+        SCCOL nEndCol = aReducedBlock.aEnd.Col();
+        SCROW nEndRow = aReducedBlock.aEnd.Row();
+        bool bShrunk = false;
+        pDoc->ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow,
+                                      false, bIncludeVisual /*bStickyTopRow*/, bIncludeVisual /*bStickyLeftCol*/,
+                                      bIncludeVisual /*bConsiderCellNotes*/, bIncludeVisual /*bConsiderCellDrawObjects*/);
+
+        if ( nPrintAreaEndRow > nEndRow )
+            nEndRow = nPrintAreaEndRow;
+
+        if ( nPrintAreaEndCol > nEndCol )
+            nEndCol = nPrintAreaEndCol;
+
+        aReducedBlock = ScRange(nStartCol, nStartRow, aReducedBlock.aStart.Tab(), nEndCol, nEndRow, aReducedBlock.aEnd.Tab());
+    }
+    return aReducedBlock;
+}
+
 bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
 {
     SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
@@ -258,39 +294,11 @@ bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor, const OUSt
             || nFormat == SotClipboardFormatId::BITMAP
             || nFormat == SotClipboardFormatId::PNG;
 
-        if (bReduceBlockFormat && (m_aBlock.aEnd.Col() == MAXCOL || m_aBlock.aEnd.Row() == MAXROW) &&
-                m_aBlock.aStart.Tab() == m_aBlock.aEnd.Tab())
-        {
-            // Shrink the block here so we don't waste time creating huge
-            // output when whole columns or rows are selected.
-
-            SCCOL nPrintAreaEndCol = 0;
-            SCROW nPrintAreaEndRow = 0;
-            const bool bIncludeVisual = (nFormat == SotClipboardFormatId::BITMAP ||
-                    nFormat == SotClipboardFormatId::PNG);
-            if (bIncludeVisual)
-                m_pDoc->GetPrintArea( m_aBlock.aStart.Tab(), nPrintAreaEndCol, nPrintAreaEndRow, true );
-
-            // Shrink the area to allow pasting to external applications.
-            // Shrink to real data area for HTML, RTF and RICHTEXT, but include
-            // all objects and top-left area for BITMAP and PNG.
-            SCCOL nStartCol = aReducedBlock.aStart.Col();
-            SCROW nStartRow = aReducedBlock.aStart.Row();
-            SCCOL nEndCol = aReducedBlock.aEnd.Col();
-            SCROW nEndRow = aReducedBlock.aEnd.Row();
-            bool bShrunk = false;
-            m_pDoc->ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow,
-                    false, bIncludeVisual /*bStickyTopRow*/, bIncludeVisual /*bStickyLeftCol*/,
-                    bIncludeVisual /*bConsiderCellNotes*/, bIncludeVisual /*bConsiderCellDrawObjects*/);
-
-            if ( nPrintAreaEndRow > nEndRow )
-                nEndRow = nPrintAreaEndRow;
-
-            if ( nPrintAreaEndCol > nEndCol )
-                nEndCol = nPrintAreaEndCol;
-
-            aReducedBlock = ScRange(nStartCol, nStartRow, aReducedBlock.aStart.Tab(), nEndCol, nEndRow, aReducedBlock.aEnd.Tab());
-        }
+        const bool bIncludeVisual = (nFormat == SotClipboardFormatId::BITMAP ||
+                                     nFormat == SotClipboardFormatId::PNG);
+
+        if (bReduceBlockFormat)
+            aReducedBlock = lcl_reduceBlock(m_pDoc, m_aBlock, bIncludeVisual);
 
         if ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR )
         {
@@ -543,6 +551,15 @@ bool ScTransferObj::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* p
     return bRet;
 }
 
+sal_Bool SAL_CALL ScTransferObj::isComplex()
+{
+    ScRange aReduced = lcl_reduceBlock(m_pDoc, m_aBlock);
+    size_t nCells = (aReduced.aEnd.Col() - aReduced.aStart.Col() + 1) *
+                    (aReduced.aEnd.Row() - aReduced.aStart.Row() + 1) *
+                    (aReduced.aEnd.Tab() - aReduced.aStart.Tab() + 1);
+    return nCells > 1000;
+}
+
 void ScTransferObj::DragFinished( sal_Int8 nDropAction )
 {
     if ( nDropAction == DND_ACTION_MOVE && !m_bDragWasInternal && !(m_nDragSourceFlags & ScDragSrc::Navigator) )
diff --git a/sc/source/ui/inc/seltrans.hxx b/sc/source/ui/inc/seltrans.hxx
index af73f0adf896..83adb2c11eb2 100644
--- a/sc/source/ui/inc/seltrans.hxx
+++ b/sc/source/ui/inc/seltrans.hxx
@@ -67,6 +67,7 @@ public:
     virtual void        AddSupportedFormats() override;
     virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override;
     virtual void        ObjectReleased() override;
+    virtual sal_Bool SAL_CALL isComplex() override;
 };
 
 #endif
diff --git a/sc/source/ui/inc/transobj.hxx b/sc/source/ui/inc/transobj.hxx
index 211fa8fc7ef2..84a04d61bbfa 100644
--- a/sc/source/ui/inc/transobj.hxx
+++ b/sc/source/ui/inc/transobj.hxx
@@ -76,6 +76,7 @@ public:
     virtual bool        WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId,
                                         const css::datatransfer::DataFlavor& rFlavor ) override;
     virtual void        DragFinished( sal_Int8 nDropAction ) override;
+    virtual sal_Bool SAL_CALL isComplex() override;
 
     ScDocument*         GetDocument() const     { return m_pDoc.get(); }        // owned by ScTransferObj
     const ScRange&      GetRange() const        { return m_aBlock; }
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index d47e3c4d4209..eca952826cc8 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -383,7 +383,7 @@ namespace
     }
 }
 
-sal_Bool SwTransferable::isComplex()
+sal_Bool SAL_CALL SwTransferable::isComplex()
 {
     // Copy into a new Doc so we don't mess with the existing one.
     //FIXME: We *should* be able to avoid this and improve the performance.
diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx
index 76dc2c69c316..ae34f203d2e3 100644
--- a/sw/source/uibase/inc/swdtflvr.hxx
+++ b/sw/source/uibase/inc/swdtflvr.hxx
@@ -150,6 +150,7 @@ protected:
                                         const css::datatransfer::DataFlavor& rFlavor ) override;
     virtual void        DragFinished( sal_Int8 nDropAction ) override;
     virtual void        ObjectReleased() override;
+    virtual sal_Bool SAL_CALL isComplex() override;
 
     using TransferableHelper::StartDrag;
 
commit 4bc90722c69971a2fccf1f1739c9eb092166448c
Author:     Henry Castro <hcastro at collabora.com>
AuthorDate: Tue Nov 13 22:31:25 2018 -0400
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:46 2019 -0400

    add parameter TransformRotationDeltaAngle to .uno:TransformDialog
    
    Change-Id: Ib22ba6956afedf1eea055e0ac3a78c53b4ee5861

diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc
index 2df9fe15843f..a3bf0d5f7f76 100644
--- a/include/svx/svxids.hrc
+++ b/include/svx/svxids.hrc
@@ -240,6 +240,7 @@ class SfxStringItem;
 #define SID_ATTR_TRANSFORM_ROT_X                        TypedWhichId<SfxInt32Item>( SID_SVX_START + 93 )
 #define SID_ATTR_TRANSFORM_ROT_Y                        TypedWhichId<SfxInt32Item>( SID_SVX_START + 94 )
 #define SID_ATTR_TRANSFORM_ANGLE                        TypedWhichId<SfxInt32Item>( SID_SVX_START + 95 )
+#define SID_ATTR_TRANSFORM_DELTA_ANGLE                  TypedWhichId<SfxInt32Item>( SID_SVX_START + 96 )
 #define SID_SIZE_ALL                                    ( SID_SVX_START + 101 )
 #define SID_DRAW_LINE                                   ( SID_SVX_START + 102 )
 #define SID_DRAW_XLINE                                  ( SID_SVX_START + 103 )
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index 9cab797fecd7..b85ec7bba866 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -1530,8 +1530,14 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr)
     }
 
     // rotation
-    if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,true,&pPoolItem)) {
-        nRotateAngle=static_cast<const SfxInt32Item*>(pPoolItem)->GetValue()-nOldRotateAngle;
+    if (SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_DELTA_ANGLE, true, &pPoolItem)) {
+        nRotateAngle = static_cast<const SfxInt32Item*>(pPoolItem)->GetValue() + nOldRotateAngle;
+        bRotate = (nRotateAngle != 0);
+    }
+
+    // rotation
+    if (SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE, true, &pPoolItem)) {
+        nRotateAngle = static_cast<const SfxInt32Item*>(pPoolItem)->GetValue() - nOldRotateAngle;
         bRotate = (nRotateAngle != 0);
     }
 
diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx
index f43cae244dad..913bbaf5c725 100644
--- a/sw/source/uibase/shells/frmsh.cxx
+++ b/sw/source/uibase/shells/frmsh.cxx
@@ -404,20 +404,30 @@ void SwFrameShell::Execute(SfxRequest &rReq)
                 bApplyNewSize = true;
             }
 
-            // RotGrfFlyFrame: Get Value and disable is in SwGrfShell::GetAttrStateForRotation, but the
-            // value setter uses SID_ATTR_TRANSFORM and a group of three values. Rotation is
-            // added now, so use it in this central place. Do no forget to convert angle from
-            // 100th degrees in SID_ATTR_TRANSFORM_ANGLE to 10th degrees in RES_GRFATR_ROTATION
-            if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem))
+            if (pArgs && (pArgs->HasItem(SID_ATTR_TRANSFORM_ANGLE) || pArgs->HasItem(SID_ATTR_TRANSFORM_DELTA_ANGLE)))
             {
-                const sal_uInt32 nNewRot(static_cast<const SfxUInt32Item*>(pItem)->GetValue() / 10);
                 SfxItemSet aSet(rSh.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} );
                 rSh.GetCurAttr(aSet);
                 const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
                 const sal_uInt32 nOldRot(rRotation.GetValue());
 
-                // RotGrfFlyFrame: Rotation change here, SwFlyFrameAttrMgr aMgr is available
-                aMgr.SetRotation(nOldRot, nNewRot, rRotation.GetUnrotatedSize());
+                if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_DELTA_ANGLE, false, &pItem))
+                {
+                    const sal_uInt32 nDeltaRot(static_cast<const SfxUInt32Item*>(pItem)->GetValue() / 10);
+                    aMgr.SetRotation(nOldRot, nOldRot + nDeltaRot, rRotation.GetUnrotatedSize());
+                }
+
+                // RotGrfFlyFrame: Get Value and disable is in SwGrfShell::GetAttrStateForRotation, but the
+                // value setter uses SID_ATTR_TRANSFORM and a group of three values. Rotation is
+                // added now, so use it in this central place. Do no forget to convert angle from
+                // 100th degrees in SID_ATTR_TRANSFORM_ANGLE to 10th degrees in RES_GRFATR_ROTATION
+                if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem))
+                {
+                    const sal_uInt32 nNewRot(static_cast<const SfxUInt32Item*>(pItem)->GetValue() / 10);
+
+                    // RotGrfFlyFrame: Rotation change here, SwFlyFrameAttrMgr aMgr is available
+                    aMgr.SetRotation(nOldRot, nNewRot, rRotation.GetUnrotatedSize());
+                }
             }
 
             if (bApplyNewPos)
commit d90bd1cf4197794f02934f09973c57e90e76e755
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Tue Jun 25 23:45:37 2019 -0400
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:45 2019 -0400

    LOK: Improved selection complexity detection
    
    Only Graphics and OLE now unconditionally
    trigger 'complex' case, and for all others,
    we actually tally the number of text characters.
    
    Currently anything above 512KB is flagged as 'complex'.
    
    Change-Id: I19fbef72f2eb725648b2a18c1ee41b1612d2bac0

diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 283f77dbe221..1b0b594609d0 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -356,7 +356,7 @@ public:
      *
      * @return an element of the LibreOfficeKitSelectionType enum.
      */
-    int getSelectionType(LibreOfficeKitDocument* pThis)
+    int getSelectionType()
     {
         return mpDoc->pClass->getSelectionType(mpDoc);
     }
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index 2b79e897eca6..d47e3c4d4209 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -383,6 +383,42 @@ namespace
     }
 }
 
+sal_Bool SwTransferable::isComplex()
+{
+    // Copy into a new Doc so we don't mess with the existing one.
+    //FIXME: We *should* be able to avoid this and improve the performance.
+    m_pClpDocFac.reset(new SwDocFac);
+    SwDoc* const pTmpDoc = lcl_GetDoc(*m_pClpDocFac);
+
+    pTmpDoc->getIDocumentFieldsAccess()
+        .LockExpFields(); // never update fields - leave text as it is
+    lclOverWriteDoc(*m_pWrtShell, *pTmpDoc);
+
+    sal_Int32 nTextLength = 0;
+    const SwNode* pEndOfContent = &m_pWrtShell->GetDoc()->GetNodes().GetEndOfContent();
+    SwNodes& aNodes = pTmpDoc->GetNodes();
+    for( sal_uLong nIndex = 0; nIndex < aNodes.Count(); ++nIndex)
+    {
+        SwNode& rNd = *aNodes[nIndex];
+        if (&rNd == pEndOfContent)
+            break;
+
+        if (rNd.IsOLENode() || rNd.IsGrfNode())
+            return true; // Complex
+
+        SwTextNode* pTextNode = rNd.GetTextNode();
+        if (pTextNode)
+        {
+            nTextLength += pTextNode->GetText().getLength();
+            if (nTextLength >= 1024 * 512)
+                return true; // Complex
+        }
+    }
+
+    // Simple
+    return false;
+}
+
 bool SwTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
 {
     SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
commit eca866b82fcb5c74ea2eb2e4851da9f85fd58ba6
Author:     Marco Cecchetti <mrcekets at gmail.com>
AuthorDate: Tue Mar 26 15:11:33 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:43 2019 -0400

    lok: update graphic selection callback description
    
    Change-Id: I1ae073cc8e307b5c42aed9b17d405ef36ce4dc43
    Reviewed-on: https://gerrit.libreoffice.org/70569
    Tested-by: Jenkins
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index f2b9ea70018d..61bf237c1caa 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -171,11 +171,40 @@ typedef enum
      */
     LOK_CALLBACK_CURSOR_VISIBLE = 5,
     /**
-     * The size and/or the position of the graphic selection changed and
-     * the rotation angle of the embedded graphic object
+     * The size and/or the position of the graphic selection changed,
+     * the rotation angle of the embedded graphic object, and a property list
+     * which can be used for informing the client about severl properties.
      *
-     * Format is "x, y, width, height, angle", where angle is in 100th
-     * of degree.
+     * Format is "x, y, width, height, angle, { list of properties }",
+     * where angle is in 100th of degree, and the property list is optional.
+     *
+     * The "{ list of properties }" part is in JSON format.
+     * Follow some examples of the property list part:
+     *
+     * 1) when the selected object is an image inserted in Writer:
+     *
+     *      { "isWriterGraphic": true }
+     *
+     * 2) when the selected object is a chart legend:
+     *
+     *      { "isDraggable": true, "isResizable": true, "isRotatable": false }
+     *
+     * 3) when the selected object is a pie segment in a chart:
+     *
+     *      {
+     *          "isDraggable": true,
+     *          "isResizable": false,
+     *          "isRotatable": false,
+     *          "dragInfo": {
+     *              "dragMethod": "PieSegmentDragging",
+     *              "initialOffset": 50,
+     *              "dragDirection": [x, y],
+     *              "svg": "<svg ..."
+     *          }
+     *      }
+     *
+     *      where the "svg" property is a string containing an svg document
+     *      which is a rapresentation of the pie segment.
      */
     LOK_CALLBACK_GRAPHIC_SELECTION = 6,
 
commit 3f6323032e9e93b2984ad6f26df5b4157249daf7
Author:     Marco Cecchetti <marco.cecchetti at collabora.com>
AuthorDate: Wed Apr 10 21:04:51 2019 +0200
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 12:03:42 2019 -0400

    lok: chart: informing the client about selection handling properties
    
    We hijack the chart CID protocol (CID:/classification/ObjectID) by
    inserting information about selection handling properties (draggable,
    resizable, rotatable) btw the classification section and the ObjectID
    section.
    This new section has the form: /Draggable=?:Resizable=?:Rotatable=?
    where in place of '?' there is 0 or 1.
    The hijacking occurs at the ChartController.getSelection method which
    is available through the XSelectionSupplier interface.
    
    Change-Id: Iaf920fe68e59c2595000e43d3fc1f976632cef18
    Reviewed-on: https://gerrit.libreoffice.org/70567
    Tested-by: Jenkins
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>

diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx
index 19500d034afa..22469e396480 100644
--- a/chart2/source/controller/inc/ChartController.hxx
+++ b/chart2/source/controller/inc/ChartController.hxx
@@ -319,6 +319,10 @@ public:
 
     static bool isObjectDeleteable( const css::uno::Any& rSelection );
 
+    bool isSelectedObjectDraggable() const;
+    bool isSelectedObjectResizable() const;
+    bool isSelectedObjectRotatable() const;
+
     void setDrawMode( ChartDrawMode eMode ) { m_eDrawMode = eMode; }
 
     bool isShapeContext() const;
diff --git a/chart2/source/controller/inc/SelectionHelper.hxx b/chart2/source/controller/inc/SelectionHelper.hxx
index b9fe3fc20377..19a40c9a5af2 100644
--- a/chart2/source/controller/inc/SelectionHelper.hxx
+++ b/chart2/source/controller/inc/SelectionHelper.hxx
@@ -38,9 +38,9 @@ public: //methods
     css::uno::Reference< css::drawing::XShape > const & getSelectedAdditionalShape();
     const ObjectIdentifier& getSelectedOID() const { return m_aSelectedOID;}
 
-    bool isResizeableObjectSelected();
-    bool isRotateableObjectSelected( const css::uno::Reference< css::frame::XModel >& xChartModel );
-    bool isDragableObjectSelected();
+    bool isResizeableObjectSelected() const;
+    bool isRotateableObjectSelected( const css::uno::Reference< css::frame::XModel >& xChartModel ) const;
+    bool isDragableObjectSelected() const;
 
     bool isAdditionalShapeSelected() const;
 
diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx
index 625c41c9617f..b1d26f3425ab 100644
--- a/chart2/source/controller/main/ChartController_Tools.cxx
+++ b/chart2/source/controller/main/ChartController_Tools.cxx
@@ -571,6 +571,23 @@ bool ChartController::isObjectDeleteable( const uno::Any& rSelection )
     return false;
 }
 
+bool ChartController::isSelectedObjectDraggable() const
+{
+    return m_aSelection.isDragableObjectSelected();
+}
+
+bool ChartController::isSelectedObjectResizable() const
+{
+    return m_aSelection.isResizeableObjectSelected();
+}
+
+bool ChartController::isSelectedObjectRotatable() const
+{
+    const ChartController* pThis = this;
+    const uno::Reference< frame::XModel >& xChartModel = const_cast<ChartController*>(pThis)->getModel();
+    return m_aSelection.isRotateableObjectSelected(xChartModel);
+}
+
 bool ChartController::isShapeContext() const
 {
     return m_aSelection.isAdditionalShapeSelected() ||
diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx
index 8a4d92b95c6b..1d058138aa49 100644
--- a/chart2/source/controller/main/ChartController_Window.cxx
+++ b/chart2/source/controller/main/ChartController_Window.cxx
@@ -1669,6 +1669,17 @@ uno::Any SAL_CALL ChartController::getSelection()
         OUString aCID( m_aSelection.getSelectedCID() );
         if ( !aCID.isEmpty() )
         {
+            if ( comphelper::LibreOfficeKit::isActive() )
+            {
+                sal_Int32 nPos = aCID.lastIndexOf('/');
+                OUString sFirst = aCID.copy(0, nPos);
+                OUString sSecond = aCID.copy(nPos);
+                aCID = sFirst;
+                aCID += "/Draggable=" + OUString::number(static_cast<int>(isSelectedObjectDraggable()));
+                aCID += ":Resizable=" + OUString::number(static_cast<int>(isSelectedObjectResizable()));
+                aCID += ":Rotatable=" + OUString::number(static_cast<int>(isSelectedObjectRotatable()));
+                aCID += sSecond;
+            }
             aReturn <<= aCID;
         }
         else
diff --git a/chart2/source/controller/main/SelectionHelper.cxx b/chart2/source/controller/main/SelectionHelper.cxx
index 7a7f08c58f3b..a0171bf04706 100644
--- a/chart2/source/controller/main/SelectionHelper.cxx
+++ b/chart2/source/controller/main/SelectionHelper.cxx
@@ -288,7 +288,7 @@ void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper
     }
 }
 
-bool Selection::isResizeableObjectSelected()
+bool Selection::isResizeableObjectSelected() const
 {
     ObjectType eObjectType = m_aSelectedOID.getObjectType();
     switch( eObjectType )
@@ -303,12 +303,12 @@ bool Selection::isResizeableObjectSelected()
     }
 }
 
-bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel )
+bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel ) const
 {
     return SelectionHelper::isRotateableObject( m_aSelectedOID.getObjectCID(), xChartModel );
 }
 
-bool Selection::isDragableObjectSelected()
+bool Selection::isDragableObjectSelected() const
 {
     return m_aSelectedOID.isDragableObject();
 }
diff --git a/chart2/source/inc/ObjectIdentifier.hxx b/chart2/source/inc/ObjectIdentifier.hxx
index 79fb15232c81..87fb5723e3fc 100644
--- a/chart2/source/inc/ObjectIdentifier.hxx
+++ b/chart2/source/inc/ObjectIdentifier.hxx
@@ -164,7 +164,7 @@ public:
     static OUString getDragMethodServiceName( const OUString& rClassifiedIdentifier );
     static OUString getDragParameterString( const OUString& rCID );
     static bool isDragableObject( const OUString& rClassifiedIdentifier );
-    bool isDragableObject();
+    bool isDragableObject() const;
     static bool isRotateableObject( const OUString& rClassifiedIdentifier );
     static bool isMultiClickObject( const OUString& rClassifiedIdentifier );
     static bool areSiblings( const OUString& rCID1, const OUString& rCID2 );//identical object is no sibling
@@ -172,7 +172,7 @@ public:
 
     static OUString getStringForType( ObjectType eObjectType );
     static ObjectType    getObjectType( const OUString& rCID );
-    ObjectType getObjectType();
+    ObjectType getObjectType() const;
 
     static OUString createSeriesSubObjectStub( ObjectType eSubObjectType
                     , const OUString& rSeriesParticle
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx
index 98e61ba1c60c..a6c6530b0886 100644
--- a/chart2/source/tools/ObjectIdentifier.cxx
+++ b/chart2/source/tools/ObjectIdentifier.cxx
@@ -818,7 +818,7 @@ bool ObjectIdentifier::isDragableObject( const OUString& rClassifiedIdentifier )
     return bReturn;
 }
 
-bool ObjectIdentifier::isDragableObject()
+bool ObjectIdentifier::isDragableObject() const
 {
     bool bReturn = false;
     if ( isAutoGeneratedObject() )
@@ -1063,7 +1063,7 @@ ObjectType ObjectIdentifier::getObjectType( const OUString& rCID )
     return eRet;
 }
 
-ObjectType ObjectIdentifier::getObjectType()
+ObjectType ObjectIdentifier::getObjectType() const
 {
     ObjectType eObjectType( OBJECTTYPE_UNKNOWN );
     if ( isAutoGeneratedObject() )
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index f1369c94f83d..b6cd8a3426ef 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -30,6 +30,7 @@
 #include <svdibrow.hxx>
 #endif
 
+#include <osl/thread.h>
 #include <svx/svdoole2.hxx>
 #include <svx/xgrad.hxx>
 #include <svx/xflgrit.hxx>
@@ -55,6 +56,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
 #include <sfx2/lokhelper.hxx>
+#include <sfx2/lokcharthelper.hxx>
 #include <sfx2/viewsh.hxx>
 
 #include <array>
@@ -797,6 +799,7 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
     tools::Rectangle aRect(GetMarkedObjRect());
     tools::Rectangle aSelection(aRect);
 
+    bool bIsChart = false;
     if (bTiledRendering && !aRect.IsEmpty())
     {
         sal_uInt32 nTotalPaintWindows = this->PaintWindowCount();
@@ -805,6 +808,7 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
             const vcl::Window* pWin = dynamic_cast<const vcl::Window*>(this->GetFirstOutputDevice());
             if (pWin && pWin->IsChart())
             {
+                bIsChart = true;
                 const vcl::Window* pViewShellWindow = GetSfxViewShell()->GetEditWindowForActiveOLEObj();
                 if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pWin))
                 {
@@ -856,17 +860,6 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
 
                 sSelection += OString(", ") + OString::number(nRotAngle);
 
-                // true if we are delaing with a RotGrfFlyFrame
-                // (SwVirtFlyDrawObj with a SwGrfNode)
-                bool bWriterGraphic = pO->HasLimitedRotation();
-
-                if (bWriterGraphic)
-                {
-                    nRotAngle *= 10;
-                }
-
-                sSelection += OString(", ") + OString::number(nRotAngle);
-
                 OStringBuffer aExtraInfo;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list