include/xmloff/xmluconv.hxx                   |    3 ++-
 sw/inc/IDocumentSettingAccess.hxx             |    1 +
 sw/qa/uibase/uno/uno.cxx                      |   24 ++++++++++++++++++++++++
 sw/source/core/doc/DocumentSettingManager.cxx |   13 +++++++++++++
 sw/source/core/inc/DocumentSettingManager.hxx |    1 +
 sw/source/core/layout/fly.cxx                 |    6 ++++++
 sw/source/filter/xml/xmlexp.cxx               |    5 ++++-
 sw/source/filter/xml/xmlimp.cxx               |   10 ++++++++++
 sw/source/uibase/uno/SwXDocumentSettings.cxx  |   18 ++++++++++++++++++
 xmloff/source/core/xmluconv.cxx               |   25 +++++++++++++++++++------
 10 files changed, 98 insertions(+), 8 deletions(-)

New commits:
commit 08fa2903df1a7cf9a1647fcf967e4c8b57dad793
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed May 24 11:00:11 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed May 24 12:38:09 2023 +0200

    sw floattable: add a DoNotBreakWrappedTables compat flag
    
    RTF doesn't break floating table across pages, and there is a matching
    DOCX compat flag to handle such documents.
    
    We can ignore floating table info on the model as a workaround, but that
    would mean the info is lost on save, so that's not ideal.
    
    Instead add a new compat flag that disables fly split at a layout level,
    which allows both not splitting tables & retaining the model-level info.
    This commit does the doc model, UNO API, layout & ODT filter, the Word
    filters are not yet updated.
    
    This compat flag is probably quite rare, so introduce a mechanism to
    only write the compat flag when it's true: this way the majority of the
    documents don't need to say anything about it and we can assume "false"
    for them. Also fix two missing xmlTextWriterEndElement() calls in the
    xml dumper.
    
    Change-Id: I32321ec204d7bfe011fcf024b97c906da0db8aae
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152190
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/xmloff/xmluconv.hxx b/include/xmloff/xmluconv.hxx
index 9af40034400a..c9e1bea3c9ec 100644
--- a/include/xmloff/xmluconv.hxx
+++ b/include/xmloff/xmluconv.hxx
@@ -288,7 +288,8 @@ public:
                                   sal_Int16 nType );
 
     static void 
convertPropertySet(css::uno::Sequence<css::beans::PropertyValue>& rProps,
-                        const css::uno::Reference<css::beans::XPropertySet>& 
aProperties);
+                        const css::uno::Reference<css::beans::XPropertySet>& 
aProperties,
+                        const std::initializer_list<std::u16string_view>* 
pOmitFalseValues = nullptr);
     static void 
convertPropertySet(css::uno::Reference<css::beans::XPropertySet> const & 
rProperties,
                         const css::uno::Sequence<css::beans::PropertyValue>& 
aProps);
 
diff --git a/sw/inc/IDocumentSettingAccess.hxx 
b/sw/inc/IDocumentSettingAccess.hxx
index c05e5d54df4b..f8d9bfa2ab59 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -92,6 +92,7 @@ enum class DocumentSettingId
     // tdf#129448: Auto first-line indent should not be effected by line space
     AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE,
     HYPHENATE_URLS, ///< tdf#152952
