sw/qa/extras/ooxmlexport/ooxmlexport11.cxx    |   13 +++
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx     |    2 
 sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx |    8 +-
 sw/source/filter/ww8/wrtw8nds.cxx             |   95 ++++++++++++++++++++++++++
 sw/source/filter/ww8/wrtww8.hxx               |    1 
 5 files changed, 114 insertions(+), 5 deletions(-)

New commits:
commit 1575b46276a44fe0566fec8910188a781589dd75
Author:     Serge Krot <serge.k...@cib.de>
AuthorDate: Thu Nov 22 10:05:47 2018 +0100
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Wed Dec 5 16:56:43 2018 +0100

    tdf#121561: sw: DOCX: add std/stdPr/stdContent around TOC
    
    During export into DOCX from ODT we need to do it
    because in this case the TOC title will be recognized
    inside MS Word as part of the TOC.
    
    Later we could add support of these keywords in LO import
    in order to detect TOC title from DOCX input.
    
    Added unit test for export.
    
    Change-Id: I7135e91dc04d4c0501e6074a046fc473e041f014
    Reviewed-on: https://gerrit.libreoffice.org/63786
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index d7fd52d87b6d..3b005e198b87 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -131,6 +131,19 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121456_tabsOffset, 
"tdf121456_tabsOffset.odt")
     }
 }
 
+// tdf#121561: make sure w:sdt/w:sdtContent around TOC is written during 
ODT->DOCX conversion
+DECLARE_OOXMLEXPORT_TEST(testTdf121561_tocTitle, "tdf121456_tabsOffset.odt")
+{
+    xmlDocPtr pXmlDoc = parseExport();
+    if (!pXmlDoc)
+        return;
+
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p/w:r/w:t", "Inhaltsverzeichnis");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p/w:r/w:instrText", " TOC \\f \\o 
\"1-9\" \\h");
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtPr/w:docPartObj/w:docPartGallery", "val", "Table 
of Contents");
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtPr/w:docPartObj/w:docPartUnique", 1);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf106174_rtlParaAlign, 
"tdf106174_rtlParaAlign.docx")
 {
     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), 
getProperty<sal_Int16>(getParagraph(1), "ParaAdjust"));
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index be20dd24b246..bd662172ae0c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -693,7 +693,7 @@ DECLARE_OOXMLEXPORT_TEST(testFdo77129, "fdo77129.docx")
        return;
 
     // Data was lost from this paragraph.
-    assertXPathContent(pXmlDoc, "/w:document/w:body/w:p[5]/w:r[1]/w:t", 
"Abstract");
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:p[4]/w:r[1]/w:t", 
"Abstract");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testfdo79969_xlsm, "fdo79969_xlsm.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 277f8b71ce22..84b38fc0a26a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -143,7 +143,7 @@ DECLARE_OOXMLEXPORT_TEST(testFieldFlagO,"TOC_field_f.docx")
 
     // FIXME "p[2]" will have to be "p[1]", once the TOC import code is fixed
     // not to insert an empty paragraph before TOC.
-    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:p[2]/w:r[2]/w:instrText", " TOC \\z \\f \\o \"1-3\" \\u 
\\h");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p[1]/w:r[2]/w:instrText", " TOC \\z 
\\f \\o \"1-3\" \\u \\h");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTOCFlag_f, "toc_doc.docx")
@@ -160,7 +160,7 @@ DECLARE_OOXMLEXPORT_TEST(testTOCFlag_f, "toc_doc.docx")
 
     // FIXME "p[2]" will have to be "p[1]", once the TOC import code is fixed
     // not to insert an empty paragraph before TOC.
-    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:p[2]/w:r[2]/w:instrText", " TOC \\z \\o \"1-3\" \\u \\h");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p[1]/w:r[2]/w:instrText", " TOC \\z 
\\o \"1-3\" \\u \\h");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testPreserveZfield,"preserve_Z_field_TOC.docx")
@@ -190,7 +190,7 @@ DECLARE_OOXMLEXPORT_TEST(testFieldFlagB,"TOC_field_b.docx")
 
     // FIXME "p[2]" will have to be "p[1]", once the TOC import code is fixed
     // not to insert an empty paragraph before TOC.
-    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:p[2]/w:r[2]/w:instrText", " TOC \\b \"bookmark111\" \\o 
\"1-9\" \\h");
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p[1]/w:r[2]/w:instrText", " TOC \\b 
\"bookmark111\" \\o \"1-9\" \\h");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testPreserveXfieldTOC, "PreserveXfieldTOC.docx")
@@ -448,7 +448,7 @@ DECLARE_OOXMLEXPORT_TEST(testFDO78654 , "fdo78654.docx")
         return;
     // In case of two "Hyperlink" tags in one paragraph and one of them
     // contains "PAGEREF" field then field end tag was missing from hyperlink.
-    assertXPath ( pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtContent/w:p[2]/w:hyperlink[3]/w:r[5]/w:fldChar", 
"fldCharType", "end" );
+    assertXPath ( pXmlDoc, 
"/w:document/w:body/w:p[2]/w:hyperlink[3]/w:r[5]/w:fldChar", "fldCharType", 
"end" );
 }
 
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index bc64e2a4362c..6f87279690f0 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -92,6 +92,7 @@
 #include <oox/export/vmlexport.hxx>
 #include <sfx2/docfile.hxx>
 #include <sal/log.hxx>
