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

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Thu Sep 5 10:47:14 UTC 2019


 sw/qa/extras/ooxmlexport/data/tdf95848_2.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx    |   65 +++++
 sw/source/filter/ww8/attributeoutputbase.hxx  |    2 
 sw/source/filter/ww8/docxattributeoutput.cxx  |   17 +
 sw/source/filter/ww8/docxattributeoutput.hxx  |    3 
 sw/source/filter/ww8/wrtw8num.cxx             |  329 +++++++++++++-------------
 sw/source/filter/ww8/wrtww8.hxx               |    3 
 7 files changed, 260 insertions(+), 159 deletions(-)

New commits:
commit 632ee9aae6d5f3cf08b6d6b2789310c20db713b7
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 4 16:03:35 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 5 12:46:19 2019 +0200

    tdf#95848 sw: DOCX export: export w:lvlOverride elements
    
    ... when necessary; factor out MSWordExportBase::NumberingLevel() so it
    can be called for this purpose.
    
    Change-Id: I958210052b162c2b23f0162ffebbf5add1ed328c
    Reviewed-on: https://gerrit.libreoffice.org/78608
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf95848_2.docx b/sw/qa/extras/ooxmlexport/data/tdf95848_2.docx
new file mode 100644
index 000000000000..33c1773d5f50
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf95848_2.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 88e65268cf01..77d20697e340 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -99,6 +99,71 @@ DECLARE_OOXMLEXPORT_TEST(testTdf95848, "tdf95848.docx")
     }
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf95848_2, "tdf95848_2.docx")
+{
+    OUString listId;
+    OUString listStyle;
+    {
+        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(xPara->getPropertyValue("NumberingStyleName") >>= listStyle);
+        CPPUNIT_ASSERT(listStyle.startsWith("WWNum"));
+        CPPUNIT_ASSERT(xPara->getPropertyValue("ListId") >>= listId);
+        CPPUNIT_ASSERT_EQUAL(OUString("1)"), getProperty<OUString>(xPara, "ListLabelString"));
+        // check indent of list style
+        auto xLevels = getProperty<uno::Reference<container::XIndexAccess>>(xPara, "NumberingRules");
+        uno::Sequence<beans::PropertyValue> aLevel;
+        xLevels->getByIndex(0) >>= aLevel; // top level
+        sal_Int32 nIndent = std::find_if(aLevel.begin(), aLevel.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "FirstLineIndent"; })->Value.get<sal_Int32>();
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(-635), nIndent);
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        // different numbering style
+        OUString listStyle2;
+        CPPUNIT_ASSERT(xPara->getPropertyValue("NumberingStyleName") >>= listStyle2);
+        CPPUNIT_ASSERT(listStyle2.startsWith("WWNum"));
+        CPPUNIT_ASSERT(listStyle2 != listStyle);
+        // but same list
+        CPPUNIT_ASSERT_EQUAL(OUString("2)"), getProperty<OUString>(xPara, "ListLabelString"));
+        CPPUNIT_ASSERT_EQUAL(listId, getProperty<OUString>(xPara, "ListId"));
+        // check indent of list style - override
+        auto xLevels = getProperty<uno::Reference<container::XIndexAccess>>(xPara, "NumberingRules");
+        uno::Sequence<beans::PropertyValue> aLevel;
+        xLevels->getByIndex(0) >>= aLevel; // top level
+        sal_Int32 nIndent = std::find_if(aLevel.begin(), aLevel.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "FirstLineIndent"; })->Value.get<sal_Int32>();
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(9366), nIndent);
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        // different numbering style
+        OUString listStyle3;
+        CPPUNIT_ASSERT(xPara->getPropertyValue("NumberingStyleName") >>= listStyle3);
+        CPPUNIT_ASSERT(listStyle3.startsWith("WWNum"));
+        CPPUNIT_ASSERT(listStyle3 != listStyle);
+        // and different list
+        CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
+        CPPUNIT_ASSERT(listId !=  getProperty<OUString>(xPara, "ListId"));
+    }
+    {
+        // continue the first list
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(listStyle, getProperty<OUString>(xPara, "NumberingStyleName"));
+        CPPUNIT_ASSERT_EQUAL(listId, getProperty<OUString>(xPara, "ListId"));
+        CPPUNIT_ASSERT_EQUAL(OUString("3)"), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+    {
+        uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+        CPPUNIT_ASSERT_EQUAL(listStyle, getProperty<OUString>(xPara, "NumberingStyleName"));
+        CPPUNIT_ASSERT_EQUAL(listId, getProperty<OUString>(xPara, "ListId"));
+        CPPUNIT_ASSERT_EQUAL(OUString("4)"), getProperty<OUString>(xPara, "ListLabelString"));
+    }
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf126723, "tdf126723.docx")
 {
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(2), "ParaLeftMargin"));
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index ef681cf01e5a..7774cc01f17b 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -347,7 +347,7 @@ public:
     virtual void NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule ) = 0;
 
     /// Numbering defintion that overrides abstract numbering definition
