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

Caolán McNamara caolanm at redhat.com
Mon Apr 20 09:11:40 PDT 2015


 dev/null                                     |binary
 sw/qa/extras/ooxmlexport/data/tdf90681-1.odt |binary
 sw/qa/extras/ooxmlexport/data/tdf90681-2.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx    |   13 +++
 sw/source/filter/ww8/docxattributeoutput.cxx |   92 +++++++++++++++++----------
 sw/source/filter/ww8/docxattributeoutput.hxx |    9 +-
 6 files changed, 78 insertions(+), 36 deletions(-)

New commits:
commit 4eff3e7c455e8db2c00b7ee5eb1d2296b45d2823
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Apr 20 16:48:33 2015 +0100

    Related: tdf#90681 table model can have truly empty cells
    
    this time the missing cells are on the left
    
    Change-Id: I55a5aa60c8d06b25b0c48b3f6a683694adca8e6a

diff --git a/sw/qa/extras/ooxmlexport/data/tdf90681.odt b/sw/qa/extras/ooxmlexport/data/tdf90681-1.odt
similarity index 100%
rename from sw/qa/extras/ooxmlexport/data/tdf90681.odt
rename to sw/qa/extras/ooxmlexport/data/tdf90681-1.odt
diff --git a/sw/qa/extras/ooxmlexport/data/tdf90681-2.odt b/sw/qa/extras/ooxmlexport/data/tdf90681-2.odt
new file mode 100644
index 0000000..3d9d46f
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf90681-2.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index ee1a075..49a1d66 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -228,7 +228,7 @@ DECLARE_OOXMLEXPORT_TEST(testFloatingTable, "fdo77887.docx")
 
 }
 
