[Libreoffice-commits] core.git: sw/qa sw/source writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Aug 27 12:00:46 UTC 2021


 sw/qa/extras/ooxmlexport/data/para-style-num-level.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx              |   11 ++++++++
 sw/qa/uitest/styleInspector/styleInspector.py           |   20 ++++++++--------
 sw/qa/uitest/styleInspector/tdf137513.py                |    2 -
 sw/source/core/bastyp/init.cxx                          |    1 
 sw/source/core/unocore/unomapproperties.hxx             |    1 
 sw/source/filter/ww8/docxattributeoutput.cxx            |   13 ++++++++++
 writerfilter/source/dmapper/DomainMapper.cxx            |    6 +++-
 8 files changed, 41 insertions(+), 13 deletions(-)

New commits:
commit 9ea594ffcf4f807306440e4628eecca8c75be8ee
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Aug 27 13:13:45 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Aug 27 14:00:12 2021 +0200

    tdf#137363 DOCX filter: don't loose  <w:ilvl w:val="..."> of paragraph styles
    
    This adds doc model, UNO API and DOCX import/export for this feature.
    The rest is not yet implemented (i.e. no layout, UI, etc.)
    
    An alternative would be to grab-bag the list level of paragraph styles,
    putting it to the doc model directly has the benefit that this is a step
    in the right direction.
    
    Change-Id: Idf7157e8a4177b4c2286d3cfb3d5acf2df845076
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121141
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx b/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx
new file mode 100644
index 000000000000..2de0c50db621
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 4eb9d0d6aa1b..1b6f6cf713d1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -42,6 +42,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf135164_cancelledNumbering, "tdf135164_cancelledN
     CPPUNIT_ASSERT_EQUAL(OUString("i"), getProperty<OUString>(xPara, "ListLabelString"));
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testParaStyleNumLevel)
+{
+    loadAndSave("para-style-num-level.docx");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/styles.xml");
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. a custom list level in a para style was lost on import+export.
+    assertXPath(pXmlDoc, "/w:styles/w:style[@w:styleId='Mystyle']/w:pPr/w:numPr/w:ilvl", "val", "1");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/uitest/styleInspector/styleInspector.py b/sw/qa/uitest/styleInspector/styleInspector.py
index 26e5c5be73a3..acaa85d693fe 100644
--- a/sw/qa/uitest/styleInspector/styleInspector.py
+++ b/sw/qa/uitest/styleInspector/styleInspector.py
@@ -24,7 +24,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without formatting and default style
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -34,7 +34,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with direct formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
 
@@ -52,7 +52,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph direct formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xParDirFormatting = xListBox.getChild('1')
             self.assertEqual(7, len(xParDirFormatting.getChildren()))
@@ -73,7 +73,7 @@ class styleNavigator(UITestCase):
             xParStyle = xListBox.getChild('0')
             self.assertEqual(3, len(xParStyle.getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(136, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(137, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Heading\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
             self.assertEqual(28, len(xParStyle.getChild('1').getChildren()))
 
@@ -107,7 +107,7 @@ class styleNavigator(UITestCase):
             xParStyle = xListBox.getChild('0')
             self.assertEqual(3, len(xParStyle.getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(136, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(137, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Text Body\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
             self.assertEqual(6, len(xParStyle.getChild('1').getChildren()))
 
@@ -142,7 +142,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -152,7 +152,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph metadata showed under direct paragraph formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xParDirFormatting = xListBox.getChild('1')
             self.assertEqual(1, len(xParDirFormatting.getChildren()))
@@ -201,7 +201,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -211,7 +211,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph metadata showed under direct paragraph formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
 
             # Outer bookmark
             xBookmarkFormatting = xListBox.getChild('4')
@@ -257,7 +257,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
 
diff --git a/sw/qa/uitest/styleInspector/tdf137513.py b/sw/qa/uitest/styleInspector/tdf137513.py
index e5a02c8f5637..b030d6e70ba7 100644
--- a/sw/qa/uitest/styleInspector/tdf137513.py
+++ b/sw/qa/uitest/styleInspector/tdf137513.py
@@ -30,7 +30,7 @@ class tdf137513(UITestCase):
             self.assertEqual(2, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
             self.assertEqual("Table Contents\t", get_state_as_dict(xListBox.getChild('0').getChild('1'))['Text'])
-            self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xTableContent = xListBox.getChild('0').getChild('1')
             self.assertEqual(5, len(xTableContent.getChildren()))
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index b3cb99f84675..0ab9a5c8ae84 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -148,6 +148,7 @@ WhichRangesContainer const aBreakSetRange(svl::Items<
 WhichRangesContainer const aTextFormatCollSetRange(svl::Items<
     RES_CHRATR_BEGIN, RES_CHRATR_END-1,
     RES_PARATR_BEGIN, RES_PARATR_END-1,
+    RES_PARATR_LIST_LEVEL, RES_PARATR_LIST_LEVEL,
     RES_FRMATR_BEGIN, RES_FRMATR_END-1,
     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
 
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index 263a712010c0..1830ca2691de 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -438,6 +438,7 @@
                     { u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE,        cppu::UnoType<sal_Int16>::get(),   PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL  },\
                     { u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE,       cppu::UnoType<sal_Int16>::get(),   PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
                     { u"" UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE,  cppu::UnoType<OUString>::get(),         PropertyAttribute::MAYBEVOID,   0},\
+                    { u"" UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL,    cppu::UnoType<sal_Int16>::get(),        PropertyAttribute::MAYBEVOID,   0},\
                     { u"" UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
                     { u"" UNO_NAME_PARA_SHADOW_FORMAT, RES_SHADOW,    cppu::UnoType<css::table::ShadowFormat>::get(),   PROPERTY_NONE, CONVERT_TWIPS},\
                     { u"" UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES,          cppu::UnoType<bool>::get(),     PROPERTY_NONE, MID_TWOLINES},\
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index c447bf7a60c8..b9cfa3c6bd37 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -8829,6 +8829,19 @@ void DocxAttributeOutput::ParaNumRule_Impl( const SwTextNode* pTextNd, sal_Int32
         return;
     }
 
+    if (!pTextNd && nLvl == 0)
+    {
+        // This is a paragraph style and the level would be zero. Then see if the importer set a
+        // custom numbering level.
+        const SfxItemSet* pSet = m_rExport.m_pISet;
+        if (pSet && pSet->HasItem(RES_PARATR_LIST_LEVEL))
+        {
+            // It did, so use that level.
+            const SfxPoolItem* pItem = pSet->GetItem(RES_PARATR_LIST_LEVEL);
+            nLvl = pItem->StaticWhichCast(RES_PARATR_LIST_LEVEL).GetValue();
+        }
+    }
+
     m_pSerializer->startElementNS(XML_w, XML_numPr);
     m_pSerializer->singleElementNS(XML_w, XML_ilvl, FSNS(XML_w, XML_val), OString::number(nLvl));
     m_pSerializer->singleElementNS(XML_w, XML_numId, FSNS(XML_w, XML_val), OString::number(nNumId));
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index f5731e735cbe..9503306b05ec 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1329,8 +1329,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
                 if (pStyleSheetPropertyMap)
                     pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
             }
-            else
-                rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny( static_cast<sal_Int16>(nIntValue) ));
+            rContext->Insert(PROP_NUMBERING_LEVEL, uno::makeAny(static_cast<sal_Int16>(nIntValue)));
         break;
     case NS_ooxml::LN_CT_NumPr_numId:
         {
@@ -1564,6 +1563,9 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
                 StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
                 if (pStyleSheetPropertyMap)
                     pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
+
+                // Prefer outline levels over numbering levels.
+                rContext->Erase(PROP_NUMBERING_LEVEL);
             }
             else
             {


More information about the Libreoffice-commits mailing list