summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comphelper/source/misc/lok.cxx12
-rw-r--r--desktop/source/lib/init.cxx2
-rw-r--r--editeng/Library_editeng.mk1
-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.cxx13
-rw-r--r--sw/source/core/crsr/viscrs.cxx6
12 files changed, 173 insertions, 10 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 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);
}
}