-DECLARE_OOXMLEXPORT_TEST(testOldComplexMerge, "tdf90681.odt")
+DECLARE_OOXMLEXPORT_TEST(testOldComplexMergeRight, "tdf90681-1.odt")
 {
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
 
@@ -241,6 +241,17 @@ DECLARE_OOXMLEXPORT_TEST(testOldComplexMerge, "tdf90681.odt")
     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[2]/w:tcPr/w:vMerge", "val", "continue");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testOldComplexMergeleft, "tdf90681-2.odt")
+{
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+
+    if (!pXmlDoc)
+       return;
+
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:vMerge", "val", "restart");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:vMerge", "val", "continue");
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTablePreferredWidth, "tablePreferredWidth.docx")
 {
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 797abe0..a88a5b2 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -237,9 +237,6 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
     // Output table/table row/table cell starts if needed
     if ( pTextNodeInfo.get() )
     {
-        sal_uInt32 nRow = pTextNodeInfo->getRow();
-        sal_uInt32 nCell = pTextNodeInfo->getCell();
-
         // New cell/row?
         if ( m_tableReference->m_nTableDepth > 0 && !m_tableReference->m_bTableCellOpen )
         {
@@ -247,9 +244,15 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
             if ( pDeepInner->getCell() == 0 )
                 StartTableRow( pDeepInner );
 
-            StartTableCell( pDeepInner );
+            const sal_uInt32 nCell = pDeepInner->getCell();
+            const sal_uInt32 nRow = pDeepInner->getRow();
+
+            SyncNodelessCells(pDeepInner, nCell, nRow);
+            StartTableCell(pDeepInner, nCell, nRow);
         }
 
+        sal_uInt32 nRow = pTextNodeInfo->getRow();
+        sal_uInt32 nCell = pTextNodeInfo->getCell();
         if ( nRow == 0 && nCell == 0 )
         {
             // Do we have to start the table?
@@ -266,7 +269,8 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
 
                     StartTable( pInner );
                     StartTableRow( pInner );
-                    StartTableCell( pInner );
+
+                    StartTableCell(pInner, 0, 0);
                 }
 
                 m_tableReference->m_nTableDepth = nCurrentDepth;
@@ -687,12 +691,34 @@ void DocxAttributeOutput::EndSdtBlock()
     m_pSerializer->endElementNS( XML_w, XML_sdt );
 }
 
+void DocxAttributeOutput::SyncNodelessCells(ww8::WW8TableNodeInfoInner::Pointer_t pInner, sal_Int32 nCell, sal_uInt32 nRow)
+{
+    sal_Int32 nOpenCell = lastOpenCell.back();
+    if (nOpenCell != -1 && nOpenCell != nCell)
+        EndTableCell(pInner, nOpenCell, nRow);
+
+    sal_Int32 nClosedCell = lastClosedCell.back();
+    for (sal_Int32 i = nClosedCell+1; i < nCell; ++i)
+    {
+        if (i >= 62)    //words limit
+            break;
+
+        if (i == 0)
+            StartTableRow(pInner);
+
+        StartTableCell(pInner, i, nRow);
+        m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
+        EndTableCell(pInner, i, nRow);
+    }
+}
+
 void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
 {
     if ( pInner.get() )
     {
         // Where are we in the table
-        sal_uInt32 nRow = pInner->getRow( );
+        sal_uInt32 nRow = pInner->getRow();
+        sal_Int32 nCell = pInner->getCell();
 
         InitTableHelper( pInner );
 
@@ -704,28 +730,32 @@ void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointe
         // so simply if there are more columns, don't close the last one msoffice will handle
         // and merge the contents of the remaining ones into it (since we don't close the cell
         // here, following ones will not be opened)
-        bool limitWorkaround = ( pInner->getCell() >= 62 && !pInner->isEndOfLine());
+        const bool limitWorkaround = (nCell >= 62 && !pInner->isEndOfLine());
         const bool bEndCell = pInner->isEndOfCell() && !limitWorkaround;
-        const bool bStartCell = bEndCell && !m_nCellsOpen;
+        const bool bEndRow = pInner->isEndOfLine();
 
         if ( bEndCell )
         {
-            if ( bForceEmptyParagraph )
+            SyncNodelessCells(pInner, nCell, nRow);
+
+            sal_Int32 nClosedCell = lastClosedCell.back();
+            if (nCell == nClosedCell)
             {
-                if (bStartCell)
-                {
-                    const sal_uInt32 nCol = pInner->getCell();
-                    StartTableCell(pInner, nCol+1, nRow);
-                }
+                //Start missing trailing cell
+                ++nCell;
+                StartTableCell(pInner, nCell, nRow);
+            }
 
+            if (bForceEmptyParagraph)
+            {
                 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
             }
 
-            EndTableCell();
+            EndTableCell(pInner, nCell, nRow);
         }
 
         // This is a line end
-        if ( pInner->isEndOfLine() )
+        if (bEndRow)
             EndTableRow();
 
         // This is the end of the table
@@ -2839,12 +2869,11 @@ void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Point
     // Horizontal spans
     const SwWriteTableRows& aRows = m_xTableWrt->GetRows( );
     SwWriteTableRow *pRow = aRows[ nRow ];
-    const SwWriteTableCells *tableCells =  &pRow->GetCells();
-    if (nCell < tableCells->size() )
+    const SwWriteTableCells& tableCells =  pRow->GetCells();
+    if (nCell < tableCells.size() )
     {
-        const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
-
-        sal_uInt16 nColSpan = pCell->GetColSpan();
+        const SwWriteTableCell& rCell = tableCells[nCell];
+        const sal_uInt16 nColSpan = rCell.GetColSpan();
         if ( nColSpan > 1 )
             m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
                     FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
@@ -2928,6 +2957,8 @@ void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTab
     m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
 
     tableFirstCells.push_back(pTableTextNodeInfoInner);
+    lastOpenCell.push_back(-1);
+    lastClosedCell.push_back(-1);
 
     InitTableHelper( pTableTextNodeInfoInner );
     TableDefinition( pTableTextNodeInfoInner );
@@ -2940,6 +2971,8 @@ void DocxAttributeOutput::EndTable()
     if ( m_tableReference->m_nTableDepth > 0 )
         --m_tableReference->m_nTableDepth;
 
+    lastClosedCell.pop_back();
+    lastOpenCell.pop_back();
     tableFirstCells.pop_back();
 
     // We closed the table; if it is a nested table, the cell that contains it
@@ -2992,13 +3025,16 @@ void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t p
 void DocxAttributeOutput::EndTableRow( )
 {
     m_pSerializer->endElementNS( XML_w, XML_tr );
+    lastOpenCell.back() = -1;
+    lastClosedCell.back() = -1;
 }
 
 void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32 nCell, sal_uInt32 nRow )
 {
+    lastOpenCell.back() = nCell;
+
     InitTableHelper( pTableTextNodeInfoInner );
 
-    ++m_nCellsOpen;
     m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
 
     // Write the cell properties here
@@ -3007,20 +3043,15 @@ void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t
     m_tableReference->m_bTableCellOpen = true;
 }
 
-void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+void DocxAttributeOutput::EndTableCell(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/, sal_uInt32 nCell, sal_uInt32 /*nRow*/)
 {
-    const sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
-    const sal_uInt32 nRow = pTableTextNodeInfoInner->getRow();
-    StartTableCell(pTableTextNodeInfoInner, nCell, nRow);
-}
+    lastClosedCell.back() = nCell;
+    lastOpenCell.back() = -1;
 
-void DocxAttributeOutput::EndTableCell( )
-{
     if (m_tableReference->m_bTableCellParaSdtOpen)
         EndParaSdtBlock();
 
     m_pSerializer->endElementNS( XML_w, XML_tc );
-    --m_nCellsOpen;
 
     m_bBtLr = false;
     m_tableReference->m_bTableCellOpen = false;
@@ -8311,7 +8342,6 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
     , m_nRunSdtPrToken(0)
     , m_nStateOfFlyFrame( FLY_NOT_PROCESSED )
     , m_bParagraphSdtHasId(false)
-    , m_nCellsOpen(0)
 {
 }
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 66964a5..3acde5b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -421,12 +421,12 @@ private:
     void InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
     void StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
     void StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
-    void StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
     void StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32 nCell, sal_uInt32 nRow );
     void TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32 nCell, sal_uInt32 nRow );
-    void EndTableCell( );
+    void EndTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32 nCell, sal_uInt32 nRow );
     void EndTableRow( );
     void EndTable();
+    void SyncNodelessCells(ww8::WW8TableNodeInfoInner::Pointer_t pInner, sal_Int32 nCell, sal_uInt32 nRow);
     void PopulateFrameProperties(const SwFrmFmt* pFrmFmt, const Size& rSize);
     bool TextBoxIsFramePr(const SwFrmFmt& rFrmFmt);
     /// End cell, row, and even the entire table if necessary.
@@ -883,6 +883,9 @@ private:
 
     // Remember first cell (used for default borders/margins) of each table
     std::vector<ww8::WW8TableNodeInfoInner::Pointer_t> tableFirstCells;
+    // Remember last open and closed cells on each level
+    std::vector<sal_Int32> lastOpenCell;
+    std::vector<sal_Int32> lastClosedCell;
 
     boost::optional<css::drawing::FillStyle> m_oFillStyle;
     /// If FormatBox() already handled fill style / gradient.
@@ -922,8 +925,6 @@ private:
     OUString m_aRunSdtPrAlias;
     /// Currently paragraph SDT has a <w:id> child element.
     bool m_bParagraphSdtHasId;
-    /// Checking for balanced table cells start/ends
-    sal_Int32 m_nCellsOpen;
 
     std::map<SvxBoxItemLine, css::table::BorderLine2> m_aTableStyleConf;
 


More information about the Libreoffice-commits mailing list