editeng/source/items/paraitem.cxx                                              
|    2 
 sw/qa/extras/ooxmlexport/data/tdf160518_allowHyphenationAtTrackBottom.docx     
|binary
 sw/qa/extras/ooxmlexport/data/tdf160518_useWord2013TrackBottomHyphenation.docx 
|binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx                                     
|   64 ++++++++++
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx                       
|    3 
 writerfilter/source/dmapper/PropertyIds.cxx                                    
|    1 
 writerfilter/source/dmapper/PropertyIds.hxx                                    
|    1 
 writerfilter/source/dmapper/SettingsTable.cxx                                  
|   17 ++
 writerfilter/source/dmapper/SettingsTable.hxx                                  
|    2 
 9 files changed, 85 insertions(+), 5 deletions(-)

New commits:
commit c8ee0e8f581b8a6e41b1a6b8aa4d40b442c1d463
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Apr 4 14:08:23 2024 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Thu Apr 4 22:46:12 2024 +0200

    tdf160518 DOCX: import hyphenation-keep to fix layout
    
    To fix layout interoperability, import DOCX compatSettings
    allowHyphenationAtTrackBottom and useWord2013TrackBottomHyphenation
    as hyphenation-keep setting "COLUMN", shifting last hyphenated
    lines of pages and columns, like MSO does.
    
    Follow-up to commit 9574a62add8e4901405e12117e75c86c2d2c2f21
    "tdf#132599 cui offapi sw xmloff: implement hyphenate-keep".
    
    Change-Id: Ib2a06efc22a4f30d8f8be8a752460b09d09e97a3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165798
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/editeng/source/items/paraitem.cxx 
b/editeng/source/items/paraitem.cxx
index 3e99813f628d..4103fe2ea521 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -616,7 +616,7 @@ bool    SvxHyphenZoneItem::QueryValue( uno::Any& rVal, 
sal_uInt8 nMemberId ) con
 bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
 {
     nMemberId &= ~CONVERT_TWIPS;
-    sal_Int16 nNewVal = 0;
+    sal_Int32 nNewVal = 0; // sal_Int32 needs for MID_HYPHEN_KEEP
 
     if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS &&
                 nMemberId != MID_HYPHEN_NO_LAST_WORD )
diff --git 
a/sw/qa/extras/ooxmlexport/data/tdf160518_allowHyphenationAtTrackBottom.docx 
b/sw/qa/extras/ooxmlexport/data/tdf160518_allowHyphenationAtTrackBottom.docx
new file mode 100644
index 000000000000..61e81cf1f539
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf160518_allowHyphenationAtTrackBottom.docx 
differ
diff --git 
a/sw/qa/extras/ooxmlexport/data/tdf160518_useWord2013TrackBottomHyphenation.docx
 
b/sw/qa/extras/ooxmlexport/data/tdf160518_useWord2013TrackBottomHyphenation.docx
new file mode 100644
index 000000000000..26acacc462b3
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf160518_useWord2013TrackBottomHyphenation.docx
 differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index a045a03407ff..c33275b62394 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -28,6 +28,8 @@
 #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <editeng/unolingu.hxx>
 
 #include <comphelper/sequenceashashmap.hxx>
 #include <officecfg/Office/Common.hxx>
@@ -1424,6 +1426,68 @@ DECLARE_OOXMLEXPORT_TEST(testTdf159032, 
"tdf124795-5.docx")
     CPPUNIT_ASSERT_EQUAL(57, getPages());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf160518, 
"tdf160518_useWord2013TrackBottomHyphenation.docx")
+{
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+        return;
+
+    // TODO: fix export too
+    if (isExported())
+        return;
+    // This was 2 (without shifting last hyphenated line of the page)
+    CPPUNIT_ASSERT_EQUAL(3, getPages());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf160518_compatible, 
"tdf160518_allowHyphenationAtTrackBottom.docx")
+{
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+        return;
+
+    // TODO: fix export too
+    if (isExported())
+        return;
+    // This is still 2
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf160518_ODT, 
"tdf160518_useWord2013TrackBottomHyphenation.docx")
+{
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+        return;
+
+    // TODO: fix export too
+    if (isExported())
+        return;
+    // This was 2 (without shifting last hyphenated line of the page)
+    CPPUNIT_ASSERT_EQUAL(3, getPages());
+
+    // check compatibility option in ODT export/import, too
+    saveAndReload("writer8");
+
+    CPPUNIT_ASSERT_EQUAL(3, getPages());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf160518_ODT_compatible, 
"tdf160518_allowHyphenationAtTrackBottom.docx")
+{
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+        return;
+
+    // TODO: fix export too
+    if (isExported())
+        return;
+    // This is still 2
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+
+    // check compatibility option in ODT export/import, too
+    saveAndReload("writer8");
+
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testHyphenationAuto)
 {
     loadAndReload("hyphenation.odt");
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index a84b4df75c35..422d643cb7ba 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -1161,7 +1161,8 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
                     // The wording is confusing here. Normally, the paragraph 
style DOES override the table-style.
                     // But for these two special situations, do not override 
the table-style. So the default is false.
                     // If false, then "CompatOverride" the normal behaviour, 
and apply the table-style's value.
-                    bCompatOverride &= 
!m_rDMapper_Impl.GetSettingsTable()->GetCompatSettingValue(u"overrideTableStyleFontSizeAndJustification");
+                    bCompatOverride &= !m_rDMapper_Impl.GetSettingsTable()->
+                        
GetCompatSettingHasAndValue(u"overrideTableStyleFontSizeAndJustification").second;
                 }
 
                 // use table style when no paragraph style setting or a 
