sw/qa/extras/ooxmlexport/data/tdf144668.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx  |    9 +++++++++
 sw/source/filter/ww8/wrtw8num.cxx           |   24 +++---------------------
 sw/source/filter/ww8/ww8par.hxx             |    2 +-
 sw/source/filter/ww8/ww8par2.cxx            |   20 ++++++++++++--------
 5 files changed, 25 insertions(+), 30 deletions(-)

New commits:
commit 6f84c1fda7654c18b1e53de7b1c077e8a31e606f
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Thu Oct 28 13:36:50 2021 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Fri Nov 5 15:55:30 2021 +0100

    tdf#144668: docx export: simpler way to create lvlText in numberings
    
    Oldr approach with populating ListLabelString with some predefined
    values and than replacing them by placeholders is not so good. It
    can lead to collisions if we use numbers in format string.
    
    Anow with support of list strings in core we do not need this: it
    is enougth to replace LO placeholders %1%, %2%, ... by MS binary
    placeholders \0, \1, ...
    
    Additionally added support for list level initialization in DOC
    import: that case was still setting just prefix/suffix leaving
    list level uninitialized.
    
    Change-Id: Ia85551f46b4e229dea93c663459ec1a8715c8a23
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124326
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit e0b41fcb56e51f20684da4ba44d7ed6e0e1a3234)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124698
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf144668.odt 
b/sw/qa/extras/ooxmlexport/data/tdf144668.odt
new file mode 100644
index 000000000000..7504adce400d
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf144668.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 5a331a5f505d..900952f90322 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -71,6 +71,15 @@ DECLARE_OOXMLEXPORT_TEST(testTdf142407, "tdf142407.docx")
     CPPUNIT_ASSERT_EQUAL( sal_Int16(36), nGridLines);   // was 23, left large 
