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

Reply via email to