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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Jan 23 12:35:57 UTC 2019


 sw/qa/extras/ooxmlexport/data/tdf115094v3.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx       |   15 +++
 sw/qa/extras/ooxmlexport/ooxmlexport3.cxx      |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx      |    6 -
 sw/qa/extras/ooxmlexport/ooxmlexport6.cxx      |    2 
 sw/source/filter/ww8/docxattributeoutput.cxx   |   98 +++++++++++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.hxx   |    3 
 7 files changed, 119 insertions(+), 7 deletions(-)

New commits:
commit 02ba8155edd409ab249e04d317181a2ef8045191
Author:     Patrick Jaap <patrick.jaap at tu-dresden.de>
AuthorDate: Fri Dec 14 12:17:18 2018 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jan 23 13:35:33 2019 +0100

    tdf#115094 part III: DOCX export: export floating tables directly
    
    If a floating table was imported from docx, it will be placed in a frame.
    A grabBag attribute remembers the original positioning values.
    
    Restore this state when exporting to docx again and do not export the
    surrounding frame.
    
    This has to be done at the start of a paragraph, so remember the exported
    table in a std::set and skip it later in frame export.
    
    Change-Id: Ib62d4b228b306e5d1c4ce61fbbd4b6c3e1206603
    Reviewed-on: https://gerrit.libreoffice.org/65982
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf115094v3.docx b/sw/qa/extras/ooxmlexport/data/tdf115094v3.docx
new file mode 100644
index 000000000000..6c7535f7b7bf
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf115094v3.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 49a6706a9f3d..8c548ec15480 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -248,9 +248,9 @@ DECLARE_OOXMLEXPORT_TEST(testShapeInFloattable, "shape-in-floattable.docx")
     {
         // No nested drawingML w:txbxContent.
         assertXPath(pXmlDoc, "//mc:Choice//w:txbxContent//w:txbxContent", 0);
-        // Instead, make sure we have a separate shape and group shape:
-        assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wps']", 1);
+        // Instead, make sure we have a separate shape and a table
         assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wpg']", 1);
+        assertXPath(pXmlDoc, "/w:document/w:body/w:tbl", 1);
     }
 }
 
@@ -936,6 +936,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf106953, "tdf106953.docx")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), comphelper::SequenceAsHashMap(xRules->getByIndex(0))["FirstLineIndent"].get<sal_Int32>());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf115094v3, "tdf115094v3.docx")
+{
+    // floating table is now exported directly without surrounding frame
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+        return;
+
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpX", "1996");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpY", "1064");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index 2a494a46e10d..494a6791e85e 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
@@ -997,7 +997,7 @@ DECLARE_OOXMLEXPORT_TEST(testFileOpenInputOutputError,"floatingtbl_with_formula.
       assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:pStyle", "val", "Normal");
 
     // let's also assert that the formula was exported properly
-    assertXPathContent(pXmlDoc, "//wps:txbx/w:txbxContent/w:tbl/w:tr/w:tc[2]/w:p/m:oMath/m:sSubSup/m:e/m:r/m:t", u"\u03C3");
+    assertXPathContent(pXmlDoc, "//w:tbl/w:tr/w:tc[2]/w:p/m:oMath/m:sSubSup/m:e/m:r/m:t", u"\u03C3");
 }
 
 #endif
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index 8a98934dd484..64b9adc07ff9 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -513,9 +513,9 @@ DECLARE_OOXMLEXPORT_TEST(testfdo79540, "fdo79540.docx")
     if (!pXmlDoc)
         return;
 
-    // Ensure that two separate w:drawing tags are written after the code changes.
-    assertXPath ( pXmlDoc, "/w:document/w:body/w:p/w:r[2]/mc:AlternateContent/mc:Choice/w:drawing",1);
-    assertXPath ( pXmlDoc, "/w:document/w:body/w:p/w:r[3]/mc:AlternateContent/mc:Choice/w:drawing",1);
+    // Ensure that two separate w:drawing tags are written and they are not nested.
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing", 1);
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing", 1);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFDO79062, "fdo79062.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index 7547d5a4f1c4..94121b7e22b4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -448,7 +448,7 @@ DECLARE_OOXMLEXPORT_TEST(testTableFloatingMargins, "table-floating-margins.docx"
     xmlDocPtr pXmlDoc = parseExport();
     if (!pXmlDoc)
         return;
-    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:textbox/w:txbxContent/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:spacing", "after", "0");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:spacing", "after", "0");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo69636, "fdo69636.docx")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 2f7dd7a5aa49..b1b915e1c447 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -316,8 +316,96 @@ static bool lcl_isOnelinerSdt(const OUString& rName)
     return rName == "Title" || rName == "Subtitle" || rName == "Company";
 }
 