+    DO_NOT_BREAK_WRAPPED_TABLES,
     // COMPATIBILITY FLAGS END
     BROWSE_MODE,
     HTML_MODE,
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index 6ad35e07466a..dd74cd716ea3 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -510,6 +510,30 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetField)
                          aBookmark.get<std::string>("name"));
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testDoNotBreakWrappedTables)
+{
+    // Given an empty document:
+    createSwDoc();
+
+    // When checking the state of the DoNotBreakWrappedTables compat flag:
+    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 bDoNotBreakWrappedTables{};
+    // Without the accompanying fix in place, this test would have failed with:
+    // An uncaught exception of type 
com.sun.star.beans.UnknownPropertyException
+    // i.e. the compat flag was not recognized.
+    xSettings->getPropertyValue("DoNotBreakWrappedTables") >>= 
bDoNotBreakWrappedTables;
+    // Then make sure it's false by default:
+    CPPUNIT_ASSERT(!bDoNotBreakWrappedTables);
+
+    // And when setting DoNotBreakWrappedTables=true:
+    xSettings->setPropertyValue("DoNotBreakWrappedTables", uno::Any(true));
+    // Then make sure it gets enabled:
+    xSettings->getPropertyValue("DoNotBreakWrappedTables") >>= 
bDoNotBreakWrappedTables;
+    CPPUNIT_ASSERT(bDoNotBreakWrappedTables);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 412d1a56b686..7eb4f9de5f20 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -252,6 +252,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ 
DocumentSettingId id) const
         case DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
             return mbAutoFirstLineIndentDisregardLineSpace;
         case DocumentSettingId::HYPHENATE_URLS: return mbHyphenateURLs;
+        case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES:
+            return mbDoNotBreakWrappedTables;
         case DocumentSettingId::WRAP_AS_CHAR_FLYS_LIKE_IN_OOXML: return 
mbWrapAsCharFlysLikeInOOXML;
         case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return 
mbNoNumberingShowFollowBy;
         case DocumentSettingId::DROP_CAP_PUNCTUATION: return 
mbDropCapPunctuation;
@@ -438,6 +440,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ 
DocumentSettingId id, /*[in]*/ boo
             mbHyphenateURLs = value;
             break;
 
+        case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES:
+            mbDoNotBreakWrappedTables = value;
+            break;
+
         case DocumentSettingId::WRAP_AS_CHAR_FLYS_LIKE_IN_OOXML:
             mbWrapAsCharFlysLikeInOOXML = value;
             break;
@@ -1054,10 +1060,17 @@ void 
sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const
     (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("mbFootnoteInColumnToPageEnd"));
     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
                                 
BAD_CAST(OString::boolean(mbFootnoteInColumnToPageEnd).getStr()));
+    (void)xmlTextWriterEndElement(pWriter);
 
     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbHyphenateURLs"));
     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
                                 
BAD_CAST(OString::boolean(mbHyphenateURLs).getStr()));
+    (void)xmlTextWriterEndElement(pWriter);
+
+    (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("mbDoNotBreakWrappedTables"));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
+                                
BAD_CAST(OString::boolean(mbDoNotBreakWrappedTables).getStr()));
+    (void)xmlTextWriterEndElement(pWriter);
 
     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mnImagePreferredDPI"));
     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
diff --git a/sw/source/core/inc/DocumentSettingManager.hxx 
b/sw/source/core/inc/DocumentSettingManager.hxx
index a1b1d639173e..54d7f2db78d0 100644
--- a/sw/source/core/inc/DocumentSettingManager.hxx
+++ b/sw/source/core/inc/DocumentSettingManager.hxx
@@ -175,6 +175,7 @@ class DocumentSettingManager final :
     sal_Int32 mnImagePreferredDPI;
     bool mbAutoFirstLineIndentDisregardLineSpace;
     bool mbHyphenateURLs = false;
+    bool mbDoNotBreakWrappedTables = false;
     // If this is on as_char flys wrapping will be handled the same like in 
Word
     bool mbWrapAsCharFlysLikeInOOXML;
     bool mbNoNumberingShowFollowBy;
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 253e858ea210..1d762012a111 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -662,6 +662,12 @@ bool SwFlyFrame::IsFlySplitAllowed() const
         return false;
     }
 
