sw/qa/extras/ooxmlimport/data/fdo65090.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 10 +++ writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 43 ++++++++++++++- writerfilter/source/dmapper/DomainMapperTableHandler.hxx | 17 +++++ writerfilter/source/dmapper/DomainMapperTableManager.cxx | 8 ++ writerfilter/source/dmapper/PropertyIds.cxx | 1 writerfilter/source/dmapper/PropertyIds.hxx | 1 7 files changed, 77 insertions(+), 3 deletions(-)
New commits: commit 97dcf77841d19d344d58d5bdacdab141cdea4817 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Dec 27 21:07:43 2013 +0100 Related: fdo#65090 DOCX import: handle w:hMerge cell property Change-Id: I82f334426715fd1a1f0105b86f763d41e66f32da diff --git a/sw/qa/extras/ooxmlimport/data/fdo65090.docx b/sw/qa/extras/ooxmlimport/data/fdo65090.docx new file mode 100644 index 0000000..4d45737 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo65090.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index e91de29..7804340 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1660,6 +1660,16 @@ DECLARE_OOXMLIMPORT_TEST(testRPrChangeClosed, "rprchange_closed.docx") CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(getParagraph(2), 1), "RedlineType")); } +DECLARE_OOXMLIMPORT_TEST(testFdo65090, "fdo65090.docx") +{ + 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); + // The first row had two cells, instead of a single horizontally merged one. + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators").getLength()); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index a098472..7e248de 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -539,7 +539,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo #define CNF_LAST_ROW_LAST_COLUMN 0x002 #define CNF_LAST_ROW_FIRST_COLUMN 0x001 -CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo) +CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges) { #ifdef DEBUG_DMAPPER_TABLE_HANDLER dmapper_logger->startElement("getCellProperties"); @@ -699,6 +699,25 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) ); + // Horizontal merge is not an UNO property, extract that info here to rMerges, and then remove it from the map. + const PropertyMap::const_iterator aHorizontalMergeIter = aCellIterator->get()->find(PROP_HORIZONTAL_MERGE); + if (aHorizontalMergeIter != aCellIterator->get()->end()) + { + if (aHorizontalMergeIter->second.getValue().get<sal_Bool>()) + { + // first cell in a merge + HorizontallyMergedCell aMerge(nRow, nCell); + rMerges.push_back(aMerge); + } + else if (!rMerges.empty()) + { + // resuming an earlier merge + HorizontallyMergedCell& rMerge = rMerges.back(); + rMerge.m_nLastRow = nRow; + rMerge.m_nLastCol = nCell; + } + aCellIterator->get()->erase(PROP_HORIZONTAL_MERGE); + } pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues(); #ifdef DEBUG_DMAPPER_TABLE_HANDLER dmapper_logger->endElement(); @@ -816,7 +835,8 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel) aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties); // expands to uno::Sequence< Sequence< beans::PropertyValues > > - CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo); + std::vector<HorizontallyMergedCell> aMerges; + CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo, aMerges); RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties(); @@ -849,8 +869,27 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel) aTableInfo.aTableProperties); if (xTable.is()) + { m_xTableRange = xTable->getAnchor( ); + if (!aMerges.empty()) + { + // Perform horizontal merges in reverse order, so the fact that merging changes the position of cells won't cause a problem for us. + for (std::vector<HorizontallyMergedCell>::reverse_iterator it = aMerges.rbegin(); it != aMerges.rend(); ++it) + { + uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xCell(xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), uno::UNO_QUERY_THROW); + OUString aFirst = xCell->getPropertyValue("CellName").get<OUString>(); + xCell.set(xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), uno::UNO_QUERY_THROW); + OUString aLast = xCell->getPropertyValue("CellName").get<OUString>(); + + uno::Reference<text::XTextTableCursor> xCursor = xTable->createCursorByCellName(aFirst); + xCursor->gotoCellByName(aLast, true); + xCursor->mergeRange(); + } + } + } + // OOXML table style may container paragraph properties, apply these now. for (int i = 0; i < aTableInfo.aTableProperties.getLength(); ++i) { diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx index 3dc75af..342eb74 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx @@ -48,6 +48,21 @@ typedef std::vector<PropertyMapVector1> PropertyMapVector2; class DomainMapper_Impl; class TableStyleSheetEntry; struct TableInfo; + +/// A horizontally merged cell is in fact a range of cells till its merge is performed. +struct HorizontallyMergedCell +{ + sal_Int32 m_nFirstRow; + sal_Int32 m_nFirstCol; + sal_Int32 m_nLastRow; + sal_Int32 m_nLastCol; + HorizontallyMergedCell(sal_Int32 nFirstRow, sal_Int32 nFirstCol) + : m_nFirstRow(nFirstRow), + m_nFirstCol(nFirstCol) + { + } +}; + class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler<Handle_t , TablePropertyMapPtr > { TextReference_t m_xText; @@ -67,7 +82,7 @@ class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler sal_Int32 m_nRowIndex; TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties); - CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo); + CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges); RowPropertyValuesSeq_t endTableGetRowProperties(); public: diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx index 7db941d..9625a1f 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -309,6 +309,14 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm) cellProps( pMergeProps); } break; + case NS_ooxml::LN_CT_TcPrBase_hMerge: + { + // values can be: LN_Value_ST_Merge_restart, LN_Value_ST_Merge_continue, in reality the second one is a 0 + TablePropertyMapPtr pMergeProps(new TablePropertyMap()); + pMergeProps->Insert(PROP_HORIZONTAL_MERGE, uno::makeAny(bool(sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart))); + cellProps(pMergeProps); + } + break; case NS_ooxml::LN_CT_TcPrBase_gridSpan: //number of grid positions spanned by this cell { #ifdef DEBUG_DOMAINMAPPER diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index a05249a..1cce816 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -359,6 +359,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_CHAR_THEME_ORIGINAL_COLOR : sName = "CharThemeOriginalColor"; break; case PROP_CHAR_THEME_COLOR_SHADE : sName = "CharThemeColorShade"; break; case PROP_CHAR_THEME_FILL : sName = "CharThemeFill"; break; + case PROP_HORIZONTAL_MERGE: sName = "HorizontalMerge"; break; } ::std::pair<PropertyNameMap_t::iterator,bool> 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 ae3e02a..2a9c1ee 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -330,6 +330,7 @@ enum PropertyIds ,PROP_CHAR_THEME_ORIGINAL_COLOR ,PROP_CHAR_THEME_COLOR_SHADE ,PROP_CHAR_THEME_FILL + ,PROP_HORIZONTAL_MERGE }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits