From 07ef4cf096015f0e427ffd17cd26bb6837e75481 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Tue, 18 Feb 2014 11:22:52 +0100 Subject: rhbz#1065629: RTF import: don't drop nested cells if not enough \cellx In this document written by "XMLmind XSL-FO Converter" there are less \cellx than \cell and thus when reading \nestrow/\row a whole buffered nested table \cell is lost and then subsequently the rest of the nested table too. Try to fix that by counting both \cell and \cellx and replaying until the maximum of those. Cannot count \intbl since we synthesize that in various places. (regression in LO 3.5) Change-Id: I3b64ad94af842e076611418589a0c83bd18841c6 --- sw/qa/extras/rtfimport/data/rhbz1065629.rtf | 81 ++++++++++++++++++++++++++ sw/qa/extras/rtfimport/rtfimport.cxx | 19 ++++++ writerfilter/source/rtftok/rtfdocumentimpl.cxx | 14 +++++ writerfilter/source/rtftok/rtfdocumentimpl.hxx | 1 + 4 files changed, 115 insertions(+) create mode 100644 sw/qa/extras/rtfimport/data/rhbz1065629.rtf diff --git a/sw/qa/extras/rtfimport/data/rhbz1065629.rtf b/sw/qa/extras/rtfimport/data/rhbz1065629.rtf new file mode 100644 index 000000000000..b22ec506622c --- /dev/null +++ b/sw/qa/extras/rtfimport/data/rhbz1065629.rtf @@ -0,0 +1,81 @@ +{\rtf1\ansi\ansicpg1252\deff0 +{\fonttbl +\f0\froman\fcharset0 Times New Roman; +\f1\fswiss\fcharset0 Arial; +\f2\fmodern\fcharset0 Courier New; +\f3\ftech\fcharset2 Symbol; +\f4\fswiss\fcharset0 Helvetica; +} +{\info +{\*\userprops +{\propname creator}\proptype30 +{\staticval XMLmind XSL-FO Converter Professional Edition 4.6.1} +} +} +\facingp\fet0\ftnbj +\sectd +\pghsxn16114\pgwsxn12514 +\margtsxn720\margbsxn907\marglsxn907\margrsxn1080 +\headery720 +\footery547 +\pgncont\pgndec + +\par +\trowd\trleft10 +\clvertalt +\clcbpat17 +\clbrdrt\brdrs\brdrw20\brdrcf2\clbrdrb\brdrs\brdrw20\brdrcf2\clbrdrl\brdrs\brdrw20\brdrcf2\clbrdrr\brdrs\brdrw20\brdrcf2\cellx10262 +\pard\intbl +{\plain\f4\fs19\b\cf15\ulc2 +Informations client +} +\cell +\row +\trowd\trleft10 +\clvertalt +\clbrdrl\brdrs\brdrw10\brdrcf2\cellx5136 +\clvertalt +\clbrdrl\brdrs\brdrw10\brdrcf2\clbrdrr\brdrs\brdrw10\brdrcf2\cellx10262 +\pard\intbl\itap2 +{\plain\f4\fs18\cf2\ulc2 +E-mail: +} +\nestcell +{\*\nesttableprops +\trowd\trleft0 +\clvertalt +\cellx5400 +\nestrow} +\pard\intbl +\cell +\pard\intbl\itap2 +{\plain\f4\fs18\b\cf2\ulc2 +Responsable Commercial: +} +\nestcell +{\*\nesttableprops +\trowd\trleft0 +\clvertalt +\cellx5400 +\nestrow} +\pard\intbl\itap2 +{\plain\f4\fs18\cf2\ulc2 +\~ +} +\par +\pard\intbl\itap2 +{\plain\f4\fs18\cf2\ulc2 +Nom: John Doe +} +\nestcell +{\*\nesttableprops +\trowd\trleft0 +\clvertalt +\cellx5400 +\nestrow} +\pard\intbl +\cell +\row + +\pard\sect +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 0289ea2ed3f8..87dee326fd7b 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -1365,6 +1365,25 @@ DECLARE_RTFIMPORT_TEST(testCp1000018, "cp1000018.rtf") #endif +DECLARE_RTFIMPORT_TEST(testNestedTable, "rhbz1065629.rtf") +{ + // nested table in second cell was missing + uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference xTable(xTables->getByIndex(1), uno::UNO_QUERY); + uno::Reference xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); + uno::Reference xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); + uno::Reference xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Responsable Commercial:"), xPara->getString()); + xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY); + xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY); + xParaEnum = xParaEnumAccess->createEnumeration(); + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Nom: John Doe"), xPara->getString()); +} + DECLARE_RTFIMPORT_TEST(testCp1000016, "hello.rtf") { // The single-line document had a second fake empty para on Windows. diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 95da80b4182b..f6651e8f8878 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -1890,6 +1890,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) RTFValue::Pointer_t pValue; m_aTableBuffer.push_back(make_pair(BUFFER_CELLEND, pValue)); m_bNeedPap = true; + m_aStates.top().nCellEnds++; } break; case RTF_ROW: @@ -1922,6 +1923,17 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) m_aStates.top().aTableCellsAttributes.pop_front(); replayBuffer(m_aTableBuffer); } + for (int i = 0; i < m_aStates.top().nCellEnds - m_aStates.top().nCells; ++i) + { + replayBuffer(m_aTableBuffer); + } + for (size_t i = 0; i < m_aTableBuffer.size(); ++i) + { + SAL_WARN_IF(BUFFER_CELLEND == m_aTableBuffer[i].first, + "writerfilter.rtf", "dropping table cell!"); + } + assert(0 == m_aStates.top().aTableCellsSprms.size()); + assert(0 == m_aStates.top().aTableCellsAttributes.size()); m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms; m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes; @@ -1974,6 +1986,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) m_bNeedFinalPar = true; m_aTableBuffer.clear(); m_aStates.top().nCells = 0; + m_aStates.top().nCellEnds = 0; m_aStates.top().aTableCellsSprms.clear(); m_aStates.top().aTableCellsAttributes.clear(); } @@ -4991,6 +5004,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl) nCellX(0), nCells(0), nInheritingCells(0), + nCellEnds(0), bIsCjk(false), nYear(0), nMonth(0), diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index a919614ae2e5..b7c299c9583b 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -236,6 +236,7 @@ namespace writerfilter { int nCellX; int nCells; int nInheritingCells; + int nCellEnds; /// CJK or CTL? bool bIsCjk; -- cgit v1.2.3