From ff2ead2c359e65afc25c0ddb74a127572aecc516 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 23 May 2013 16:20:27 +0200 Subject: bnc#819882 DOCX import: backport table-related fixes from libreoffice-4-1 7705a50ba330cd3fa08f5edfe6617d9acde8e8a5 2012-11-06 docx import: round float value to int when computing cells width b261177e5d81a662c76d523e447d80c108ebdf5b 2012-11-08 round() is not portable d276d3f3ae112a11c8cb5768650d147cbb94275e 2013-01-14 fdo#44053 fix this again and this time add a testcase as well 6718482c072defe5d885030826fef5ef833732e9 2013-03-28 fixed table width, supporting rel table width, fixed grid handling 84f1fa190fc2b91d21b685f4d0ea99aaeea26fe0 2013-03-28 WaE: -Wsign-compare Change-Id: I419636a4d115ef97033b6b2ac0424c66318f0009 --- .../source/dmapper/DomainMapperTableHandler.cxx | 15 ++++- .../source/dmapper/DomainMapperTableManager.cxx | 70 +++++++++------------- .../source/dmapper/DomainMapperTableManager.hxx | 3 +- writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2 +- writerfilter/source/dmapper/MeasureHandler.hxx | 3 + writerfilter/source/dmapper/PropertyIds.cxx | 2 + writerfilter/source/dmapper/PropertyIds.hxx | 2 + writerfilter/source/dmapper/PropertyMap.hxx | 1 + 8 files changed, 50 insertions(+), 48 deletions(-) diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 9c2d298d4037..a3bdb71b715b 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #ifdef DEBUG_DMAPPER_TABLE_HANDLER @@ -328,6 +329,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo sal_Int32 nGapHalf = 0; sal_Int32 nLeftMargin = 0; sal_Int32 nTableWidth = 0; + sal_Int32 nTableWidthType = text::SizeType::FIX; PropertyMap::iterator aTableStyleIter = m_aTableProperties->find( PropertyDefinition( META_PROP_TABLE_STYLE_NAME, false ) ); @@ -460,8 +462,17 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo } m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth ); - if( nTableWidth > 0 ) - m_aTableProperties->Insert( PROP_WIDTH, false, uno::makeAny( nTableWidth )); + m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType ); + if( nTableWidthType == text::SizeType::FIX ) + { + if( nTableWidth > 0 ) + m_aTableProperties->Insert( PROP_WIDTH, false, uno::makeAny( nTableWidth )); + } + else + { + m_aTableProperties->Insert( PROP_RELATIVE_WIDTH, false, uno::makeAny( sal_Int16( nTableWidth ) ) ); + m_aTableProperties->Insert( PROP_IS_WIDTH_RELATIVE, false, uno::makeAny( sal_Bool( sal_True ) ) ); + } sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH; m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ; diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx index a396d69fac35..ad905c9fa24e 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -49,7 +49,7 @@ using namespace ::com::sun::star; using namespace ::std; -DomainMapperTableManager::DomainMapperTableManager(bool bOOXML, bool bImplicitMerges) : +DomainMapperTableManager::DomainMapperTableManager(bool bOOXML) : m_nRow(0), m_nCell(), m_nGridSpan(1), @@ -59,7 +59,6 @@ DomainMapperTableManager::DomainMapperTableManager(bool bOOXML, bool bImplicitMe m_nHeaderRepeat(0), m_nTableWidth(0), m_bOOXML( bOOXML ), - m_bImplicitMerges(bImplicitMerges), m_bPushCurrentWidth(false), m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) ) { @@ -122,7 +121,23 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm) { m_nTableWidth = pMeasureHandler->getMeasureValue(); if( m_nTableWidth ) + { + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX ); pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); + } + else if( sal::static_int_cast(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_pct ) + { + sal_Int32 nPercent = pMeasureHandler->getValue() / 50; + if(nPercent > 100) + nPercent = 100; + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, nPercent ); + } + else if( sal::static_int_cast(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto ) + { + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); + pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, 100 ); + } } #ifdef DEBUG_DOMAINMAPPER pPropMap->dumpXml( dmapper_logger ); @@ -473,13 +488,6 @@ void DomainMapperTableManager::endOfRowAction() m_nTableWidth += *aCellIter++; } - if( m_nTableWidth > 0) - { - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); - insertTableProps(pPropMap); - } - #ifdef DEBUG_DOMAINMAPPER dmapper_logger->endElement(); #endif @@ -516,10 +524,14 @@ void DomainMapperTableManager::endOfRowAction() for( ; aGridSpanIter != pCurrentSpans->end(); ++aGridSpanIter) nGrids += *aGridSpanIter; - //determine table width - double nFullWidth = m_nTableWidth; - //the positions have to be distibuted in a range of 10000 - const double nFullWidthRelative = 10000.; + // sj: the grid is having no units... they is containing only relative values. + // a table with a grid of "1:2:1" looks identical as if the table is having + // a grid of "20:40:20" and it doesn't have to do something with the tableWidth + // -> so we have get the sum of each grid entry for the fullWidthRelative: + int nFullWidthRelative = 0; + for (unsigned int i = 0 ; i < (*pTableGrid.get()).size(); i++ ) + nFullWidthRelative += (*pTableGrid.get())[ i ]; + if( pTableGrid->size() == ( m_nGridBefore + nGrids + m_nGridAfter ) && m_nCell.back( ) > 0 ) { uno::Sequence< text::TableColumnSeparator > aSeparators( m_nCell.back( ) - 1 ); @@ -538,7 +550,7 @@ void DomainMapperTableManager::endOfRowAction() }while( --nGridCount ); sal_Int16 nRelPos = - sal::static_int_cast< sal_Int16 >(fGridWidth * nFullWidthRelative / nFullWidth ); + sal::static_int_cast< sal_Int16 >((fGridWidth * 10000) / nFullWidthRelative); pSeparators[nBorder].Position = nRelPos + nLastRelPos; pSeparators[nBorder].IsVisible = sal_True; @@ -548,34 +560,6 @@ void DomainMapperTableManager::endOfRowAction() 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); - } - else if (m_bImplicitMerges && pTableGrid->size()) - { - // More grid than cells definitions? Then take the last ones. - // This feature is used by the RTF implicit horizontal cell merges. - uno::Sequence< text::TableColumnSeparator > aSeparators(m_nCell.back( ) - 1); - text::TableColumnSeparator* pSeparators = aSeparators.getArray(); - - sal_Int16 nSum = 0; - sal_uInt32 nPos = 0; - sal_uInt32 nSizeTableGrid = pTableGrid->size(); - // Ignoring the i=0 case means we assume that the width of the last cell matches the table width - for (sal_uInt32 i = m_nCell.back( ); i > 1 && nSizeTableGrid >= i; i--) - { - nSum += (*pTableGrid.get())[pTableGrid->size() - i]; // Size of the current cell - pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth; // Relative position - 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 ); @@ -597,7 +581,7 @@ void DomainMapperTableManager::endOfRowAction() for (sal_uInt32 i = 0; i < pCellWidths->size() - 1; ++i) { nSum += (*pCellWidths.get())[i]; - pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth; + pSeparators[nPos].Position = (nSum * 10000) / nFullWidthRelative; // Relative position pSeparators[nPos].IsVisible = sal_True; nPos++; } diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx index 424c10814cac..0e54981e9104 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -53,7 +53,6 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t sal_Int32 m_nHeaderRepeat; //counter of repeated headers - if == -1 then the repeating stops sal_Int32 m_nTableWidth; //might be set directly or has to be calculated from the column positions bool m_bOOXML; - bool m_bImplicitMerges; ::rtl::OUString m_sTableStyleName; std::vector< TablePositionHandlerPtr > m_aTablePositions; PropertyMapPtr m_pTableStyleTextProperies; @@ -72,7 +71,7 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t public: - DomainMapperTableManager(bool bOOXML, bool bImplicitMerges); + DomainMapperTableManager(bool bOOXML); virtual ~DomainMapperTableManager(); // use this method to avoid adding the properties for the table diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 5fa3f42dcb8b..cc6fd63c2f4d 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -580,7 +580,7 @@ public: void appendTableManager( ) { boost::shared_ptr< DomainMapperTableManager > pMngr( - new DomainMapperTableManager( m_eDocumentType == DOCUMENT_OOXML || m_eDocumentType == DOCUMENT_RTF, m_eDocumentType == DOCUMENT_RTF ) ); + new DomainMapperTableManager( m_eDocumentType == DOCUMENT_OOXML || m_eDocumentType == DOCUMENT_RTF ) ); m_aTableManagers.push( pMngr ); } diff --git a/writerfilter/source/dmapper/MeasureHandler.hxx b/writerfilter/source/dmapper/MeasureHandler.hxx index 3c9de2427d06..50ed17ee73e1 100644 --- a/writerfilter/source/dmapper/MeasureHandler.hxx +++ b/writerfilter/source/dmapper/MeasureHandler.hxx @@ -56,6 +56,9 @@ public: sal_Int32 getMeasureValue() const; + sal_Int32 getValue() const { return m_nMeasureValue; } + sal_Int32 getUnit() const { return m_nUnit; } + sal_Int16 GetRowHeightSizeType() const { return m_nRowHeightSizeType;} }; typedef boost::shared_ptr diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 0f46606f2598..0a2a313b30dc 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -325,6 +325,8 @@ const rtl::OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_IS_VISIBLE: sName = "IsVisible"; break; case PROP_PAGE_STYLE_LAYOUT: sName = "PageStyleLayout"; break; case PROP_Z_ORDER: sName = "ZOrder"; break; + case PROP_RELATIVE_WIDTH: sName = "RelativeWidth"; break; + case PROP_IS_WIDTH_RELATIVE: sName = "IsWidthRelative"; break; } ::std::pair aInsertIt = m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName )); diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index 39853bfec2fe..1d39dbb024a1 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -298,6 +298,8 @@ enum PropertyIds ,PROP_PARA_CONTEXT_MARGIN ,PROP_PAGE_STYLE_LAYOUT ,PROP_Z_ORDER + ,PROP_RELATIVE_WIDTH + ,PROP_IS_WIDTH_RELATIVE }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 77c6680ba156..baf2d69bfa52 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -510,6 +510,7 @@ public: CELL_MAR_TOP, CELL_MAR_BOTTOM, TABLE_WIDTH, + TABLE_WIDTH_TYPE, GAP_HALF, LEFT_MARGIN, HORI_ORIENT, -- cgit v1.2.3