diff options
-rw-r--r-- | comphelper/source/misc/lok.cxx | 12 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.cxx | 3 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitEnums.h | 8 | ||||
-rw-r--r-- | include/comphelper/lok.hxx | 6 | ||||
-rw-r--r-- | include/sfx2/lokhelper.hxx | 2 | ||||
-rw-r--r-- | libreofficekit/source/gtk/lokdocview.cxx | 17 | ||||
-rw-r--r-- | sfx2/source/view/lokhelper.cxx | 16 | ||||
-rw-r--r-- | sw/qa/extras/tiledrendering/tiledrendering.cxx | 97 | ||||
-rw-r--r-- | sw/source/core/crsr/crsrsh.cxx | 13 | ||||
-rw-r--r-- | sw/source/core/crsr/viscrs.cxx | 6 |
11 files changed, 172 insertions, 10 deletions
diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx index 203426bdc691..8beb633a9218 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 67beb36d3a56..28feff959221 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -3514,6 +3514,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 dabcd1c61d87..99d49c1eeae4 100644 --- a/editeng/source/editeng/impedit.cxx +++ b/editeng/source/editeng/impedit.cxx @@ -42,6 +42,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; @@ -1112,7 +1113,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 300d91e1c8c4..74d49fa15824 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 8a76c78e1151..e55592e9c1da 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -1163,13 +1163,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; @@ -2701,6 +2713,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 b84496be2c27..be2d5e3887a2 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 06a7ae836033..6d1dbaed5d27 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); @@ -160,6 +161,7 @@ public: CPPUNIT_TEST(testIMESupport); CPPUNIT_TEST(testSplitNodeRedlineCallback); CPPUNIT_TEST(testDeleteNodeRedlineCallback); + CPPUNIT_TEST(testVisCursorInvalidation); CPPUNIT_TEST_SUITE_END(); private: @@ -672,6 +674,7 @@ class ViewCallback { public: bool m_bOwnCursorInvalidated; + int m_nOwnCursorInvalidatedBy; bool m_bOwnCursorAtOrigin; tools::Rectangle m_aOwnCursor; bool m_bViewCursorInvalidated; @@ -693,6 +696,7 @@ public: ViewCallback() : m_bOwnCursorInvalidated(false), + m_nOwnCursorInvalidatedBy(-1), m_bOwnCursorAtOrigin(false), m_bViewCursorInvalidated(false), m_bOwnSelectionSet(false), @@ -726,7 +730,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()); @@ -2276,6 +2291,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 f8f1e606b1d3..9fc5a8cb7fc9 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1411,6 +1411,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 = SfxLokHelper::getView() != SfxLokHelper::getView(GetSfxViewShell()); + } + if (ActionPend()) { if ( eFlags & SwCursorShell::READONLY ) @@ -1553,7 +1560,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()) ) { @@ -1811,7 +1818,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()) ) { @@ -1823,7 +1830,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 b7f370608115..443e494b6a7d 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); } } |