Related: tdf#150408 DOC filter: handle legal numbering

The bugdoc's 2nd para started with 'Sect I.01', while Word rendered this
as 'Sect 1.01'.

The reason for this difference is that there is an "is legal" boolean
property on the numbering that we ignored from [MS-DOC] during
import/export.

Fix the problem by WW8ListManager::ReadLVL() and
WW8AttributeOutput::NumberingLevel() to handle this, building on top of
the existing DOCX work.

RTF still needs doing.

Change-Id: I57ec402c1dd829251afa639ddfa7fc6620da1125
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164000
Reviewed-by: Miklos Vajna <[email protected]>
Tested-by: Jenkins
diff --git a/sw/qa/extras/ww8export/data/listWithLgl.doc b/sw/qa/extras/ww8export/data/listWithLgl.doc
new file mode 100644
index 0000000..94de296
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/listWithLgl.doc
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx b/sw/qa/extras/ww8export/ww8export4.cxx
index 92023fb..ea50ed2 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -230,6 +230,30 @@ DECLARE_WW8EXPORT_TEST(testInlinePageBreakFirstLine, "inlinePageBreakFirstLine.d
    CPPUNIT_ASSERT(IsFirstLine(aTextNodes[2]));
}

CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
{
    auto verify = [this]() {
        // Second level's numbering should use Arabic numbers for first level reference
        auto xPara = getParagraph(1);
        CPPUNIT_ASSERT_EQUAL(OUString("CH I"), getProperty<OUString>(xPara, "ListLabelString"));
        xPara = getParagraph(2);
        // Without the accompanying fix in place, this test would have failed with:
        // - Expected: Sect 1.01
        // - Actual  : Sect I.01
        // i.e. fLegal was ignored on import/export.
        CPPUNIT_ASSERT_EQUAL(OUString("Sect 1.01"), getProperty<OUString>(xPara, "ListLabelString"));
        xPara = getParagraph(3);
        CPPUNIT_ASSERT_EQUAL(OUString("CH II"), getProperty<OUString>(xPara, "ListLabelString"));
        xPara = getParagraph(4);
        CPPUNIT_ASSERT_EQUAL(OUString("Sect 2.01"), getProperty<OUString>(xPara, "ListLabelString"));
    };

    createSwDoc("listWithLgl.doc");
    verify();
    saveAndReload(mpFilter);
    verify();
}

DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, "nonInlinePageBreakFirstLine.doc")
{
    SwDoc* pDoc = getSwDoc();
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 8d59434..681961a 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -279,7 +279,7 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
        sal_Int16 nListTabPos,
        const OUString &rNumberingString,
        const SvxBrushItem* pBrush, //For i120928,to transfer graphic of bullet
        bool /*isLegal*/
        bool isLegal
    )
{
    // Start value
@@ -303,6 +303,13 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
        nAlign = 0;
        break;
    }

    if (isLegal)
    {
        // 3rd bit.
        nAlign |= 0x04;
    }

    m_rWW8Export.m_pTableStrm->WriteUChar( nAlign );

    // Write the rgbxchNums[9], positions of placeholders for paragraph
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index 85563c7..3af2f3d 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -365,6 +365,8 @@ struct WW8LVL   // only THE entries, WE need!
    short   nDxaLeft1;          // first line indent

    sal_uInt8   nNFC;               // number format code
    /// Legal numbering: whether this level overrides the nfc of all inherited level numbers.
    bool fLegal;
    // Offset of fieldcodes in Num-X-String
    sal_uInt8   aOfsNumsXCH[WW8ListManager::nMaxLevel];
    sal_uInt8   nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
@@ -659,7 +661,15 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
    m_rSt.ReadUChar( aLVL.nNFC );
    m_rSt.ReadUChar( aBits1 );
    if( ERRCODE_NONE != m_rSt.GetError() ) return false;
    // 1st..2nd bits.
    aLVL.nAlign = (aBits1 & 0x03);

    if (aBits1 & 0x04)
    {
        // 3rd bit.
        aLVL.fLegal = true;
    }

    if( aBits1 & 0x10 ) aLVL.bV6Prev    = true;
    if( aBits1 & 0x20 ) aLVL.bV6PrSp    = true;
    if( aBits1 & 0x40 ) aLVL.bV6        = true;
@@ -895,6 +905,7 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
    if( bSetStartNo && 0 <= aLVL.nStartAt)
        rNumFormat.SetStart(o3tl::narrowing<sal_uInt16>(aLVL.nStartAt));
    rNumFormat.SetNumberingType( nType );
    rNumFormat.SetIsLegal(aLVL.fLegal);
    rNumFormat.SetNumAdjust( eAdj );

    if( style::NumberingType::CHAR_SPECIAL == nType )