From 9223a8766e5a055f77e9cc7bccbfa718e6122e28 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 8 May 2018 09:06:26 +0200 Subject: tdf#117403 RTF import: fix lost cell border of merged cell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If two source cells have different border types, then Writer takes the second, Word takes the first. So mimic the MSO behavior explicitly in dmapper. (cherry picked from commit 42b32321381126ad70700424b8970dbc45a843f5) Change-Id: I25adc62e024a929216c7b05fec44e1f602f28285 Reviewed-on: https://gerrit.libreoffice.org/54089 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- sw/qa/extras/rtfimport/data/tdf117403.rtf | 15 ++++++++++ sw/qa/extras/rtfimport/rtfimport.cxx | 14 +++++++++ .../source/dmapper/DomainMapperTableHandler.cxx | 35 +++++++++++++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 sw/qa/extras/rtfimport/data/tdf117403.rtf diff --git a/sw/qa/extras/rtfimport/data/tdf117403.rtf b/sw/qa/extras/rtfimport/data/tdf117403.rtf new file mode 100644 index 000000000000..243fe548c246 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/tdf117403.rtf @@ -0,0 +1,15 @@ +{\rtf\ansi\ansicpg1252\deff2 +{\fonttbl +{\f0\fcharset238\froman Tms Rmn;} +{\f1\fdecor Symbol;} +{\f2\fcharset238\fswiss Helv;} +{\f3\fcharset238\fmodern Courier New;} +} +\sectd +\pgwsxn16837\pghsxn11905\marglsxn400\margrsxn400\margtsxn801\margbsxn801\lndscpsxn\plain\fs20\pard\qc +\pard\pard +\par +\trowd\clmgf\clbrdrb\brdrs\brdrw1\cellx1764\clmrg\cellx2325 +\pard\intbl \qc \fs12 A1\cell +\pard\intbl \cell +\row \pard \par} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index b3ca9eeedd25..565e26a49714 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -1319,6 +1319,20 @@ DECLARE_RTFIMPORT_TEST(testTdf78506, "tdf78506.rtf") } } +DECLARE_RTFIMPORT_TEST(testTdf117403, "tdf117403.rtf") +{ + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); + CPPUNIT_ASSERT(xCell.is()); + table::BorderLine2 aExpected(static_cast(COL_BLACK), 0, 4, 0, + table::BorderLineStyle::SOLID, 4); + // This failed, border was not imported, OuterLineWidth was 0 instead of 4. + CPPUNIT_ASSERT_BORDER_EQUAL(aExpected, getProperty(xCell, "BottomBorder")); +} + DECLARE_RTFIMPORT_TEST(testImportHeaderFooter, "tdf108055.rtf") { // The RTF import sometimes added Header and Footer multiple Times diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index e6f993e19387..1466787b8fb5 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -1030,21 +1030,48 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab { if (!aMerges.empty()) { + static const std::vector aBorderNames + = { "TopBorder", "LeftBorder", "BottomBorder", "RightBorder" }; + // 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::reverse_iterator it = aMerges.rbegin(); it != aMerges.rend(); ++it) { uno::Reference xCellRange(xTable, uno::UNO_QUERY_THROW); - uno::Reference xCell(xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), uno::UNO_QUERY_THROW); - OUString aFirst = xCell->getPropertyValue("CellName").get(); + uno::Reference xFirstCell( + xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), + uno::UNO_QUERY_THROW); + OUString aFirst + = xFirstCell->getPropertyValue("CellName").get(); // tdf#105852: Only try to merge if m_nLastCol is set (i.e. there were some merge continuation cells) if (it->m_nLastCol != -1) { - xCell.set(xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), uno::UNO_QUERY_THROW); - OUString aLast = xCell->getPropertyValue("CellName").get(); + // Save border properties of the first cell + // before merge. + table::BorderLine2 aBorderValues[4]; + for (size_t i = 0; i < aBorderNames.size(); ++i) + xFirstCell->getPropertyValue(aBorderNames[i]) + >>= aBorderValues[i]; + + uno::Reference xLastCell( + xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), + uno::UNO_QUERY_THROW); + OUString aLast + = xLastCell->getPropertyValue("CellName").get(); uno::Reference xCursor = xTable->createCursorByCellName(aFirst); xCursor->gotoCellByName(aLast, true); + xCursor->mergeRange(); + + // Handle conflicting properties: mergeRange() + // takes the last cell, Word takes the first + // cell. + for (size_t i = 0; i < aBorderNames.size(); ++i) + { + if (aBorderValues[i].LineStyle != table::BorderLineStyle::NONE) + xFirstCell->setPropertyValue( + aBorderNames[i], uno::makeAny(aBorderValues[i])); + } } } } -- cgit v1.2.3