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.