summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/lib/init.cxx3
-rw-r--r--include/LibreOfficeKit/LibreOfficeKitEnums.h16
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx21
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx43
-rw-r--r--sw/source/core/crsr/crsrsh.cxx9
5 files changed, 88 insertions, 4 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index ae92ce78777a..f25c861d4f2c 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -455,6 +455,7 @@ CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, Li
m_states.emplace(LOK_CALLBACK_CELL_VIEW_CURSOR, "NIL");
m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL");
m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
+ m_states.emplace(LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "NIL");
m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
Start();
@@ -498,6 +499,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
type != LOK_CALLBACK_INVALIDATE_TILES &&
type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
type != LOK_CALLBACK_CURSOR_VISIBLE &&
+ type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
type != LOK_CALLBACK_TEXT_SELECTION)
{
//SAL_WARN("lokevt", "Skipping while painting [" + std::to_string(type) + "]: [" + payload + "].");
@@ -559,6 +561,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
case LOK_CALLBACK_CELL_VIEW_CURSOR:
case LOK_CALLBACK_CELL_FORMULA:
case LOK_CALLBACK_CURSOR_VISIBLE:
+ case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
case LOK_CALLBACK_SET_PART:
case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
removeAllButLast(type, false);
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index d8e46dbddfd3..63abda8ecebd 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -374,6 +374,22 @@ typedef enum
*/
LOK_CALLBACK_GRAPHIC_VIEW_SELECTION,
+ /**
+ * The blinking text cursor in one of the other views is now visible or
+ * not.
+ *
+ * The payload format:
+ *
+ * {
+ * "viewId": "..."
+ * "visible": "..."
+ * }
+ *
+ * - viewId is a value returned earlier by lok::Document::createView()
+ * - visible uses the format of LOK_CALLBACK_CURSOR_VISIBLE.
+ */
+ LOK_CALLBACK_VIEW_CURSOR_VISIBLE,
+
}
LibreOfficeKitCallbackType;
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 8bf889ff9f79..667b4d4feb98 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -83,6 +83,9 @@ struct LOKDocViewPrivateImpl
gboolean m_bCursorOverlayVisible;
/// Cursor is visible or hidden (e.g. for graphic selection).
gboolean m_bCursorVisible;
+ /// Visibility of view selections. The current view can only see / them,
+ /// can't modify them. Key is the view id.
+ std::map<int, bool> m_aViewCursorVisibilities;
/// Time of the last button press.
guint32 m_nLastButtonPressTime;
/// Time of the last button release.
@@ -324,6 +327,8 @@ callbackTypeToString (int nType)
return "LOK_CALLBACK_TEXT_SELECTION_END";
case LOK_CALLBACK_CURSOR_VISIBLE:
return "LOK_CALLBACK_CURSOR_VISIBLE";
+ case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
+ return "LOK_CALLBACK_VIEW_CURSOR_VISIBLE";
case LOK_CALLBACK_GRAPHIC_SELECTION:
return "LOK_CALLBACK_GRAPHIC_SELECTION";
case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
@@ -1222,6 +1227,18 @@ callback (gpointer pData)
gtk_widget_queue_draw(GTK_WIDGET(pDocView));
break;
}
+ case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
+ {
+ std::stringstream aStream(pCallback->m_aPayload);
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aStream, aTree);
+ int nViewId = aTree.get<int>("viewId");
+ const std::string& rVisible = aTree.get<std::string>("visible");
+ priv->m_aViewCursorVisibilities[nViewId] = rVisible == "true";
+ gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+ break;
+ }
+ break;
case LOK_CALLBACK_CELL_VIEW_CURSOR:
{
std::stringstream aStream(pCallback->m_aPayload);
@@ -1523,6 +1540,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
{
for (auto& rPair : priv->m_aViewCursors)
{
+ auto itVisibility = priv->m_aViewCursorVisibilities.find(rPair.first);
+ if (itVisibility != priv->m_aViewCursorVisibilities.end() && !itVisibility->second)
+ continue;
+
GdkRectangle& rCursor = rPair.second;
if (rCursor.width < 30)
// Set a minimal width if it would be 0.
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 7709df87b1f4..476b6d618066 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -53,6 +53,7 @@ public:
void testPartHash();
void testViewCursors();
void testMissingInvalidation();
+ void testViewCursorVisibility();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -73,6 +74,7 @@ public:
CPPUNIT_TEST(testPartHash);
CPPUNIT_TEST(testViewCursors);
CPPUNIT_TEST(testMissingInvalidation);
+ CPPUNIT_TEST(testViewCursorVisibility);
CPPUNIT_TEST_SUITE_END();
private:
@@ -553,13 +555,15 @@ public:
bool m_bOwnSelectionSet;
bool m_bViewSelectionSet;
bool m_bTilesInvalidated;
+ bool m_bViewCursorVisible;
ViewCallback()
: m_bOwnCursorInvalidated(false),
m_bViewCursorInvalidated(false),
m_bOwnSelectionSet(false),
m_bViewSelectionSet(false),
- m_bTilesInvalidated(false)
+ m_bTilesInvalidated(false),
+ m_bViewCursorVisible(false)
{
}
@@ -568,7 +572,7 @@ public:
static_cast<ViewCallback*>(pData)->callbackImpl(nType, pPayload);
}
- void callbackImpl(int nType, const char* /*pPayload*/)
+ void callbackImpl(int nType, const char* pPayload)
{
switch (nType)
{
@@ -597,6 +601,11 @@ public:
m_bViewSelectionSet = true;
}
break;
+ case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
+ {
+ m_bViewCursorVisible = OString("true") == pPayload;
+ }
+ break;
}
}
};
@@ -680,6 +689,36 @@ void SwTiledRenderingTest::testViewCursors()
comphelper::LibreOfficeKit::setActive(false);
}
+void SwTiledRenderingTest::testViewCursorVisibility()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ // Load a document that has a shape and create two views.
+ SwXTextDocument* pXTextDocument = createDoc("shape.fodt");
+ ViewCallback aView1;
+ SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1);
+ SfxLokHelper::createView();
+ pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+ ViewCallback aView2;
+ SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2);
+
+ // Click on the shape in the second view.
+ aView1.m_bViewCursorVisible = true;
+ SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+ SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
+ SdrObject* pObject = pPage->GetObj(0);
+ Point aCenter = pObject->GetSnapRect().Center();
+ pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aCenter.getX(), aCenter.getY(), 1);
+ pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aCenter.getX(), aCenter.getY(), 1);
+ Scheduler::ProcessEventsToIdle();
+ // Make sure the "view/text" cursor of the first view gets a notification.
+ CPPUNIT_ASSERT(!aView1.m_bViewCursorVisible);
+ 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 bd7670136ac2..62f751d1d125 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -64,6 +64,7 @@
#include <IDocumentLayoutAccess.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
#include <comphelper/string.hxx>
#include <PostItMgr.hxx>
@@ -2138,7 +2139,9 @@ void SwCursorShell::ShowCursor()
if (comphelper::LibreOfficeKit::isActive())
{
- GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr());
+ OString aPayload = OString::boolean(m_bSVCursorVis);
+ GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr());
+ SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
}
UpdateCursor();
@@ -2157,7 +2160,9 @@ void SwCursorShell::HideCursor()
if (comphelper::LibreOfficeKit::isActive())
{
- GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr());
+ OString aPayload = OString::boolean(m_bSVCursorVis);
+ GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr());
+ SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
}
}
}