+// write a floating table directly to docx without the surrounding frame
+void DocxAttributeOutput::WriteFloatingTable(ww8::Frame const* pParentFrame)
+{
+    sax_fastparser::FSHelperPtr pFS = GetSerializer();
+    const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
+    m_aFloatingTablesOfParagraph.insert(&rFrameFormat);
+    const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
+
+    sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
+    sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
+
+    //Save data here and restore when out of scope
+    ExportDataSaveRestore aDataGuard(GetExport(), nStt, nEnd, pParentFrame);
+
+    // unset parent frame, otherwise exporter thinks we are still in a frame
+    m_rExport.m_pParentFrame = nullptr;
+
+    GetExport().WriteText();
+}
+
+static void checkAndWriteFloatingTables(DocxAttributeOutput& rDocxAttributeOutput)
+{
+    const auto& rExport = rDocxAttributeOutput.GetExport();
+    // iterate though all SpzFrameFormats and check whether they are anchored to the current text node
+    for( sal_uInt16 nCnt = rExport.m_pDoc->GetSpzFrameFormats()->size(); nCnt; )
+    {
+        const SwFrameFormat* pFrameFormat = (*rExport.m_pDoc->GetSpzFrameFormats())[ --nCnt ];
+        const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
+        const SwPosition* pPosition = rAnchor.GetContentAnchor();
+
+        if (!pPosition || ! rExport.m_pCurPam->GetNode().GetTextNode())
+            continue;
+
+        if (pPosition->nNode != rExport.m_pCurPam->GetNode().GetTextNode()->GetIndex())
+            continue;
+
+        const SwNodeIndex* pStartNode = pFrameFormat->GetContent().GetContentIdx();
+        if (!pStartNode)
+            continue;
+
+        SwNodeIndex aStartNode = *pStartNode;
+
+        // go to the next node (actual content)
+        aStartNode++;
+
+        // this has to be a table
+        if (!aStartNode.GetNode().IsTableNode())
+            continue;
+
+        // go to the end of the table
+        sal_uLong aEndIndex = aStartNode.GetNode().EndOfSectionIndex();
+        // go one deeper
+        aEndIndex++;
+        // this has to be the end of the content
+        if (aEndIndex != pFrameFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionIndex())
+            continue;
+
+        // check for a grabBag and "TablePosition" attribute -> then we can export the table directly
+        SwTableNode* pTableNode = aStartNode.GetNode().GetTableNode();
+        SwTable& rTable = pTableNode->GetTable();
+        SwFrameFormat* pTableFormat = rTable.GetFrameFormat();
+        const SfxGrabBagItem* pTableGrabBag = pTableFormat->GetAttrSet().GetItem<SfxGrabBagItem>(RES_FRMATR_GRABBAG);
+        std::map<OUString, css::uno::Any> aTableGrabBag = pTableGrabBag->GetGrabBag();
+        // no grabbag?
+        if (aTableGrabBag.find("TablePosition") == aTableGrabBag.end())
+            continue;
+
+        // overwrite the table size from the surrounding frame format
+        // TODO remove this de-const HACK
+        const SwFormatFrameSize& aFramesize = pFrameFormat->GetFrameSize();
+        SwFormatFrameSize* pFormatFrameSize = const_cast<SwFormatFrameSize*>(&pTableFormat->GetFrameSize());
+        if(pFormatFrameSize)
+        {
+            *pFormatFrameSize = aFramesize;
+        }
+
+        ww8::Frame aFrame(*pFrameFormat,*pPosition);
+        rDocxAttributeOutput.WriteFloatingTable(&aFrame);
+    }
+}
+
 void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
 {
+    // look ahead for floating tables that where put into a frame during import
+    // flaoting tables in shapes are not supported: exclude this case
+    if (!pTextNodeInfo && !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen())
+    {
+        checkAndWriteFloatingTables(*this);
+    }
+
     if ( m_nColBreakStatus == COLBRK_POSTPONE )
         m_nColBreakStatus = COLBRK_WRITE;
 
@@ -615,6 +703,12 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
         m_pPostponedCustomShape.reset(nullptr);
 
         m_aFramesOfParagraph.clear();
+
+        if (!pTextNodeInfoInner)
+        {
+            // Ending a non-table paragraph, clear floating tables before paragraph.
+            m_aFloatingTablesOfParagraph.clear();
+        }
     }
 
     --m_nTextFrameLevel;
@@ -5512,6 +5606,10 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const ww8::Frame &rFrame, const P
                 if (DocxSdrExport::isTextBox(rFrame.GetFrameFormat()))
                     break;
 
+                // If this is a TextBox containing a table which we already exported directly, ignore it
+                if (m_aFloatingTablesOfParagraph.find(&rFrame.GetFrameFormat()) != m_aFloatingTablesOfParagraph.end())
+                    break;
+
                 // The frame output is postponed to the end of the anchor paragraph
                 bool bDuplicate = false;
                 const OUString& rName = rFrame.GetFrameFormat().GetName();
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 7e852aa33bec..62e9e1822f1e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -353,6 +353,8 @@ public:
     /// End possibly opened paragraph sdt block.
     void EndParaSdtBlock();
 
+    void WriteFloatingTable(ww8::Frame const* pParentFrame);
+
 private:
     /// Initialize the structures where we are going to collect some of the paragraph properties.
     ///
@@ -825,6 +827,7 @@ private:
     bool m_bPostponedPageBreak;
 
     std::vector<ww8::Frame> m_aFramesOfParagraph;
+    std::set<const SwFrameFormat*> m_aFloatingTablesOfParagraph;
     sal_Int32 m_nTextFrameLevel;
 
     // close of hyperlink needed


More information about the Libreoffice-commits mailing list