-    virtual void OverrideNumberingDefinition(sal_uInt16 /*nNum*/, sal_uInt16 /*nAbstractNum*/)
+    virtual void OverrideNumberingDefinition(SwNumRule const&, sal_uInt16 /*nNum*/, sal_uInt16 /*nAbstractNum*/)
     { assert(false); } // TODO implement for WW8/RTF
 
     /// Start of the abstract numbering definition instance.
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index deaf3fd59917..4f6b492d5d33 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6559,13 +6559,28 @@ void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &
 }
 
 void DocxAttributeOutput::OverrideNumberingDefinition(
+        SwNumRule const& rRule,
         sal_uInt16 const nNum, sal_uInt16 const nAbstractNum)
 {
     m_pSerializer->startElementNS(XML_w, XML_num, FSNS(XML_w, XML_numId), OString::number(nNum));
 
     m_pSerializer->singleElementNS(XML_w, XML_abstractNumId, FSNS(XML_w, XML_val), OString::number(nAbstractNum));
 
-    // TODO: write SwNumRule into w:lvlOverride
+    SwNumRule const& rAbstractRule = *(*m_rExport.m_pUsedNumTable)[nAbstractNum - 1];
+    sal_uInt8 const nLevels = static_cast<sal_uInt8>(rRule.IsContinusNum()
+        ? WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
+    for (sal_uInt8 nLevel = 0; nLevel < nLevels; ++nLevel)
+    {
+        // only export it if it differs from abstract numbering definition
+        if (rRule.Get(nLevel) != rAbstractRule.Get(nLevel))
+        {
+            m_pSerializer->startElementNS(XML_w, XML_lvlOverride, FSNS(XML_w, XML_ilvl), OString::number(nLevel));
+
+            GetExport().NumberingLevel(rRule, nLevel);
+
+            m_pSerializer->endElementNS(XML_w, XML_lvlOverride);
+        }
+    }
 
     m_pSerializer->endElementNS( XML_w, XML_num );
 }
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index d40a6c317342..478f4b39f2fd 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -324,7 +324,8 @@ public:
     virtual void NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule ) override;
 
     /// Numbering defintion that overrides abstract numbering definition
-    virtual void OverrideNumberingDefinition(sal_uInt16 nNum, sal_uInt16 nAbstractNum) override;
+    virtual void OverrideNumberingDefinition(SwNumRule const& rRule,
+            sal_uInt16 nNum, sal_uInt16 nAbstractNum) override;
 
     /// Start of the abstract numbering definition instance.
     virtual void StartAbstractNumbering( sal_uInt16 nId ) override;
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 8d9321b71798..807c85251ed1 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -39,6 +39,8 @@
 #include "wrtww8.hxx"
 #include "ww8par.hxx"
 
+#include <mutex>
+
 using namespace ::com::sun::star;
 using namespace sw::types;
 using namespace sw::util;
@@ -204,7 +206,7 @@ void MSWordExportBase::NumberingDefinitions()
     // Write static data of SwNumRule - LSTF
     for ( sal_uInt16 n = 0; n < nCount; ++n )
     {
-        const SwNumRule *const pRule = (*m_pUsedNumTable)[ n ];
+        const SwNumRule * pRule = (*m_pUsedNumTable)[ n ];
         if (pRule)
         {
             AttrOutput().NumberingDefinition(n + 1, *pRule);
@@ -213,7 +215,9 @@ void MSWordExportBase::NumberingDefinitions()
         {
             auto it = m_OverridingNums.find(n);
             assert(it != m_OverridingNums.end());
-            AttrOutput().OverrideNumberingDefinition(n + 1, it->second.second + 1);
+            pRule = (*m_pUsedNumTable)[it->second.first];
+            assert(pRule);
+            AttrOutput().OverrideNumberingDefinition(*pRule, n + 1, it->second.second + 1);
         }
     }
 }
@@ -383,11 +387,6 @@ void MSWordExportBase::AbstractNumberingDefinitions()
     sal_uInt16 nCount = m_pUsedNumTable->size();
     sal_uInt16 n;
 
-    // prepare the NodeNum to generate the NumString
-    SwNumberTree::tNumberVector aNumVector;
-    for ( n = 0; n < WW8ListManager::nMaxLevel; ++n )
-        aNumVector.push_back( n );
-
     for( n = 0; n < nCount; ++n )
     {
         if (nullptr == (*m_pUsedNumTable)[ n ])
@@ -403,180 +402,198 @@ void MSWordExportBase::AbstractNumberingDefinitions()
             WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
         for( nLvl = 0; nLvl < nLevels; ++nLvl )
         {
-            // write the static data of the SwNumFormat of this level
-            sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
+            NumberingLevel(rRule, nLvl);
+        }
 
-            const SwNumFormat& rFormat = rRule.Get( nLvl );
+        AttrOutput().EndAbstractNumbering();
+    }
+}
 
-            sal_uInt8 nFollow = 0;
-            // #i86652#
-            if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+void MSWordExportBase::NumberingLevel(
+        SwNumRule const& rRule, sal_uInt8 const nLvl)
+{
+    // prepare the NodeNum to generate the NumString
+    static SwNumberTree::tNumberVector aNumVector;
+    static std::once_flag aInitOnce;
+    std::call_once(aInitOnce, []
+        {
+            for (int n = 0; n < WW8ListManager::nMaxLevel; ++n)
+            {
+                aNumVector.push_back( n );
+            }
+        });
+
+    // write the static data of the SwNumFormat of this level
+    sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
+
+    const SwNumFormat& rFormat = rRule.Get( nLvl );
+
+    sal_uInt8 nFollow = 0;
+    // #i86652#
+    if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+    {
+        nFollow = 2;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
+    }
+    else if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+    {
+        switch (rFormat.GetLabelFollowedBy())
+        {
+            case SvxNumberFormat::LISTTAB:
             {
-                nFollow = 2;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
+                // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
+                nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 0 : 2;
             }
-            else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+            break;
+            case SvxNumberFormat::SPACE:
             {
-                switch ( rFormat.GetLabelFollowedBy() )
-                {
-                    case SvxNumberFormat::LISTTAB:
-                    {
-            // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
-            nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 0 : 2;
-                    }
-                    break;
-                    case SvxNumberFormat::SPACE:
-                    {
-            // 1 (space) unless there would be no content before the space in which case 2 (nothing)
-            nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 1 : 2;
-                    }
-                    break;
-                    case SvxNumberFormat::NOTHING:
-                    {
-                        nFollow = 2;
-                    }
-                    break;
-                    default:
-                    {
-                        nFollow = 0;
-                        OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
-                    }
-                }
+                // 1 (space) unless there would be no content before the space in which case 2 (nothing)
+                nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 1 : 2;
             }
-
-            // Build the NumString for this Level
-            OUString sNumStr;
-            OUString sFontName;
-            bool bWriteBullet = false;
-            const vcl::Font* pBulletFont=nullptr;
-            rtl_TextEncoding eChrSet=0;
-            FontFamily eFamily=FAMILY_DECORATIVE;
-            if( SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
-                SVX_NUM_BITMAP == rFormat.GetNumberingType() )
+            break;
+            case SvxNumberFormat::NOTHING:
             {
-                sNumStr = OUString(rFormat.GetBulletChar());
-                bWriteBullet = true;
+                nFollow = 2;
+            }
+            break;
+            default:
+            {
+                nFollow = 0;
+                OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
+            }
+        }
+    }
 
-                pBulletFont = rFormat.GetBulletFont();
-                if (!pBulletFont)
-                {
-                    pBulletFont = &numfunc::GetDefBulletFont();
-                }
+    // Build the NumString for this Level
+    OUString sNumStr;
+    OUString sFontName;
+    bool bWriteBullet = false;
+    const vcl::Font* pBulletFont=nullptr;
+    rtl_TextEncoding eChrSet=0;
+    FontFamily eFamily=FAMILY_DECORATIVE;
+    if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
+        SVX_NUM_BITMAP == rFormat.GetNumberingType())
+    {
+        sNumStr = OUString(rFormat.GetBulletChar());
+        bWriteBullet = true;
 
-                eChrSet = pBulletFont->GetCharSet();
-                sFontName = pBulletFont->GetFamilyName();
-                eFamily = pBulletFont->GetFamilyType();
+        pBulletFont = rFormat.GetBulletFont();
+        if (!pBulletFont)
+        {
+            pBulletFont = &numfunc::GetDefBulletFont();
+        }
 
-                if ( IsStarSymbol(sFontName) )
-                    SubstituteBullet( sNumStr, eChrSet, sFontName );
+        eChrSet = pBulletFont->GetCharSet();
+        sFontName = pBulletFont->GetFamilyName();
+        eFamily = pBulletFont->GetFamilyType();
 
-                // #i86652#
-                if ( rFormat.GetPositionAndSpaceMode() ==
-                                        SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+        if (IsStarSymbol(sFontName))
+            SubstituteBullet( sNumStr, eChrSet, sFontName );
+
+        // #i86652#
+        if (rFormat.GetPositionAndSpaceMode() ==
+                                SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+        {
+            // <nFollow = 2>, if minimum label width equals 0 and
+            // minimum distance between label and text equals 0
+            nFollow = (rFormat.GetFirstLineOffset() == 0 &&
+                       rFormat.GetCharTextDistance() == 0)
+                      ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
+        }
+    }
+    else
+    {
+        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, false, true, nLvl);
+
+            // 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 )
                 {
-                    // <nFollow = 2>, if minimum label width equals 0 and
-                    // minimum distance between label and text equals 0
-                    nFollow = ( rFormat.GetFirstLineOffset() == 0 &&
-                                rFormat.GetCharTextDistance() == 0 )
-                              ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
+                    *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1 );
+                    ++pLvlPos;
+                    sNumStr = sNumStr.replaceAt( nFnd, 1, OUString(static_cast<char>(i)) );
                 }
             }
