dictionaries                                    |    2 
 sw/qa/extras/ooxmlexport/data/tdf152425.docx    |binary
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx      |    8 
 sw/qa/extras/ooxmlexport/ooxmlexport16.cxx      |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport18.cxx      |   14 +
 sw/source/filter/inc/wwstyles.hxx               |    1 
 sw/source/filter/ww8/docxattributeoutput.cxx    |   16 -
 sw/source/filter/ww8/styles.cxx                 |  186 +++++++++----------
 sw/source/filter/ww8/wrtw8sty.cxx               |  149 ++++++++-------
 sw/source/filter/ww8/wrtww8.hxx                 |   10 -
 writerfilter/source/dmapper/StyleSheetTable.cxx |  232 +++++++++++++-----------
 11 files changed, 340 insertions(+), 280 deletions(-)

New commits:
commit 7f0b6db955ee52f4216416566e108245f2b3a821
Author:     Shulhan <m...@kilabit.info>
AuthorDate: Thu Jan 12 11:34:31 2023 +0700
Commit:     Gerrit Code Review <ger...@gerrit.libreoffice.org>
CommitDate: Thu Jan 12 04:34:31 2023 +0000

    Update git submodules
    
    * Update dictionaries from branch 'master'
      to 40580c5dbb5b06fbf402b5864e736527b05cd2f5
      - id: sync dictionaries to version v2.3.0 (2022.09.21)
    
        In the dictionary file we add 15773 new root words, sort them out to
        simplify search and update in the future.
    
        In the affix file we fix some format for Lucene.
    
        The README updated to match with upstream [1].
    
        [1] https://github.com/shuLhan/hunspell-id
    
        Change-Id: Ie96776aba2399b90cfbc113782c720a157458bc3
        Reviewed-on: https://gerrit.libreoffice.org/c/dictionaries/+/140263
        Tested-by: Aron Budea <aron.bu...@collabora.com>
        Reviewed-by: Aron Budea <aron.bu...@collabora.com>

diff --git a/dictionaries b/dictionaries
index f191df059976..40580c5dbb5b 160000
--- a/dictionaries
+++ b/dictionaries
@@ -1 +1 @@
-Subproject commit f191df059976deba5f60983bb4a87ab184835fd4
+Subproject commit 40580c5dbb5b06fbf402b5864e736527b05cd2f5
commit 13d30067370353ae5a43c2f2cbd69bb824363815
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Jan 11 17:02:04 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Jan 12 04:34:27 2023 +0000

    tdf#152425 Synchronize import and export style names mapping
    
    1. Make the mapping in StyleSheetTable::ConvertStyleName match the
       opposite direction mapping happening in MSWordStyles::GetWWId and
       ww::GetEnglishNameFromSti. Add missing styles, provide comments to
       clarify the process and find respective pool format ids.
    2. Instead of appending " (user)" to conflicting style names, which
       is the method used by SwStyleNameMapper to disambiguate API names,
       append " (WW)", which allows to avoid unwanted merging conflicting
       styles.
    
    Change-Id: I47b1c7f570da6e6e21155669fdd1b77de5cc17da
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145349
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index 92e13b4b7d3b..7b7213e0f019 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -264,17 +264,12 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf152425)
 
     // Check that "List Number" and "List 5" styles don't get merged
     const OUString Para3Style = getProperty<OUString>(getParagraph(3), 
"ParaStyleName");
-    CPPUNIT_ASSERT_EQUAL(OUString("List Number"), Para3Style);
+    CPPUNIT_ASSERT_EQUAL(OUString("Numbering 1"), Para3Style);
     const OUString Para4Style = getProperty<OUString>(getParagraph(4), 
"ParaStyleName");
-    // Eventually, we need to check this:
-    // CPPUNIT_ASSERT_EQUAL(OUString("List 5"), Para4Style);
-    // But for now, just make sure that the style names differ
-    CPPUNIT_ASSERT(Para4Style != Para3Style);
+    CPPUNIT_ASSERT_EQUAL(OUString("List 5 (WW)"), Para4Style);
+    // Also check that "List 5" and "List Bullet 5" styles don't get merged
     const OUString Para5Style = getProperty<OUString>(getParagraph(5), 
"ParaStyleName");
-    // Eventually, we need to check this:
-    // CPPUNIT_ASSERT_EQUAL(OUString("List Bullet 5"), Para5Style);
-    // But for now, just make sure that the style names differ
-    CPPUNIT_ASSERT(Para5Style != Para4Style);
+    CPPUNIT_ASSERT_EQUAL(OUString("List 5"), Para5Style);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/styles.cxx b/sw/source/filter/ww8/styles.cxx
index c7a28e77e60b..33d0ad3dec5f 100644
--- a/sw/source/filter/ww8/styles.cxx
+++ b/sw/source/filter/ww8/styles.cxx
@@ -23,6 +23,7 @@
 
 namespace
 {
+    // Keep in sync with StyleSheetTable::ConvertStyleName
     const char **GetStiNames() noexcept
     {
         // Matches enum ww::sti in sw/source/filter/inc/wwstyles.hxx
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx 
b/sw/source/filter/ww8/wrtw8sty.cxx
index 9f534b1b55d2..72fca1b3696f 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -200,6 +200,7 @@ static sal_uInt16 BuildGetSlot(const SwFormat& rFormat)
 }
 
 
+// Keep in sync with StyleSheetTable::ConvertStyleName
 sal_uInt16 MSWordStyles::GetWWId( const SwFormat& rFormat )
 {
     sal_uInt16 nRet = ww::stiUser;    // user style as default
@@ -319,6 +320,14 @@ void MSWordStyles::BuildStylesTable()
     }
 }
 
