diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-06-08 10:25:13 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-06-08 11:14:38 +0100 |
commit | 89a28f54a295e1e05116176346763b16c8d187e0 (patch) | |
tree | b9884fde3266d030a522399d7a904652e8731ab0 | |
parent | 0f71828a9582f241dcddac5fe9a11fdf3a1a4e1c (diff) |
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
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/ooo47778-3.odt | bin | 0 -> 9872 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 6 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.cxx | 46 |
3 files changed, 49 insertions, 3 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt b/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt Binary files differnew file mode 100644 index 000000000000..69005b11e17c --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt 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(); |