[Libreoffice-commits] core.git: Branch 'libreoffice-6-4-5' - sw/qa sw/source writerfilter/source

Vasily Melenchuk (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 23 14:10:34 UTC 2020


 sw/qa/extras/ooxmlexport/data/tdf120394.docx     |binary
 sw/qa/extras/ooxmlexport/data/tdf132754.docx     |binary
 sw/qa/extras/ooxmlexport/data/tdf83309.docx      |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx       |   55 ++++++++++++++
 sw/qa/extras/rtfimport/rtfimport.cxx             |    5 -
 sw/source/core/doc/number.cxx                    |    7 +
 sw/source/core/text/txttab.cxx                   |   10 ++
 sw/source/filter/ww8/docxattributeoutput.cxx     |    2 
 sw/source/filter/ww8/wrtw8num.cxx                |   32 ++++----
 writerfilter/source/dmapper/NumberingManager.cxx |   90 ++++++++---------------
 writerfilter/source/dmapper/NumberingManager.hxx |    9 +-
 11 files changed, 131 insertions(+), 79 deletions(-)

New commits:
commit 3c09eb16f4e0dea47839adbef66584a6e7bbca63
Author:     Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri May 15 18:36:08 2020 +0300
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Jun 23 16:10:01 2020 +0200

    fix tdf#83309 tdf#120394 tdf#132754: squashed fix backport
    
    SW DOCX import: list import fixes
    
    These changes are already in 6.4, 7.0 branch and
    are resolving set of bugs and regressions related
    to DOCX lists support.
    
    This is a combination of 4 commits.
    
    tdf#120394: docx import: support for w:styleLink
    
    Previous implementation for w:numStyleLink was referring
    just ordinal styles, but there can be another abstract
    list marked with w:styleLink which should be used in
    given context.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94332
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95892
    
    tdf#132754: DOCX import: changed default list start nubmer
    
    Default value for list numbering startAt is zero. If it is not
    proveded numbering starts from this value.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93899
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit f8211e84a5239de25fe6dc45a4bb6b6f8673a1ee)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96048
    
    tdf#120394: DOCX list import: simplify zero width space hack
    
    Since introducion of list format string hack with creation
    of zero-width-space can be much more simple. It was being
    used to indicate existing, but empty list label suffix to
    avoid stripping down numbering.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94383
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95346
    
    tdf#83309: docx import: allow for lists tabstop at zero position
    
    Zero position is valid value for tabstop, but previously it was
    treated as "no tab stop defined". Right now writer distinguishes
    tab stop at zero postion and no tab stop.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95132
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit d2e428d1abb9f2907c0b87d55830e8742f8209b9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95561
    (cherry picked from commit a380a06c1872091e8fa8c810e95a8e1d5dfe1820)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96178
    Change-Id: I9717058e450282dfd3ee84b839f8ec9868787196
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96391
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    Reviewed-by: Vasily Melenchuk <vasily.melenchuk at cib.de>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf120394.docx b/sw/qa/extras/ooxmlexport/data/tdf120394.docx
new file mode 100644
index 000000000000..39bd5886c0fe
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf120394.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf132754.docx b/sw/qa/extras/ooxmlexport/data/tdf132754.docx
new file mode 100644
index 000000000000..baec54f5e0d7
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf132754.docx differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf83309.docx b/sw/qa/extras/ooxmlexport/data/tdf83309.docx
new file mode 100644
index 000000000000..8dfddb6ed201
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf83309.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index f410c889375d..c9d8ed8b24aa 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -237,6 +237,20 @@ DECLARE_OOXMLIMPORT_TEST(testTdf125038c, "tdf125038c.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("email: test at test.test"), aActual);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf83309, "tdf83309.docx")
+{
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    OUString sNodeType;
+
+    // First paragraph does not have tab before
+    sNodeType = parseDump("/root/page/body/txt[1]/Text[1]", "nType");
+    CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Text"), sNodeType);
+
+    // Second paragraph starts with tab
+    sNodeType = parseDump("/root/page/body/txt[2]/Text[1]", "nType");
+    CPPUNIT_ASSERT_EQUAL(OUString("PortionType::TabLeft"), sNodeType);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf121661, "tdf121661.docx")
 {
     xmlDocPtr pXmlSettings = parseExport("word/settings.xml");
@@ -351,6 +365,22 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128889, "tdf128889.fodt")
     assertXPath(pXml, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", "page");
 }
 
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf132754, "tdf132754.docx")
+{
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("0.0.0."), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("0.0.1."), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("0.0.2."), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf129353, "tdf129353.docx")
 {
     CPPUNIT_ASSERT_EQUAL(8, getParagraphs());
@@ -378,6 +408,31 @@ DECLARE_OOXMLEXPORT_TEST(testTdf129353, "tdf129353.docx")
                          aIndexString);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf120394, "tdf120394.docx")
