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
diff --git a/sw/qa/extras/rtfimport/data/rhbz1065629.rtf b/sw/qa/extras/rtfimport/data/rhbz1065629.rtf
new file mode 100644
index 0000000..b22ec50
--- /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 0289ea2..87dee32 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<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(1), uno::UNO_QUERY);
    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
    uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
    uno::Reference<text::XTextRange> 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 95da80b..f6651e8 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 a919614..b7c299c 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;