comphelper/source/misc/lok.cxx                 |   12 +++
 desktop/source/lib/init.cxx                    |    2 
 editeng/Library_editeng.mk                     |    1 
 editeng/source/editeng/impedit.cxx             |    3 
 include/LibreOfficeKit/LibreOfficeKitEnums.h   |    8 +-
 include/comphelper/lok.hxx                     |    6 +
 include/sfx2/lokhelper.hxx                     |    2 
 libreofficekit/source/gtk/lokdocview.cxx       |   17 +++-
 sfx2/source/view/lokhelper.cxx                 |   16 ++++
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   97 ++++++++++++++++++++++++-
 sw/source/core/crsr/crsrsh.cxx                 |   13 ++-
 sw/source/core/crsr/viscrs.cxx                 |    6 +
 12 files changed, 173 insertions(+), 10 deletions(-)

New commits:
commit 715d76c61f5ae114df607e91cc4204b62530c8e4
Author: Tamás Zolnai <tamas.zol...@collabora.com>
Date:   Tue Apr 10 16:27:10 2018 +0200

    sw lok: View jumps to cursor position even if it is moved by an other view.
    
    Scrolling is done twice. Once in SwCursorShell::UpdateCursor() by
    SCROLLWIN flag. Here we can check the actual viewid and avoid scrolling
    if the cursor is move by an other user.
    The second instance in the LO online code, for it we need to pass the
    viewid identifying the view which moved the cursor.
    
    Change-Id: I033274f88ce41acbb632e2aeb0d986ab11cd2d52
    Reviewed-on: https://gerrit.libreoffice.org/52220
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/52675
    Reviewed-by: Jan Holesovsky <ke...@collabora.com>
    Tested-by: Jan Holesovsky <ke...@collabora.com>

diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx
index 589f57b61bce..05a991dad074 100644
--- a/comphelper/source/misc/lok.cxx
+++ b/comphelper/source/misc/lok.cxx
@@ -29,6 +29,8 @@ static bool g_bTiledAnnotations(true);
 
 static bool g_bRangeHeaders(false);
 
+static bool g_bViewIdForVisCursorInvalidation(false);
+
 static bool g_bLocalRendering(false);
 
 static LanguageTag g_aLanguageTag("en-US", true);
@@ -88,6 +90,16 @@ void setRangeHeaders(bool bRangeHeaders)
     g_bRangeHeaders = bRangeHeaders;
 }
 
+void setViewIdForVisCursorInvalidation(bool bViewIdForVisCursorInvalidation)
+{
+    g_bViewIdForVisCursorInvalidation = bViewIdForVisCursorInvalidation;
+}
+
+bool isViewIdForVisCursorInvalidation()
+{
+    return g_bViewIdForVisCursorInvalidation;
+}
+
 bool isRangeHeaders()
 {
     return g_bRangeHeaders;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index d8c229aef7c2..81700d548e26 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3448,6 +3448,8 @@ static void lo_setOptionalFeatures(LibreOfficeKit* pThis, 
unsigned long long con
         comphelper::LibreOfficeKit::setTiledAnnotations(false);
     if (features & LOK_FEATURE_RANGE_HEADERS)
         comphelper::LibreOfficeKit::setRangeHeaders(true);
+    if (features & LOK_FEATURE_VIEWID_IN_VISCURSOR_INVALIDATION_CALLBACK)
+        comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(true);
 }
 
 static void lo_setDocumentPassword(LibreOfficeKit* pThis,
diff --git a/editeng/Library_editeng.mk b/editeng/Library_editeng.mk
index c6c2fa06b666..88ba8557bb50 100644
--- a/editeng/Library_editeng.mk
+++ b/editeng/Library_editeng.mk
@@ -136,6 +136,7 @@ $(eval $(call gb_Library_use_libraries,editeng,\
     vcl \
     svl \
     sot \
+    sfx \
     utl \
     tl \
     comphelper \
diff --git a/editeng/source/editeng/impedit.cxx 
b/editeng/source/editeng/impedit.cxx
index 644317c4509a..845ac73a0f18 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -49,6 +49,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/string.hxx>
 #include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -1071,7 +1072,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
             }
             else
             {
-                
mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, 
sRect.getStr());
+                SfxLokHelper::notifyVisCursorInvalidation(mpViewShell, sRect);
                 
mpViewShell->NotifyOtherViews(LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", 
sRect);
             }
         }
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index d1ac3b3d40db..bec5d0d7eca8 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -84,7 +84,13 @@ typedef enum
     /**
      * Enable range based header data
      */
-    LOK_FEATURE_RANGE_HEADERS = (1ULL << 4)
+    LOK_FEATURE_RANGE_HEADERS = (1ULL << 4),
+
+    /**
+     * Request to have the active view's Id as the 1st value in the
+     * LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR payload.
+     */
+    LOK_FEATURE_VIEWID_IN_VISCURSOR_INVALIDATION_CALLBACK = (1ULL << 5)
 }
 LibreOfficeKitOptionalFeatures;
 
diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx
index 9759bb524541..e0bd65690261 100644
--- a/include/comphelper/lok.hxx
+++ b/include/comphelper/lok.hxx
@@ -67,6 +67,12 @@ COMPHELPER_DLLPUBLIC void setRangeHeaders(bool 
bTiledAnnotations);
 /// Check if range based header data is enabled
 COMPHELPER_DLLPUBLIC bool isRangeHeaders();
 
+
+/// Check whether clients want viewId in visible cursor invalidation payload.
+COMPHELPER_DLLPUBLIC bool isViewIdForVisCursorInvalidation();
+/// Set whether clients want viewId in visible cursor invalidation payload.
+COMPHELPER_DLLPUBLIC void setViewIdForVisCursorInvalidation(bool 
bViewIdForVisCursorInvalidation);
+
 /// Update the current LOK's language.
 COMPHELPER_DLLPUBLIC void setLanguageTag(const LanguageTag& languageTag);
 /// Get the current LOK's language.
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 22630dd9cb5b..ddad7d91472f 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -50,6 +50,8 @@ public:
                              const std::vector<vcl::LOKPayloadItem>& rPayload 
= std::vector<vcl::LOKPayloadItem>());
     /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to 
setOptionalFeatures() if needed.
     static void notifyInvalidation(SfxViewShell* pThisView, const OString& 
rPayload);
+    /// Emits a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, but tweaks it 
according to setOptionalFeatures() if needed.
+    static void notifyVisCursorInvalidation(OutlinerViewShell const* 
pThisView, const OString& rRectangle);
     /// Notifies all views with the given type and payload.
     static void notifyAllViews(int nType, const OString& rPayload);
     /// A special value to signify 'infinity'.
diff --git a/libreofficekit/source/gtk/lokdocview.cxx 
b/libreofficekit/source/gtk/lokdocview.cxx
index 714d937772d2..b4eec4bcf32b 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1160,13 +1160,25 @@ callback (gpointer pData)
     break;
     case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
     {
-        priv->m_aVisibleCursor = payloadToRectangle(pDocView, 
pCallback->m_aPayload.c_str());
+
+        std::stringstream aStream(pCallback->m_aPayload);
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+        const std::string& rRectangle = aTree.get<std::string>("rectangle");
+        int nViewId = aTree.get<int>("viewId");
+
+        priv->m_aVisibleCursor = payloadToRectangle(pDocView, 
rRectangle.c_str());
         priv->m_bCursorOverlayVisible = true;
-        g_signal_emit(pDocView, doc_view_signals[CURSOR_CHANGED], 0,
+        std::cerr << nViewId;
+        std::cerr << priv->m_nViewId;
+        if(nViewId == priv->m_nViewId)
+        {
+            g_signal_emit(pDocView, doc_view_signals[CURSOR_CHANGED], 0,
                       priv->m_aVisibleCursor.x,
                       priv->m_aVisibleCursor.y,
                       priv->m_aVisibleCursor.width,
                       priv->m_aVisibleCursor.height);
+        }
         gtk_widget_queue_draw(GTK_WIDGET(pDocView));
     }
     break;
@@ -2675,6 +2687,7 @@ static gboolean lok_doc_view_initable_init (GInitable 
*initable, GCancellable* /
         return FALSE;
     }
     priv->m_nLOKFeatures |= LOK_FEATURE_PART_IN_INVALIDATION_CALLBACK;
+    priv->m_nLOKFeatures |= 
LOK_FEATURE_VIEWID_IN_VISCURSOR_INVALIDATION_CALLBACK;
     priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, 
priv->m_nLOKFeatures);
 
     return TRUE;
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 740587ef7c82..e74c4a238e20 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -17,6 +17,7 @@
 #include <sfx2/viewfrm.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