+{
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(OUString("1.2.1"), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+}
+
 DECLARE_OOXMLEXPORT_TEST(testHyphenationAuto, "hyphenation.odt")
 {
     // Explicitly set hyphenation=auto on document level
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 3fe90033be59..d2c2d4d24c8f 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -341,8 +341,7 @@ CPPUNIT_TEST_FIXTURE(Test, testFdo49692)
 
         if (rProp.Name == "Suffix")
         {
-            OUString aExpected(u'\x200B');
-            CPPUNIT_ASSERT_EQUAL(aExpected, rProp.Value.get<OUString>());
+            CPPUNIT_ASSERT(rProp.Value.get<OUString>().isEmpty());
         }
     }
 }
@@ -1367,7 +1366,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf78506)
 
         if (rProp.Name == "Suffix")
             // This was '0', invalid \levelnumbers wasn't ignored.
-            CPPUNIT_ASSERT_EQUAL(CHAR_ZWSP, rProp.Value.get<OUString>().toChar());
+            CPPUNIT_ASSERT(rProp.Value.get<OUString>().isEmpty());
     }
 }
 
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index 481ebfada8eb..c636273e6f54 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -664,6 +664,13 @@ OUString SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVecto
                     if (nPosition >= 0)
                         sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
                 }
+
+                // As a fallback: caller code expects nonempty string as a result.
+                // But if we have empty string (and had no errors before) this is valid result.
+                // So use classical hack with zero-width-space as a string filling.
+                if (sLevelFormat.isEmpty())
+                    sLevelFormat = OUStringChar(CHAR_ZWSP);
+
                 aStr = sLevelFormat;
             }
             else
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
index c2fded221827..37b00c532bae 100644
--- a/sw/source/core/text/txttab.cxx
+++ b/sw/source/core/text/txttab.cxx
@@ -122,7 +122,7 @@ SwTabPortion *SwTextFormatter::NewTabPortion( SwTextFormatInfo &rInf, bool bAuto
 
         // #i24363# tab stops relative to indent
         // nSearchPos: The current position relative to the tabs origin
-        const SwTwips nSearchPos = bRTL ?
+        SwTwips nSearchPos = bRTL ?
                                    nTabLeft - nCurrentAbsPos :
                                    nCurrentAbsPos - nTabLeft;
 
@@ -130,6 +130,14 @@ SwTabPortion *SwTextFormatter::NewTabPortion( SwTextFormatInfo &rInf, bool bAuto
         // any hard set tab stops:
         // Note: If there are no user defined tab stops, there is always a
         // default tab stop.
+
+        // If search is started from zero position (beginning of line), than
+        // lets do it from -1: this will allow to include into account potential
+        // tab stop at zero position. Yes, it will be zero width tab useless
+        // mostly, but this have sense in case of lists.
+        if (nSearchPos == 0)
+            nSearchPos = -1;
+
         const SvxTabStop* pTabStop = m_aLineInf.GetTabStop( nSearchPos, nMyRight );
         if ( pTabStop )
         {
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 478179cf8d0a..efaa4cd7eb9c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6840,7 +6840,7 @@ void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
 
     // indentation
     m_pSerializer->startElementNS(XML_w, XML_pPr);
-    if( nListTabPos != 0 )
+    if( nListTabPos >= 0 )
     {
         m_pSerializer->startElementNS(XML_w, XML_tabs);
         m_pSerializer->singleElementNS( XML_w, XML_tab,
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index d08a7703ce50..aef96bcd23cb 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -493,12 +493,7 @@ void MSWordExportBase::NumberingLevel(
     const vcl::Font* pBulletFont=nullptr;
     rtl_TextEncoding eChrSet=0;
     FontFamily eFamily=FAMILY_DECORATIVE;
-    if (rRule.Get(nLvl).HasListFormat())
-    {
-        // Nothing to construct: we have it already
-        sNumStr = rRule.Get(nLvl).GetListFormat();
-    }
-    else if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
+    if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
         SVX_NUM_BITMAP == rFormat.GetNumberingType())
     {
         // Use bullet
@@ -506,7 +501,9 @@ void MSWordExportBase::NumberingLevel(
     }
     else
     {
-        // Construct list format string from prefix, level numbers and suffix
+        // Create level string
+        // For docx it is not the best way: we can just take it from rRule.Get(nLvl).GetListFormat()
+        // But for compatibility with doc we follow same routine
         if (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType())
         {
             sal_uInt8* pLvlPos = aNumLvlPos;
@@ -517,20 +514,23 @@ void MSWordExportBase::NumberingLevel(
             // now search the nums in the string
             for (sal_uInt8 i = 0; i <= nLvl; ++i)
             {
-                OUString sSrch( OUString::number( i ));
-                sal_Int32 nFnd = sNumStr.indexOf( sSrch );
-                if( -1 != nFnd )
+                OUString sSrch(OUString::number(i));
+                sal_Int32 nFnd = sNumStr.indexOf(sSrch);
+                if (-1 != nFnd)
                 {
-                    *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1 );
+                    *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1);
                     ++pLvlPos;
-                    sNumStr = sNumStr.replaceAt( nFnd, 1, OUString(static_cast<char>(i)) );
+                    sNumStr = sNumStr.replaceAt(nFnd, 1, OUString(static_cast<char>(i)));
                 }
             }
         }
 
-        if (!rFormat.GetPrefix().isEmpty())
-            sNumStr = rFormat.GetPrefix() + sNumStr;
-        sNumStr += rFormat.GetSuffix();
+        if (!rRule.Get(nLvl).HasListFormat())
+        {
+            if (!rFormat.GetPrefix().isEmpty())
+                sNumStr = rFormat.GetPrefix() + sNumStr;
+            sNumStr += rFormat.GetSuffix();
+        }
     }
 
     if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
@@ -582,7 +582,7 @@ void MSWordExportBase::NumberingLevel(
 
     sal_Int16 nIndentAt = 0;
     sal_Int16 nFirstLineIndex = 0;
-    sal_Int16 nListTabPos = 0;
+    sal_Int16 nListTabPos = -1;
 
     // #i86652#
     if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index 764fe2a387a7..b197e4db80c2 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -187,18 +187,16 @@ uno::Sequence<beans::PropertyValue> ListLevel::GetLevelProperties(bool bDefaults
 {
     std::vector<beans::PropertyValue> aNumberingProperties;
 
-    if( m_nIStartAt >= 0)
+    if (m_nIStartAt >= 0)
         aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, m_nIStartAt) );
+    else if (bDefaults)
+        aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, 0));
 
     sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC);
     if( m_nNFC >= 0)
     {
         if (m_xGraphicBitmap.is())
             nNumberFormat = style::NumberingType::BITMAP;
-        else if (m_sBulletChar.isEmpty() && nNumberFormat != style::NumberingType::CHAR_SPECIAL)
-            // w:lvlText is empty, that means no numbering in Word.
-            // CHAR_SPECIAL is handled separately below.
-            nNumberFormat = style::NumberingType::NUMBER_NONE;
         aNumberingProperties.push_back(lcl_makePropVal(PROP_NUMBERING_TYPE, nNumberFormat));
     }
 
@@ -221,8 +219,8 @@ uno::Sequence<beans::PropertyValue> ListLevel::GetLevelProperties(bool bDefaults
         aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_SIZE, m_aGraphicSize));
     }
 
-    if (bDefaults || m_nTabstop != 0)
-        aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, m_nTabstop));
+    if (m_nTabstop.has_value())
+        aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, *m_nTabstop));
 
     //TODO: handling of nFLegal?
     //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
