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

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Thu Sep 5 08:18:57 UTC 2019


 sw/inc/list.hxx                              |    4 +-
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx   |    3 -
 sw/source/filter/ww8/attributeoutputbase.hxx |    4 ++
 sw/source/filter/ww8/docxattributeoutput.cxx |   12 ++++++
 sw/source/filter/ww8/docxattributeoutput.hxx |    3 +
 sw/source/filter/ww8/rtfattributeoutput.cxx  |    2 -
 sw/source/filter/ww8/rtfexport.cxx           |    4 +-
 sw/source/filter/ww8/wrtw8num.cxx            |   50 +++++++++++++++++++++++----
 sw/source/filter/ww8/wrtww8.hxx              |   11 +++++
 sw/source/filter/ww8/ww8atr.cxx              |   29 ++++++++++++++-
 10 files changed, 107 insertions(+), 15 deletions(-)

New commits:
commit 1f6b7030cbdc81e8e408e3a13bfcd01fcbdd7550
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 4 12:27:52 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 5 10:18:12 2019 +0200

    tdf#95848 sw: DOCX export: crude implementation of abstractNum mapping
    
    The abstractNum needs to correspond to a SwList, not to a SwNumRule as
    it is currently implemented.
    
    Add a mapping to MSWordExportBase for "overriding" numbering
    definitions; these are added to m_pUsedNumTable, which appears to be
    necessary to interact with DuplicateNumRule(), but here we just add
    nullpointers, because we don't need to modify the SwNumrule, and neither
    do we want the vector to double-delete it.
    
    The mapping is created while iterating over the document, in
    AttributeOutputBase::ParaNumRule().
    
    It turns out that this approach would work for WW8 too as
    DuplicateNumRule() was originally added for that format but it won't
    work easily for RTF; in the DOCX case the WriteNumbering() is called
    after the main text and footnotes/endnotes, but with RTF it's the
    other way around :(
    
    Change-Id: Ia0409f5ad0b2e089005024ef7f61850a06d4dcbe
    Reviewed-on: https://gerrit.libreoffice.org/78607
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/inc/list.hxx b/sw/inc/list.hxx
index 1cfdad5e0716..d8b3e16943ea 100644
--- a/sw/inc/list.hxx
+++ b/sw/inc/list.hxx
@@ -24,6 +24,8 @@
 #include <rtl/ustring.hxx>
 #include <memory>
 
+#include "swdllapi.h"
+
 class SwNumRule;
 class SwNodes;
 class SwNodeNum;
@@ -40,7 +42,7 @@ class SwList
 
         const OUString & GetListId() const;
 
-        const OUString & GetDefaultListStyleName() const;
+        SW_DLLPUBLIC const OUString & GetDefaultListStyleName() const;
         void SetDefaultListStyleName(OUString const&);
 
         void InsertListItem( SwNodeNum& rNodeNum,
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index ed6bcc309c93..88e65268cf01 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -66,8 +66,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121374_sectionHF2, "tdf121374_sectionHF2.doc")
     CPPUNIT_ASSERT( xHeaderText->getString().startsWith("virkamatka-anomus") );
 }
 
-// TODO export has the same wrong assumption that abstractNum = SwNumRule
-DECLARE_SW_EXPORT_TEST(testTdf95848, "tdf95848.docx", nullptr, Test)
+DECLARE_OOXMLEXPORT_TEST(testTdf95848, "tdf95848.docx")
 {
     OUString listId;
     OUString listStyle;
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index b6eca7f2da22..ef681cf01e5a 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -346,6 +346,10 @@ public:
     /// Definition of a numbering instance.
     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*/)
+    { assert(false); } // TODO implement for WW8/RTF
+
     /// Start of the abstract numbering definition instance.
     virtual void StartAbstractNumbering( sal_uInt16 /*nId*/ ) {}
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index debba8ae9ae1..deaf3fd59917 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6558,6 +6558,18 @@ void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &
     m_pSerializer->endElementNS( XML_w, XML_num );
 }
 
+void DocxAttributeOutput::OverrideNumberingDefinition(
+        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
+
+    m_pSerializer->endElementNS( XML_w, XML_num );
+}
+
 void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
 {
     const SwNumRule* pRule = (*m_rExport.m_pUsedNumTable)[nId - 1];
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 899c99f45a04..d40a6c317342 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -323,6 +323,9 @@ public:
     /// Definition of a numbering instance.
     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;
+
     /// 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 4b8938dd0e5d..8d9321b71798 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -70,6 +70,31 @@ sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8
     return nNumId;
 }
 