+#include <comphelper/propertysequence.hxx>
 
 #include "sprmids.hxx"
 
@@ -3055,7 +3056,101 @@ void MSWordExportBase::OutputSectionNode( const 
SwSectionNode& rSectionNode )
         }
     }
     if ( TOX_CONTENT_SECTION == rSection.GetType() )
+    {
         m_bStartTOX = true;
+        UpdateTocSectionNodeProperties(rSectionNode);
+    }
+}
+
+// tdf#121561: During export of the ODT file with TOC inside into DOCX format,
+// the TOC title is being exported as regular paragraph. We should surround it
+// with <w:sdt><w:sdtPr><w:sdtContent> to make it (TOC title) recognizable
+// by MS Word as part of the TOC.
+void MSWordExportBase::UpdateTocSectionNodeProperties(const SwSectionNode& 
rSectionNode)
+{
+    // check section type
+    {
+        const SwSection& rSection = rSectionNode.GetSection();
+        if (TOX_CONTENT_SECTION != rSection.GetType())
+            return;
+
+        const SwTOXBase* pTOX = rSection.GetTOXBase();
+        if (pTOX)
+        {
+            TOXTypes type = pTOX->GetType();
+            if (type != TOXTypes::TOX_CONTENT)
+                return;
+        }
+    }
+
+    // get section node, skip toc-header node
+    const SwSectionNode* pSectNd = &rSectionNode;
+    {
+        SwNodeIndex aIdxNext( *pSectNd, 1 );
+        const SwNode& rNdNext = aIdxNext.GetNode();
+
+        if (rNdNext.IsSectionNode())
+        {
+            const SwSectionNode* pSectNdNext = static_cast<const 
SwSectionNode*>(&rNdNext);
+            if (TOX_HEADER_SECTION == pSectNdNext->GetSection().GetType() &&
+                pSectNdNext->StartOfSectionNode()->IsSectionNode())
+            {
+                pSectNd = pSectNdNext;
+            }
+        }
+    }
+
+    // get node of the first paragraph inside TOC
+    SwNodeIndex aIdxNext( *pSectNd, 1 );
+    const SwNode& rNdTocPara = aIdxNext.GetNode();
+    const SwContentNode* pNode = rNdTocPara.GetContentNode();
+    if (!pNode)
+        return;
+
+    // put required flags into grab bag of the first node in TOC
+    {
+        uno::Sequence<beans::PropertyValue> 
aDocPropertyValues(comphelper::InitPropertySequence(
+        {
+            {"ooxml:CT_SdtDocPart_docPartGallery", 
uno::makeAny(OUString("Table of Contents"))},
+            {"ooxml:CT_SdtDocPart_docPartUnique",  
uno::makeAny(OUString("true"))},
+        }));
+
+        uno::Sequence<beans::PropertyValue> 
aSdtPrPropertyValues(comphelper::InitPropertySequence(
+        {
+            {"ooxml:CT_SdtPr_docPartObj", uno::makeAny(aDocPropertyValues)},
+        }));
+
+        SfxGrabBagItem aGrabBag(RES_PARATR_GRABBAG);
+        aGrabBag.GetGrabBag()["SdtPr"] <<= aSdtPrPropertyValues;
+
+        // create temp attr set
+        SwAttrSet aSet(pNode->GetSwAttrSet());
+        aSet.Put(aGrabBag);
+
+        // set new attr to node
+        const_cast<SwContentNode*>(pNode)->SetAttr(aSet);
+    }
+
+    // set flag for the next node after TOC
+    // in order to indicate that std area has been finished
+    // see, DomainMapper::lcl_startParagraphGroup() for the same functionality 
during load
+    {
+        SwNodeIndex aEndTocNext( *rSectionNode.EndOfSectionNode(), 1 );
+        const SwNode& rEndTocNextNode = aEndTocNext.GetNode();
+        const SwContentNode* pNodeAfterToc = rEndTocNextNode.GetContentNode();
+        if (pNodeAfterToc)
+        {
+            SfxGrabBagItem aGrabBag(RES_PARATR_GRABBAG);
+            aGrabBag.GetGrabBag()["ParaSdtEndBefore"] <<= true;
+
+            // create temp attr set
+            SwAttrSet aSet(pNodeAfterToc->GetSwAttrSet());
+            aSet.Put(aGrabBag);
+
+            // set new attr to node
+            const_cast<SwContentNode*>(pNodeAfterToc)->SetAttr(aSet);
+        }
+    }
 }
 
 void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const 
SwSectionFormat* pFormat, sal_uLong nLnNum )
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 90e1a815a140..9ad0d0bfb1c5 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -843,6 +843,7 @@ protected:
 
     /// Output SwSectionNode
     void OutputSectionNode( const SwSectionNode& );
+    static void UpdateTocSectionNodeProperties(const SwSectionNode& 
rSectionNode);
 
     virtual void AppendSection( const SwPageDesc *pPageDesc, const 
SwSectionFormat* pFormat, sal_uLong nLnNum ) = 0;
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to