summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamás Zolnai <tamas.zolnai@collabora.com>2018-04-05 22:23:28 +0200
committerAron Budea <aron.budea@collabora.com>2018-04-20 11:25:01 +0200
commit19a2c9ca42bab45f1e4e258d1023b62557f8f1fe (patch)
treed99bfff7d826479dd3f6220601f2717c7cd9720e
parent2e396d37d96e1bc535da75cfc5f2afeac6b68d25 (diff)
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 <ci@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit 83b7bfc0efefb3c77e5c59553320e98539250c62) sw lok: followup commit for change about scrolling to visible cursor Revert small part of this commit: 83b7bfc0efefb3c77e5c59553320e98539250c62 Thanks Jan Holesovsky to catching it. Change-Id: I885c9f3da622052685d1e46f6358783fc7f8cb9a Reviewed-on: https://gerrit.libreoffice.org/52684 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit 508013d799358bb1c92b5cfea5257fe53c695cee) Reviewed-on: https://gerrit.libreoffice.org/53178 Reviewed-by: Aron Budea <aron.budea@collabora.com> Tested-by: Aron Budea <aron.budea@collabora.com>
-rw-r--r--comphelper/source/misc/lok.cxx12
-rw-r--r--desktop/source/lib/init.cxx2
-rw-r--r--editeng/source/editeng/impedit.cxx3
-rw-r--r--include/LibreOfficeKit/LibreOfficeKitEnums.h8
-rw-r--r--include/comphelper/lok.hxx6
-rw-r--r--include/sfx2/lokhelper.hxx2
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx17
-rw-r--r--sfx2/source/view/lokhelper.cxx16
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx97
-rw-r--r--sw/source/core/crsr/crsrsh.cxx2
-rw-r--r--sw/source/core/crsr/viscrs.cxx6
11 files changed, 163 insertions, 8 deletions
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 862022863885..5e00b5d09ea0 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3521,6 +3521,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/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index 884f6e99327b..8e5c8c71540f 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -43,6 +43,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;
@@ -1120,7 +1121,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 0c223463fdb8..767a0bb04366 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 b2307eb428a6..08424a90f770 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 const* 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 8fa945ae2db7..a48026a7b796 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1162,13 +1162,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;
@@ -2700,6 +2712,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 6fd6a7699038..e6fb475846a8 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>
@@ -199,6 +200,21 @@ void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, const OStri
pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, aBuf.makeStringAndClear().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 6232239d0758..b5c6a4b35161 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -106,6 +106,7 @@ public:
void testIMESupport();
void testSplitNodeRedlineCallback();
void testDeleteNodeRedlineCallback();
+ void testVisCursorInvalidation();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -159,6 +160,7 @@ public:
CPPUNIT_TEST(testIMESupport);
CPPUNIT_TEST(testSplitNodeRedlineCallback);
CPPUNIT_TEST(testDeleteNodeRedlineCallback);
+ CPPUNIT_TEST(testVisCursorInvalidation);
CPPUNIT_TEST_SUITE_END();
private:
@@ -671,6 +673,7 @@ class ViewCallback
{
public:
bool m_bOwnCursorInvalidated;
+ int m_nOwnCursorInvalidatedBy;
bool m_bOwnCursorAtOrigin;
tools::Rectangle m_aOwnCursor;
bool m_bViewCursorInvalidated;
@@ -692,6 +695,7 @@ public:
ViewCallback()
: m_bOwnCursorInvalidated(false),
+ m_nOwnCursorInvalidatedBy(-1),
m_bOwnCursorAtOrigin(false),
m_bViewCursorInvalidated(false),
m_bOwnSelectionSet(false),
@@ -725,7 +729,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());
@@ -2235,6 +2250,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 bffde7e0a90e..7f7e17a8a65a 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1554,7 +1554,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( eFlags & SwCursorShell::SCROLLWIN &&
(HasSelection() || eFlags & SwCursorShell::READONLY ||
!IsCursorReadonly()) )
{
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 5de324db4c85..7acfdcc4fdf4 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -214,13 +214,15 @@ void SwVisibleCursor::SetPosAndShow(SfxViewShell const * 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);
}
}