+// Ideally we want to map SwList to w:abstractNum and SwNumRule to w:num
+// The current approach is to keep exporting every SwNumRule to
+// 1 w:abstractNum and 1 w:num, and then add extra w:num via this function
+// that reference an existing w:abstractNum and may override its formatting;
+// of course this will end up exporting some w:num that aren't actually used.
+sal_uInt16 MSWordExportBase::OverrideNumRule(
+        SwNumRule const& rExistingRule,
+        SwNumRule const& rAbstractRule)
+{
+    assert(&rExistingRule != &rAbstractRule);
+    auto const numdef = GetNumberingId(rExistingRule);
+    auto const absnumdef = GetNumberingId(rAbstractRule);
+    auto const mapping = std::make_pair(numdef, absnumdef);
+
+    auto it = m_OverridingNumsR.find(mapping);
+    if (it == m_OverridingNumsR.end())
+    {
+        it = m_OverridingNumsR.insert(std::make_pair(mapping, m_pUsedNumTable->size())).first;
+        m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), mapping));
+        m_pUsedNumTable->push_back(nullptr); // dummy, it's unique_ptr...
+        ++m_nUniqueList; // counter for DuplicateNumRule...
+    }
+    return it->second;
+}
+
 sal_uInt16 MSWordExportBase::GetNumberingId( const SwNumRule& rNumRule )
 {
     if ( !m_pUsedNumTable )
@@ -179,9 +204,17 @@ void MSWordExportBase::NumberingDefinitions()
     // Write static data of SwNumRule - LSTF
     for ( sal_uInt16 n = 0; n < nCount; ++n )
     {
-        const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
-
-        AttrOutput().NumberingDefinition( n + 1, rRule );
+        const SwNumRule *const pRule = (*m_pUsedNumTable)[ n ];
+        if (pRule)
+        {
+            AttrOutput().NumberingDefinition(n + 1, *pRule);
+        }
+        else
+        {
+            auto it = m_OverridingNums.find(n);
+            assert(it != m_OverridingNums.end());
+            AttrOutput().OverrideNumberingDefinition(n + 1, it->second.second + 1);
+        }
     }
 }
 
@@ -357,6 +390,11 @@ void MSWordExportBase::AbstractNumberingDefinitions()
 
     for( n = 0; n < nCount; ++n )
     {
+        if (nullptr == (*m_pUsedNumTable)[ n ])
+        {
+            continue;
+        }
+
         AttrOutput().StartAbstractNumbering( n + 1 );
 
         const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 4d9e637f442d..c35163c067b8 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -460,6 +460,10 @@ public:
     const SfxItemSet* m_pISet;    // for double attributes
     WW8_WrPct*  m_pPiece;         // Pointer to Piece-Table
     std::unique_ptr<SwNumRuleTable> m_pUsedNumTable;  // all used NumRules
+    /// overriding numdef index -> (existing numdef index, abstractnumdef index)
+    std::map<size_t, std::pair<size_t, size_t>> m_OverridingNums;
+    /// same in reverse
+    std::map<std::pair<size_t, size_t>, size_t> m_OverridingNumsR;
     const SwTextNode *m_pTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft
     std::map< sal_uInt16, sal_uInt16 > m_aRuleDuplicates; //map to Duplicated numrules
     std::stack< sal_Int32 > m_aCurrentCharPropStarts; ///< To remember the position in a run.
@@ -650,6 +654,11 @@ public:
     /// which duplicates words behaviour in this respect.
     sal_uInt16 DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal );
 
+    /// Create a overriding numbering definition (if it does not yet exist)
+    /// @return index of the overriding numbering definition
+    sal_uInt16 OverrideNumRule(SwNumRule const& rExistingRule,
+                               SwNumRule const& rAbstractRule);
+
     /// Access to the attribute output class.
     virtual AttributeOutputBase& AttrOutput() const = 0;
 
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index d3cc0bedfff4..6aa988a4caa1 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -94,6 +94,8 @@
 #include <IDocumentSettingAccess.hxx>
 #include <IDocumentFieldsAccess.hxx>
 #include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentListsAccess.hxx>
+#include <list.hxx>
 #include <docary.hxx>
 #include <pam.hxx>
 #include <paratr.hxx>
@@ -3555,6 +3557,28 @@ void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
                             if ( USHRT_MAX != nNumId )
                                 ++nNumId;
                         }
