summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorAdam Co <rattles2013@gmail.com>2013-10-17 11:48:31 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2013-11-05 16:22:49 +0100
commit57c54792781cc9befe3a65a97b37fa85f89da0ae (patch)
tree729e09641bb3ddccb620dd5443d5cfc707d6d897 /sw
parentf689578dc4f3a77f6a3e72bbf32adf88a2c55526 (diff)
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
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/data/fdo69644.docxbin0 -> 18215 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx9
-rw-r--r--sw/source/filter/ww8/WW8TableInfo.cxx96
-rw-r--r--sw/source/filter/ww8/WW8TableInfo.hxx3
-rw-r--r--sw/source/filter/ww8/attributeoutputbase.hxx1
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx4
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx6
7 files changed, 114 insertions, 5 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/fdo69644.docx b/sw/qa/extras/ooxmlexport/data/fdo69644.docx
new file mode 100644
index 000000000000..1a254db3b4d6
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/fdo69644.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 028189b18881..6aeae7b3c970 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 9a0b188a95e3..aa39f3d6b33c 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 92fe35d47bb0..894a29bee866 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 7ad8d3a7f3ea..22de507be996 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 62afa65ebd51..755f606ac841 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 627ed854a0f4..ec537447ab50 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;