sw/qa/extras/ooxmlimport/data/table-auto-column-fixed-size.docx |binary sw/qa/extras/ooxmlimport/data/table-auto-nested.docx |binary sw/qa/extras/ooxmlimport/data/table-floating.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 44 ++++++++ writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 30 ++++- writerfilter/source/dmapper/DomainMapperTableHandler.hxx | 4 writerfilter/source/dmapper/DomainMapperTableManager.cxx | 55 +++++++++- writerfilter/source/dmapper/DomainMapperTableManager.hxx | 1 writerfilter/source/dmapper/TablePositionHandler.cxx | 12 +- writerfilter/source/dmapper/TablePositionHandler.hxx | 2 10 files changed, 135 insertions(+), 13 deletions(-)
New commits: commit cb5a333fdda48ec1d141d1aa9ce7ae899aea2777 Author: Miklos Vajna <vmik...@suse.cz> Date: Tue Sep 3 15:23:46 2013 +0200 bnc#816593 DOCX import: fix auto table width wrt nested tables This is a backport of the fix + 3 other commits from master, which were needed to make the testcase pass on -4-1 as well. (cherry picked from commits 74c5ed19f430327988194cdcd6bdff09591a93fa, 824cc4bf4ae9035d4108e8da8e81eb57284f0b54, 53d27a30ce5f2c9f7d37a4089286116854c16215 and 76d1ca523ddcf89cc269fe51c70e66066943ef5a) Change-Id: I62a1f526cf1d4e4056daa1495d61f1b9f5c0b1b2 Reviewed-on: https://gerrit.libreoffice.org/5785 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/sw/qa/extras/ooxmlimport/data/table-auto-column-fixed-size.docx b/sw/qa/extras/ooxmlimport/data/table-auto-column-fixed-size.docx new file mode 100644 index 0000000..557edcb Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-auto-column-fixed-size.docx differ diff --git a/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx b/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx new file mode 100755 index 0000000..85f47db Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx differ diff --git a/sw/qa/extras/ooxmlimport/data/table-floating.docx b/sw/qa/extras/ooxmlimport/data/table-floating.docx new file mode 100755 index 0000000..1e0cb30 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-floating.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 9a685c4..0c066df 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -126,6 +126,9 @@ public: void testFdo46361(); void testFdo65632(); void testN816593(); + void testTableAutoColumnFixedSize(); + void testTableFloating(); + void testTableAutoNested(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -217,6 +220,9 @@ void Test::run() {"fdo46361.docx", &Test::testFdo46361}, {"fdo65632.docx", &Test::testFdo65632}, {"n816593.docx", &Test::testN816593}, + {"table-auto-column-fixed-size.docx", &Test::testTableAutoColumnFixedSize}, + {"table-floating.docx", &Test::testTableFloating}, + {"table-auto-nested.docx", &Test::testTableAutoNested}, }; header(); for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) @@ -1539,6 +1545,44 @@ void Test::testN816593() CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount()); } +void Test::testTableAutoColumnFixedSize() +{ + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); + + // Width was not recognized during import when table size was 'auto' + CPPUNIT_ASSERT_EQUAL(sal_Int32(TWIP_TO_MM100(3996)), getProperty<sal_Int32>(xTextTable, "Width")); +} + +void Test::testTableFloating() +{ + // Both the size and the position of the table was incorrect. + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + // Second table was too wide: 16249, i.e. as wide as the first table. + CPPUNIT_ASSERT_EQUAL(sal_Int32(11248), getProperty<sal_Int32>(xTables->getByIndex(1), "Width")); + + uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + // This was 0, should be the the opposite of (left margin + half of the border width). + CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xFrame, "HoriOrientPosition")); + // Was 0 as well, should be the right margin. + CPPUNIT_ASSERT_EQUAL(sal_Int32(191), getProperty<sal_Int32>(xFrame, "RightMargin")); +} + +void Test::testTableAutoNested() +{ + // This was 176, when compat option is not enabled, the auto paragraph bottom margin value was incorrect. + CPPUNIT_ASSERT_EQUAL(sal_Int32(494), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin")); + + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + // This was 115596, i.e. the width of the outer table was too large. + CPPUNIT_ASSERT_EQUAL(sal_Int32(23051), getProperty<sal_Int32>(xTables->getByIndex(1), "Width")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 7586396..8cbf48c 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -38,8 +38,6 @@ namespace dmapper { using namespace ::com::sun::star; using namespace ::std; -#define DEF_BORDER_DIST 190 //0,19cm - #ifdef DEBUG_DMAPPER_TABLE_HANDLER static void lcl_printProperties( PropertyMapPtr pProps ) { @@ -308,7 +306,7 @@ bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const Prope } -TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo) +TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties) { // will receive the table style if any TableStyleSheetEntry* pTableStyle = NULL; @@ -428,7 +426,25 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo aTableBorder.IsLeftLineValid = sal_True; // Only top level table position depends on border width if (rInfo.nNestLevel == 1) - rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5; + { + if (!rFrameProperties.hasElements()) + rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5; + else + { + // If this is a floating table, then the position of the frame should be adjusted, instead. + for (sal_Int32 i = 0; i < rFrameProperties.getLength(); ++i) + { + beans::PropertyValue& rPropertyValue = rFrameProperties[i]; + if (rPropertyValue.Name == "HoriOrientPosition") + { + sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>(); + nValue -= aLeftBorder.LineWidth * 0.5; + rPropertyValue.Value <<= nValue; + break; + } + } + } + } } if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine)) { @@ -762,9 +778,11 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel) dmapper_logger->startElement("tablehandler.endTable"); #endif + // If we want to make this table a floating one. + uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition(); TableInfo aTableInfo; aTableInfo.nNestLevel = nestedTableLevel; - aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo); + aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties); // expands to uno::Sequence< Sequence< beans::PropertyValues > > CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo); @@ -779,8 +797,6 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel) { uno::Reference<text::XTextRange> xStart; uno::Reference<text::XTextRange> xEnd; - // If we want to make this table a floating one. - uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition(); bool bFloating = aFrameProperties.hasElements(); // Additional checks: if we can do this. if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0) diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx index ea4c421..792b978 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx @@ -45,6 +45,8 @@ typedef ::com::sun::star::uno::Sequence< RowPropertyValuesSeq_t> CellProperty typedef std::vector<PropertyMapPtr> PropertyMapVector1; typedef std::vector<PropertyMapVector1> PropertyMapVector2; +#define DEF_BORDER_DIST 190 //0,19cm + class DomainMapper_Impl; class TableStyleSheetEntry; struct TableInfo; @@ -66,7 +68,7 @@ class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler sal_Int32 m_nCellIndex; sal_Int32 m_nRowIndex; - TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo); + TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties); CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo); RowPropertyValuesSeq_t endTableGetRowProperties(); diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx index 48d1e31..c3f4c5b 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -57,6 +57,7 @@ DomainMapperTableManager::DomainMapperTableManager(bool bOOXML) : m_bRowSizeTypeInserted(false), m_bTableSizeTypeInserted(false), m_nLayoutType(0), + m_nMaxFixedWidth(0), m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) ) { m_pTablePropsHandler->SetTableManager( this ); @@ -132,8 +133,47 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm) } else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto ) { - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, 100 ); + /* + This attribute specifies the width type of table. This is used as part of the table layout + algorithm specified by the tblLayout element.(See 17.4.64 and 17.4.65 of the ISO/IEC 29500-1:2011.) + If this valus is 'auto', the table layout has to uses the preferred widths on the table items to generate + the final sizing of the table, but then must use the contents of each cell to determine final column widths. + (See 17.18.87 of the ISO/IEC 29500-1:2011.) + */ + bool bFixed = false; + sal_Int32 nRowFixedWidth = 0; + if (!m_aCellWidths.empty()) + { + // Step 1. Check whether any cell has fixed width in the given row of table. + ::std::vector< IntVectorPtr >::iterator itr; + for (itr = m_aCellWidths.begin(); itr != m_aCellWidths.end(); itr ++) + { + IntVectorPtr itrVal = (*itr); + for (std::vector<sal_Int32>::const_iterator aValIter = itrVal->begin(); aValIter != itrVal->end(); ++aValIter) + { + // Sum the width of cells to find the total width of given row + nRowFixedWidth += (*aValIter); + bFixed = true; + } + } + } + + // Check whether the total width of given row is compared with the maximum value of rows (m_nMaxFixedWidth). + if (bFixed ) + { + // Check if total width + if (m_nMaxFixedWidth < nRowFixedWidth) + m_nMaxFixedWidth = nRowFixedWidth; + + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nMaxFixedWidth ); + } + else + { + // Set the width type of table with 'Auto' and set the width value to 100(%) + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, 100 ); + } } m_bTableSizeTypeInserted = true; } @@ -425,6 +465,7 @@ void DomainMapperTableManager::startLevel( ) m_nCell.push_back( 0 ); m_nTableWidth = 0; m_nLayoutType = 0; + m_nMaxFixedWidth = 0; // And push it back to the right level. if (oCurrentWidth) @@ -435,10 +476,20 @@ void DomainMapperTableManager::endLevel( ) { m_aTableGrid.pop_back( ); m_aGridSpans.pop_back( ); + + // Do the same trick as in startLevel(): pop the value that was pushed too early. + boost::optional<sal_Int32> oCurrentWidth; + if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty()) + oCurrentWidth.reset(m_aCellWidths.back()->back()); m_aCellWidths.pop_back( ); + // And push it back to the right level. + if (oCurrentWidth) + m_aCellWidths.back()->push_back(*oCurrentWidth); + m_nCell.pop_back( ); m_nTableWidth = 0; m_nLayoutType = 0; + m_nMaxFixedWidth = 0; m_aTmpPosition.pop_back( ); m_aTmpTableProperties.pop_back( ); diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx index 1384197..6243b61 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -62,6 +62,7 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t bool m_bTableSizeTypeInserted; /// Table layout algorithm, IOW if we should consider fixed column width or not. sal_uInt32 m_nLayoutType; + sal_Int32 m_nMaxFixedWidth; TablePropertiesHandler *m_pTablePropsHandler; PropertyMapPtr m_pStyleProps; diff --git a/writerfilter/source/dmapper/TablePositionHandler.cxx b/writerfilter/source/dmapper/TablePositionHandler.cxx index 3e30919..6d32bba 100644 --- a/writerfilter/source/dmapper/TablePositionHandler.cxx +++ b/writerfilter/source/dmapper/TablePositionHandler.cxx @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <TablePositionHandler.hxx> +#include <DomainMapperTableHandler.hxx> #include <PropertyMap.hxx> #include <doctok/resourceids.hxx> #include <ConversionHelper.hxx> @@ -28,7 +29,9 @@ TablePositionHandler::TablePositionHandler() : m_aHorzAnchor( "text" ), m_aXSpec( ), m_nY( 0 ), - m_nX( 0 ) + m_nX( 0 ), + m_nLeftBorderDistance(DEF_BORDER_DIST), + m_nRightBorderDistance(DEF_BORDER_DIST) { } @@ -75,7 +78,7 @@ void TablePositionHandler::lcl_sprm(Sprm& /*rSprm*/) uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() const { - uno::Sequence< beans::PropertyValue > aFrameProperties(18); + uno::Sequence< beans::PropertyValue > aFrameProperties(19); beans::PropertyValue* pFrameProperties = aFrameProperties.getArray(); pFrameProperties[0].Name = "LeftBorderDistance"; @@ -132,7 +135,7 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con pFrameProperties[13].Name = "HoriOrientRelation"; pFrameProperties[13].Value <<= nHoriOrientRelation; pFrameProperties[14].Name = "HoriOrientPosition"; - pFrameProperties[14].Value <<= m_nX; + pFrameProperties[14].Value <<= m_nX - m_nLeftBorderDistance; // Vertical positioning @@ -161,6 +164,9 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con pFrameProperties[17].Name = "VertOrientPosition"; pFrameProperties[17].Value <<= m_nY; + pFrameProperties[18].Name = "RightMargin"; + pFrameProperties[18].Value <<= m_nRightBorderDistance; + return aFrameProperties; } diff --git a/writerfilter/source/dmapper/TablePositionHandler.hxx b/writerfilter/source/dmapper/TablePositionHandler.hxx index b6ddd50..43eabbc 100644 --- a/writerfilter/source/dmapper/TablePositionHandler.hxx +++ b/writerfilter/source/dmapper/TablePositionHandler.hxx @@ -27,6 +27,8 @@ namespace writerfilter { OUString m_aXSpec; sal_Int32 m_nY; sal_Int32 m_nX; + sal_Int32 m_nLeftBorderDistance; + sal_Int32 m_nRightBorderDistance; // Properties virtual void lcl_attribute(Id Name, Value & val);
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits