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

Adam Co rattles2013 at gmail.com
Tue Nov 5 16:23:11 CET 2013


 sw/qa/extras/ooxmlexport/data/fdo69644.docx  |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx     |    9 ++
 sw/source/filter/ww8/WW8TableInfo.cxx        |   96 ++++++++++++++++++++++++++-
 sw/source/filter/ww8/WW8TableInfo.hxx        |    3 
 sw/source/filter/ww8/attributeoutputbase.hxx |    1 
 sw/source/filter/ww8/docxattributeoutput.cxx |    4 -
 sw/source/filter/ww8/wrtww8.cxx              |    6 +
 7 files changed, 114 insertions(+), 5 deletions(-)

New commits:
commit 57c54792781cc9befe3a65a97b37fa85f89da0ae
Author: Adam Co <rattles2013 at gmail.com>
Date:   Thu Oct 17 11:48:31 2013 +0200

    fdo#69644 - fix docx export of wrong number and width of columns
    
    When the DOCX exporter exported a table, it filled the table
    column definitions with the column sizes of the FIRST row only.
    This was ok for tables that have the same columns on all rows,
    but for more complex tables with different cell widths - the
    filter exported the wrong number of columns and the wrong width.
    A followup fix would fix the rounding problems there still are
    with the column widths that are exported in the table
    definition.
    
    Conflicts:
    	sw/qa/extras/ooxmlexport/ooxmlexport.cxx
    
    Change-Id: Ie95dfe60b1c1811776433e457ca04e728623e01e
    Reviewed-on: https://gerrit.libreoffice.org/6290

diff --git a/sw/qa/extras/ooxmlexport/data/fdo69644.docx b/sw/qa/extras/ooxmlexport/data/fdo69644.docx
new file mode 100644
index 0000000..1a254db
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/fdo69644.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 028189b..6aeae7b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -1534,6 +1534,15 @@ DECLARE_OOXML_TEST(testCustomXmlGrabBag, "customxml.docx")
    CPPUNIT_ASSERT(CustomXml); // Grab Bag has all the expected elements
 }
 
+DECLARE_OOXML_TEST(testFdo69644, "fdo69644.docx")
+{
+    // The problem was that the exporter exported the table definition
+    // with only 3 columns, instead of 5 columns.
+    // Check that the table grid is exported with 5 columns
+    xmlDocPtr pXmlDoc = parseExport();
+    assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblGrid/w:gridCol", 5);
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/WW8TableInfo.cxx b/sw/source/filter/ww8/WW8TableInfo.cxx
index 9a0b188..aa39f3d 100644
--- a/sw/source/filter/ww8/WW8TableInfo.cxx
+++ b/sw/source/filter/ww8/WW8TableInfo.cxx
@@ -190,10 +190,43 @@ TableBoxVectorPtr WW8TableNodeInfoInner::getTableBoxesOfRow()
     return pResult;
 }
 
-GridColsPtr WW8TableNodeInfoInner::getGridColsOfRow(AttributeOutputBase & rBase)
+GridColsPtr WW8TableNodeInfoInner::getGridColsOfRow(AttributeOutputBase & rBase, bool calculateColumnsFromAllRows)
 {
     GridColsPtr pResult(new GridCols);
-    WidthsPtr pWidths(getWidthsOfRow());
+    WidthsPtr pWidths;
+
+    // Check which columns should be checked - only the current row,
+    // or all the rows together
+    if (calculateColumnsFromAllRows)
+    {
+        // Calculate the width of all the columns based on ALL the rows.
+        // The difference is that this kind of draws vertical lines,
+        // so that if the rows look like this:
+        //
+        //  ------------------------
+        //  |                   |  |
+        //  ------------------------
+        //  |   |                  |
+        //  ------------------------
+        //  |       |              |
+        //  ------------------------
+        //
+        // then the actual column widths will be broken down like this:
+        //
+        //  ------------------------
+        //  |   |   |           |  |
+        //  ------------------------
+        //
+        // See the example at
+        // http://officeopenxml.com/WPtableGrid.php
+        // Under "Word 2007 Example"
+        pWidths = getColumnWidthsBasedOnAllRows();
+    }
+    else
+    {
+        // Calculate the width of all the columns based on the current row
+        pWidths = getWidthsOfRow();
+    }
 
     const SwFrmFmt *pFmt = getTable()->GetFrmFmt();
     OSL_ENSURE(pFmt,"Impossible");
@@ -226,6 +259,65 @@ GridColsPtr WW8TableNodeInfoInner::getGridColsOfRow(AttributeOutputBase & rBase)
     return pResult;
 }
 