+// StyleSheetTable::ConvertStyleName appends the suffix do disambiguate 
conflicting style names
+static OUString StripWWSuffix(const OUString& s)
+{
+    OUString ret = s;
+    ret.endsWith(" (WW)", &ret);
+    return ret;
+}
+
 void MSWordStyles::BuildWwNames()
 {
     std::unordered_set<OUString> aUsed;
@@ -363,9 +372,9 @@ void MSWordStyles::BuildWwNames()
         if (!entry.ww_name.isEmpty())
             continue;
         if (entry.format)
-            entry.ww_name = entry.format->GetName();
+            entry.ww_name = StripWWSuffix(entry.format->GetName());
         else if (entry.num_rule)
-            entry.ww_name = entry.num_rule->GetName();
+            entry.ww_name = StripWWSuffix(entry.num_rule->GetName());
         else
             continue;
         makeUniqueName(entry.ww_name);
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx 
b/writerfilter/source/dmapper/StyleSheetTable.cxx
index 9641a2a032bd..963ff9c907b6 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -1420,129 +1420,141 @@ OUString StyleSheetTable::ConvertStyleName( const 
OUString& rWWName, bool bExten
         //search for the rWWName in the IdentifierD of the existing styles and 
convert the sStyleName member
         auto findIt = m_pImpl->m_aStyleSheetEntriesMap.find(rWWName);
         if (findIt != m_pImpl->m_aStyleSheetEntriesMap.end())
+        {
+            if (!findIt->second->sConvertedStyleName.isEmpty())
+                return findIt->second->sConvertedStyleName;
             sRet = findIt->second->sStyleName;
+        }
     }
 
     // create a map only once
+    // This maps Word's special style manes to Writer's (the opposite to what 
MSWordStyles::GetWWId
+    // and ww::GetEnglishNameFromSti do on export). The mapping gives a 
Writer's style name, which
+    // will point to a style with specific RES_POOL* in its m_nPoolFormatId. 
Then on export, the
+    // pool format id will map to a ww::sti enum value, and finally to a Word 
style name. Keep this
+    // part in sync with the export functions mentioned above!
+    // In addition to "standard" names, some case variations are handled here; 
and also there are
+    // a number of strange mappings like "BodyTextIndentItalic" -> "Text body 
indent italic", which
+    // map something unused in Word to something unused in Writer :-/
     static const std::map< OUString, OUString> StyleNameMap {
-        { "Normal", "Standard" },
-        { "heading 1", "Heading 1" },
-        { "heading 2", "Heading 2" },
-        { "heading 3", "Heading 3" },
-        { "heading 4", "Heading 4" },
-        { "heading 5", "Heading 5" },
-        { "heading 6", "Heading 6" },
-        { "heading 7", "Heading 7" },
-        { "heading 8", "Heading 8" },
-        { "heading 9", "Heading 9" },
-        { "Heading 1", "Heading 1" },
-        { "Heading 2", "Heading 2" },
-        { "Heading 3", "Heading 3" },
-        { "Heading 4", "Heading 4" },
-        { "Heading 5", "Heading 5" },
-        { "Heading 6", "Heading 6" },
-        { "Heading 7", "Heading 7" },
-        { "Heading 8", "Heading 8" },
-        { "Heading 9", "Heading 9" },
-        { "Index 1", "Index 1" },
-        { "Index 2", "Index 2" },
-        { "Index 3", "Index 3" },
+        { "Normal", "Standard" }, // RES_POOLCOLL_STANDARD
+        { "heading 1", "Heading 1" }, // RES_POOLCOLL_HEADLINE1
+        { "heading 2", "Heading 2" }, // RES_POOLCOLL_HEADLINE2
+        { "heading 3", "Heading 3" }, // RES_POOLCOLL_HEADLINE3
+        { "heading 4", "Heading 4" }, // RES_POOLCOLL_HEADLINE4
+        { "heading 5", "Heading 5" }, // RES_POOLCOLL_HEADLINE5
+        { "heading 6", "Heading 6" }, // RES_POOLCOLL_HEADLINE6
+        { "heading 7", "Heading 7" }, // RES_POOLCOLL_HEADLINE7
+        { "heading 8", "Heading 8" }, // RES_POOLCOLL_HEADLINE8
+        { "heading 9", "Heading 9" }, // RES_POOLCOLL_HEADLINE9
+        { "Heading 1", "Heading 1" }, // RES_POOLCOLL_HEADLINE1
+        { "Heading 2", "Heading 2" }, // RES_POOLCOLL_HEADLINE2
+        { "Heading 3", "Heading 3" }, // RES_POOLCOLL_HEADLINE3
+        { "Heading 4", "Heading 4" }, // RES_POOLCOLL_HEADLINE4
+        { "Heading 5", "Heading 5" }, // RES_POOLCOLL_HEADLINE5
+        { "Heading 6", "Heading 6" }, // RES_POOLCOLL_HEADLINE6
+        { "Heading 7", "Heading 7" }, // RES_POOLCOLL_HEADLINE7
+        { "Heading 8", "Heading 8" }, // RES_POOLCOLL_HEADLINE8
+        { "Heading 9", "Heading 9" }, // RES_POOLCOLL_HEADLINE9
+        { "Index 1", "Index 1" }, // RES_POOLCOLL_TOX_IDX1
+        { "Index 2", "Index 2" }, // RES_POOLCOLL_TOX_IDX2
+        { "Index 3", "Index 3" }, // RES_POOLCOLL_TOX_IDX3
 //        { "Index 4", "" },
 //        { "Index 5", "" },
 //        { "Index 6", "" },
 //        { "Index 7", "" },
 //        { "Index 8", "" },
 //        { "Index 9", "" },
-        { "TOC 1", "Contents 1" },
-        { "TOC 2", "Contents 2" },
-        { "TOC 3", "Contents 3" },
-        { "TOC 4", "Contents 4" },
-        { "TOC 5", "Contents 5" },
-        { "TOC 6", "Contents 6" },
-        { "TOC 7", "Contents 7" },
-        { "TOC 8", "Contents 8" },
-        { "TOC 9", "Contents 9" },
-        { "TOC Heading", "Contents Heading" },
-        { "TOCHeading", "Contents Heading" },
-        { "toc 1", "Contents 1" },
-        { "toc 2", "Contents 2" },
-        { "toc 3", "Contents 3" },
-        { "toc 4", "Contents 4" },
-        { "toc 5", "Contents 5" },
-        { "toc 6", "Contents 6" },
-        { "toc 7", "Contents 7" },
-        { "toc 8", "Contents 8" },
-        { "toc 9", "Contents 9" },
-        { "TOC1", "Contents 1" },
-        { "TOC2", "Contents 2" },
-        { "TOC3", "Contents 3" },
-        { "TOC4", "Contents 4" },
-        { "TOC5", "Contents 5" },
-        { "TOC6", "Contents 6" },
-        { "TOC7", "Contents 7" },
-        { "TOC8", "Contents 8" },
-        { "TOC9", "Contents 9" },
+        { "TOC 1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
+        { "TOC 2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
+        { "TOC 3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
+        { "TOC 4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
+        { "TOC 5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
+        { "TOC 6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
+        { "TOC 7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
+        { "TOC 8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
+        { "TOC 9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
+        { "TOC Heading", "Contents Heading" }, // RES_POOLCOLL_TOX_CNTNTH
+        { "TOCHeading", "Contents Heading" }, // RES_POOLCOLL_TOX_CNTNTH
+        { "toc 1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
+        { "toc 2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
+        { "toc 3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
+        { "toc 4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
+        { "toc 5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
+        { "toc 6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
+        { "toc 7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
+        { "toc 8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
+        { "toc 9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
+        { "TOC1", "Contents 1" }, // RES_POOLCOLL_TOX_CNTNT1
+        { "TOC2", "Contents 2" }, // RES_POOLCOLL_TOX_CNTNT2
+        { "TOC3", "Contents 3" }, // RES_POOLCOLL_TOX_CNTNT3
+        { "TOC4", "Contents 4" }, // RES_POOLCOLL_TOX_CNTNT4
+        { "TOC5", "Contents 5" }, // RES_POOLCOLL_TOX_CNTNT5
+        { "TOC6", "Contents 6" }, // RES_POOLCOLL_TOX_CNTNT6
+        { "TOC7", "Contents 7" }, // RES_POOLCOLL_TOX_CNTNT7
+        { "TOC8", "Contents 8" }, // RES_POOLCOLL_TOX_CNTNT8
+        { "TOC9", "Contents 9" }, // RES_POOLCOLL_TOX_CNTNT9
 //        { "Normal Indent", "" },
-        { "footnote text", "Footnote" },
-        { "Footnote Text", "Footnote" },
-//        { "Annotation Text", "" },
-        { "Header", "Header" },
-        { "header", "Header" },
-        { "Footer", "Footer" },
-        { "footer", "Footer" },
-        { "Index Heading", "Index Heading" },
-//        { "Caption", "" },
-//        { "Table of Figures", "" },
-        { "Envelope Address", "Addressee" },
-        { "Envelope Return", "Sender" },
-        { "footnote reference", "Footnote Symbol" },
-        { "Footnote Reference", "Footnote Symbol" },
+        { "footnote text", "Footnote" }, // RES_POOLCOLL_FOOTNOTE
+        { "Footnote Text", "Footnote" }, // RES_POOLCOLL_FOOTNOTE
+        { "Annotation Text", "Marginalia" }, // RES_POOLCOLL_MARGINAL
+        { "Header", "Header" }, // RES_POOLCOLL_HEADER
+        { "header", "Header" }, // RES_POOLCOLL_HEADER
+        { "Footer", "Footer" }, // RES_POOLCOLL_FOOTER
+        { "footer", "Footer" }, // RES_POOLCOLL_FOOTER
+        { "Index Heading", "Index Heading" }, // RES_POOLCOLL_TOX_IDXH
+        { "Caption", "Caption" }, // RES_POOLCOLL_LABEL
+        { "Table of Figures", "Drawing" }, // RES_POOLCOLL_LABEL_DRAWING
+        { "Envelope Address", "Addressee" }, // RES_POOLCOLL_ENVELOPE_ADDRESS
+        { "Envelope Return", "Sender" }, // RES_POOLCOLL_SEND_ADDRESS
+        { "footnote reference", "Footnote Symbol" }, // RES_POOLCHR_FOOTNOTE; 
tdf#82173
+        { "Footnote Reference", "Footnote Symbol" }, // RES_POOLCHR_FOOTNOTE; 
tdf#82173
 //        { "Annotation Reference", "" },
-        { "Line Number", "Line numbering" },
-        { "Page Number", "Page Number" },
-        { "endnote reference", "Endnote Symbol" },
-        { "Endnote Reference", "Endnote Symbol" },
-        { "endnote text", "Endnote" },
-        { "Endnote Text", "Endnote" },
-//        { "Table of Authorities", "" },
+        { "Line Number", "Line numbering" }, // RES_POOLCHR_LINENUM
+        { "Page Number", "Page Number" }, // RES_POOLCHR_PAGENO
+        { "endnote reference", "Endnote Symbol" }, // RES_POOLCHR_ENDNOTE; 
tdf#82173
+        { "Endnote Reference", "Endnote Symbol" }, // RES_POOLCHR_ENDNOTE; 
tdf#82173
+        { "endnote text", "Endnote" }, // RES_POOLCOLL_ENDNOTE
+        { "Endnote Text", "Endnote" }, // RES_POOLCOLL_ENDNOTE
+        { "Table of Authorities", "Bibliography Heading" }, // 
RES_POOLCOLL_TOX_AUTHORITIESH
 //        { "Macro Text", "" },
 //        { "TOA Heading", "" },
-        { "List", "List" },
+        { "List", "List" }, // RES_POOLCOLL_NUMBER_BULLET_BASE
 //        { "List 2", "" },
 //        { "List 3", "" },
 //        { "List 4", "" },
 //        { "List 5", "" },
-//        { "List Bullet", "" },
-//        { "List Bullet 2", "" },
-//        { "List Bullet 3", "" },
-//        { "List Bullet 4", "" },
-//        { "List Bullet 5", "" },
-//        { "List Number", "" },
-//        { "List Number 2", "" },
-//        { "List Number 3", "" },
-//        { "List Number 4", "" },
-//        { "List Number 5", "" },
-        { "Title", "Title" },
-//        { "Closing", "" },
-        { "Signature", "Signature" },
+        { "List Bullet", "List 1" }, // RES_POOLCOLL_BULLET_LEVEL1
+        { "List Bullet 2", "List 2" }, // RES_POOLCOLL_BULLET_LEVEL2
+        { "List Bullet 3", "List 3" }, // RES_POOLCOLL_BULLET_LEVEL3
+        { "List Bullet 4", "List 4" }, // RES_POOLCOLL_BULLET_LEVEL4
+        { "List Bullet 5", "List 5" }, // RES_POOLCOLL_BULLET_LEVEL5
+        { "List Number", "Numbering 1" }, // RES_POOLCOLL_NUM_LEVEL1
+        { "List Number 2", "Numbering 2" }, // RES_POOLCOLL_NUM_LEVEL2
+        { "List Number 3", "Numbering 3" }, // RES_POOLCOLL_NUM_LEVEL3
+        { "List Number 4", "Numbering 4" }, // RES_POOLCOLL_NUM_LEVEL4
+        { "List Number 5", "Numbering 5" }, // RES_POOLCOLL_NUM_LEVEL5
+        { "Title", "Title" }, // RES_POOLCOLL_DOC_TITLE
+        { "Closing", "Appendix" }, // RES_POOLCOLL_DOC_APPENDIX
+        { "Signature", "Signature" }, // RES_POOLCOLL_SIGNATURE
 //        { "Default Paragraph Font", "" },
         { "DefaultParagraphFont", "Default Paragraph Font" },
-        { "Body Text", "Text body" },
-        { "BodyText", "Text body" },
+        { "Body Text", "Text body" }, // RES_POOLCOLL_TEXT
+        { "BodyText", "Text body" }, // RES_POOLCOLL_TEXT
         { "BodyTextIndentItalic", "Text body indent italic" },
-        { "Body Text Indent", "Text body indent" },
-        { "BodyTextIndent", "Text body indent" },
+        { "Body Text Indent", "Text body indent" }, // RES_POOLCOLL_TEXT_MOVE
+        { "BodyTextIndent", "Text body indent" }, // RES_POOLCOLL_TEXT_MOVE
         { "BodyTextIndent2", "Text body indent2" },
-//        { "List Continue", "" },
-//        { "List Continue 2", "" },
-//        { "List Continue 3", "" },
-//        { "List Continue 4", "" },
-//        { "List Continue 5", "" },
+        { "List Continue", "List 1 Cont." }, // RES_POOLCOLL_BULLET_NONUM1
+        { "List Continue 2", "List 2 Cont." }, // RES_POOLCOLL_BULLET_NONUM2
+        { "List Continue 3", "List 3 Cont." }, // RES_POOLCOLL_BULLET_NONUM3
+        { "List Continue 4", "List 4 Cont." }, // RES_POOLCOLL_BULLET_NONUM4
+        { "List Continue 5", "List 5 Cont." }, // RES_POOLCOLL_BULLET_NONUM5
 //        { "Message Header", "" },
-        { "Subtitle", "Subtitle" },
-//        { "Salutation", "" },
+        { "Subtitle", "Subtitle" }, // RES_POOLCOLL_DOC_SUBTITLE
+        { "Salutation", "Salutation" }, // RES_POOLCOLL_GREETING
 //        { "Date", "" },
-        { "Body Text First Indent", "Body Text Indent" },
+        { "Body Text First Indent", "First line indent" }, // 
RES_POOLCOLL_TEXT_IDENT
 //        { "Body Text First Indent 2", "" },
 //        { "Note Heading", "" },
 //        { "Body Text 2", "" },
@@ -1550,15 +1562,16 @@ OUString StyleSheetTable::ConvertStyleName( const 
OUString& rWWName, bool bExten
 //        { "Body Text Indent 2", "" },
 //        { "Body Text Indent 3", "" },
 //        { "Block Text", "" },
-        { "Hyperlink", "Internet link" },
-        { "FollowedHyperlink", "Visited Internet Link" },
-        { "Emphasis", "Emphasis" },
+        { "Hyperlink", "Internet link" }, // RES_POOLCHR_INET_NORMAL
+        { "FollowedHyperlink", "Visited Internet Link" }, // 
RES_POOLCHR_INET_VISIT
+        { "Strong", "Strong Emphasis" }, // RES_POOLCHR_HTML_STRONG
+        { "Emphasis", "Emphasis" }, // RES_POOLCHR_HTML_EMPHASIS
 //        { "Document Map", "" },
 //        { "Plain Text", "" },
         { "NoList", "No List" },
         { "AbstractHeading", "Abstract Heading" },
         { "AbstractBody", "Abstract Body" },
-        { "PageNumber", "page number" },
+        { "PageNumber", "Page Number" }, // RES_POOLCHR_PAGENO
         { "TableNormal", "Normal Table" },
         { "DocumentMap", "Document Map" },
     };
@@ -1577,10 +1590,17 @@ OUString StyleSheetTable::ConvertStyleName( const 
OUString& rWWName, bool bExten
                 set.insert(pair.second);
             return set;
         }();
-        // SwStyleNameMapper doc says: If the UI style name equals a
-        // programmatic name, then it must append " (user)" to the end.
-        if (ReservedStyleNames.find(sRet) != ReservedStyleNames.end())
-            sRet += " (user)";
+        // Similar to SwStyleNameMapper convention (where a " (user)" suffix 
is used to
+        // disambiguate user styles with reserved names in localization where 
respective
+        // built-in styles have different UI names), we add a " (WW)" suffix 
here. Unlike
+        // the " (user)" suffix, it is not hidden from the UI; it will be 
handled when
+        // exported to Word formats - see MSWordStyles::BuildWwNames.
+        // We can't use the " (user)" suffix, because that system is built 
upon the assumption
+        // that UI names of respective built-in styles are different from the 
user style name.
+        // That is not necessarily true here, since the current localization 
may not change
+        // the UI names of built-in styles.
+        if (ReservedStyleNames.find(sRet) != ReservedStyleNames.end() || 
sRet.endsWith(" (WW)"))
+            sRet += " (WW)";
     }
 
     return sRet;
commit 319e2e0cbc6a1d25abd01fb27d6250cee825c072
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Dec 10 08:58:10 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Jan 12 04:34:22 2023 +0000

    tdf#152425 Make Word names unique, and use them for style ids generation
    
    Before, a style id was generated from LibreOffice name, and then the
    name was replaced with Word name. Given that Writer's List N maps to
    Word's List Bullet N, and Word's List N doesn't map to anything in
    Writer, this led to styles.xml having after roundtrip:
    
        <w:style w:type="paragraph" w:styleId="List5">
            <w:name w:val="List Bullet 5"/>
        ...
        <w:style w:type="paragraph" w:styleId="ListBullet5">
            <w:name w:val="List Bullet 5"/>
    
    So the idea is to do the following steps:
    
    1. Collect all the exported styles (unchanged);
    2. Build unique Word names for collected styles (new):
       a. Process all the styles that map to special Word styles first,
          so that their Word names don't get changed when made unique;
       b. Process the rest of the styles, making sure to append a sequential
          number after the Writer name, if a clash happens.
    3. Build Style Ids from the Word names (previously Writer name could be
       used), also making sure they are unique.
    
    Change-Id: I9f8f254aa6ae713671234f0109b94cc72a588150
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143905
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index f42b5e7f9a28..a1610c35dbbb 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -1228,8 +1228,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf123628)
 
     xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
 
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:hyperlink/w:r/w:rPr/w:rStyle", "val", 
"InternetLink");
-    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='InternetLink']/w:name", "val", "Hyperlink");
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:hyperlink/w:r/w:rPr/w:rStyle", "val", "Hyperlink");
+    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='Hyperlink']/w:name", "val", "Hyperlink");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf127741, "tdf127741.docx")
@@ -1255,7 +1255,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf127925)
     loadAndSave("tdf127925.odt");
     CPPUNIT_ASSERT_EQUAL(1, getPages());
     xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
-    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='VisitedInternetLink']/w:name", "val", 
"FollowedHyperlink");
+    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='FollowedHyperlink']/w:name", "val", 
"FollowedHyperlink");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf127579)
@@ -1263,7 +1263,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf127579)
     loadAndSave("tdf127579.odt");
     CPPUNIT_ASSERT_EQUAL(1, getPages());
     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:rStyle", "val", "InternetLink");
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:rStyle", "val", "Hyperlink");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf128304)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index f5230adb643a..4c27a18101fd 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -1013,7 +1013,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf143726)
     CPPUNIT_ASSERT(pXmlStyles);
     // Without the fix this was "TOA Heading" which belongs to the "Table of 
Authorities" index in Word
     // TOC's heading style should be exported as "TOC Heading" as that's the 
default Word style name
-    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='ContentsHeading']/w:name", "val", "TOC Heading");
+    assertXPath(pXmlStyles, 
"/w:styles/w:style[@w:styleId='TOCHeading']/w:name", "val", "TOC Heading");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf152153)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index c9d7528f6297..92e13b4b7d3b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -270,6 +270,11 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf152425)
     // CPPUNIT_ASSERT_EQUAL(OUString("List 5"), Para4Style);
     // But for now, just make sure that the style names differ
     CPPUNIT_ASSERT(Para4Style != Para3Style);
+    const OUString Para5Style = getProperty<OUString>(getParagraph(5), 
"ParaStyleName");
+    // Eventually, we need to check this:
+    // CPPUNIT_ASSERT_EQUAL(OUString("List Bullet 5"), Para5Style);
+    // But for now, just make sure that the style names differ
+    CPPUNIT_ASSERT(Para5Style != Para4Style);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 7b6f8126afe1..db4299d582b3 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3874,7 +3874,12 @@ void DocxAttributeOutput::Redline( const SwRedlineData* 
pRedlineData)
 
                     m_pSerializer->startElementNS(XML_w, XML_pPr);
 
-                    OString sStyleName = MSWordStyles::CreateStyleId( 
sParaStyleName );
+                    OString sStyleName;
+                    if (auto format = 
m_rExport.m_rDoc.FindTextFormatCollByName(sParaStyleName))
+                        if (auto slot = m_rExport.m_pStyles->GetSlot(format); 
slot != 0xfff)
+                            sStyleName = m_rExport.m_pStyles->GetStyleId(slot);
+                    if (sStyleName.isEmpty())
+                        sStyleName = 
MSWordStyles::CreateStyleId(sParaStyleName);
                     if ( !sStyleName.isEmpty() )
                         m_pSerializer->singleElementNS(XML_w, XML_pStyle, 
FSNS(XML_w, XML_val), sStyleName);
 
@@ -7164,20 +7169,14 @@ void DocxAttributeOutput::StartStyle( const OUString& 
rName, StyleType eType,
             SAL_WARN("sw.ww8", "Unhandled style property: " << rProp.Name);
     }
 
-    // MSO exports English names and writerfilter only recognize them.
-    const char *pEnglishName = nullptr;
     const char* pType = nullptr;
     switch (eType)
     {
         case STYLE_TYPE_PARA:
             pType = "paragraph";
-            if ( nWwId < ww::stiMax)
-                pEnglishName = ww::GetEnglishNameFromSti( 
static_cast<ww::sti>(nWwId ) );
             break;
         case STYLE_TYPE_CHAR:
             pType = "character";
-            if (nWwId < ww::stiMax)
-                pEnglishName = 
ww::GetEnglishNameFromSti(static_cast<ww::sti>(nWwId));
             break;
         case STYLE_TYPE_LIST: pType = "numbering"; break;
     }
@@ -7188,8 +7187,7 @@ void DocxAttributeOutput::StartStyle( const OUString& 
rName, StyleType eType,
     if (bCustomStyle)
         pStyleAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
     m_pSerializer->startElementNS( XML_w, XML_style, pStyleAttributeList);
-    m_pSerializer->singleElementNS( XML_w, XML_name,
-            FSNS( XML_w, XML_val ), pEnglishName ? pEnglishName : 
rName.toUtf8() );
+    m_pSerializer->singleElementNS(XML_w, XML_name, FSNS(XML_w, XML_val), 
rName);
 
     if ( nBase != 0x0FFF && eType != STYLE_TYPE_LIST)
     {
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx 
b/sw/source/filter/ww8/wrtw8sty.cxx
index efd2c230465f..9f534b1b55d2 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -158,6 +158,7 @@ MSWordStyles::MSWordStyles( MSWordExportBase& rExport, bool 
bListStyles )
     memset( m_aHeadingParagraphStyles, -1 , MAXLEVEL * sizeof( sal_uInt16));
 
     BuildStylesTable();
+    BuildWwNames();
     BuildStyleIds();
 }
 
@@ -288,7 +289,7 @@ void MSWordStyles::BuildStylesTable()
         sal_uInt16 nSlot = BuildGetSlot(*pFormat);
         if (nSlot != 0xfff)
         {
-            m_aStyles[nSlot].format = pFormat;
+            m_aStyles[nSlot] = { pFormat };
         }
         else
         {
@@ -318,6 +319,59 @@ void MSWordStyles::BuildStylesTable()
     }
 }
 
+void MSWordStyles::BuildWwNames()
+{
+    std::unordered_set<OUString> aUsed;
+
+    auto makeUniqueName = [&aUsed](OUString& name) {
+        // toAsciiLowerCase rules out e.g. user's "normal"; no problem if 
there are non-ASCII chars
+        OUString lower(name.toAsciiLowerCase());
+        if (!aUsed.insert(lower).second)
+        {
+            int nFree = 1;
+            while (!aUsed.insert(lower + OUString::number(nFree)).second)
+                ++nFree;
+
+            name += OUString::number(nFree);
+        }
+    };
+
+    // We want to map LO's default style to Word's "Normal" style.
+    // Word looks for this specific style name when reading docx files.
+    // (It must be the English word regardless of language settings)
+    assert(!m_aStyles.empty());
+    assert(!m_aStyles[0].format || m_aStyles[0].ww_id == ww::stiNormal);
+    m_aStyles[0].ww_name = "Normal";
+    aUsed.insert("normal");
+
+    // 1. Handle styles having special wwIds, and thus pre-defined names
+    for (auto& entry : m_aStyles)
+    {
+        if (!entry.ww_name.isEmpty())
+            continue; // "Normal" is already added
+        if (entry.ww_id >= ww::stiMax)
+            continue; // Not a format with special name
+        assert(entry.format);
+
+        entry.ww_name = 
OUString::createFromAscii(ww::GetEnglishNameFromSti(static_cast<ww::sti>(entry.ww_id)));
+        makeUniqueName(entry.ww_name);
+    }
+
+    // 2. Now handle other styles
+    for (auto& entry : m_aStyles)
+    {
+        if (!entry.ww_name.isEmpty())
+            continue;
+        if (entry.format)
+            entry.ww_name = entry.format->GetName();
+        else if (entry.num_rule)
+            entry.ww_name = entry.num_rule->GetName();
+        else
+            continue;
+        makeUniqueName(entry.ww_name);
+    }
+}
+
 OString MSWordStyles::CreateStyleId(std::u16string_view aName)
 {
     OStringBuffer aStyleIdBuf(aName.size());
@@ -340,23 +394,9 @@ void MSWordStyles::BuildStyleIds()
 {
     std::unordered_set<OString> aUsed;
 
-    assert(!m_aStyles.empty());
-    m_aStyles[0].style_id = "Normal";
-    aUsed.insert("normal");
-
     for (auto& entry : m_aStyles)
     {
-        if (!entry.style_id.isEmpty())
-            continue; // "Normal" is already added
-
-        assert(entry.style_id.isEmpty());
-        OUString name;
-        if (entry.format)
-            name = entry.format->GetName();
-        else if (entry.num_rule)
-            name = entry.num_rule->GetName();
-
-        OString aStyleId = CreateStyleId(name);
+        OString aStyleId = CreateStyleId(entry.ww_name);
 
         if (aStyleId.isEmpty())
             aStyleId = "Style";
@@ -589,68 +629,45 @@ void WW8AttributeOutput::DefaultStyle()
     m_rWW8Export.m_pTableStrm->WriteUInt16(0);   // empty Style
 }
 
-void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nSlot)
+void MSWordStyles::OutputStyle(sal_uInt16 nSlot)
 {
-    m_rExport.AttrOutput().StartStyle( pNumRule->GetName(), STYLE_TYPE_LIST,
+    const auto& entry = m_aStyles[nSlot];
+
+    if (entry.num_rule)
+    {
+        m_rExport.AttrOutput().StartStyle( entry.ww_name, STYLE_TYPE_LIST,
             /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWwLink =*/ 0, /*nWWId =*/ 0, 
nSlot,
             /*bAutoUpdateFormat =*/ false );
 
-    m_rExport.AttrOutput().EndStyle();
-}
-
-// OutputStyle applies for TextFormatColls and CharFormats
-void MSWordStyles::OutputStyle( const SwFormat* pFormat, sal_uInt16 nSlot)
-{
-    if ( !pFormat )
+        m_rExport.AttrOutput().EndStyle();
+    }
+    else if (!entry.format)
+    {
         m_rExport.AttrOutput().DefaultStyle();
+    }
     else
     {
         bool bFormatColl;
         sal_uInt16 nBase, nWwNext;
         sal_uInt16 nWwLink = 0x0FFF;
 
-        GetStyleData(pFormat, bFormatColl, nBase, nWwNext, nWwLink);
+        GetStyleData(entry.format, bFormatColl, nBase, nWwNext, nWwLink);
 
-        OUString aName = pFormat->GetName();
-        // We want to map LO's default style to Word's "Normal" style.
-        // Word looks for this specific style name when reading docx files.
-        // (It must be the English word regardless of language settings)
-        if (nSlot == 0)
-        {
-            assert( pFormat->GetPoolFormatId() == RES_POOLCOLL_STANDARD );
-            aName = "Normal";
-        }
-        else if (aName.equalsIgnoreAsciiCase("Normal"))
-        {
-            // If LO has a style named "Normal"(!) rename it to something 
unique
-            const OUString aBaseName = "LO-" + aName;
-            aName = aBaseName;
-            // Check if we still have a clash, in which case we add a suffix
-            for ( int nSuffix = 0; ; ++nSuffix ) {
-                if (std::none_of(m_aStyles.begin() + 1, m_aStyles.end(),
-                                 [&aName](const auto& entry) {
-                                     return entry.format
-                                            && 
entry.format->GetName().equalsIgnoreAsciiCase(aName);
-                                 }))
-                    break; // Found a unique name
-                aName = aBaseName + OUString::number(nSuffix);
-            }
-        }
-        else if (!bFormatColl && m_rExport.GetExportFormat() == 
MSWordExportBase::DOCX &&
-                        
m_rExport.m_pStyles->GetStyleId(nSlot).startsWith("ListLabel"))
+        if (!bFormatColl && m_rExport.GetExportFormat() == 
MSWordExportBase::DOCX &&
+                        entry.style_id.startsWith("ListLabel"))
         {
             // tdf#92335 don't export redundant DOCX import style "ListLabel"
             return;
         }
 
-        m_rExport.AttrOutput().StartStyle( aName, (bFormatColl ? 
STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
-                nBase, nWwNext, nWwLink, GetWWId( *pFormat ), nSlot,
-                pFormat->IsAutoUpdateOnDirectFormat() );
+        m_rExport.AttrOutput().StartStyle(entry.ww_name, (bFormatColl ? 
STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
+                nBase, nWwNext, nWwLink, m_aStyles[nSlot].ww_id, nSlot,
+                entry.format->IsAutoUpdateOnDirectFormat() );
 
         if ( bFormatColl )
-            WriteProperties( pFormat, true, nSlot, nBase==0xfff );           
// UPX.papx
+            WriteProperties( entry.format, true, nSlot, nBase==0xfff );        
   // UPX.papx
 
-        WriteProperties( pFormat, false, nSlot, bFormatColl && nBase==0xfff ); 
 // UPX.chpx
+        WriteProperties( entry.format, false, nSlot, bFormatColl && 
nBase==0xfff );  // UPX.chpx
 
         m_rExport.AttrOutput().EndStyle();
     }
@@ -699,12 +716,7 @@ void MSWordStyles::OutputStylesTable()
     // Implementing check for all exports DOCX, DOC, RTF
     assert(m_aStyles.size() <= MSWORD_MAX_STYLES_LIMIT);
     for (size_t slot = 0; slot < m_aStyles.size(); ++slot)
-    {
-        if (m_aStyles[slot].num_rule)
-            OutputStyle(m_aStyles[slot].num_rule, slot);
-        else
-            OutputStyle(m_aStyles[slot].format, slot);
-    }
+        OutputStyle(slot);
 
     m_rExport.AttrOutput().EndStyles(m_aStyles.size());
 
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 5af10e91fdc3..cf5d0bfa104b 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1587,10 +1587,12 @@ class MSWordStyles
         const SwFormat* format = nullptr;
         const SwNumRule* num_rule = nullptr;
         /// We need to build style id's for DOCX export; ideally we should 
roundtrip that, but this is good enough.
+        sal_uInt16 ww_id = ww::stiUser;
+        OUString ww_name;
         OString style_id;
 
         MapEntry() = default;
-        MapEntry(const SwFormat* f) : format(f) {}
+        MapEntry(const SwFormat* f) : format(f) { if (f) ww_id = GetWWId(*f); }
         MapEntry(const SwNumRule* r) : num_rule(r) {}
     };
     std::vector<MapEntry> m_aStyles; ///< Slot <-> Character/paragraph/list 
style array.
@@ -1599,6 +1601,9 @@ class MSWordStyles
     /// Create the style table, called from the constructor.
     void BuildStylesTable();
 
+    /// Generate proper Word names, taking mapping between special types into 
account
+    void BuildWwNames();
+
     /// Based on style names, fill in unique, MS-like names.
     void BuildStyleIds();
 
@@ -1613,8 +1618,7 @@ class MSWordStyles
     void SetStyleDefaults( const SwFormat& rFormat, bool bPap );
 
     /// Outputs one style - called (in a loop) from OutputStylesTable().
-    void OutputStyle( const SwFormat* pFormat, sal_uInt16 nSlot );
-    void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nSlot);
+    void OutputStyle( sal_uInt16 nSlot );
 
     MSWordStyles( const MSWordStyles& ) = delete;
     MSWordStyles& operator=( const MSWordStyles& ) = delete;
commit 4ac0a27c7cb0e8d09e701aaf150414d136e58310
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Dec 8 19:13:43 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Jan 12 04:34:14 2023 +0000

    tdf#152425 Fix order in stiName array
    
    Since their introduction in commit 552d05f57175ecdd0736dc257319bc30aa88d696
    (INTEGRATION: CWS portlaoisefilterteam16 (1.1.2); FILE ADDED, 2003-12-09)
    and commit 9ba054a180fe1fcd410a2887351c2ff1fcb30847 (INTEGRATION: CWS
    portlaoisefilterteam16 (1.1.2); FILE ADDED, 2003-12-09), the enum sti
    and GetStiNames were accidentally not matching each other.
    
    commit 78284714b73a8307174c596295894e8f3951e09a (tdf#76817: fix missing
    heading styles assigned to outline levels in ooxml, 2016-02-04) introduced
    a use of ww::GetEnglishNameFromSti, and since then, the unmatched elements
    started to get written to DOCX styles with wrong names, like
    
        <w:style w:type="paragraph" w:styleId="List5">
            <w:name w:val="List Number"/>
    
    instead of original name "List 5".
    
    Change-Id: I8888b3f117e0b7f57c2dbb90565475d529416c60
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143828
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf152425.docx 
b/sw/qa/extras/ooxmlexport/data/tdf152425.docx
new file mode 100644
index 000000000000..53a65cc63438
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf152425.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index a145a3054a4e..c9d7528f6297 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -258,6 +258,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf126477)
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aSeq2.getLength());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf152425)
+{
+    loadAndReload("tdf152425.docx");
+
+    // Check that "List Number" and "List 5" styles don't get merged
+    const OUString Para3Style = getProperty<OUString>(getParagraph(3), 
"ParaStyleName");
+    CPPUNIT_ASSERT_EQUAL(OUString("List Number"), Para3Style);
+    const OUString Para4Style = getProperty<OUString>(getParagraph(4), 
"ParaStyleName");
+    // Eventually, we need to check this:
+    // CPPUNIT_ASSERT_EQUAL(OUString("List 5"), Para4Style);
+    // But for now, just make sure that the style names differ
+    CPPUNIT_ASSERT(Para4Style != Para3Style);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/inc/wwstyles.hxx 
b/sw/source/filter/inc/wwstyles.hxx
index 32dce11e3692..7a253d87c508 100644
--- a/sw/source/filter/inc/wwstyles.hxx
+++ b/sw/source/filter/inc/wwstyles.hxx
@@ -24,6 +24,7 @@
 
 namespace ww
 {
+    // When changing, make sure to update GetStiNames in 
sw/source/filter/ww8/styles.cxx accordingly
     enum sti : sal_uInt16
     {
         stiNormal = 0,                  // 0x0000
diff --git a/sw/source/filter/ww8/styles.cxx b/sw/source/filter/ww8/styles.cxx
index 86ec89a37798..c7a28e77e60b 100644
--- a/sw/source/filter/ww8/styles.cxx
+++ b/sw/source/filter/ww8/styles.cxx
@@ -25,102 +25,103 @@ namespace
 {
     const char **GetStiNames() noexcept
     {
+        // Matches enum ww::sti in sw/source/filter/inc/wwstyles.hxx
         static const char *stiName[] =
         {
-            "Normal",
-            "Heading 1",
-            "Heading 2",
-            "Heading 3",
-            "Heading 4",
-            "Heading 5",
-            "Heading 6",
-            "Heading 7",
-            "Heading 8",
-            "Heading 9",
-            "Index 1",
-            "Index 2",
-            "Index 3",
-            "Index 4",
-            "Index 5",
-            "Index 6",
-            "Index 7",
-            "Index 8",
-            "Index 9",
-            "TOC 1",
-            "TOC 2",
-            "TOC 3",
-            "TOC 4",
-            "TOC 5",
-            "TOC 6",
-            "TOC 7",
-            "TOC 8",
-            "TOC 9",
-            "Normal Indent",
-            "Footnote Text",
-            "Annotation Text",
-            "Header",
-            "Footer",
-            "Index Heading",
-            "Caption",
-            "Table of Figures",
-            "Envelope Address",
-            "Envelope Return",
-            "Footnote Reference",
-            "Annotation Reference",
-            "Line Number",
-            "Page Number",
-            "Endnote Reference",
-            "Endnote Text",
-            "Table of Authorities",
-            "Macro Text",
-            "TOC Heading",
-            "List",
-            "List 2",
-            "List 3",
-            "List 4",
-            "List 5",
-            "List Bullet",
-            "List Bullet 2",
-            "List Bullet 3",
-            "List Bullet 4",
-            "List Bullet 5",
-            "List Number",
-            "List Number 2",
-            "List Number 3",
-            "List Number 4",
-            "List Number 5",
-            "Title",
-            "Closing",
-            "Signature",
-            "Default Paragraph Font",
-            "Body Text",
-            "Body Text Indent",
-            "List Continue",
-            "List Continue 2",
-            "List Continue 3",
-            "List Continue 4",
-            "List Continue 5",
-            "Message Header",
-            "Subtitle",
-            "Salutation",
-            "Date",
-            "Body Text First Indent",
-            "Body Text First Indent 2",
-            "Note Heading",
-            "Body Text 2",
-            "Body Text 3",
-            "Body Text Indent 2",
-            "Body Text Indent 3",
-            "Block Text",
-            "Hyperlink",
-            "FollowedHyperlink",
-            "Strong",
-            "Emphasis",
-            "Document Map",
-            "Plain Text"
+            "Normal",                   // stiNormal
+            "Heading 1",                // stiLev1
+            "Heading 2",                // stiLev2
+            "Heading 3",                // stiLev3
+            "Heading 4",                // stiLev4
+            "Heading 5",                // stiLev5
+            "Heading 6",                // stiLev6
+            "Heading 7",                // stiLev7
+            "Heading 8",                // stiLev8
+            "Heading 9",                // stiLev9
+            "Index 1",                  // stiIndex1
+            "Index 2",                  // stiIndex2
+            "Index 3",                  // stiIndex3
+            "Index 4",                  // stiIndex4
+            "Index 5",                  // stiIndex5
+            "Index 6",                  // stiIndex6
+            "Index 7",                  // stiIndex7
+            "Index 8",                  // stiIndex8
+            "Index 9",                  // stiIndex9
+            "TOC 1",                    // stiToc1
+            "TOC 2",                    // stiToc2
+            "TOC 3",                    // stiToc3
+            "TOC 4",                    // stiToc4
+            "TOC 5",                    // stiToc5
+            "TOC 6",                    // stiToc6
+            "TOC 7",                    // stiToc7
+            "TOC 8",                    // stiToc8
+            "TOC 9",                    // stiToc9
+            "Normal Indent",            // stiNormIndent
+            "Footnote Text",            // stiFootnoteText
+            "Annotation Text",          // stiAtnText
+            "Header",                   // stiHeader
+            "Footer",                   // stiFooter
+            "Index Heading",            // stiIndexHeading
+            "Caption",                  // stiCaption
+            "Table of Figures",         // stiToCaption
+            "Envelope Address",         // stiEnvAddr
+            "Envelope Return",          // stiEnvRet
+            "Footnote Reference",       // stiFootnoteRef
+            "Annotation Reference",     // stiAtnRef
+            "Line Number",              // stiLnn
+            "Page Number",              // stiPgn
+            "Endnote Reference",        // stiEdnRef
+            "Endnote Text",             // stiEdnText
+            "Table of Authorities",     // stiToa
+            "Macro Text",               // stiMacro
+            "TOC Heading",              // stiToaHeading - tdf143726
+            "List",                     // stiList
+            "List Bullet",              // stiListBullet
+            "List Number",              // stiListNumber
+            "List 2",                   // stiList2
+            "List 3",                   // stiList3
+            "List 4",                   // stiList4
+            "List 5",                   // stiList5
+            "List Bullet 2",            // stiListBullet2
+            "List Bullet 3",            // stiListBullet3
+            "List Bullet 4",            // stiListBullet4
+            "List Bullet 5",            // stiListBullet5
+            "List Number 2",            // stiListNumber2
+            "List Number 3",            // stiListNumber3
+            "List Number 4",            // stiListNumber4
+            "List Number 5",            // stiListNumber5
+            "Title",                    // stiTitle
+            "Closing",                  // stiClosing
+            "Signature",                // stiSignature
+            "Default Paragraph Font",   // stiNormalChar
+            "Body Text",                // stiBodyText
+            "Body Text Indent",         // stiBodyTextInd1
+            "List Continue",            // stiListCont
+            "List Continue 2",          // stiListCont2
+            "List Continue 3",          // stiListCont3
+            "List Continue 4",          // stiListCont4
+            "List Continue 5",          // stiListCont5
+            "Message Header",           // stiMsgHeader
+            "Subtitle",                 // stiSubtitle
+            "Salutation",               // stiSalutation
+            "Date",                     // stiDate
+            "Body Text First Indent",   // stiBodyText1I
+            "Body Text First Indent 2", // stiBodyText1I2
+            "Note Heading",             // stiNoteHeading
+            "Body Text 2",              // stiBodyText2
+            "Body Text 3",              // stiBodyText3
+            "Body Text Indent 2",       // stiBodyTextInd2
+            "Body Text Indent 3",       // stiBodyTextInd3
+            "Block Text",               // stiBlockQuote
+            "Hyperlink",                // stiHyperlink
+            "FollowedHyperlink",        // stiHyperlinkFollowed
+            "Strong",                   // stiStrong
+            "Emphasis",                 // stiEmphasis
+            "Document Map",             // stiNavPane
+            "Plain Text",               // stiPlainText
         };
 
-        OSL_ENSURE( SAL_N_ELEMENTS(stiName) == ww::stiMax, "WrongSizeOfArray" 
);
+        static_assert(SAL_N_ELEMENTS(stiName) == ww::stiMax, 
"WrongSizeOfArray");
 
         return stiName;
     }

Reply via email to