+    const IDocumentSettingAccess& rIDSA = 
GetFormat()->getIDocumentSettingAccess();
+    if (rIDSA.get(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES))
+    {
+        return false;
+    }
+
     if (FindFooterOrHeader())
     {
         // Adding a new page would not increase the header/footer area.
diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index ff8cc2ed2c49..693c2b7c6b7b 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -394,7 +394,10 @@ void SwXMLExport::GetConfigurationSettings( Sequence < 
PropertyValue >& rProps)
     if (!xProps.is())
         return;
 
-    SvXMLUnitConverter::convertPropertySet( rProps, xProps );
+    static const std::initializer_list<std::u16string_view> vOmitFalseValues = 
{
+        u"DoNotBreakWrappedTables",
+    };
+    SvXMLUnitConverter::convertPropertySet( rProps, xProps, &vOmitFalseValues 
);
 
     // tdf#144532 if NoEmbDataSet was set, to indicate not to write an embedded
     // database for the case of a temporary mail merge preview document, then
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index e22b40589da6..7ae8c966c46e 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -1302,6 +1302,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence 
< PropertyValue > & aC
     bool bCollapseEmptyCellPara = false;
     bool bAutoFirstLineIndentDisregardLineSpace = false;
     bool bHyphenateURLs = false;
+    bool bDoNotBreakWrappedTables = false;
     bool bDropCapPunctuation = false;
 
     const PropertyValue* currentDatabaseDataSource = nullptr;
@@ -1400,6 +1401,10 @@ void SwXMLImport::SetConfigurationSettings(const 
Sequence < PropertyValue > & aC
                 {
                     bHyphenateURLs = true;
                 }
+                else if (rValue.Name == "DoNotBreakWrappedTables")
+                {
+                    rValue.Value >>= bDoNotBreakWrappedTables;
+                }
                 else if ( rValue.Name == "DropCapPunctuation" )
                     bDropCapPunctuation = true;
             }
@@ -1569,6 +1574,11 @@ void SwXMLImport::SetConfigurationSettings(const 
Sequence < PropertyValue > & aC
         xProps->setPropertyValue("HyphenateURLs", Any(true));
     }
 
+    if (bDoNotBreakWrappedTables)
+    {
+        xProps->setPropertyValue("DoNotBreakWrappedTables", Any(true));
+    }
+
     // LO 7.4 and previous versions had different drop cap punctuation: very 
long dashes.
     // In order to keep backwards compatibility, DropCapPunctuation option is 
written to .odt
     // files, and the default for new documents is 'true'. Files without this 
option
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx 
b/sw/source/uibase/uno/SwXDocumentSettings.cxx
index 9786964a4282..5273bc0e5432 100644
--- a/sw/source/uibase/uno/SwXDocumentSettings.cxx
+++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx
@@ -153,6 +153,7 @@ enum SwDocumentSettingsPropertyHandles
     HANDLE_IMAGE_PREFERRED_DPI,
     HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE,
     HANDLE_HYPHENATE_URLS,
+    HANDLE_DO_NOT_BREAK_WRAPPED_TABLES,
     HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS,
     HANDLE_NO_NUMBERING_SHOW_FOLLOWBY,
     HANDLE_DROP_CAP_PUNCTUATION,
@@ -256,6 +257,7 @@ static rtl::Reference<MasterPropertySetInfo> 
lcl_createSettingsInfo()
         { OUString("ImagePreferredDPI"), HANDLE_IMAGE_PREFERRED_DPI, 
cppu::UnoType<sal_Int32>::get(), 0 },
         { OUString("AutoFirstLineIndentDisregardLineSpace"), 
HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE, cppu::UnoType<bool>::get(), 
0 },
         { OUString("HyphenateURLs"), HANDLE_HYPHENATE_URLS, 
cppu::UnoType<bool>::get(), 0 },
+        { OUString("DoNotBreakWrappedTables"), 
HANDLE_DO_NOT_BREAK_WRAPPED_TABLES, cppu::UnoType<bool>::get(), 0 },
         { OUString("WordLikeWrapForAsCharFlys"), 
HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS, cppu::UnoType<bool>::get(), 0 },
         { OUString("NoNumberingShowFollowBy"), 
HANDLE_NO_NUMBERING_SHOW_FOLLOWBY, cppu::UnoType<bool>::get(), 0 },
         { OUString("DropCapPunctuation"), HANDLE_DROP_CAP_PUNCTUATION, 
cppu::UnoType<bool>::get(), 0 },
@@ -1070,6 +1072,16 @@ void SwXDocumentSettings::_setSingleValue( const 
comphelper::PropertyInfo & rInf
             }
         }
         break;