+WidthsPtr WW8TableNodeInfoInner::getColumnWidthsBasedOnAllRows()
+{
+    WidthsPtr pWidths;
+
+    WW8TableCellGrid::Pointer_t pCellGrid =
+        mpParent->getParent()->getCellGridForTable(getTable(), false);
+
+    if (pCellGrid.get() == NULL)
+    {
+        const SwTable * pTable = getTable();
+        const SwTableLines& rTableLines = pTable->GetTabLines();
+        sal_uInt16 nNumOfLines = rTableLines.size();
+
+        // Go over all the rows - and for each row - calculate where
+        // there is a separator between columns
+        WidthsPtr pSeparators(new Widths);
+        for ( sal_uInt32 nLineIndex = 0; nLineIndex < nNumOfLines; nLineIndex++)
+        {
+            const SwTableLine *pCurrentLine = rTableLines[nLineIndex];
+            const SwTableBoxes & rTabBoxes = pCurrentLine->GetTabBoxes();
+            sal_uInt32 nBoxes = rTabBoxes.size();
+            if ( nBoxes > MAXTABLECELLS )
+                nBoxes = MAXTABLECELLS;
+
+            sal_uInt32 nSeparatorPosition = 0;
+            for (sal_uInt32 nBoxIndex = 0; nBoxIndex < nBoxes; nBoxIndex++)
+            {
+                const SwFrmFmt* pBoxFmt = rTabBoxes[ nBoxIndex ]->GetFrmFmt();
+                const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize();
+                nSeparatorPosition += rLSz.GetWidth();
+                pSeparators->push_back(nSeparatorPosition);
+            }
+        }
+
+        // Sort the separator positions and remove any duplicates
+        std::sort(pSeparators->begin(), pSeparators->end());
+        std::vector<sal_uInt32>::iterator it = std::unique(pSeparators->begin(), pSeparators->end());
+        pSeparators->erase(it, pSeparators->end());
+
+        // Calculate the widths based on the position of the unique & sorted
+        // column separators
+        pWidths = WidthsPtr(new Widths);
+        sal_uInt32 nPreviousWidth = 0;
+        Widths::const_iterator aItEnd2 = pSeparators->end();
+        for (Widths::const_iterator aIt2 = pSeparators->begin(); aIt2 != aItEnd2; ++aIt2)
+        {
+            sal_uInt32 nCurrentWidth = *aIt2;
+            pWidths->push_back(nCurrentWidth - nPreviousWidth);
+            nPreviousWidth = nCurrentWidth;
+        }
+    }
+    else
+    {
+        pWidths = pCellGrid->getWidthsOfRow(this);
+    }
+
+    return pWidths;
+}
+
 WidthsPtr WW8TableNodeInfoInner::getWidthsOfRow()
 {
     WidthsPtr pWidths;
diff --git a/sw/source/filter/ww8/WW8TableInfo.hxx b/sw/source/filter/ww8/WW8TableInfo.hxx
index 92fe35d..894a29b 100644
--- a/sw/source/filter/ww8/WW8TableInfo.hxx
+++ b/sw/source/filter/ww8/WW8TableInfo.hxx
@@ -104,7 +104,8 @@ public:
 
     TableBoxVectorPtr getTableBoxesOfRow();
     WidthsPtr getWidthsOfRow();
-    GridColsPtr getGridColsOfRow(AttributeOutputBase & rBase);
+    WidthsPtr getColumnWidthsBasedOnAllRows();
+    GridColsPtr getGridColsOfRow(AttributeOutputBase & rBase, bool calculateColumnsFromAllRows = false);
     RowSpansPtr getRowSpansOfRow();
 
 #ifdef DBG_UTIL
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 7ad8d3a..22de507 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -604,6 +604,7 @@ protected:
     virtual bool AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark );
 
     ww8::GridColsPtr GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+    ww8::WidthsPtr   GetColumnWidths( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
 
 public:
     AttributeOutputBase() {}
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 62afa65..755f606 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2168,8 +2168,8 @@ void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t
     // Write the table grid infos
     m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
     sal_Int32 nPrv = 0;
-    ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
-    for ( ww8::GridCols::const_iterator it = pGridCols->begin(); it != pGridCols->end(); ++it )
+    ww8::WidthsPtr pColumnWidths = GetColumnWidths( pTableTextNodeInfoInner );
+    for ( ww8::Widths::const_iterator it = pColumnWidths->begin(); it != pColumnWidths->end(); ++it )
     {
         sal_Int32 nWidth  =  sal_Int32( *it ) - nPrv;
         m_pSerializer->singleElementNS( XML_w, XML_gridCol,
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 627ed85..ec53744 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -2310,6 +2310,12 @@ ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::P
     return pTableTextNodeInfoInner->getGridColsOfRow(*this);
 }
 
+ww8::WidthsPtr AttributeOutputBase::GetColumnWidths( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+    // Get the column widths based on ALL the rows, not just the current row
+    return pTableTextNodeInfoInner->getGridColsOfRow(*this, true);
+}
+
 void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize )
 {
     sal_uInt32 nPageSize = 0;


More information about the Libreoffice-commits mailing list