sw/CppunitTest_sw_layoutwriter.mk | 4 sw/qa/extras/layout/data/redline_footnotes.odt |binary sw/qa/extras/layout/layout.cxx | 141 +++++++++++++++++++++++++ sw/source/core/text/txtfrm.cxx | 2 sw/source/core/txtnode/ndtxt.cxx | 5 5 files changed, 150 insertions(+), 2 deletions(-)
New commits: commit 63e3426cf4cee7ce1d292497cd660fc4d6f06709 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Mon Sep 24 10:08:40 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Mon Oct 1 10:38:02 2018 +0200 sw_redlinehide_2: add unit test with footnotes Change-Id: I19dd7862460373a9cee0f950dcc285c043cc608c Reviewed-on: https://gerrit.libreoffice.org/60934 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/CppunitTest_sw_layoutwriter.mk b/sw/CppunitTest_sw_layoutwriter.mk index b10f624259f4..37a142ec61ac 100644 --- a/sw/CppunitTest_sw_layoutwriter.mk +++ b/sw/CppunitTest_sw_layoutwriter.mk @@ -59,6 +59,10 @@ $(eval $(call gb_CppunitTest_use_vcl,sw_layoutwriter)) $(eval $(call gb_CppunitTest_use_rdb,sw_layoutwriter,services)) +$(eval $(call gb_CppunitTest_use_custom_headers,sw_layoutwriter,\ + officecfg/registry \ +)) + $(eval $(call gb_CppunitTest_use_configuration,sw_layoutwriter)) $(eval $(call gb_CppunitTest_use_uiconfigs,sw_layoutwriter, \ diff --git a/sw/qa/extras/layout/data/redline_footnotes.odt b/sw/qa/extras/layout/data/redline_footnotes.odt new file mode 100644 index 000000000000..383fc7273ee7 Binary files /dev/null and b/sw/qa/extras/layout/data/redline_footnotes.odt differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 99376832c634..0b5630361e49 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -11,6 +11,8 @@ #include <comphelper/propertysequence.hxx> #include <test/mtfxmldump.hxx> #include <com/sun/star/linguistic2/LinguServiceManager.hpp> +#include <com/sun/star/frame/DispatchHelper.hpp> +#include <officecfg/Office/Common.hxx> #include <comphelper/scopeguard.hxx> #include <unotools/syslocaleoptions.hxx> @@ -19,7 +21,10 @@ static char const DATA_DIRECTORY[] = "/sw/qa/extras/layout/data/"; /// Test to assert layout / rendering result of Writer. class SwLayoutWriter : public SwModelTestBase { + void CheckRedlineFootnotesHidden(); + public: + void testRedlineFootnotes(); void testTdf116830(); void testTdf116925(); void testTdf117028(); @@ -40,6 +45,7 @@ public: void testTdf119875(); CPPUNIT_TEST_SUITE(SwLayoutWriter); + CPPUNIT_TEST(testRedlineFootnotes); CPPUNIT_TEST(testTdf116830); CPPUNIT_TEST(testTdf116925); CPPUNIT_TEST(testTdf117028); @@ -73,6 +79,141 @@ SwDoc* SwLayoutWriter::createDoc(const char* pName) return pTextDoc->GetDocShell()->GetDoc(); } +static void lcl_dispatchCommand(const uno::Reference<lang::XComponent>& xComponent, + const OUString& rCommand, + const uno::Sequence<beans::PropertyValue>& rPropertyValues) +{ + uno::Reference<frame::XController> xController + = uno::Reference<frame::XModel>(xComponent, uno::UNO_QUERY)->getCurrentController(); + CPPUNIT_ASSERT(xController.is()); + uno::Reference<frame::XDispatchProvider> xFrame(xController->getFrame(), uno::UNO_QUERY); + CPPUNIT_ASSERT(xFrame.is()); + + uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext(); + uno::Reference<frame::XDispatchHelper> xDispatchHelper(frame::DispatchHelper::create(xContext)); + CPPUNIT_ASSERT(xDispatchHelper.is()); + + xDispatchHelper->executeDispatch(xFrame, rCommand, OUString(), 0, rPropertyValues); +} + +// this is a member because our test classes have protected members :( +void SwLayoutWriter::CheckRedlineFootnotesHidden() +{ + discardDumpedLayout(); + xmlDocPtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/merged", "paraPropsNodeIndex", "24"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[1]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[1]", "rText", "1"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "Portion", "foaz"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[2]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[2]", "rText", "5"); // TODO 2 + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/merged", "paraPropsNodeIndex", "13"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Special[1]", "rText", "1"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[1]", "Portion", "ac"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/merged", "paraPropsNodeIndex", "16"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Special[1]", "rText", "5"); // TODO 2 + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Text[1]", "Portion", "mo"); +} + +void SwLayoutWriter::testRedlineFootnotes() +{ + // currently need experimental mode + Resetter _([]() { + std::shared_ptr<comphelper::ConfigurationChanges> pBatch( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::Misc::ExperimentalMode::set(false, pBatch); + return pBatch->commit(); + }); + std::shared_ptr<comphelper::ConfigurationChanges> pBatch( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::Misc::ExperimentalMode::set(true, pBatch); + pBatch->commit(); + + createDoc("redline_footnotes.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc(pTextDoc->GetDocShell()->GetDoc()); + SwRootFrame* pLayout(pDoc->getIDocumentLayoutAccess().GetCurrentLayout()); + CPPUNIT_ASSERT(pLayout->IsHideRedlines()); + + // verify after load + CheckRedlineFootnotesHidden(); + + lcl_dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + CPPUNIT_ASSERT(!pLayout->IsHideRedlines()); + discardDumpedLayout(); + xmlDocPtr pXmlDoc = parseLayoutDump(); + + // show: nothing is merged + xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//merged"); + xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; + CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlNodes)); + xmlXPathFreeObject(pXmlObj); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[1]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[1]", "rText", "1"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "Portion", "fo"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[2]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[2]", "Portion", "o"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[2]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Special[2]", "rText", "2"); + + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Special[1]", "rText", "1"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[1]", "Portion", "a"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[2]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[2]", "Portion", "b"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[3]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[1]/txt[1]/Text[3]", "Portion", "c"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Special[1]", "rText", "2"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[2]/txt[1]/Text[1]", "Portion", "def"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[1]", "Portion", "b"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Special[1]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Special[1]", "rText", "3"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[2]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[2]", "Portion", "ar"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[3]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[3]/txt[1]/Special[1]", "rText", "3"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[3]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[3]/txt[1]/Text[1]", "Portion", "ghi"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Special[1]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Special[1]", "rText", "4"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[1]", "Portion", "b"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[2]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[2]", "Portion", "az"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Special[2]", "nType", "POR_FTN"); + assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Special[2]", "rText", "5"); + + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[4]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[4]/txt[1]/Special[1]", "rText", "4"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[4]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[4]/txt[1]/Text[1]", "Portion", "jkl"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Special[1]", "nType", "POR_FTNNUM"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Special[1]", "rText", "5"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[1]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[1]", "Portion", "m"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[2]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[2]", "Portion", "n"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[3]", "nType", "POR_TXT"); + assertXPath(pXmlDoc, "/root/page[1]/ftncont/ftn[5]/txt[1]/Text[3]", "Portion", "o"); + + // verify after hide + lcl_dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + CPPUNIT_ASSERT(pLayout->IsHideRedlines()); + discardDumpedLayout(); + CheckRedlineFootnotesHidden(); +} + void SwLayoutWriter::testTdf116830() { SwDoc* pDoc = createDoc("tdf116830.odt"); commit 1e79f6f01a8afc55a455b0c52fd5cf2b766e1e08 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Sep 21 17:07:30 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Mon Oct 1 10:37:48 2018 +0200 sw_redlinehide_2: more footnote assert problems If there are multiple footnotes in a node, the notifications that happen during Cut require that the text is still in the source node. 4 sw::MapModelToView(sw::MergedPara const&, SwTextNode const*, int) (rMerged=..., pNode=0x5975180, nIndex=5) at sw/source/core/text/txtfrm.cxx:1020 5 SwTextFrame::MapModelToView(SwTextNode const*, int) const (this=0x5a7b5f0, pNode=0x5975180, nIndex=5) at sw/source/core/text/txtfrm.cxx:1061 6 SwTextFrame::SwClientNotify(SwModify const&, SfxHint const&) (this=0x5a7b5f0, rModify=..., rHint=...) at sw/source/core/text/txtfrm.cxx:2092 ... 14 SwContentNode::ModifyNotification(SfxPoolItem const*, SfxPoolItem const*) (this=0x5975180, pOld=0x0, pNew=0x59b7300) at sw/inc/node.hxx:477 15 SwTextFootnote::SetNumber(unsigned short, rtl::OUString const&) (this=0x5967a90, nNewNum=2, sNumStr="") at sw/source/core/txtnode/atrftn.cxx:341 16 SwFootnoteIdxs::UpdateFootnote(SwNodeIndex const&) (this=0x58d3070, rStt=SwNodeIndex (node 29)) at sw/source/core/doc/ftnidx.cxx:154 17 SwTextNode::InsertHint(SwTextAttr*, SetAttrMode) (this=0x77f63e0, pAttr=0x59b6bd0, nMode=(SetAttrMode::DONTREPLACE | SetAttrMode::NOTXTATRCHR)) at sw/source/core/txtnode/thints.cxx:1461 18 SwTextNode::CutImpl(SwTextNode*, SwIndex const&, SwIndex const&, int, bool) (this=0x5975180, pDest=0x77f63e0, rDestStart=SwIndex (offset 0), rStart=SwIndex (offset 0), nLen=3, bUpdate=false) at sw/source/core/txtnode/ndtxt.cxx:2594 Change-Id: Id9863fa455207c6fab97f9561c6c390c15dd2ea6 Reviewed-on: https://gerrit.libreoffice.org/60933 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 02d3244e0118..86fa875516a4 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1703,7 +1703,7 @@ void UpdateMergedParaForMove(sw::MergedPara & rMerged, break; } } - if (nLastEnd != rNode.Len() + nLen) // add nLen, string was removed already + if (nLastEnd != rNode.Len()) // without nLen, string yet to be removed { assert(rNode.Len() == 0 || nLastEnd < nSourceEnd); if (nLastEnd < nSourceEnd) diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 514efdfc1c84..e0e6d4223840 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -2442,7 +2442,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, } pDest->m_Text = pDest->m_Text.replaceAt(nDestStart, 0, m_Text.copy(nTextStartIdx, nLen)); - m_Text = m_Text.replaceAt(nTextStartIdx, nLen, ""); + OUString const newText = m_Text.replaceAt(nTextStartIdx, nLen, ""); nLen = pDest->m_Text.getLength() - nInitSize; // update w/ current size! if (!nLen) // String didn't grow? return; @@ -2659,6 +2659,9 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart, Update( rStart, nLen, true, true ); } + // set after moving hints + m_Text = newText; + if (bMergePortionsNeeded) { m_pSwpHints->MergePortions(*this); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits