diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-10-16 08:46:54 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-10-16 09:53:35 +0200 |
commit | 33ade4171a1a443fd24e6463a9eaa279f7d778bb (patch) | |
tree | 9f850d200381808809f4f75df9eef80737f51922 | |
parent | 5af582071da444af338c8cd0a9657f73f9a5f52f (diff) |
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.
Change-Id: I0cb1230ee40994f59b816c42f8e7d2ac658b3212
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158013
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/filter/ww8/ww8.cxx | 23 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 12 | ||||
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx | 18 | ||||
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx | bin | 0 -> 13446 bytes | |||
-rw-r--r-- | writerfilter/source/dmapper/SettingsTable.cxx | 23 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLPropertySet.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLPropertySet.hxx | 2 |
7 files changed, 79 insertions, 1 deletions
diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx index 6a858193e776..1d863545578e 100644 --- a/sw/qa/filter/ww8/ww8.cxx +++ b/sw/qa/filter/ww8/ww8.cxx @@ -332,6 +332,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 61319d5e2f3b..42ff0fdf7a09 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -1435,6 +1435,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 Binary files differnew file mode 100644 index 000000000000..91d6686a365e --- /dev/null +++ b/writerfilter/qa/cppunittests/dmapper/data/floattable-wrap-on-all-pages.docx 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 36c41187a560..2c760519b69f 100644 --- a/writerfilter/source/ooxml/OOXMLPropertySet.cxx +++ b/writerfilter/source/ooxml/OOXMLPropertySet.cxx @@ -202,7 +202,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 2c851ab53823..465873963a78 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; |