sw/qa/filter/ww8/ww8.cxx | 23 ++++++++++ sw/source/filter/ww8/docxexport.cxx | 12 +++++ writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx | 18 +++++++ writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx |binary writerfilter/source/dmapper/SettingsTable.cxx | 23 ++++++++++ writerfilter/source/ooxml/OOXMLPropertySet.cxx | 2 writerfilter/source/ooxml/OOXMLPropertySet.hxx | 2 7 files changed, 79 insertions(+), 1 deletion(-)
New commits: commit 9b5755140b6014c59920dff05e4dc1264905f952 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Oct 16 08:46:54 2023 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue Oct 17 15:02:09 2023 +0200 sw floattable, wrap on all pages: add DOCX filter - map DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK to <w:compatSetting w:name="allowTextAfterFloatingTableBreak"> on export - do the opposite on import - this requires a bit of rework, to avoid routing <w:compatSetting> via a grab-bag when we want to actually read it during import - also expose GetBooleanValue() from the OOXML tokenizer, so dmapper can know when the value of the compat flag is a true-like string. Note that it seems DOC and RTF don't have a matching compat flag for this. (cherry picked from commit 33ade4171a1a443fd24e6463a9eaa279f7d778bb) Change-Id: I0cb1230ee40994f59b816c42f8e7d2ac658b3212 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158070 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx index 2a5fd2c08416..2b1a3087c4c8 100644 --- a/sw/qa/filter/ww8/ww8.cxx +++ b/sw/qa/filter/ww8/ww8.cxx @@ -307,6 +307,29 @@ CPPUNIT_TEST_FIXTURE(Test, testDoNotBreakWrappedTables) assertXPath(pXmlDoc, "/w:settings/w:compat/w:doNotBreakWrappedTables", 1); } +CPPUNIT_TEST_FIXTURE(Test, testAllowTextAfterFloatingTableBreak) +{ + // Given a document with the ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK compat mode enabled: + createSwDoc(); + SwDoc* pDoc = getSwDoc(); + IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess(); + rIDSA.set(DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK, true); + + // When saving to docx: + save("Office Open XML Text"); + + // Then make sure the compat flag is serialized: + xmlDocUniquePtr pXmlDoc = parseExport("word/settings.xml"); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // - XPath '/w:settings/w:compat/w:compatSetting[@w:name='allowTextAfterFloatingTableBreak']' number of nodes is incorrect + // i.e. the compat flag was lost on export. + assertXPath(pXmlDoc, + "/w:settings/w:compat/w:compatSetting[@w:name='allowTextAfterFloatingTableBreak']", + "val", "1"); +} + CPPUNIT_TEST_FIXTURE(Test, testDOCfDontBreakWrappedTables) { // Given a document with fDontBreakWrappedTables: diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 41bfeed89771..e5f751722594 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -1433,6 +1433,18 @@ void DocxExport::WriteSettings() FSNS( XML_w, XML_name ), "compatibilityMode", FSNS( XML_w, XML_uri ), "http://schemas.microsoft.com/office/word", FSNS( XML_w, XML_val ), OString::number(nTargetCompatibilityMode)); + + const IDocumentSettingAccess& rIDSA = m_rDoc.getIDocumentSettingAccess(); + if (rIDSA.get(DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK)) + { + // AllowTextAfterFloatingTableBreak doesn't have its own XML element, it's a + // <w:compatSetting> with a specific name. + pFS->singleElementNS(XML_w, XML_compatSetting, + FSNS(XML_w, XML_name), "allowTextAfterFloatingTableBreak", + FSNS(XML_w, XML_uri), "http://schemas.microsoft.com/office/word", + FSNS(XML_w, XML_val), "1"); + } + pFS->endElementNS( XML_w, XML_compat ); } diff --git a/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx b/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx index 8b36a6170bb0..00d4147bfb05 100644 --- a/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx +++ b/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx @@ -41,6 +41,24 @@ CPPUNIT_TEST_FIXTURE(Test, testDoNotBreakWrappedTables) // set. CPPUNIT_ASSERT(bDoNotBreakWrappedTables); } + +CPPUNIT_TEST_FIXTURE(Test, testAllowTextAfterFloatingTableBreak) +{ + // Given a document with <w:compatSetting w:name="allowTextAfterFloatingTableBreak">: + // When importing that document: + loadFromURL(u"floattable-wrap-on-all-pages.docx"); + + // Then make sure that the matching compat flag is set: + uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xSettings( + xDocument->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); + bool bAllowTextAfterFloatingTableBreak{}; + xSettings->getPropertyValue("AllowTextAfterFloatingTableBreak") + >>= bAllowTextAfterFloatingTableBreak; + // Without the accompanying fix in place, this test would have failed, the compat flag was not + // set. + CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx b/writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx new file mode 100644 index 000000000000..91d6686a365e Binary files /dev/null and b/writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx differ diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index 586d8b752ef9..a6bae79e1e69 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -37,6 +37,8 @@ #include <comphelper/propertysequence.hxx> #include <comphelper/propertyvalue.hxx> #include <comphelper/sequence.hxx> + +#include <ooxml/OOXMLPropertySet.hxx> #include "ConversionHelper.hxx" #include "DomainMapper.hxx" #include "util.hxx" @@ -103,12 +105,16 @@ struct SettingsTable_Impl std::vector<beans::PropertyValue> m_aCompatSettings; uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting; + OUString m_aCurrentCompatSettingName; + OUString m_aCurrentCompatSettingUri; + OUString m_aCurrentCompatSettingValue; OUString m_sCurrentDatabaseDataSource; std::shared_ptr<DocumentProtection> m_pDocumentProtection; std::shared_ptr<WriteProtection> m_pWriteProtection; bool m_bGutterAtTop = false; bool m_bDoNotBreakWrappedTables = false; + bool m_bAllowTextAfterFloatingTableBreak = false; SettingsTable_Impl() : m_nDefaultTabStop( 720 ) //default is 1/2 in @@ -198,14 +204,17 @@ void SettingsTable::lcl_attribute(Id nName, Value & val) m_pImpl->m_aDocVars.back().second = sStringValue; break; case NS_ooxml::LN_CT_CompatSetting_name: + m_pImpl->m_aCurrentCompatSettingName = sStringValue; m_pImpl->m_pCurrentCompatSetting.getArray()[0] = comphelper::makePropertyValue("name", sStringValue); break; case NS_ooxml::LN_CT_CompatSetting_uri: + m_pImpl->m_aCurrentCompatSettingUri = sStringValue; m_pImpl->m_pCurrentCompatSetting.getArray()[1] = comphelper::makePropertyValue("uri", sStringValue); break; case NS_ooxml::LN_CT_CompatSetting_val: + m_pImpl->m_aCurrentCompatSettingValue = sStringValue; m_pImpl->m_pCurrentCompatSetting.getArray()[2] = comphelper::makePropertyValue("val", sStringValue); break; @@ -349,6 +358,15 @@ void SettingsTable::lcl_sprm(Sprm& rSprm) aValue.Name = "compatSetting"; aValue.Value <<= m_pImpl->m_pCurrentCompatSetting; m_pImpl->m_aCompatSettings.push_back(aValue); + + OString aCompatSettingValue = rtl::OUStringToOString( + m_pImpl->m_aCurrentCompatSettingValue, RTL_TEXTENCODING_UTF8); + if (m_pImpl->m_aCurrentCompatSettingName == "allowTextAfterFloatingTableBreak" + && m_pImpl->m_aCurrentCompatSettingUri == "http://schemas.microsoft.com/office/word" + && ooxml::GetBooleanValue(aCompatSettingValue)) + { + m_pImpl->m_bAllowTextAfterFloatingTableBreak = true; + } } } break; @@ -639,6 +657,11 @@ void SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& x xDocumentSettings->setPropertyValue("DoNotBreakWrappedTables", uno::Any(true)); } + if (m_pImpl->m_bAllowTextAfterFloatingTableBreak) + { + xDocumentSettings->setPropertyValue("AllowTextAfterFloatingTableBreak", uno::Any(true)); + } + // Auto hyphenation: turns on hyphenation by default, <w:suppressAutoHyphens/> may still disable it at a paragraph level. // Situation is similar for RTF_WIDOWCTRL, which turns on widow / orphan control by default. if (!(m_pImpl->m_bAutoHyphenation || m_pImpl->m_bNoHyphenateCaps || m_pImpl->m_bWidowControl)) diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.cxx b/writerfilter/source/ooxml/OOXMLPropertySet.cxx index 230a58f34ecf..71ee28507573 100644 --- a/writerfilter/source/ooxml/OOXMLPropertySet.cxx +++ b/writerfilter/source/ooxml/OOXMLPropertySet.cxx @@ -203,7 +203,7 @@ OOXMLValue * OOXMLBinaryValue::clone() const class OOXMLBooleanValue */ -static bool GetBooleanValue(std::string_view pValue) +bool GetBooleanValue(std::string_view pValue) { return pValue == "true" || pValue == "True" diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.hxx b/writerfilter/source/ooxml/OOXMLPropertySet.hxx index 3393050afa23..a9d41c812b40 100644 --- a/writerfilter/source/ooxml/OOXMLPropertySet.hxx +++ b/writerfilter/source/ooxml/OOXMLPropertySet.hxx @@ -94,6 +94,8 @@ public: virtual OOXMLValue* clone() const override; }; +bool GetBooleanValue(std::string_view pValue); + class OOXMLBooleanValue final : public OOXMLValue { bool mbValue;