@@ -536,40 +534,14 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
                 if (pLevel.get() && !pLevel->GetBulletChar().isEmpty())
                     sText = pLevel->GetBulletChar( );
 
-                if (sText.isEmpty())
-                {
-                    // Empty <w:lvlText>? Then put a Unicode "zero width space" as a suffix, so LabelFollowedBy is still shown, as in Word.
-                    // With empty suffix, Writer does not show LabelFollowedBy, either.
-                    OUString sSuffix;
-                    auto it = std::find_if(aLvlProps.begin(), aLvlProps.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "NumberingType"; });
-                    if (it != aLvlProps.end())
-                    {
-                        sal_Int16 nNumberFormat = it->Value.get<sal_Int16>();
+                aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PREFIX), OUString("")));
+                aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), OUString("")));
+                aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LIST_FORMAT), sText));
 
-                        // No need for a zero width space without a real LabelFollowedBy.
-                        bool bLabelFollowedBy = true;
-                        it = std::find_if(aLvlProps.begin(), aLvlProps.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "LabelFollowedBy"; });
-                        if (it != aLvlProps.end())
-                        {
-                            sal_Int16 nValue;
-                            if (it->Value >>= nValue)
-                                bLabelFollowedBy = nValue != SvxNumberFormat::NOTHING;
-                        }
-
-                        if (bLabelFollowedBy && nNumberFormat == style::NumberingType::NUMBER_NONE)
-                            sSuffix = OUString(u'\x200B');
-                    }
-                    aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), sSuffix));
-                }
-                else
-                {
-                    aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LIST_FORMAT), sText));
-
-                    // Total count of replacement holders is determining amount of required parent numbering to include
-                    // TODO: not sure how "%" symbol is escaped. This is not supported yet
-                    sal_Int16 nParentNum = comphelper::string::getTokenCount(sText, '%');
-                    aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum));
-                }
+                // Total count of replacement holders is determining amount of required parent numbering to include
+                // TODO: not sure how "%" symbol is escaped. This is not supported yet
+                sal_Int16 nParentNum = comphelper::string::getTokenCount(sText, '%');
+                aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum));
 
                 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_POSITION_AND_SPACE_MODE), sal_Int16(text::PositionAndSpaceMode::LABEL_ALIGNMENT)));
 
