1dbb415
From 14a54bf2e11446b822cc32f610f13368aa7d5233 Mon Sep 17 00:00:00 2001
1dbb415
From: Michael Stahl <mstahl@redhat.com>
1dbb415
Date: Wed, 25 Jan 2017 16:42:16 +0100
1dbb415
Subject: [PATCH] sw: revert ToX hyperlinks to LO 4.3 behaviour
1dbb415
1dbb415
Commit 94b296d5416dd71d721ad16216b50bce79e3dc04 changed this to
1dbb415
potentially insert multiple overlapping hyperlink items.
1dbb415
1dbb415
Unfortunately Writer can only have one RES_TXTATR_INETFMT on any given
1dbb415
position in the paragraph, so the hyperlink hints inevitably overwrite
1dbb415
each other.
1dbb415
1dbb415
Revert this to do it the same way as the old code in LO 4.3 did: match
1dbb415
the last unmatched link-start with the first link-end, and ignore all
1dbb415
the link-start before the matching one, as well as the link-end after
1dbb415
the matching one.
1dbb415
1dbb415
This should prevent surprising formatting changes on index update,
1dbb415
including entries spontaneously turning green, and there is no reason
1dbb415
why the result of the new way is objectively better than the old one.
1dbb415
1dbb415
Change-Id: I55be9c212c473908428fa8bd6487d136343fe852
1dbb415
(cherry picked from commit 68f7be01a78a5bad56ddd94c04764131676d6cc0)
1dbb415
1dbb415
sw: stop swapping start and end position of links in ToX
1dbb415
1dbb415
This causes:
1dbb415
1dbb415
sw/source/core/txtnode/thints.cxx:3198: +SwpHints::Insert: invalid hint, end < start
1dbb415
1dbb415
Change-Id: I933c790127ab1469bb57c4d288dbb49be16ace19
1dbb415
(cherry picked from commit 4a43ffcef946067c5b3992a00c765a36804a194f)
1dbb415
---
1dbb415
 sw/inc/ToxLinkProcessor.hxx             |  9 +++++---
1dbb415
 sw/qa/core/test_ToxLinkProcessor.cxx    | 38 +++++++++++++++------------------
1dbb415
 sw/source/core/tox/ToxLinkProcessor.cxx | 18 ++++++++--------
1dbb415
 3 files changed, 32 insertions(+), 33 deletions(-)
1dbb415
1dbb415
diff --git a/sw/inc/ToxLinkProcessor.hxx b/sw/inc/ToxLinkProcessor.hxx
1dbb415
index 699c0ec..78bb7fb 100644
1dbb415
--- a/sw/inc/ToxLinkProcessor.hxx
1dbb415
+++ b/sw/inc/ToxLinkProcessor.hxx
1dbb415
@@ -69,8 +69,11 @@ private:
1dbb415
      * A link is closed if it has both a start and an end token.
1dbb415
      */
