sw/qa/filter/html/html.cxx         |   44 +++++++++++++++++++++++++++++++++++++
 sw/source/filter/html/htmlfldw.cxx |   26 +++++++++++++++++++--
 2 files changed, 67 insertions(+), 3 deletions(-)

New commits:
commit 419c9f40eca646a59b57486ef13f8b8fefb9ba8f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Aug 9 08:18:41 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Aug 9 10:57:51 2024 +0200

    tdf#160583 sw HTML export: fix empty field content on copy
    
    Regression from e09d7acd6148b8417487a4473fdc038c7e30d1c4 (sw: fix crash
    in OutHTML_SwFormatField(), 2023-04-24), copy a mail merge field to the
    clipboard using the HTML export, the value of that field is now lost.
    
    Digging deeper, this started with
    1916d161902bdd52b8cfa5b29153c8f8c39fce52 (De-static-izing colors in
    SwViewOption, 2023-03-16), previously the field shading setting was not
    part of the view, so the HTML copy of the document could take it into
    account, even if clipboard documents don't have a view.
    
    Fix the problem by shrinking the scope of the "do we have a doc shell"
    check, so field content is exported again, we just assume that no
    shading is wanted for clipboard documents.
    
    Test this via getTransferData(), normal HTML export would work on the
    non-clipboard document that has a doc shell, and then the problem is not
    visible.
    
    Change-Id: Ib9094eb1d5fc51819279fc58c442e5a507ef2e69
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171661
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/filter/html/html.cxx b/sw/qa/filter/html/html.cxx
index 377505da9b14..541d8d277aa7 100644
--- a/sw/qa/filter/html/html.cxx
+++ b/sw/qa/filter/html/html.cxx
@@ -10,6 +10,8 @@
 #include <swmodeltestbase.hxx>
 #include <test/htmltesttools.hxx>
 
+#include <com/sun/star/text/XDependentTextField.hpp>
+
 #include <vcl/gdimtf.hxx>
 
 #include <docsh.hxx>
@@ -19,6 +21,7 @@
 #include <itabenum.hxx>
 #include <wrtsh.hxx>
 #include <cellatr.hxx>
+#include <swdtflvr.hxx>
 
 namespace
 {
@@ -240,6 +243,47 @@ CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSImport)
     // i.e. the table alignment was lost on import.
     CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, eHoriOrient);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testMailmergeCopy)
+{
+    // Given a document with a mail merge field:
+    createSwDoc();
+    uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFieldMaster(
+        xMSF->createInstance(u"com.sun.star.text.FieldMaster.Database"_ustr), 
uno::UNO_QUERY);
+    xFieldMaster->setPropertyValue(u"DataBaseName"_ustr, uno::Any(u"Address 
Book File"_ustr));
+    xFieldMaster->setPropertyValue(u"DataTableName"_ustr, 
uno::Any(u"address"_ustr));
+    xFieldMaster->setPropertyValue(u"DataColumnName"_ustr, 
uno::Any(u"FIRSTNAME"_ustr));
+    uno::Reference<text::XDependentTextField> xField(
+        xMSF->createInstance(u"com.sun.star.text.TextField.Database"_ustr), 
uno::UNO_QUERY);
+    xField->attachTextFieldMaster(xFieldMaster);
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<beans::XPropertySet> xFieldProps(xField, uno::UNO_QUERY);
+    xFieldProps->setPropertyValue(u"Content"_ustr, uno::Any(u"content"_ustr));
+    xText->insertTextContent(xCursor, xField, false);
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->SelAll();
+    rtl::Reference<SwTransferable> xTransferable(new 
SwTransferable(*pWrtShell));
+    xTransferable->Cut();
+
+    // When copying that as HTML:
+    datatransfer::DataFlavor aFlavor;
+    aFlavor.MimeType = "text/html";
+    aFlavor.DataType = cppu::UnoType<uno::Sequence<sal_Int8>>::get();
+    uno::Any aData = xTransferable->getTransferData(aFlavor);
+
+    // Then make sure the field value is part of the HTML produced from the 
clipboard document:
+    uno::Sequence<sal_Int8> aBytes;
+    aData >>= aBytes;
+    SvMemoryStream aMemory;
+    aMemory.WriteBytes(aBytes.getConstArray(), aBytes.getLength());
+    aMemory.Seek(0);
+    htmlDocUniquePtr pHtmlDoc = parseHtmlStream(&aMemory);
+    OUString aContent = getXPathContent(pHtmlDoc, "/html/body/p/text()"_ostr);
+    CPPUNIT_ASSERT_EQUAL(u"content"_ustr, aContent.trim());
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/htmlfldw.cxx 
b/sw/source/filter/html/htmlfldw.cxx
index 65f0d7167d2a..d0288a3887d0 100644
--- a/sw/source/filter/html/htmlfldw.cxx
+++ b/sw/source/filter/html/htmlfldw.cxx
@@ -441,6 +441,26 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
     return rWrt;
 }
 
+namespace
+{
+const SwViewOption* GetViewOptionFromDoc(SwDoc* pDoc)
+{
+    SwDocShell* pDocShell = pDoc->GetDocShell();
+    if (!pDocShell)
+    {
+        return nullptr;
+    }
+
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    if (!pWrtShell)
+    {
+        return nullptr;
+    }
+
+    return pWrtShell->GetViewOptions();
+}
+}
+
 SwHTMLWriter& OutHTML_SwFormatField( SwHTMLWriter& rWrt, const SfxPoolItem& 
rHt )
 {
     const SwFormatField & rField = static_cast<const SwFormatField&>(rHt);
@@ -542,11 +562,11 @@ SwHTMLWriter& OutHTML_SwFormatField( SwHTMLWriter& rWrt, 
const SfxPoolItem& rHt
     {
         const SwTextField *pTextField = rField.GetTextField();
         OSL_ENSURE( pTextField, "Where is the txt fld?" );
-        if (pTextField && rWrt.m_pDoc->GetDocShell() && 
rWrt.m_pDoc->GetDocShell()->GetView())
+        if (pTextField)
         {
+            const SwViewOption* pViewOptions = 
GetViewOptionFromDoc(rWrt.m_pDoc);
             // ReqIF-XHTML doesn't allow specifying a background color.
-            const SwViewOption* pViewOptions = 
rWrt.m_pDoc->GetDocShell()->GetView()->GetWrtShell().GetViewOptions();
-            bool bFieldShadings = pViewOptions->IsFieldShadings() && 
!rWrt.mbReqIF;
+            bool bFieldShadings = pViewOptions && 
pViewOptions->IsFieldShadings() && !rWrt.mbReqIF;
             if (bFieldShadings)
             {
                 // If there is a text portion background started already, that 
should have priority.

Reply via email to