summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/ooxmlimport/data/fdo65090.docxbin0 -> 10409 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx12
-rw-r--r--sw/qa/extras/rtfimport/data/fdo65090.rtf6
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx12
-rw-r--r--sw/source/core/unocore/unotbl.cxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.cxx43
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.hxx17
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.cxx8
-rw-r--r--writerfilter/source/dmapper/PropertyIds.cxx1
-rw-r--r--writerfilter/source/dmapper/PropertyIds.hxx1
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx12
11 files changed, 110 insertions, 4 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/fdo65090.docx b/sw/qa/extras/ooxmlimport/data/fdo65090.docx
new file mode 100644
index 000000000000..4d45737ddc37
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/fdo65090.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index d1fa6507598b..2c72214bf1cb 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -136,6 +136,7 @@ public:
void testGroupshapeSdt();
void testBnc779620();
void testRPrChangeClosed();
+ void testFdo65090();
CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -237,6 +238,7 @@ void Test::run()
{"groupshape-sdt.docx", &Test::testGroupshapeSdt},
{"bnc779620.docx", &Test::testBnc779620},
{"rprchange_closed.docx", &Test::testRPrChangeClosed},
+ {"fdo65090.docx", &Test::testFdo65090},
};
header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1661,6 +1663,16 @@ void Test::testRPrChangeClosed()
CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(getParagraph(2), 1), "RedlineType"));
}
+void Test::testFdo65090()
+{
+ 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());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/rtfimport/data/fdo65090.rtf b/sw/qa/extras/rtfimport/data/fdo65090.rtf
new file mode 100644
index 000000000000..8a3eabd25723
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo65090.rtf
@@ -0,0 +1,6 @@
+{\rtf\ansi
+{
+\trowd\trgaph30\trleft-30\trrh242\clmgf\clvertalc\cellx1280\clmrg\clvertalb\cellx2560\clvertalb\cellx3840\pard\plain\intbl
+\qc a\cell\cell\ql b\cell\row
+}
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 687baacc6f48..eca16e3440f7 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -161,6 +161,7 @@ public:
void testFdo68291();
void testFdo69384();
void testFdo70221();
+ void testFdo65090();
CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -306,6 +307,7 @@ void Test::run()
{"fdo68291.odt", &Test::testFdo68291},
{"hello.rtf", &Test::testFdo69384},
{"fdo70221.rtf", &Test::testFdo70221},
+ {"fdo65090.rtf", &Test::testFdo65090},
};
header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1488,6 +1490,16 @@ void Test::testFdo70221()
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount());
}
+void Test::testFdo65090()
+{
+ 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 3 cells, instead of a horizontally merged one and a normal one (2 -> 1 separator).
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators").getLength());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
index 49fc1a3b6ee1..3fd23507d581 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -1709,7 +1709,7 @@ sal_Bool SwXTextTableCursor::mergeRange(void) throw( uno::RuntimeException )
if(bRet)
{
size_t nCount = pTblCrsr->GetSelectedBoxesCount();
- while (--nCount)
+ while (nCount--)
{
pTblCrsr->DeleteBox(nCount);
}
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index b613c07cd177..28be09cc1258 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -536,7 +536,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");
@@ -692,6 +692,25 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, false,
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(PropertyDefinition(PROP_HORIZONTAL_MERGE, false));
+ if (aHorizontalMergeIter != aCellIterator->get()->end())
+ {
+ if (aHorizontalMergeIter->second.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(PropertyDefinition(PROP_HORIZONTAL_MERGE, false));
+ }
pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues();
#ifdef DEBUG_DMAPPER_TABLE_HANDLER
dmapper_logger->endElement();
@@ -804,7 +823,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();
@@ -837,8 +857,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 792b978b46c0..6b284f71e76f 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -50,6 +50,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;
@@ -69,7 +84,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 c3f4c5b6427d..59afbb3e9310 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -298,6 +298,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, false, 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 46a316cb31ac..f305c0318433 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -325,6 +325,7 @@ const OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const
case PROP_GRAPHIC_URL: sName = "GraphicURL"; break;
case PROP_GRAPHIC_BITMAP: sName = "GraphicBitmap"; break;
case PROP_LABEL_CATEGORY: sName = "LabelCategory"; 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 92d3928d8638..194d7c53c40e 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -296,6 +296,7 @@ enum PropertyIds
,PROP_IS_WIDTH_RELATIVE
,PROP_GRAPHIC_URL
,PROP_GRAPHIC_BITMAP
+ ,PROP_HORIZONTAL_MERGE
};
struct PropertyNameSupplier_Impl;
class PropertyNameSupplier
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5e7ea2ac984f..2deb1effaa24 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -2394,6 +2394,18 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
m_aStates.top().nBorderState = BORDER_PARAGRAPH;
}
break;
+ case RTF_CLMGF:
+ {
+ RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+ }
+ break;
+ case RTF_CLMRG:
+ {
+ RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue));
+ m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+ }
+ break;
case RTF_CLVMGF:
{
RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));