sw/source/core/unocore/unotext.cxx                                             
|   24 +++
 writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx              
|   24 +++
 writerfilter/qa/cppunittests/dmapper/data/table-style-para-border-spacing.docx 
|binary
 writerfilter/source/dmapper/DomainMapper.cxx                                   
|   67 +++++++---
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx                       
|   48 ++++++-
 writerfilter/source/dmapper/PropertyIds.cxx                                    
|   27 ++--
 writerfilter/source/dmapper/PropertyIds.hxx                                    
|   12 +
 7 files changed, 171 insertions(+), 31 deletions(-)

New commits:
commit 86a5e47b07d5b8140434d24f74230eacaac16bd4
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jun 11 10:49:29 2024 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Thu Jun 13 10:57:22 2024 +0200

    tdf#161443 DOCX import, table style: handle para border in table cell paras
    
    Open the bugdoc, the in-table paragraphs have some top and bottom
    paragraph borders in Word, not in Writer -- because the cell and
    paragraph UNO object both have a property named TopBorder as mentioned
    in commit 39c54c0ef837e0e23a676a4d1fa5da667e18939c (tdf#161443 DOCX
    import, table style: fix para border leaking into cell border,
    2024-06-07).
    
    The previous fix avoided the problem that the unwanted border affects,
    the cell, but re-routing the property to affect the in-table paragraph
    were not done.
    
    Fix the problem by adding 3 new meta-properties with a "Para" prefix for
    all 4 border locations (top/left/bottom/right), this way the paragraph
    borders defined in a table style can affect the in-table paragraphs, but
    not the table cells.
    
    Apart from the border itself, this also affected the border spacing,
    which means that the position of all text inside and below the table is
    now also correct. Unfortunately this also means we need to move away
    from the constexpr frozen container that is only suitable for a limited
    number of items:
    sw/source/writerfilter/dmapper/PropertyIds.cxx:394:6: error: ‘constexpr’ 
evaluation operation count exceeds limit of 33554432 (use 
‘-fconstexpr-ops-limit=’ to increase the limit)
    Returning to std::unordered_map is good enough for our needs.
    
    (cherry picked from commit 013300c751d7a9ede12c1bf1c784254d1c6c5433)
    
    Change-Id: I478f274800a1d0b200f10226438ab4cfd4957b74
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168696
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    (cherry picked from commit dded9c034bd1be2fdac41923ec0724e52505d40b)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168711
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 3f720e452f15..30b89a06e0c4 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -2113,6 +2113,18 @@ lcl_ApplyCellProperties(
             {
                 static const std::initializer_list<std::u16string_view> 
vDenylist = {
                     u"LeftMargin",
+                    u"ParaTopBorder",
+                    u"ParaTopBorderDistance",
+                    u"ParaTopBorderComplexColor",
+                    u"ParaLeftBorder",
+                    u"ParaLeftBorderDistance",
+                    u"ParaLeftBorderComplexColor",
+                    u"ParaBottomBorder",
+                    u"ParaBottomBorderDistance",
+                    u"ParaBottomBorderComplexColor",
+                    u"ParaRightBorder",
+                    u"ParaRightBorderDistance",
+                    u"ParaRightBorderComplexColor",
                 };
                 if (std::find(vDenylist.begin(), vDenylist.end(), rName) == 
vDenylist.end())
                 {
@@ -2251,6 +2263,18 @@ SwXText::convertToTable(
                     u"RightBorder",
                     u"TopBorder",
                     u"VerticalBorder",
+                    u"ParaTopBorder",
+                    u"ParaTopBorderDistance",
+                    u"ParaTopBorderComplexColor",
+                    u"ParaLeftBorder",
+                    u"ParaLeftBorderDistance",
+                    u"ParaLeftBorderComplexColor",
+                    u"ParaBottomBorder",
+                    u"ParaBottomBorderDistance",
+                    u"ParaBottomBorderComplexColor",
+                    u"ParaRightBorder",
+                    u"ParaRightBorderDistance",
+                    u"ParaRightBorderComplexColor",
                 };
                 if (std::find(vDenylist.begin(), vDenylist.end(), 
rTableProperty.Name) == vDenylist.end())
                 {
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
index 5924fb90bc2a..7f7cfd9b008b 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
@@ -229,6 +229,30 @@ CPPUNIT_TEST_FIXTURE(Test, 
testDOCXFloatingTableHeaderBodyOverlap)
     // Fly bottom was 3063, body text top was 7148.
     CPPUNIT_ASSERT_LESS(nBodyTextTop, nFlyBottom);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTableStyleParaBorderSpacing)
+{
+    // Given a document with a table style, table style defines top and bottom 
border for
+    // paragraphs:
+    // When loading that document:
+    loadFromFile(u"table-style-para-border-spacing.docx");
+
+    // Then make sure the in-table paragraph gets its top border:
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xText(xTextDocument->getText(), uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParaEnum = 
xText->createEnumeration();
+    uno::Reference<text::XTextTable> xPara(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xCell(xPara->getCellByName("A1"), uno::UNO_QUERY);
+    xParaEnum = xCell->createEnumeration();
+    uno::Reference<beans::XPropertySet> xParaProps(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+    sal_Int32 nTopBorderDistance{};
+    xParaProps->getPropertyValue("TopBorderDistance") >>= nTopBorderDistance;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 35
+    // - Actual  : 0
+    // i.e. the top and bottom border and its 1pt spacing was not set on the 
in-table paragraph.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(35), nTopBorderDistance);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/table-style-para-border-spacing.docx
 
b/writerfilter/qa/cppunittests/dmapper/data/table-style-para-border-spacing.docx
new file mode 100644
index 000000000000..b8382000b2b5
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/table-style-para-border-spacing.docx
 differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 0c2cb13a3185..36fb00408ddb 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1610,34 +1610,65 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
             PropertyIds eBorderDistId = PropertyIds::INVALID;
 
             const StyleSheetEntryPtr& pEntry = 
GetStyleSheetTable()->GetCurrentEntry();
-            if (pEntry && pEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
-            {
-                // This would map para borders in table style to cell borders, 
avoid that till we
-                // have separate property names for these.
-                break;
-            }
+            bool bInTableStyle = pEntry && pEntry->m_nStyleTypeCode == 
STYLE_TYPE_TABLE;
 
             switch( nSprmId )
             {
             case NS_ooxml::LN_CT_PBdr_top:
-                eBorderId = PROP_TOP_BORDER;
-                eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
-                eBorderDistId = PROP_TOP_BORDER_DISTANCE;
+                if (bInTableStyle)
+                {
+                    eBorderId = PROP_PARA_TOP_BORDER;
+                    eBorderComplexColorId = PROP_PARA_BORDER_TOP_COMPLEX_COLOR;
+                    eBorderDistId = PROP_PARA_TOP_BORDER_DISTANCE;
+                }
+                else
+                {
+                    eBorderId = PROP_TOP_BORDER;
+                    eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
+                    eBorderDistId = PROP_TOP_BORDER_DISTANCE;
+                }
                 break;
             case NS_ooxml::LN_CT_PBdr_left:
-                eBorderId = PROP_LEFT_BORDER;
-                eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
-                eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
+                if (bInTableStyle)
+                {
+                    eBorderId = PROP_PARA_LEFT_BORDER;
+                    eBorderComplexColorId = 
PROP_PARA_BORDER_LEFT_COMPLEX_COLOR;
+                    eBorderDistId = PROP_PARA_LEFT_BORDER_DISTANCE;
+                }
+                else
+                {
+                    eBorderId = PROP_LEFT_BORDER;
+                    eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
+                    eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
+                }
                 break;
             case NS_ooxml::LN_CT_PBdr_bottom:
-                eBorderId = PROP_BOTTOM_BORDER;
-                eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
-                eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
+                if (bInTableStyle)
+                {
+                    eBorderId = PROP_PARA_BOTTOM_BORDER;
+                    eBorderComplexColorId = 
PROP_PARA_BORDER_BOTTOM_COMPLEX_COLOR;
+                    eBorderDistId = PROP_PARA_BOTTOM_BORDER_DISTANCE;
+                }
+                else
+                {
+                    eBorderId = PROP_BOTTOM_BORDER;
+                    eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
+                    eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
+                }
                 break;
             case NS_ooxml::LN_CT_PBdr_right:
-                eBorderId = PROP_RIGHT_BORDER;
-                eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
-                eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
+                if (bInTableStyle)
+                {
+                    eBorderId = PROP_PARA_RIGHT_BORDER;
+                    eBorderComplexColorId = 
PROP_PARA_BORDER_RIGHT_COMPLEX_COLOR;
+                    eBorderDistId = PROP_PARA_RIGHT_BORDER_DISTANCE;
+                }
+                else
+                {
+                    eBorderId = PROP_RIGHT_BORDER;
+                    eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
+                    eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
+                }
                 break;
             case NS_ooxml::LN_CT_PBdr_between:
                 if (m_pImpl->handlePreviousParagraphBorderInBetween())
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 0ecc6701551a..1a25f2c856aa 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -1091,7 +1091,7 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
     std::vector<beans::PropertyValue> aProps;
     std::optional<OUString> oParagraphText;
 
-    for( auto const& eId : aAllTableParaProperties )
+    for( auto eId : aAllTableParaProperties )
     {
         // apply paragraph and character properties of the table style on 
table paragraphs
         // if there is no direct paragraph formatting
@@ -1105,7 +1105,51 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
                 continue;
             }
 
+            PropertyIds eMappedId = eId;
+            switch (eId)
+            {
+                case PROP_PARA_TOP_BORDER:
+                    eMappedId = PROP_TOP_BORDER;
+                    break;
+                case PROP_PARA_TOP_BORDER_DISTANCE:
+                    eMappedId = PROP_TOP_BORDER_DISTANCE;
+                    break;
+                case PROP_PARA_BORDER_TOP_COMPLEX_COLOR:
+                    eMappedId = PROP_BORDER_TOP_COMPLEX_COLOR;
+                    break;
+                case PROP_PARA_LEFT_BORDER:
+                    eMappedId = PROP_LEFT_BORDER;
+                    break;
+                case PROP_PARA_LEFT_BORDER_DISTANCE:
+                    eMappedId = PROP_LEFT_BORDER_DISTANCE;
+                    break;
+                case PROP_PARA_BORDER_LEFT_COMPLEX_COLOR:
+                    eMappedId = PROP_BORDER_LEFT_COMPLEX_COLOR;
+                    break;
+                case PROP_PARA_BOTTOM_BORDER:
+                    eMappedId = PROP_BOTTOM_BORDER;
+                    break;
+                case PROP_PARA_BOTTOM_BORDER_DISTANCE:
+                    eMappedId = PROP_BOTTOM_BORDER_DISTANCE;
+                    break;
+                case PROP_PARA_BORDER_BOTTOM_COMPLEX_COLOR:
+                    eMappedId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
+                    break;
+                case PROP_PARA_RIGHT_BORDER:
+                    eMappedId = PROP_RIGHT_BORDER;
+                    break;
+                case PROP_PARA_RIGHT_BORDER_DISTANCE:
+                    eMappedId = PROP_RIGHT_BORDER_DISTANCE;
+                    break;
+                case PROP_PARA_BORDER_RIGHT_COMPLEX_COLOR:
+                    eMappedId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
+                    break;
+                default:
+                    break;
+            }
+
             OUString sPropertyName = getPropertyName(eId);
+            OUString sMappedPropertyName = getPropertyName(eMappedId);
 
             auto pCellProp = std::find_if(rCellProperties.begin(), 
rCellProperties.end(),
                 [&](const beans::PropertyValue& rProp) { return rProp.Name == 
sPropertyName; });
@@ -1168,7 +1212,7 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
                 if (!aParaStyle.hasValue() || bDocDefault || bCompatOverride) 
try
                 {
                     // apply style setting when the paragraph doesn't modify it
-                    
aProps.push_back(comphelper::makePropertyValue(sPropertyName, 
pCellProp->Value));
+                    
aProps.push_back(comphelper::makePropertyValue(sMappedPropertyName, 
pCellProp->Value));
                     if (eId == PROP_FILL_COLOR)
                     {
                         // we need this for complete import of table-style 
based paragraph background color
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index b8b4efc06222..0b599a0a4a28 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -18,16 +18,13 @@
  */
 #include <rtl/ustring.hxx>
 #include "PropertyIds.hxx"
-#include <frozen/bits/defines.h>
-#include <frozen/bits/elsa_std.h>
-#include <frozen/unordered_map.h>
+#include <unordered_map>
 
 namespace writerfilter::dmapper{
 
-namespace
+OUString getPropertyName( PropertyIds eId )
 {
-    constexpr auto constPropertyMap = frozen::make_unordered_map<PropertyIds, 
std::u16string_view>(
-    {
+    static const std::unordered_map<PropertyIds, std::u16string_view> 
constPropertyMap {
         { PROP_CHAR_WEIGHT, u"CharWeight"},
         { PROP_CHAR_POSTURE, u"CharPosture"},
         { PROP_CHAR_STRIKEOUT, u"CharStrikeout"},
@@ -106,6 +103,18 @@ namespace
         { PROP_PARA_IS_HANGING_PUNCTUATION, u"ParaIsHangingPunctuation"},
         { PROP_PARA_LINE_SPACING, u"ParaLineSpacing"},
         { PROP_PARA_TAB_STOPS, u"ParaTabStops"},
+        { PROP_PARA_TOP_BORDER, u"ParaTopBorder"},
+        { PROP_PARA_TOP_BORDER_DISTANCE, u"ParaTopBorderDistance"},
+        { PROP_PARA_BORDER_TOP_COMPLEX_COLOR, u"ParaTopBorderComplexColor"},
+        { PROP_PARA_LEFT_BORDER, u"ParaLeftBorder"},
+        { PROP_PARA_LEFT_BORDER_DISTANCE, u"ParaLeftBorderDistance"},
+        { PROP_PARA_BORDER_LEFT_COMPLEX_COLOR, u"ParaLeftBorderComplexColor"},
+        { PROP_PARA_BOTTOM_BORDER, u"ParaBottomBorder"},
+        { PROP_PARA_BOTTOM_BORDER_DISTANCE, u"ParaBottomBorderDistance"},
+        { PROP_PARA_BORDER_BOTTOM_COMPLEX_COLOR, 
u"ParaBottomBorderComplexColor"},
+        { PROP_PARA_RIGHT_BORDER, u"ParaRightBorder"},
+        { PROP_PARA_RIGHT_BORDER_DISTANCE, u"ParaRightBorderDistance"},
+        { PROP_PARA_BORDER_RIGHT_COMPLEX_COLOR, 
u"ParaRightBorderComplexColor"},
         { PROP_PARA_WIDOWS, u"ParaWidows"},
         { PROP_PARA_ORPHANS, u"ParaOrphans"},
         { PROP_PARA_LINE_NUMBER_START_VALUE, u"ParaLineNumberStartValue"},
@@ -384,11 +393,7 @@ namespace
         { PROP_PARA_CONNECT_BORDERS, u"ParaIsConnectBorder"},
         { PROP_DECORATIVE, u"Decorative"},
         { PROP_PAPER_TRAY, u"PrinterPaperTray"},
-    });
-} // end anonymous ns
-
-OUString getPropertyName( PropertyIds eId )
-{
+    };
     auto iterator = constPropertyMap.find(eId);
     if (iterator != constPropertyMap.end())
         return OUString(iterator->second);
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index b39fcd24fa49..ba62c34000ed 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -261,6 +261,18 @@ enum PropertyIds
         ,PROP_PARA_TAB_STOPS
         ,PROP_PARA_TOP_MARGIN
         ,PROP_PARA_VERT_ALIGNMENT
+        ,PROP_PARA_TOP_BORDER
+        ,PROP_PARA_TOP_BORDER_DISTANCE
+        ,PROP_PARA_BORDER_TOP_COMPLEX_COLOR
+        ,PROP_PARA_LEFT_BORDER
+        ,PROP_PARA_LEFT_BORDER_DISTANCE
+        ,PROP_PARA_BORDER_LEFT_COMPLEX_COLOR
+        ,PROP_PARA_BOTTOM_BORDER
+        ,PROP_PARA_BOTTOM_BORDER_DISTANCE
+        ,PROP_PARA_BORDER_BOTTOM_COMPLEX_COLOR
+        ,PROP_PARA_RIGHT_BORDER
+        ,PROP_PARA_RIGHT_BORDER_DISTANCE
+        ,PROP_PARA_BORDER_RIGHT_COMPLEX_COLOR
         ,PROP_PARA_WIDOWS
         ,PROP_PAPER_TRAY
         ,PROP_PARENT_NUMBERING

Reply via email to