From 89a28f54a295e1e05116176346763b16c8d187e0 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 8 Jun 2015 10:25:13 +0100 Subject: Resolves: crash on export of ooo47778-3.sxw to docx This is a horror where the table in the frame has its cells out of visual sequence, so the last row appears before the last node so on hitting the last node we have to really jump backwards to a previously skipped set of nodes to find the end of the table Change-Id: I93545e0c425267647d5f048c3bd95fe0cfddf8f3 --- sw/qa/extras/ooxmlexport/data/ooo47778-3.odt | Bin 0 -> 9872 bytes sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 6 ++++ sw/source/filter/ww8/wrtww8.cxx | 46 +++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/ooo47778-3.odt (limited to 'sw') diff --git a/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt b/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt new file mode 100644 index 000000000000..69005b11e17c Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx index f97d6a3a2329..6b2fb6eff4e1 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx @@ -813,6 +813,12 @@ DECLARE_OOXMLEXPORT_TEST(testSectionHeader, "sectionprot.odt") } } +DECLARE_OOXMLEXPORT_TEST(testOO47778, "ooo47778-3.odt") +{ + if (xmlDocPtr pXmlDoc = parseExport("word/document.xml")) + assertXPathContent(pXmlDoc, "(//w:t)[3]", "c"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 432a287dc193..41cf0c2d43f3 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -2531,11 +2531,51 @@ void WW8Export::SectionBreaksAndFrames( const SwTextNode& rNode ) OutWW6FlyFrmsInContent( rNode ); } +class TrackContentToExport +{ +private: + SwPaM *m_pCurPam; + SwPaM m_aOrigPam; +public: + TrackContentToExport(SwPaM *pCurPam) + : m_pCurPam(pCurPam) + , m_aOrigPam(*pCurPam, NULL) + { + } + + bool contentRemainsToExport(ww8::WW8TableInfo *pTableInfo) + { + bool bSimpleContentRemains = m_pCurPam->GetPoint()->nNode < m_pCurPam->GetMark()->nNode || + (m_pCurPam->GetPoint()->nNode == m_pCurPam->GetMark()->nNode && + m_pCurPam->GetPoint()->nContent.GetIndex() <= m_pCurPam->GetMark()->nContent.GetIndex()); + if (bSimpleContentRemains) + return true; + + if (!pTableInfo) + return false; + + //An old-school table where one cell may points back to a previous node as the next cell + //so if this node is the last node in the range, we may need to jump back to a previously + //skipped cell to output it in a sane sequence. See ooo47778-3.sxw for one of these + //horrors. So if we are at the end of the selection, but this end point is a table + //cell whose next cell is in the selection allow jumping back to it + const SwNode* pCurrentNode = &m_pCurPam->GetPoint()->nNode.GetNode(); + const SwNode* pNextNode = pTableInfo->getNextNode(pCurrentNode); + + if (pNextNode && pCurrentNode != pNextNode) + { + return pNextNode->GetIndex() >= m_aOrigPam.GetPoint()->nNode.GetIndex() && + pNextNode->GetIndex() < m_aOrigPam.GetMark()->nNode.GetIndex(); + } + + return false; + } +}; + void MSWordExportBase::WriteText() { - while( m_pCurPam->GetPoint()->nNode < m_pCurPam->GetMark()->nNode || - ( m_pCurPam->GetPoint()->nNode == m_pCurPam->GetMark()->nNode && - m_pCurPam->GetPoint()->nContent.GetIndex() <= m_pCurPam->GetMark()->nContent.GetIndex() ) ) + TrackContentToExport aContentTracking(m_pCurPam); + while (aContentTracking.contentRemainsToExport(m_pTableInfo.get())) { SwNode& rNd = m_pCurPam->GetNode(); -- cgit