@@ -1036,6 +1008,12 @@ void ListsManager::lcl_sprm( Sprm& rSprm )
                 m_pCurrentDefinition->SetNumStyleLink(sStyleName);
             }
             break;
+            case NS_ooxml::LN_CT_AbstractNum_styleLink:
+            {
+                OUString sStyleName = rSprm.getValue()->getString();
+                m_pCurrentDefinition->SetStyleLink(sStyleName);
+            }
+            break;
             case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties
             case NS_ooxml::LN_EG_RPrBase_color:
             case NS_ooxml::LN_EG_RPrBase_u:
@@ -1074,21 +1052,17 @@ void ListsManager::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref
 
 AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId )
 {
-    AbstractListDef::Pointer pAbstractList;
-
-    int nLen = m_aAbstractLists.size( );
-    int i = 0;
-    while ( !pAbstractList.get( ) && i < nLen )
+    for (const auto& listDef : m_aAbstractLists)
     {
-        if ( m_aAbstractLists[i]->GetId( ) == nId )
+        if (listDef->GetId( ) == nId)
         {
-            if ( m_aAbstractLists[i]->GetNumStyleLink().getLength() > 0 )
+            if (listDef->GetNumStyleLink().getLength() > 0)
             {
                 // If the abstract num has a style linked, check the linked style's number id.
                 StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
 
                 const StyleSheetEntryPtr pStyleSheetEntry =
-                    pStylesTable->FindStyleSheetByISTD( m_aAbstractLists[i]->GetNumStyleLink() );
+                    pStylesTable->FindStyleSheetByISTD(listDef->GetNumStyleLink() );
 
                 const StyleSheetPropertyMap* pStyleSheetProperties =
                     dynamic_cast<const StyleSheetPropertyMap*>(pStyleSheetEntry ? pStyleSheetEntry->pProperties.get() : nullptr);
@@ -1098,20 +1072,24 @@ AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId )
                     ListDef::Pointer pList = GetList( pStyleSheetProperties->GetNumId() );
                     if ( pList!=nullptr )
                         return pList->GetAbstractDefinition();
-                    else
-                        pAbstractList = m_aAbstractLists[i];
                 }
 
+                // In stylesheet we did not found anything useful. Try to find base abstractnum having this stylelink
+                for (const auto & baseListDef : m_aAbstractLists)
+                {
+                    if (baseListDef->GetStyleLink() == listDef->GetNumStyleLink())
+                    {
+                        return baseListDef;
+                    }
+                }
             }
-            else
-            {
-                pAbstractList = m_aAbstractLists[i];
-            }
+
+            // Standalone abstract list
+            return listDef;
         }
