From 378f8ffee21ce20b5bb44b81ce76b4ff834fc49d Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 13 Feb 2015 13:47:30 +0100 Subject: cp#1000115 SwTxtFrm: don't join follow just because it has no content The problem was that the bugdoc had a table, and inside the table there was a long paragraph that flows to the next page, but only the paragraph mark of it does so. We first split the frame to have space for the paragraph mark, but later decided that all the content would fit the first frame, and this way the last hard line break and the paragraph mark was painted on each other. This is normally not a problem without tables, because SwTxtFrm::FormatAdjust() just calls SplitFrm(), sets its nNew flag to non-zero make sure that later SwTxtFrm::_AdjustFollow() doesn't try to join it, and we're ready. However, when the paragraph is inside a table, then the paragraph was formatted multiple times, and next time when we already had a follow nNew was not set, so even if there was a correct split first, the new frame was joined later. Fix the problem by explicitly setting nNew for the "in a table and paragraph ends with a hard line break" case, that way we don't blindly join the frame, only in case there is enough space for the follow in the master. (cherry picked from commit 7e33cce05b2df3f1761bcc66606c4d3b2b2671e9) Conflicts: sw/CppunitTest_sw_uiwriter.mk sw/qa/extras/uiwriter/uiwriter.cxx Change-Id: Iede654740dcb0d8aa768d742ee330208291a383a --- sw/CppunitTest_sw_uiwriter.mk | 33 +---- sw/qa/extras/inc/swmodeltestbase.hxx | 9 ++ sw/qa/extras/uiwriter/data/cp1000115.fodt | 208 ++++++++++++++++++++++++++++++ sw/qa/extras/uiwriter/uiwriter.cxx | 13 ++ sw/source/core/text/frmform.cxx | 8 ++ 5 files changed, 239 insertions(+), 32 deletions(-) create mode 100644 sw/qa/extras/uiwriter/data/cp1000115.fodt diff --git a/sw/CppunitTest_sw_uiwriter.mk b/sw/CppunitTest_sw_uiwriter.mk index 0f29e7e02e25..ec43e5b7f366 100644 --- a/sw/CppunitTest_sw_uiwriter.mk +++ b/sw/CppunitTest_sw_uiwriter.mk @@ -52,38 +52,7 @@ $(eval $(call gb_CppunitTest_use_api,sw_uiwriter,\ $(eval $(call gb_CppunitTest_use_ure,sw_uiwriter)) -$(eval $(call gb_CppunitTest_use_components,sw_uiwriter,\ - basic/util/sb \ - comphelper/util/comphelp \ - configmgr/source/configmgr \ - embeddedobj/util/embobj \ - filter/source/config/cache/filterconfig1 \ - filter/source/storagefilterdetect/storagefd \ - framework/util/fwk \ - i18npool/util/i18npool \ - linguistic/source/lng \ - package/util/package2 \ - package/source/xstor/xstor \ - sw/util/msword \ - sw/util/sw \ - sw/util/swd \ - sax/source/expatwrap/expwrap \ - sfx2/util/sfx \ - svl/source/fsstor/fsstorage \ - svtools/util/svt \ - toolkit/util/tk \ - ucb/source/core/ucb1 \ - ucb/source/ucp/file/ucpfile1 \ - unotools/util/utl \ - unoxml/source/service/unoxml \ - uui/util/uui \ - $(if $(filter-out MACOSX WNT,$(OS)), \ - vcl/vcl.unx \ - ) \ - $(if $(filter DESKTOP,$(BUILD_TYPE)),xmlhelp/util/ucpchelp1) \ - writerfilter/util/writerfilter \ - xmloff/util/xo \ -)) +$(eval $(call gb_CppunitTest_use_rdb,sw_uiwriter,services)) $(eval $(call gb_CppunitTest_use_configuration,sw_uiwriter)) diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index da802cff0216..0654220e1ad5 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -328,6 +328,15 @@ protected: return xAutoStyleFamily; } + /// Similar to parseExport(), but this gives the xmlDocPtr of the layout dump. + xmlDocPtr parseLayoutDump() + { + if (!mpXmlBuffer) + dumpLayout(); + + return xmlParseMemory((const char*)xmlBufferContent(mpXmlBuffer), xmlBufferLength(mpXmlBuffer));; + } + /** * Extract a value from the layout dump using an XPath expression and an attribute name. * diff --git a/sw/qa/extras/uiwriter/data/cp1000115.fodt b/sw/qa/extras/uiwriter/data/cp1000115.fodt new file mode 100644 index 000000000000..55227ff56e1e --- /dev/null +++ b/sw/qa/extras/uiwriter/data/cp1000115.fodt @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Start. + + + + + + + + First table. + + + + + + + one point one + two point one + + + + + + + + 2nd + + + + + + + + + + + + + End. + + + + + + + diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 53f967a8d875..e407f9af589b 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -38,6 +38,7 @@ public: void testFdo74981(); void testCp1000071(); void testCommentedWord(); + void testCp1000115(); CPPUNIT_TEST_SUITE(SwUiWriterTest); CPPUNIT_TEST(testReplaceForward); @@ -51,6 +52,7 @@ public: CPPUNIT_TEST(testFdo74981); CPPUNIT_TEST(testCp1000071); CPPUNIT_TEST(testCommentedWord); + CPPUNIT_TEST(testCp1000115); CPPUNIT_TEST_SUITE_END(); private: @@ -321,6 +323,17 @@ void SwUiWriterTest::testCommentedWord() CPPUNIT_ASSERT_EQUAL(OUString("word"), xField->getAnchor()->getString()); } +void SwUiWriterTest::testCp1000115() +{ + createDoc("cp1000115.fodt"); + xmlDocPtr pXmlDoc = parseLayoutDump(); + xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt"); + // This was 1: the long paragraph in the B1 cell did flow over to the + // second page, so there was only one paragraph in the second cell of the + // second page. + CPPUNIT_ASSERT_EQUAL(2, xmlXPathNodeSetGetLength(pXmlNodes)); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 3699c3907f43..11d9e18d321d 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -1053,6 +1053,14 @@ void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine, { nNew |= 3; } + else if (FindTabFrm() && nEnd > 0 && rLine.GetInfo().GetChar(nEnd - 1) == CH_BREAK) + { + // We are in a table, the paragraph has a follow and the text + // ends with a hard line break. Don't join the follow just + // because the follow would have no content, we may still need it + // for the paragraph mark. + nNew |= 1; + } CHG_OFFSET( GetFollow(), nEnd ) GetFollow()->ManipOfst( nEnd ); } -- cgit v1.2.3