-            else
+            // #i86652#
+            if (rFormat.GetPositionAndSpaceMode() ==
+                                    SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
             {
-                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, false, true, nLvl);
-
-                    // 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 )
-                        {
-                            *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1 );
-                            ++pLvlPos;
-                            sNumStr = sNumStr.replaceAt( nFnd, 1, OUString(static_cast<char>(i)) );
-                        }
-                    }
-                    // #i86652#
-                    if ( rFormat.GetPositionAndSpaceMode() ==
-                                            SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
-                    {
-                        // <nFollow = 2>, if minimum label width equals 0 and
-                        // minimum distance between label and text equals 0
-                        nFollow = ( rFormat.GetFirstLineOffset() == 0 &&
-                                    rFormat.GetCharTextDistance() == 0 )
-                                  ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
-                    }
-                }
-
-                if( !rFormat.GetPrefix().isEmpty() )
-                    sNumStr = rFormat.GetPrefix() + sNumStr;
-                sNumStr += rFormat.GetSuffix();
+                // <nFollow = 2>, if minimum label width equals 0 and
+                // minimum distance between label and text equals 0
+                nFollow = (rFormat.GetFirstLineOffset() == 0 &&
+                           rFormat.GetCharTextDistance() == 0)
+                          ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
             }
+        }
 
-            // Attributes of the numbering
-            std::unique_ptr<wwFont> pPseudoFont;
-            const SfxItemSet* pOutSet = nullptr;
+        if (!rFormat.GetPrefix().isEmpty())
+            sNumStr = rFormat.GetPrefix() + sNumStr;
+        sNumStr += rFormat.GetSuffix();
+    }
 