+#include <editeng/outliner.hxx>
 
 #include <shellimpl.hxx>
 
@@ -185,6 +186,21 @@ void SfxLokHelper::notifyInvalidation(SfxViewShell* 
pThisView, const OString& rP
     pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, 
aPayload.getStr());
 }
 
+void SfxLokHelper::notifyVisCursorInvalidation(OutlinerViewShell const* 
pThisView, const OString& rRectangle)
+{
+    OString sPayload;
+    if (comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
+    {
+        sPayload = OString("{ \"viewId\": \"") + 
OString::number(SfxLokHelper::getView()) +
+            "\", \"rectangle\": \"" + rRectangle + "\" }";
+    }
+    else
+    {
+        sPayload = rRectangle;
+    }
+    
pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, 
sPayload.getStr());
+}
+
 void SfxLokHelper::notifyAllViews(int nType, const OString& rPayload)
 {
     const auto payload = rPayload.getStr();
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 37a4d0a1ee9c..cc660f268ad0 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -99,6 +99,7 @@ public:
     void testIMESupport();
     void testSplitNodeRedlineCallback();
     void testDeleteNodeRedlineCallback();
+    void testVisCursorInvalidation();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -152,6 +153,7 @@ public:
     CPPUNIT_TEST(testIMESupport);
     CPPUNIT_TEST(testSplitNodeRedlineCallback);
     CPPUNIT_TEST(testDeleteNodeRedlineCallback);
+    CPPUNIT_TEST(testVisCursorInvalidation);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -664,6 +666,7 @@ class ViewCallback
 {
 public:
     bool m_bOwnCursorInvalidated;
+    int m_nOwnCursorInvalidatedBy;
     bool m_bOwnCursorAtOrigin;
     Rectangle m_aOwnCursor;
     bool m_bViewCursorInvalidated;
@@ -685,6 +688,7 @@ public:
 
     ViewCallback()
         : m_bOwnCursorInvalidated(false),
+          m_nOwnCursorInvalidatedBy(-1),
           m_bOwnCursorAtOrigin(false),
           m_bViewCursorInvalidated(false),
           m_bOwnSelectionSet(false),
@@ -718,7 +722,18 @@ public:
         {
             m_bOwnCursorInvalidated = true;
 
-            uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(OUString::fromUtf8(aPayload));
+            OString sRect;
+            if(comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
+            {
+                std::stringstream aStream(pPayload);
+                boost::property_tree::ptree aTree;
+                boost::property_tree::read_json(aStream, aTree);
+                sRect = 
aTree.get_child("rectangle").get_value<std::string>().c_str();
+                m_nOwnCursorInvalidatedBy = 
aTree.get_child("viewId").get_value<int>();
+            }
+            else
+                sRect = aPayload;
+            uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(OUString::fromUtf8(sRect));
             if (OString("EMPTY") == pPayload)
                 return;
             CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), aSeq.getLength());
@@ -2169,6 +2184,86 @@ void 
SwTiledRenderingTest::testDeleteNodeRedlineCallback()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+
+void SwTiledRenderingTest::testVisCursorInvalidation()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+    ViewCallback aView1;
+    
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback,
 &aView1);
+    int nView1 = SfxLokHelper::getView();
+
+    SfxLokHelper::createView();
+    int nView2 = SfxLokHelper::getView();
+    ViewCallback aView2;
+    
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback,
 &aView2);
