sc/inc/global.hxx                            |    2 -
 sc/qa/unit/tiledrendering/tiledrendering.cxx |   30 +++++++++++++++++++++++++++
 sc/source/core/data/global.cxx               |   11 +++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

New commits:
commit e0f3c1bdbcaad359a8df1cbabd7b6c497d9d1818
Author:     Miklos Vajna <[email protected]>
AuthorDate: Tue Dec 19 15:30:27 2023 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Wed Dec 20 11:11:56 2023 +0100

    cool#7853 sc lok: fix bad view id on hyperlink click
    
    The document had 2 windows. The first window was typing in column A, the
    second window ctrl-clicked on a hyperlink in column B. The LOK callback
    was emitted in window 1, not in window 2, which is unexpected.
    
    What happens is that ScGlobal::OpenURL() dispatched an async command
    when window 2 was active, and we happened to be in window 1 when
    processing that user event from the main loop.
    
    Fix the problem by dispatching the URL open command in a synchronous
    way, so the LOK view can't be different.
    
    An alternative would be to track the current LOK view id for posted user
    events, and set the view back to the one which was current at post-time
    before executing the event. We can consider doing that in a follow-up
    change, but this fixes the problem at hand and is a safe fix.
    
    (cherry picked from commit e83309d97d0bbad131a7fdfd365fb6122d6f415b)
    
    Conflicts:
            sc/qa/unit/tiledrendering/tiledrendering.cxx
    
    Change-Id: I9a3c9fc1b90ad538d8b2510c7844549c9881ca56
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161047
    Reviewed-by: Michael Meeks <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 1e42e6060d0e..6b4451397203 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -574,7 +574,7 @@ public:
      * Open the specified URL.
      * @param bIgnoreSettings - If true, ignore security settings (Ctrl-Click) 
and just open the URL.
      */
-    static void OpenURL(const OUString& rURL, const OUString& rTarget, bool 
bIgnoreSettings = false);
+    SC_DLLPUBLIC static void OpenURL(const OUString& rURL, const OUString& 
rTarget, bool bIgnoreSettings = false);
     /// Whether the URL can be opened according to current security options 
(Click/Ctrl-Click)
     static bool                 ShouldOpenURL();
     SC_DLLPUBLIC static OUString            GetAbsDocName( const OUString& 
rFileName,
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 7d89cb787c85..0f962c5fabdb 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -156,6 +156,7 @@ public:
     void testUndoReorderingMulti();
     void testGetViewRenderState();
     void testInvalidateOnTextEditWithDifferentZoomLevels(const ColRowZoom& 
rData);
+    void testOpenURL();
 
     CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
     CPPUNIT_TEST(testRowColumnHeaders);
@@ -225,6 +226,7 @@ public:
                                    // zoom level 40%
                                    {0, 999, -5}, {99, 0, -5}
                                });
+    CPPUNIT_TEST(testOpenURL);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -618,6 +620,7 @@ public:
     TextSelectionMessage m_aTextSelectionResult;
     OString m_sInvalidateHeader;
     OString m_sInvalidateSheetGeometry;
+    OString m_aHyperlinkClicked;
     OString m_ShapeSelection;
     TestLokCallbackWrapper m_callbackWrapper;
 
@@ -754,6 +757,11 @@ public:
             m_aInvalidateCursorResult.parseMessage(pPayload);
         }
         break;
+        case LOK_CALLBACK_HYPERLINK_CLICKED:
+        {
+            m_aHyperlinkClicked = pPayload;
+        }
+        break;
         case LOK_CALLBACK_TEXT_SELECTION:
         {
             m_aTextSelectionResult.parseMessage(pPayload);
@@ -3401,6 +3409,28 @@ void 
ScTiledRenderingTest::testInvalidateOnTextEditWithDifferentZoomLevels(const
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Invalidation rectangle is wrong.", 
aInvRect1, aInvRect2);
 }
 
+void ScTiledRenderingTest::testOpenURL()
+{
+    // Given a document that has 2 views:
+    createDoc("empty.ods");
+    int nView1 = SfxLokHelper::getView();
+    ViewCallback aView1;
+    SfxLokHelper::createView();
+    ViewCallback aView2;
+
+    // When clicking on a link in view 2, but switching to view 1 before 
processing async events:
+    ScGlobal::OpenURL(/*aUrl=*/u"http://www.example.com/";, /*aTarget=*/u"",
+                      /*bIgnoreSettings=*/true);
+    SfxLokHelper::setView(nView1);
+    Scheduler::ProcessEventsToIdle();
+
+    // Then make sure view 2 gets the callback, not view 1:
+    // Without the accompanying fix in place, this test would have failed, 
view 1 got the hyperlink
+    // callback.
+    CPPUNIT_ASSERT(aView1.m_aHyperlinkClicked.isEmpty());
+    CPPUNIT_ASSERT(!aView2.m_aHyperlinkClicked.isEmpty());
+}
+
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
index f8d268ae843e..7dbc458e2059 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -870,8 +870,17 @@ void ScGlobal::OpenURL(const OUString& rURL, const 
OUString& rTarget, bool bIgno
     SfxBoolItem aBrowsing( SID_BROWSE, true );
 
     // No SID_SILENT anymore
+    SfxCallMode nCall = SfxCallMode::RECORD;
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        nCall |= SfxCallMode::SYNCHRON;
+    }
+    else
+    {
+        nCall |= SfxCallMode::ASYNCHRON;
+    }
     pViewFrm->GetDispatcher()->ExecuteList(SID_OPENDOC,
-            SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
+            nCall,
             { &aUrl, &aTarget, &aFrm, &aReferer, &aNewView, &aBrowsing });
 }
 

Reply via email to