docDefault value is applied instead of it
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index b8b4efc06222..316298adfb43 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -102,6 +102,7 @@ namespace
         { PROP_PARA_IS_HYPHENATION, u"ParaIsHyphenation"},
         { PROP_PARA_HYPHENATION_NO_CAPS, u"ParaHyphenationNoCaps"},
         { PROP_PARA_HYPHENATION_ZONE, u"ParaHyphenationZone"},
+        { PROP_PARA_HYPHENATION_KEEP, u"ParaHyphenationKeep"},
         { PROP_PARA_LINE_NUMBER_COUNT, u"ParaLineNumberCount"},
         { PROP_PARA_IS_HANGING_PUNCTUATION, u"ParaIsHangingPunctuation"},
         { PROP_PARA_LINE_SPACING, u"ParaLineSpacing"},
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index b39fcd24fa49..8c0b07a70928 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -248,6 +248,7 @@ enum PropertyIds
         ,PROP_PARA_IS_HYPHENATION
         ,PROP_PARA_HYPHENATION_NO_CAPS
         ,PROP_PARA_HYPHENATION_ZONE
+        ,PROP_PARA_HYPHENATION_KEEP
         ,PROP_PARA_KEEP_TOGETHER
         ,PROP_PARA_LAST_LINE_ADJUST
         ,PROP_PARA_LEFT_MARGIN
diff --git a/writerfilter/source/dmapper/SettingsTable.cxx 
b/writerfilter/source/dmapper/SettingsTable.cxx
index 14a7808d5d44..35683ca531f4 100644
--- a/writerfilter/source/dmapper/SettingsTable.cxx
+++ b/writerfilter/source/dmapper/SettingsTable.cxx
@@ -26,6 +26,7 @@
 
 #include <rtl/ustring.hxx>
 #include <sfx2/zoomitem.hxx>
+#include <com/sun/star/text/ParagraphHyphenationKeepType.hpp>
 #include <com/sun/star/text/XDependentTextField.hpp>
 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -699,10 +700,21 @@ void 
SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& x
         xPropertySet->setPropertyValue("ParaWidows", aAny);
         xPropertySet->setPropertyValue("ParaOrphans", aAny);
     }
+
+    std::pair<bool, bool> aAllow = 
GetCompatSettingHasAndValue(u"allowHyphenationAtTrackBottom");
+    std::pair<bool, bool> aUse = 
GetCompatSettingHasAndValue(u"useWord2013TrackBottomHyphenation");
+    // if allowHyphenationAtTrackBottom is not true and 
useWord2013TrackBottomHyphenation is
+    // not present or it is true, set ParaHyphenationKeep to COLUMN
+    if ( !aAllow.second && ( !aUse.first || aUse.second ) )
+    {
+        uno::Reference<beans::XPropertySet> xPropertySet(xDefault, 
uno::UNO_QUERY);
+        xPropertySet->setPropertyValue("ParaHyphenationKeep", 
uno::Any(text::ParagraphHyphenationKeepType::COLUMN));
+    }
 }
 
-bool SettingsTable::GetCompatSettingValue( std::u16string_view sCompatName ) 
const
+std::pair<bool, bool> SettingsTable::GetCompatSettingHasAndValue( 
std::u16string_view sCompatName ) const
 {
+    bool bHas = false;
     bool bRet = false;
     for (const auto& rProp : m_pImpl->m_aCompatSettings)
     {
@@ -725,10 +737,11 @@ bool SettingsTable::GetCompatSettingValue( 
std::u16string_view sCompatName ) con
             aCurrentCompatSettings[2].Value >>= sVal;
             // if repeated, what happens?  Last one wins
             bRet = sVal.toBoolean();
+            bHas = true;
         }
     }
 
-    return bRet;
+    return std::pair<bool, bool>(bHas, bRet);
 }
 
 //Keep this function in-sync with the one in sw/.../docxattributeoutput.cxx
diff --git a/writerfilter/source/dmapper/SettingsTable.hxx 
b/writerfilter/source/dmapper/SettingsTable.hxx
index f44338aab670..f5ccb1bec96e 100644
--- a/writerfilter/source/dmapper/SettingsTable.hxx
+++ b/writerfilter/source/dmapper/SettingsTable.hxx
@@ -91,7 +91,7 @@ public:
 
     void ApplyProperties(css::uno::Reference<css::text::XTextDocument> const& 
xDoc);
 
-    bool GetCompatSettingValue(std::u16string_view sCompatName) const;
+    std::pair<bool, bool> GetCompatSettingHasAndValue(std::u16string_view 
sCompatName) const;
     sal_Int32 GetWordCompatibilityMode() const;
 
     const OUString& GetCurrentDatabaseDataSource() const;

Reply via email to