-            // cbGrpprlChpx
-            SfxItemSet aSet( m_pDoc->GetAttrPool(), svl::Items<RES_CHRATR_BEGIN,
-                                                  RES_CHRATR_END>{} );
-            if ( rFormat.GetCharFormat() || bWriteBullet )
-            {
-                if ( bWriteBullet )
-                {
-                    pOutSet = &aSet;
+    // Attributes of the numbering
+    std::unique_ptr<wwFont> pPseudoFont;
+    const SfxItemSet* pOutSet = nullptr;
 
-                    if ( rFormat.GetCharFormat() )
-                        aSet.Put( rFormat.GetCharFormat()->GetAttrSet() );
-                    aSet.ClearItem( RES_CHRATR_CJK_FONT );
-                    aSet.ClearItem( RES_CHRATR_FONT );
+    // cbGrpprlChpx
+    SfxItemSet aSet( m_pDoc->GetAttrPool(), svl::Items<RES_CHRATR_BEGIN,
+                                          RES_CHRATR_END>{} );
+    if (rFormat.GetCharFormat() || bWriteBullet)
+    {
+        if (bWriteBullet)
+        {
+            pOutSet = &aSet;
 
-                    if ( sFontName.isEmpty() )
-                        sFontName = pBulletFont->GetFamilyName();
+            if (rFormat.GetCharFormat())
+                aSet.Put( rFormat.GetCharFormat()->GetAttrSet() );
+            aSet.ClearItem( RES_CHRATR_CJK_FONT );
+            aSet.ClearItem( RES_CHRATR_FONT );
 
-                    pPseudoFont.reset(new wwFont( sFontName, pBulletFont->GetPitch(),
-                        eFamily, eChrSet));
-                }
-                else
-                    pOutSet = &rFormat.GetCharFormat()->GetAttrSet();
-            }
+            if (sFontName.isEmpty())
+                sFontName = pBulletFont->GetFamilyName();
 
-            sal_Int16 nIndentAt = 0;
-            sal_Int16 nFirstLineIndex = 0;
-            sal_Int16 nListTabPos = 0;
+            pPseudoFont.reset(new wwFont( sFontName, pBulletFont->GetPitch(),
+                eFamily, eChrSet));
+        }
+        else
+            pOutSet = &rFormat.GetCharFormat()->GetAttrSet();
+    }
 
-            // #i86652#
-            if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
-            {
-                nIndentAt = nListTabPos = rFormat.GetAbsLSpace(); //TODO: overflow
-                nFirstLineIndex = GetWordFirstLineOffset(rFormat);
-            }
-            else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
-            {
-                nIndentAt = static_cast<sal_Int16>(rFormat.GetIndentAt());
-                nFirstLineIndex = static_cast<sal_Int16>(rFormat.GetFirstLineIndent());
-                nListTabPos = rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
-                              static_cast<sal_Int16>( rFormat.GetListtabPos() ) : 0;
-            }
+    sal_Int16 nIndentAt = 0;
+    sal_Int16 nFirstLineIndex = 0;
+    sal_Int16 nListTabPos = 0;
 
-            AttrOutput().NumberingLevel( nLvl,
-                    rFormat.GetStart(),
-                    rFormat.GetNumberingType(),
-                    rFormat.GetNumAdjust(),
-                    aNumLvlPos,
-                    nFollow,
-                    pPseudoFont.get(), pOutSet,
-                    nIndentAt, nFirstLineIndex, nListTabPos,
-                    sNumStr,
-                    rFormat.GetNumberingType()==SVX_NUM_BITMAP ? rFormat.GetBrush():nullptr);
-        }
-        AttrOutput().EndAbstractNumbering();
+    // #i86652#
+    if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+    {
+        nIndentAt = nListTabPos = rFormat.GetAbsLSpace(); //TODO: overflow
+        nFirstLineIndex = GetWordFirstLineOffset(rFormat);
+    }
+    else if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+    {
+        nIndentAt = static_cast<sal_Int16>(rFormat.GetIndentAt());
+        nFirstLineIndex = static_cast<sal_Int16>(rFormat.GetFirstLineIndent());
+        nListTabPos = rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
+                      static_cast<sal_Int16>( rFormat.GetListtabPos() ) : 0;
     }
+
+    AttrOutput().NumberingLevel( nLvl,
+            rFormat.GetStart(),
+            rFormat.GetNumberingType(),
+            rFormat.GetNumAdjust(),
+            aNumLvlPos,
+            nFollow,
+            pPseudoFont.get(), pOutSet,
+            nIndentAt, nFirstLineIndex, nListTabPos,
+            sNumStr,
+            rFormat.GetNumberingType()==SVX_NUM_BITMAP ? rFormat.GetBrush() : nullptr);
 }
 
 void WW8Export::OutOverrideListTab()
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index c35163c067b8..5ca2c60fed45 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -758,6 +758,9 @@ public:
     /// Write all Levels for all SwNumRules - LVLF
     void AbstractNumberingDefinitions();
 
+    /// Write one numbering level
+    void NumberingLevel(SwNumRule const& rRule, sal_uInt8 nLvl);
+
     // Convert the bullet according to the font.
     void SubstituteBullet( OUString& rNumStr, rtl_TextEncoding& rChrSet,
         OUString& rFontName ) const;


More information about the Libreoffice-commits mailing list