summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-06-08 10:25:13 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-06-08 11:14:38 +0100
commit89a28f54a295e1e05116176346763b16c8d187e0 (patch)
treeb9884fde3266d030a522399d7a904652e8731ab0
parent0f71828a9582f241dcddac5fe9a11fdf3a1a4e1c (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.odtbin0 -> 9872 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport5.cxx6
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx46
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
new file mode 100644
index 000000000000..69005b11e17c
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/ooo47778-3.odt
Binary files 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();