+    Scheduler::ProcessEventsToIdle();
+
+
+    // Move visible cursor in the first view
+    SfxLokHelper::setView(nView1);
+    Scheduler::ProcessEventsToIdle();
+
+    aView1.m_bOwnCursorInvalidated = false;
+    aView1.m_bViewCursorInvalidated = false;
+    aView2.m_bOwnCursorInvalidated = false;
+    aView2.m_bViewCursorInvalidated = false;
+
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RIGHT);
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT(!aView1.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(aView1.m_bOwnCursorInvalidated);
+    CPPUNIT_ASSERT(aView2.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(!aView2.m_bOwnCursorInvalidated);
+
+    // Insert text in the second view which moves the other view's cursor too
+    SfxLokHelper::setView(nView2);
+
+    aView1.m_bOwnCursorInvalidated = false;
+    aView1.m_bViewCursorInvalidated = false;
+    aView2.m_bOwnCursorInvalidated = false;
+    aView2.m_bViewCursorInvalidated = false;
+
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT(aView1.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(aView1.m_bOwnCursorInvalidated);
+    CPPUNIT_ASSERT(aView2.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(aView2.m_bOwnCursorInvalidated);
+
+    // Do the same as before, but set the related compatibility flag first
+    SfxLokHelper::setView(nView2);
+
+    comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(true);
+
+    aView1.m_bOwnCursorInvalidated = false;
+    aView1.m_bViewCursorInvalidated = false;
+    aView2.m_bOwnCursorInvalidated = false;
+    aView2.m_bViewCursorInvalidated = false;
+
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT(aView1.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(aView1.m_bOwnCursorInvalidated);
+    CPPUNIT_ASSERT_EQUAL(nView2, aView1.m_nOwnCursorInvalidatedBy);
+    CPPUNIT_ASSERT(aView2.m_bViewCursorInvalidated);
+    CPPUNIT_ASSERT(aView2.m_bOwnCursorInvalidated);
+    CPPUNIT_ASSERT_EQUAL(nView2, aView2.m_nOwnCursorInvalidatedBy);
+
+    comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(false);
+
+    mxComponent->dispose();
+    mxComponent.clear();
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index e7f211c3d7ac..02439fbb437c 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1428,6 +1428,13 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, 
bool bIdleEnd )
     SET_CURR_SHELL( this );
     ClearUpCursors();
 
+    bool bScrollWin = eFlags & SwCursorShell::SCROLLWIN;
+    // Don't scroll to the cursor if it's moved by an other view
+    if(comphelper::LibreOfficeKit::isActive() && bScrollWin)
+    {
+        bScrollWin = SfxLokHelper::getView() != 
SfxLokHelper::getView(GetSfxViewShell());
+    }
+
     // In a BasicAction the cursor must be updated, e.g. to create the
     // TableCursor. EndAction now calls UpdateCursor!
     if( ActionPend() && BasicActionPend() )
@@ -1570,7 +1577,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool 
bIdleEnd )
 
             m_pVisibleCursor->Hide(); // always hide visible Cursor
             // scroll Cursor to visible area
-            if( (eFlags & SwCursorShell::SCROLLWIN) &&
+            if( bScrollWin &&
                 (HasSelection() || eFlags & SwCursorShell::READONLY ||
                  !IsCursorReadonly()) )
             {
@@ -1825,7 +1832,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool 
bIdleEnd )
         }
 
         // scroll Cursor to visible area
-        if( m_bHasFocus && eFlags & SwCursorShell::SCROLLWIN &&
+        if( m_bHasFocus && bScrollWin&&
             (HasSelection() || eFlags & SwCursorShell::READONLY ||
              !IsCursorReadonly() || GetViewOptions()->IsSelectionInReadonly()) 
)
         {
@@ -1837,7 +1844,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool 
bIdleEnd )
             m_bSVCursorVis = bSav;
         }
 
-    } while( eFlags & SwCursorShell::SCROLLWIN );
+    } while( bScrollWin );
 
     if( m_pBlockCursor )
         RefreshBlockCursor();
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 696ddc26213d..8a09b2039023 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -214,13 +214,15 @@ void SwVisibleCursor::SetPosAndShow(SfxViewShell* 
pViewShell)
         if (pViewShell)
         {
             if (pViewShell == m_pCursorShell->GetSfxViewShell())
-                
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, 
sRect.getStr());
+            {
+                SfxLokHelper::notifyVisCursorInvalidation(pViewShell, sRect);
+            }
             else
                 
SfxLokHelper::notifyOtherView(m_pCursorShell->GetSfxViewShell(), pViewShell, 
LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect);
         }
         else
         {
-            
m_pCursorShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
 sRect.getStr());
+            
SfxLokHelper::notifyVisCursorInvalidation(m_pCursorShell->GetSfxViewShell(), 
sRect);
             SfxLokHelper::notifyOtherViews(m_pCursorShell->GetSfxViewShell(), 
LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect);
         }
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to