-        i++;
     }
 
-    return pAbstractList;
+    return nullptr;
 }
 
 ListDef::Pointer ListsManager::GetList( sal_Int32 nId )
diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx
index 3949c3bf7dcd..268322ce9978 100644
--- a/writerfilter/source/dmapper/NumberingManager.hxx
+++ b/writerfilter/source/dmapper/NumberingManager.hxx
@@ -49,7 +49,7 @@ class ListLevel : public PropertyMap
     OUString                               m_sBulletChar;
     css::awt::Size                         m_aGraphicSize;
     css::uno::Reference<css::awt::XBitmap> m_xGraphicBitmap;
-    sal_Int32                                     m_nTabstop;
+    std::optional<sal_Int32>               m_nTabstop;
     tools::SvRef< StyleSheetEntry >          m_pParaStyle;
     bool                                          m_outline;
     bool m_bHasValues = false;
@@ -63,7 +63,6 @@ public:
         ,m_nStartOverride(-1)
         ,m_nNFC(-1)
         ,m_nXChFollow(SvxNumberFormat::LISTTAB)
-        ,m_nTabstop( 0 )
         ,m_outline(false)
         {}
 
@@ -130,6 +129,9 @@ private:
     // The style name linked to.
     OUString                      m_sNumStyleLink;
 
+    // This absract numbering is a base definition for this style
+    OUString                      m_sStyleLink;
+
     /// list id to use for all derived numbering definitions
     boost::optional<OUString> m_oListId;
 
@@ -157,6 +159,9 @@ public:
     void                  SetNumStyleLink(const OUString& sValue) { m_sNumStyleLink = sValue; };
     const OUString&       GetNumStyleLink() const { return m_sNumStyleLink; };
 
+    void                  SetStyleLink(const OUString& sValue) { m_sStyleLink = sValue; };
+    const OUString&       GetStyleLink() const { return m_sStyleLink; };
+
     const OUString& MapListId(OUString const& rId);
 };
 


More information about the Libreoffice-commits mailing list