[Libreoffice-commits] core.git: Branch 'libreoffice-6-2' - sw/qa sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Jan 29 17:35:20 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 d8f427ae7b96fcdc74f45517843c28617a709f8b
Author:     Patrick Jaap <patrick.jaap at tu-dresden.de>
AuthorDate: Fri Dec 14 12:17:18 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Jan 29 18:34:55 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>
    (cherry picked from commit 02ba8155edd409ab249e04d317181a2ef8045191)
    Reviewed-on: https://gerrit.libreoffice.org/67070
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

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 c5d6b88db4b2..3c84ed37e97e 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 c6cff7b56f42..2c4638bfbfef 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -315,8 +315,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;
 
@@ -611,6 +699,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;
@@ -5511,6 +5605,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 b09b0bea01ac..052dff8fb01c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -354,6 +354,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.
     ///
@@ -826,6 +828,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