+        case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
+        {
+            bool bTmp;
+            if (rValue >>= bTmp)
+            {
+                mpDoc->getIDocumentSettingAccess().set(
+                    DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES, bTmp);
+            }
+        }
+        break;
         case HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS:
         {
             bool bTmp;
@@ -1630,6 +1642,12 @@ void SwXDocumentSettings::_getSingleValue( const 
comphelper::PropertyInfo & rInf
                 DocumentSettingId::HYPHENATE_URLS);
         }
         break;
+        case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
+        {
+            rValue <<= mpDoc->getIDocumentSettingAccess().get(
+                DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES);
+        }
+        break;
         case HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS:
         {
             rValue <<= mpDoc->getIDocumentSettingAccess().get(
diff --git a/xmloff/source/core/xmluconv.cxx b/xmloff/source/core/xmluconv.cxx
index 7c16b202681f..a95de5ecb66c 100644
--- a/xmloff/source/core/xmluconv.cxx
+++ b/xmloff/source/core/xmluconv.cxx
@@ -49,6 +49,7 @@
 #include <basegfx/vector/b3dvector.hxx>
 
 #include <sax/tools/converter.hxx>
+#include <comphelper/sequence.hxx>
 
 
 using namespace com::sun::star;
@@ -778,7 +779,8 @@ void SvXMLUnitConverter::convertNumLetterSync( 
OUStringBuffer& rBuffer,
 }
 
 void 
SvXMLUnitConverter::convertPropertySet(uno::Sequence<beans::PropertyValue>& 
rProps,
-                    const uno::Reference<beans::XPropertySet>& aProperties)
+                    const uno::Reference<beans::XPropertySet>& aProperties,
+                    const std::initializer_list<std::u16string_view>* 
pOmitFalseValues)
 {
     uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = 
aProperties->getPropertySetInfo();
     if (!xPropertySetInfo.is())
@@ -787,14 +789,25 @@ void 
SvXMLUnitConverter::convertPropertySet(uno::Sequence<beans::PropertyValue>&
     const uno::Sequence< beans::Property > aProps = 
xPropertySetInfo->getProperties();
     if (aProps.hasElements())
     {
-        rProps.realloc(aProps.getLength());
-        beans::PropertyValue* pProps = rProps.getArray();
+        std::vector<beans::PropertyValue> aPropsVec;
         for (const auto& rProp : aProps)
         {
-            pProps->Name = rProp.Name;
-            pProps->Value = aProperties->getPropertyValue(rProp.Name);
-            ++pProps;
+            uno::Any aPropertyValue = 
aProperties->getPropertyValue(rProp.Name);
+            if (pOmitFalseValues && aPropertyValue.has<bool>() && 
!aPropertyValue.get<bool>())
+            {
+                const std::initializer_list<std::u16string_view>& 
rOmitFalseValues = *pOmitFalseValues;
+                if (std::find(rOmitFalseValues.begin(), 
rOmitFalseValues.end(), rProp.Name) != rOmitFalseValues.end())
+                {
+                    continue;
+                }
+            }
+
+            beans::PropertyValue aValue;
+            aValue.Name = rProp.Name;
+            aValue.Value = aPropertyValue;
+            aPropsVec.push_back(aValue);
         }
+        rProps = comphelper::containerToSequence(aPropsVec);
     }
 }
 

Reply via email to