diff options
-rwxr-xr-x | sw/qa/extras/ooxmlimport/data/n780645.docx | bin | 0 -> 4001 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 13 | ||||
-rw-r--r-- | writerfilter/inc/resourcemodel/TableManager.hxx | 5 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableManager.cxx | 68 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableManager.hxx | 5 |
5 files changed, 90 insertions, 1 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/n780645.docx b/sw/qa/extras/ooxmlimport/data/n780645.docx Binary files differnew file mode 100755 index 000000000000..12ffa3870130 --- /dev/null +++ b/sw/qa/extras/ooxmlimport/data/n780645.docx diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 2c98832414be..36fdba3e367a 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -107,6 +107,7 @@ public: void testFdo52208(); void testN785767(); void testN773061(); + void testN780645(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -167,6 +168,7 @@ void Test::run() {"fdo52208.docx", &Test::testFdo52208}, {"n785767.docx", &Test::testN785767}, {"n773061.docx", &Test::testN773061}, + {"n780645.docx", &Test::testN780645}, }; for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) { @@ -1030,6 +1032,17 @@ void Test::testN773061() CPPUNIT_ASSERT_EQUAL( getProperty< sal_Int32 >( xFrame, "BottomBorderDistance" ), sal_Int32( 0 )); } +void Test::testN780645() +{ + // The problem was that when the number of cells didn't match the grid, we + // didn't take care of direct cell widths. + 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); + uno::Reference<table::XTableRows> xTableRows(xTextTable->getRows(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2135), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(1), "TableColumnSeparators")[0].Position); // was 1999 +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/inc/resourcemodel/TableManager.hxx b/writerfilter/inc/resourcemodel/TableManager.hxx index 71d9a819a61d..b6555cc00264 100644 --- a/writerfilter/inc/resourcemodel/TableManager.hxx +++ b/writerfilter/inc/resourcemodel/TableManager.hxx @@ -467,6 +467,11 @@ protected: sal_uInt32 getTableDepthNew() { return mnTableDepthNew; } /** + Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc. + */ + sal_uInt32 getTableDepthDifference() { return mnTableDepthNew - mnTableDepth; } + + /** Action to be carried out at the end of the last paragraph of a cell. */ diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx index 085370024f23..afe9d6c829cf 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -16,6 +16,7 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <boost/optional.hpp> #include <DomainMapperTableManager.hxx> #include <resourcemodel/WW8ResourceModel.hxx> #include <BorderHandler.hxx> @@ -51,6 +52,7 @@ DomainMapperTableManager::DomainMapperTableManager(bool bOOXML, bool bImplicitMe m_nTableWidth(0), m_bOOXML( bOOXML ), m_bImplicitMerges(bImplicitMerges), + m_bPushCurrentWidth(false), m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) ) { m_pTablePropsHandler->SetTableManager( this ); @@ -282,7 +284,21 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm) break; } case NS_ooxml::LN_CT_TcPrBase_tcW: - break; //fixed column width is not supported + { + // Contains unit and value, but unit is not interesting for + // us, later we'll just distribute these values in a + // 0..10000 scale. + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get()) + { + MeasureHandlerPtr pMeasureHandler(new MeasureHandler()); + pProperties->resolve(*pMeasureHandler); + getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue()); + if (getTableDepthDifference() > 0) + m_bPushCurrentWidth = true; + } + } + break; case NS_ooxml::LN_CT_TrPrBase_cnfStyle: { TablePropertyMapPtr pProps( new TablePropertyMap ); @@ -338,6 +354,11 @@ boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentSpa return m_aGridSpans.back( ); } +boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentCellWidths( ) +{ + return m_aCellWidths.back( ); +} + const OUString& DomainMapperTableManager::getTableVertAnchor() const { return m_sTableVertAnchor; @@ -347,18 +368,33 @@ void DomainMapperTableManager::startLevel( ) { DomainMapperTableManager_Base_t::startLevel( ); + // If requested, 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.back()->pop_back(); + } + IntVectorPtr pNewGrid( new vector<sal_Int32> ); IntVectorPtr pNewSpans( new vector<sal_Int32> ); + IntVectorPtr pNewCellWidths( new vector<sal_Int32> ); m_aTableGrid.push_back( pNewGrid ); m_aGridSpans.push_back( pNewSpans ); + m_aCellWidths.push_back( pNewCellWidths ); m_nCell.push_back( 0 ); m_nTableWidth = 0; + + // And push it back to the right level. + if (oCurrentWidth) + m_aCellWidths.back()->push_back(*oCurrentWidth); } void DomainMapperTableManager::endLevel( ) { m_aTableGrid.pop_back( ); m_aGridSpans.pop_back( ); + m_aCellWidths.pop_back( ); m_nCell.pop_back( ); m_nTableWidth = 0; @@ -394,6 +430,7 @@ void DomainMapperTableManager::endOfRowAction() #endif IntVectorPtr pTableGrid = getCurrentGrid( ); + IntVectorPtr pCellWidths = getCurrentCellWidths( ); if(!m_nTableWidth && pTableGrid->size()) { ::std::vector<sal_Int32>::const_iterator aCellIter = pTableGrid->begin(); @@ -523,11 +560,40 @@ void DomainMapperTableManager::endOfRowAction() #endif insertRowProps(pPropMap); } + else if (pCellWidths->size() > 0) + { + // If we're here, then the number of cells does not equal to the amount + // defined by the grid, even after taking care of + // gridSpan/gridBefore/gridAfter. Handle this by ignoring the grid and + // providing the separators based on the provided cell widths. + uno::Sequence< text::TableColumnSeparator > aSeparators(pCellWidths->size() - 1); + text::TableColumnSeparator* pSeparators = aSeparators.getArray(); + sal_Int16 nSum = 0; + sal_uInt32 nPos = 0; + + for (sal_uInt32 i = 0; i < pCellWidths->size() - 1; ++i) + { + nSum += (*pCellWidths.get())[i]; + pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth; + pSeparators[nPos].IsVisible = sal_True; + nPos++; + } + + TablePropertyMapPtr pPropMap( new TablePropertyMap ); + pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) ); +#ifdef DEBUG_DOMAINMAPPER + dmapper_logger->startElement("rowProperties"); + pPropMap->dumpXml( dmapper_logger ); + dmapper_logger->endElement(); +#endif + insertRowProps(pPropMap); + } ++m_nRow; m_nCell.back( ) = 0; m_nCellBorderIndex = 0; pCurrentSpans->clear(); + pCellWidths->clear(); m_nGridBefore = m_nGridAfter = 0; diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx index 7f3215c73f74..e7965bd05a94 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -50,6 +50,10 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t ::std::vector< IntVectorPtr > m_aTableGrid; ::std::vector< IntVectorPtr > m_aGridSpans; + /// If this is true, then we pushed a width before the next level started, and that should be carried over when starting the next level. + bool m_bPushCurrentWidth; + /// Individual table cell width values, used only in case the number of cells doesn't match the table grid. + ::std::vector< IntVectorPtr > m_aCellWidths; TablePropertiesHandler *m_pTablePropsHandler; PropertyMapPtr m_pStyleProps; @@ -75,6 +79,7 @@ public: IntVectorPtr getCurrentGrid( ); IntVectorPtr getCurrentSpans( ); + IntVectorPtr getCurrentCellWidths( ); const OUString& getTableStyleName() const { return m_sTableStyleName; } const OUString& getTableVertAnchor() const; |