1dbb415
     struct ClosedLink {
1dbb415
-        ClosedLink(const OUString& url, sal_Int32 startPosition, sal_Int32 endPosition) :
1dbb415
-                mINetFormat(url, OUString()), mStartTextPos(endPosition), mEndTextPos(startPosition) {
1dbb415
+        ClosedLink(const OUString& url, sal_Int32 startPosition, sal_Int32 endPosition)
1dbb415
+            : mINetFormat(url, OUString())
1dbb415
+            , mStartTextPos(startPosition)
1dbb415
+            , mEndTextPos(endPosition)
1dbb415
+        {
1dbb415
         }
1dbb415
         SwFormatINetFormat mINetFormat;
1dbb415
         sal_Int32 mStartTextPos;
1dbb415
@@ -79,7 +82,7 @@ private:
1dbb415
 
1dbb415
     std::vector<std::unique_ptr<ClosedLink>> m_ClosedLinks;
1dbb415
 
1dbb415
-    std::vector<std::unique_ptr<StartedLink>> m_StartedLinks;
1dbb415
+    std::unique_ptr<StartedLink> m_pStartedLink;
1dbb415
 
1dbb415
     friend class ::ToxLinkProcessorTest;
1dbb415
 };
1dbb415
diff --git a/sw/qa/core/test_ToxLinkProcessor.cxx b/sw/qa/core/test_ToxLinkProcessor.cxx
1dbb415
index 0a15982..d2d4721 100644
1dbb415
--- a/sw/qa/core/test_ToxLinkProcessor.cxx
1dbb415
+++ b/sw/qa/core/test_ToxLinkProcessor.cxx
1dbb415
@@ -30,17 +30,15 @@ using namespace sw;
1dbb415
 class ToxLinkProcessorTest : public test::BootstrapFixture
1dbb415
 {
1dbb415
     void NoExceptionIsThrownIfTooManyLinksAreClosed();
1dbb415
-    void AddingAndClosingTwoLinksResultsInTwoClosedLinks();
1dbb415
+    void AddingAndClosingTwoOverlappingLinksResultsInOneClosedLink();
1dbb415
     void LinkIsCreatedCorrectly();
1dbb415
     void LinkSequenceIsPreserved();
1dbb415
-    void StandardOpenLinkIsAddedWhenMoreLinksThanAvaiableAreClosed();
1dbb415
 
1dbb415
     CPPUNIT_TEST_SUITE(ToxLinkProcessorTest);
1dbb415
     CPPUNIT_TEST(NoExceptionIsThrownIfTooManyLinksAreClosed);
1dbb415
-    CPPUNIT_TEST(AddingAndClosingTwoLinksResultsInTwoClosedLinks);
1dbb415
+    CPPUNIT_TEST(AddingAndClosingTwoOverlappingLinksResultsInOneClosedLink);
1dbb415
     CPPUNIT_TEST(LinkIsCreatedCorrectly);
1dbb415
     CPPUNIT_TEST(LinkSequenceIsPreserved);
1dbb415
-    CPPUNIT_TEST(StandardOpenLinkIsAddedWhenMoreLinksThanAvaiableAreClosed);
1dbb415
     CPPUNIT_TEST_SUITE_END();
1dbb415
 public:
1dbb415
     void setUp() override {
1dbb415
@@ -71,30 +69,28 @@ ToxLinkProcessorTest::NoExceptionIsThrownIfTooManyLinksAreClosed()
1dbb415
     sut.CloseLink(1, URL_1);
1dbb415
     // fdo#85872 actually it turns out the UI does something like this
1dbb415
     // so an exception must not be thrown!
1dbb415
-    sut.CloseLink(1, URL_1);
1dbb415
+    // should not succeed either (for backward compatibility)
1dbb415
+    sut.CloseLink(2, URL_1);
1dbb415
+    CPPUNIT_ASSERT_EQUAL(1u, static_cast<unsigned>(sut.m_ClosedLinks.size()));
1dbb415
+    CPPUNIT_ASSERT_EQUAL(1u, static_cast<unsigned>(sut.m_ClosedLinks.at(0)->mEndTextPos));
1dbb415
+    CPPUNIT_ASSERT_MESSAGE("no links are open", sut.m_pStartedLink == nullptr);
1dbb415
 }
1dbb415
 
1dbb415
 void
1dbb415
-ToxLinkProcessorTest::StandardOpenLinkIsAddedWhenMoreLinksThanAvaiableAreClosed()
1dbb415
-{
1dbb415
-    ToxLinkProcessor sut;
1dbb415
-    sut.StartNewLink(0, STYLE_NAME_1);
1dbb415
-    sut.CloseLink(1, URL_1);
1dbb415
-    sut.CloseLink(1, URL_1);
1dbb415
-    CPPUNIT_ASSERT_EQUAL(2u, static_cast<unsigned>(sut.m_ClosedLinks.size()));
1dbb415
-    CPPUNIT_ASSERT_EQUAL(0u, static_cast<unsigned>(sut.m_ClosedLinks.at(1)->mEndTextPos));
1dbb415
-}
1dbb415
-
1dbb415
-void
1dbb415
-ToxLinkProcessorTest::AddingAndClosingTwoLinksResultsInTwoClosedLinks()
1dbb415
+ToxLinkProcessorTest::AddingAndClosingTwoOverlappingLinksResultsInOneClosedLink()
1dbb415
 {
1dbb415
     ToxLinkProcessor sut;
1dbb415
     sut.StartNewLink(0, STYLE_NAME_1);
1dbb415
     sut.StartNewLink(0, STYLE_NAME_2);
1dbb415
     sut.CloseLink(1, URL_1);
1dbb415
+    // this should not cause an error, and should not succeed either
1dbb415
+    // (for backward compatibility)
1dbb415
     sut.CloseLink(1, URL_2);
1dbb415
-    CPPUNIT_ASSERT_EQUAL(2u, static_cast<unsigned>(sut.m_ClosedLinks.size()));
1dbb415
-    CPPUNIT_ASSERT_MESSAGE("no links are open", sut.m_StartedLinks.empty());
1dbb415
+    CPPUNIT_ASSERT_EQUAL(1u, static_cast<unsigned>(sut.m_ClosedLinks.size()));
1dbb415
+    CPPUNIT_ASSERT_MESSAGE("no links are open", sut.m_pStartedLink == nullptr);
1dbb415
+    // backward compatibility: the last start is closed by the first end
1dbb415
+    CPPUNIT_ASSERT_EQUAL(STYLE_NAME_2, sut.m_ClosedLinks[0]->mINetFormat.GetINetFormat());
1dbb415
+    CPPUNIT_ASSERT_EQUAL(URL_1, sut.m_ClosedLinks[0]->mINetFormat.GetValue());
1dbb415
 }
1dbb415
 
1dbb415
 class ToxLinkProcessorWithOverriddenObtainPoolId : public ToxLinkProcessor {
1dbb415
@@ -131,10 +127,10 @@ ToxLinkProcessorTest::LinkSequenceIsPreserved()
1dbb415
     // obtainpoolid needs to be overridden to check what we are
1dbb415
     ToxLinkProcessorWithOverriddenObtainPoolId sut;
1dbb415
 
1dbb415
-    sut.StartNewLink(0, STYLE_NAME_1);
1dbb415
     sut.StartNewLink(0, STYLE_NAME_2);
1dbb415
     sut.CloseLink(1, URL_2);
1dbb415
-    sut.CloseLink(1, URL_1);
1dbb415
+    sut.StartNewLink(1, STYLE_NAME_1);
1dbb415
+    sut.CloseLink(2, URL_1);
1dbb415
 
1dbb415
     // check first closed element
1dbb415
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Style is stored correctly in link",
1dbb415
diff --git a/sw/source/core/tox/ToxLinkProcessor.cxx b/sw/source/core/tox/ToxLinkProcessor.cxx
1dbb415
index 1ef40d2..f9fa4c1 100644
1dbb415
--- a/sw/source/core/tox/ToxLinkProcessor.cxx
1dbb415
+++ b/sw/source/core/tox/ToxLinkProcessor.cxx
1dbb415
@@ -21,19 +21,18 @@ namespace sw {
1dbb415
 void
1dbb415
 ToxLinkProcessor::StartNewLink(sal_Int32 startPosition, const OUString& characterStyle)
1dbb415
 {
1dbb415
-    m_StartedLinks.push_back(o3tl::make_unique<StartedLink>(
1dbb415
-                startPosition, characterStyle));
1dbb415
+    SAL_INFO_IF(m_pStartedLink, "sw.core", "ToxLinkProcessor: LS without LE");
1dbb415
+    m_pStartedLink = o3tl::make_unique<StartedLink>(
1dbb415
+                startPosition, characterStyle);
1dbb415
 }
1dbb415
 
1dbb415
 void
1dbb415
 ToxLinkProcessor::CloseLink(sal_Int32 endPosition, const OUString& url)
1dbb415
 {
1dbb415
-    StartedLink const startedLink( (m_StartedLinks.empty())
1dbb415
-        ? StartedLink(0, SW_RES(STR_POOLCHR_TOXJUMP))
1dbb415
-        : *m_StartedLinks.back() );
1dbb415
-    if (!m_StartedLinks.empty())
1dbb415
+    if (m_pStartedLink == nullptr)
1dbb415
     {
1dbb415
-        m_StartedLinks.pop_back();
1dbb415
+        SAL_INFO("sw.core", "ToxLinkProcessor: LE without LS");
1dbb415
+        return;
1dbb415
     }
1dbb415
 
1dbb415
     if (url.isEmpty()) {
1dbb415
@@ -41,14 +40,15 @@ ToxLinkProcessor::CloseLink(sal_Int32 endPosition, const OUString& url)
1dbb415
     }
1dbb415
 
1dbb415
     std::unique_ptr<ClosedLink> pClosedLink(
1dbb415
-            new ClosedLink(url, startedLink.mStartPosition, endPosition));
1dbb415
+            new ClosedLink(url, m_pStartedLink->mStartPosition, endPosition));
1dbb415
 
1dbb415
-    const OUString& characterStyle = startedLink.mCharacterStyle;
1dbb415
+    const OUString& characterStyle = m_pStartedLink->mCharacterStyle;
1dbb415
     sal_uInt16 poolId = ObtainPoolId(characterStyle);
1dbb415
     pClosedLink->mINetFormat.SetVisitedFormatAndId(characterStyle, poolId);
1dbb415
     pClosedLink->mINetFormat.SetINetFormatAndId(characterStyle, poolId);
1dbb415
 
1dbb415
     m_ClosedLinks.push_back(std::move(pClosedLink));
1dbb415
+    m_pStartedLink.reset();
1dbb415
 }
1dbb415
 
1dbb415
 sal_uInt16
1dbb415
-- 
1dbb415
2.9.3
1dbb415