+                        else if (GetExport().GetExportFormat() == MSWordExportBase::DOCX) // FIXME
+                        {
+                            // tdf#95848 find the abstract list definition
+                            OUString const listId(pTextNd->GetListId());
+                            if (!listId.isEmpty()
+                                && listId != pRule->GetDefaultListId())
+                            {
+                                SwList const*const pList(
+                                    GetExport().m_pDoc->getIDocumentListsAccess().getListByName(listId));
+                                if (pList)
+                                {
+                                    SwNumRule const*const pAbstractRule(
+                                        GetExport().m_pDoc->FindNumRulePtr(
+                                            pList->GetDefaultListStyleName()));
+                                    assert(pAbstractRule);
+                                    nNumId = GetExport().OverrideNumRule(
+                                            *pRule, *pAbstractRule);
+                                    assert(nNumId != USHRT_MAX);
+                                    ++nNumId;
+                                }
+                            }
+                        }
                     }
                     else
                     {
commit 276156a882fb5bd5a60411f636ce76f6e46f7bc7
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 3 18:37:34 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 5 10:18:04 2019 +0200

    sw: rename one MSWordExportBase::GetId() overload
    
    Change-Id: I9d87b5e987dc60431d8de5f5dde0cf7cc436bf97
    Reviewed-on: https://gerrit.libreoffice.org/78606
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c9705c740717..80c677fdf7ce 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -2960,7 +2960,7 @@ void RtfAttributeOutput::ParaNumRule_Impl(const SwTextNode* pTextNd, sal_Int32 n
         else
             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
-        m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetId(*pRule)) + 1);
+        m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetNumberingId(*pRule)) + 1);
         m_aStyles.append(' ');
     }
     FormatLRSpace(aLR);
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index d76d52cb7608..f237d3e2a6cd 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -209,7 +209,7 @@ void RtfExport::BuildNumbering()
 
     SwNumRule* pOutlineRule = m_pDoc->GetOutlineNumRule();
     if (IsExportNumRule(*pOutlineRule))
-        GetId(*pOutlineRule);
+        GetNumberingId(*pOutlineRule);
 
     for (auto n = rListTable.size(); n;)
     {
@@ -218,7 +218,7 @@ void RtfExport::BuildNumbering()
             continue;
 
         if (IsExportNumRule(*pRule))
-            GetId(*pRule);
+            GetNumberingId(*pRule);
     }
 }
 
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 508ea7d0aad6..4b8938dd0e5d 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -62,15 +62,15 @@ sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8
     aNumFormat.SetStart( nVal );
     pMyNumRule->Set( nLevel, aNumFormat );
 
-    nNumId = GetId( *pMyNumRule );
+    nNumId = GetNumberingId( *pMyNumRule );
 
     // Map the old list to our new list
-    m_aRuleDuplicates[GetId( *pRule )] = nNumId;
+    m_aRuleDuplicates[GetNumberingId( *pRule )] = nNumId;
 
     return nNumId;
 }
 
-sal_uInt16 MSWordExportBase::GetId( const SwNumRule& rNumRule )
+sal_uInt16 MSWordExportBase::GetNumberingId( const SwNumRule& rNumRule )
 {
     if ( !m_pUsedNumTable )
     {
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 883f9b5eeba2..4d9e637f442d 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -599,7 +599,7 @@ public:
     void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars = false );
 
     /// Return the numeric id of the numbering rule
-    sal_uInt16 GetId( const SwNumRule& rNumRule );
+    sal_uInt16 GetNumberingId( const SwNumRule& rNumRule );
 
     /// Return the numeric id of the style.
     sal_uInt16 GetId( const SwTextFormatColl& rColl ) const;
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 0e2ddb3ba90a..d3cc0bedfff4 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -720,7 +720,7 @@ void WW8AttributeOutput::OutlineNumbering(sal_uInt8 nLvl)
     m_rWW8Export.pO->push_back( nLvl );
     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::sprmPIlfo );
     SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
-            1 + m_rWW8Export.GetId( *m_rWW8Export.m_pDoc->GetOutlineNumRule() ) );
+        1 + m_rWW8Export.GetNumberingId(*m_rWW8Export.m_pDoc->GetOutlineNumRule()) );
 }
 
 // #i77805#
@@ -3526,7 +3526,8 @@ void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
     {
         const SwNumRule* pRule = GetExport().m_pDoc->FindNumRulePtr(
                                         rNumRule.GetValue() );
-        if ( pRule && USHRT_MAX != ( nNumId = GetExport().GetId( *pRule ) ) )
+        nNumId = pRule ? GetExport().GetNumberingId(*pRule) : USHRT_MAX;
+        if (USHRT_MAX != nNumId)
         {
             ++nNumId;
             if ( GetExport().m_pOutFormatNode )


More information about the Libreoffice-commits mailing list