space before text.
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf144668, "tdf144668.odt")
+{
+    uno::Reference<beans::XPropertySet> xPara1(getParagraph(1, u"level1"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("[0001]"), getProperty<OUString>(xPara1, 
"ListLabelString"));
+
+    uno::Reference<beans::XPropertySet> xPara2(getParagraph(2, u"level2"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("[001]"), getProperty<OUString>(xPara2, 
"ListLabelString"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8num.cxx 
b/sw/source/filter/ww8/wrtw8num.cxx
index 3ebc95e2407c..19a21f268034 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -435,13 +435,6 @@ void MSWordExportBase::AbstractNumberingDefinitions()
 void MSWordExportBase::NumberingLevel(
         SwNumRule const& rRule, sal_uInt8 const nLvl)
 {
-    // prepare the NodeNum to generate the NumString
-    static const SwNumberTree::tNumberVector aNumVector = [] {
-        SwNumberTree::tNumberVector vec(WW8ListManager::nMaxLevel);
-        std::iota(vec.begin(), vec.end(), 0);
-        return vec;
-    }();
-
     // write the static data of the SwNumFormat of this level
     sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
 
@@ -503,35 +496,24 @@ void MSWordExportBase::NumberingLevel(
     else
     {
         // 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;
-            // the numbering string has to be restrict
-            // to the level currently working on.
-            sNumStr = rRule.MakeNumString(aNumVector, true, true, nLvl);
+            sNumStr = rFormat.GetListFormat();
 
             // now search the nums in the string
             for (sal_uInt8 i = 0; i <= nLvl; ++i)
             {
-                OUString sSrch(OUString::number(i));
+                OUString sSrch("%" + OUString::number(i+1) + "%");
                 sal_Int32 nFnd = sNumStr.indexOf(sSrch);
                 if (-1 != nFnd)
                 {
                     *pLvlPos = static_cast<sal_uInt8>(nFnd + 1);
                     ++pLvlPos;
-                    sNumStr = sNumStr.replaceAt(nFnd, 1, 
OUString(static_cast<char>(i)));
+                    sNumStr = sNumStr.replaceAt(nFnd, sSrch.getLength(), 
OUString(static_cast<char>(i)));
                 }
             }
         }
-
-        if (!rRule.Get(nLvl).HasListFormat())
-        {
-            if (!rFormat.GetPrefix().isEmpty())
-                sNumStr = rFormat.GetPrefix() + sNumStr;
-            sNumStr += rFormat.GetSuffix();
-        }
     }
 
     if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index aa245b43bb68..240730d07f68 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1580,7 +1580,7 @@ private:
 // rglst, hpllfo and hsttbListNames
 // the corresponding structures are: LSTF, LVLF, LFO LFOLVL
 
-    void SetAnlvStrings(SwNumFormat &rNum, WW8_ANLV const &rAV, const 
sal_uInt8* pText,
+    void SetAnlvStrings(SwNumFormat &rNum, int nLevel, WW8_ANLV const &rAV, 
const sal_uInt8* pText,
         size_t nStart, size_t nElements, bool bOutline);
     void SetAnld(SwNumRule* pNumR, WW8_ANLD const * pAD, sal_uInt8 nSwLevel, 
bool bOutLine);
     void SetNumOlst( SwNumRule* pNumR, WW8_OLST* pO, sal_uInt8 nSwLevel );
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index df36492f1b82..b08212882c25 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -585,7 +585,7 @@ static void SetBaseAnlv(SwNumFormat &rNum, WW8_ANLV const 
&rAV, sal_uInt8 nSwLev
     }
 }
 
-void SwWW8ImplReader::SetAnlvStrings(SwNumFormat &rNum, WW8_ANLV const &rAV,
+void SwWW8ImplReader::SetAnlvStrings(SwNumFormat &rNum, int nLevel, WW8_ANLV 
const &rAV,
     const sal_uInt8* pText, size_t nStart, size_t nElements, bool bOutline)
 {
     if (nStart > nElements)
@@ -683,16 +683,20 @@ void SwWW8ImplReader::SetAnlvStrings(SwNumFormat &rNum, 
WW8_ANLV const &rAV,
     if( !bInsert )
         return;
 
+    OUString sPrefix;
+    OUString sSuffix;
     if (rAV.cbTextBefore)
     {
-        OUString sP( sText.copy( 0, rAV.cbTextBefore ).makeStringAndClear() );
-        rNum.SetPrefix( sP );
+        sPrefix = sText.copy( 0, rAV.cbTextBefore ).makeStringAndClear();
     }
     if( rAV.cbTextAfter )
     {
-        OUString sP( rNum.GetSuffix() );
-        sP += sText.copy( rAV.cbTextBefore, 
rAV.cbTextAfter).makeStringAndClear();
-        rNum.SetSuffix( sP );
+        sSuffix = rNum.GetSuffix();
+        sSuffix += sText.copy( rAV.cbTextBefore, 
rAV.cbTextAfter).makeStringAndClear();
+    }
+    if (rAV.cbTextBefore || rAV.cbTextAfter)
+    {
+        rNum.SetListFormat(sPrefix, sSuffix, nLevel);
     }
 // The characters before and after multiple digits do not apply because
 // those are handled differently by the writer and the result is in most
@@ -711,7 +715,7 @@ void SwWW8ImplReader::SetAnld(SwNumRule* pNumR, WW8_ANLD 
const * pAD, sal_uInt8
         m_bCurrentAND_fNumberAcross = 0 != pAD->fNumberAcross;
         WW8_ANLV const &rAV = pAD->eAnlv;
         SetBaseAnlv(aNF, rAV, nSwLevel);                    // set the base 
format
-        SetAnlvStrings(aNF, rAV, pAD->rgchAnld, 0, 
SAL_N_ELEMENTS(pAD->rgchAnld), bOutLine); // set the rest
+        SetAnlvStrings(aNF, nSwLevel, rAV, pAD->rgchAnld, 0, 
SAL_N_ELEMENTS(pAD->rgchAnld), bOutLine); // set the rest
     }
     pNumR->Set(nSwLevel, aNF);
 }
@@ -849,7 +853,7 @@ void SwWW8ImplReader::SetNumOlst(SwNumRule* pNumR, 
WW8_OLST* pO, sal_uInt8 nSwLe
 
     if (!m_bVer67)
         nTextOfs *= 2;
-    SetAnlvStrings(aNF, rAV, pO->rgch, nTextOfs, SAL_N_ELEMENTS(pO->rgch), 
true); // and apply
+    SetAnlvStrings(aNF, nSwLevel, rAV, pO->rgch, nTextOfs, 
SAL_N_ELEMENTS(pO->rgch), true); // and apply
     pNumR->Set(nSwLevel, aNF);
 }
 

Reply via email to