diff options
-rw-r--r-- | sw/qa/extras/ww8export/data/tdf91083_tableKeep.doc | bin | 0 -> 16384 bytes | |||
-rw-r--r-- | sw/qa/extras/ww8export/ww8export.cxx | 30 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par2.cxx | 54 |
3 files changed, 84 insertions, 0 deletions
diff --git a/sw/qa/extras/ww8export/data/tdf91083_tableKeep.doc b/sw/qa/extras/ww8export/data/tdf91083_tableKeep.doc Binary files differnew file mode 100644 index 000000000000..2215ab0e92d3 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf91083_tableKeep.doc diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx index a0b651eb6c27..f8fc27a5df69 100644 --- a/sw/qa/extras/ww8export/ww8export.cxx +++ b/sw/qa/extras/ww8export/ww8export.cxx @@ -701,9 +701,39 @@ DECLARE_WW8EXPORT_TEST(testTableKeep, "tdf91083.odt") //emulate table "keep with next" -do not split table CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[3]/body/tab[1]/row[2]/cell[1]/txt[1]") ); CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[6]/body/tab[1]/row[2]/cell[1]/txt[1]") ); + + // detect and re-enable keep-with-next and dont-split-table settings + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable (xTables->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTable, "Split")); } #endif +DECLARE_WW8EXPORT_TEST(testTdf91083_tableKeep, "tdf91083_tableKeep.doc") +{ + // detect and re-enable keep-with-next and dont-split-table settings + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + + // single-row table - kept with next + uno::Reference<text::XTextTable> xTable (xTables->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTable, "Split")); + // I don't know how to test for SvxFormatKeepItem + + // complex table - kept with next + xTables->getByIndex(1) >>= xTable; + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTable, "Split")); + + //single row table - do not split + xTables->getByIndex(3) >>= xTable; + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTable, "Split")); + + //multi-row table - do not split + xTables->getByIndex(4) >>= xTable; + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTable, "Split")); +} + DECLARE_WW8EXPORT_TEST(testMoveRange, "fdo66304-1.odt") { //the save must survive without asserting diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx index e88d7cfa09d2..b0490ded08f6 100644 --- a/sw/source/filter/ww8/ww8par2.cxx +++ b/sw/source/filter/ww8/ww8par2.cxx @@ -2727,6 +2727,60 @@ void WW8TabDesc::FinishSwTable() pIo->m_pFormatOfJustInsertedApo = nullptr; m_MergeGroups.clear(); } + + // since Word formats don't have table "keep with next paragraph" and "don't split table" settings, + // they were emulated in MSWordExportBase::OutputTextNode. Now we need to re-create those settings, reversing that logic. + // bKeep: if first paragraph of EVERY row is marked keep-with-next (implies bDontSplit). + bool bKeep = true; + // bDontSplit table: if first paragraph of every row EXCEPT the last one is kept. + bool bDontSplit = false; + sal_uInt32 nRow=0; + std::vector< SwTextNode* > vEmulatedNodes; + while( bKeep && nRow < pTabLines->size() ) + { + const SwTableLine* pIterTableRow = (*pTabLines)[ nRow ]; + const SwTableBoxes& rIterTableBoxes = pIterTableRow->GetTabBoxes(); + const SwTableBox* pIterFirstCell = rIterTableBoxes.empty() ? nullptr : rIterTableBoxes.front(); + // only for non-complex tables + if( pIterFirstCell && !pIterTableRow->GetUpper() ) + { + // check the first paragraph from each row + SwPaM aPam( *pIterFirstCell->GetSttNd(), 0 ); + aPam.GetPoint()->nNode++; + SwNode & rNode = aPam.GetPoint()->nNode.GetNode(); + SwTextNode* pFirstParagraphNode = nullptr; + if( rNode.IsTextNode() ) + pFirstParagraphNode = rNode.GetTextNode(); + + if( pFirstParagraphNode ) + { + if( !pFirstParagraphNode->GetSwAttrSet().GetKeep().GetValue() ) + bKeep = false; + // all rows except the last one have been kept + else if ( nRow == pTabLines->size() - 2 ) + bDontSplit = true; + + // save the node, so the paragraph's keep-with-next-paragraph setting can be removed later if it was added for the emulation + vEmulatedNodes.push_back( pFirstParagraphNode ); + } + } + ++nRow; + } + + if( bDontSplit || (bKeep && !vEmulatedNodes.empty()) ) + { + // clear the emulated row's paragraph property + while( !vEmulatedNodes.empty() ) + { + vEmulatedNodes.back()->ResetAttr( RES_KEEP ); + vEmulatedNodes.pop_back(); + } + + // Set the table properties + pTable->GetFrameFormat()->SetFormatAttr(SwFormatLayoutSplit( false )); + if( bKeep ) + pTable->GetFrameFormat()->SetFormatAttr(SvxFormatKeepItem( true, RES_KEEP )); + } } // browse m_MergeGroups, detect the index of the first fitting group or -1 otherwise |