[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