diff options
-rw-r--r-- | include/sfx2/lokhelper.hxx | 2 | ||||
-rw-r--r-- | include/sfx2/request.hxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/global.cxx | 11 | ||||
-rw-r--r-- | sd/source/ui/view/viewshel.cxx | 15 | ||||
-rw-r--r-- | sfx2/source/control/request.cxx | 11 | ||||
-rw-r--r-- | sfx2/source/notify/hintpost.cxx | 37 | ||||
-rw-r--r-- | sfx2/source/view/lokhelper.cxx | 11 |
7 files changed, 81 insertions, 11 deletions
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx index 98eeccb74476..dc144503b8dd 100644 --- a/include/sfx2/lokhelper.hxx +++ b/include/sfx2/lokhelper.hxx @@ -93,6 +93,8 @@ public: static void destroyView(int nId); /// Set a view shell as current one. static void setView(int nId); + /// Determines if a call to setView() is in progress or not. + static bool isSettingView(); /// Set the edit mode for a document with callbacks disabled. static void setEditMode(int nMode, vcl::ITiledRenderable* pDoc); /// Get view shell with id diff --git a/include/sfx2/request.hxx b/include/sfx2/request.hxx index 5c7db9925560..16c1ad8c7273 100644 --- a/include/sfx2/request.hxx +++ b/include/sfx2/request.hxx @@ -119,6 +119,11 @@ public: /** Return the window that should be used as the parent for any dialogs this request creates */ weld::Window* GetFrameWeld() const; + + void SetLokViewId(int nId); + + int GetLokViewId() const; + private: const SfxRequest& operator=(const SfxRequest &) = delete; }; diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 15fdc7dfb39d..29a616c6b6e8 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -879,17 +879,8 @@ void ScGlobal::OpenURL(const OUString& rURL, const OUString& rTarget, bool bIgno SfxBoolItem aBrowsing( SID_BROWSE, true ); // No SID_SILENT anymore - SfxCallMode nCall = SfxCallMode::RECORD; - if (comphelper::LibreOfficeKit::isActive()) - { - nCall |= SfxCallMode::SYNCHRON; - } - else - { - nCall |= SfxCallMode::ASYNCHRON; - } pViewFrm->GetDispatcher()->ExecuteList(SID_OPENDOC, - nCall, + SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aUrl, &aTarget, &aFrm, &aReferer, &aNewView, &aBrowsing }); } diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 09c1f95102f9..2ed4099fc5d9 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -307,10 +307,23 @@ void ViewShell::Activate(bool bIsMDIActivate) // thus, the Navigator will also get a current status SfxBoolItem aItem( SID_NAVIGATOR_INIT, true ); if (GetDispatcher() != nullptr) + { + SfxCallMode nCall = SfxCallMode::RECORD; + if (comphelper::LibreOfficeKit::isActive()) + { + // Make sure the LOK case doesn't dispatch async events while switching views, that + // would lead to a loop, see SfxHintPoster::DoEvent_Impl(). + nCall |= SfxCallMode::SYNCHRON; + } + else + { + nCall |= SfxCallMode::ASYNCHRON; + } GetDispatcher()->ExecuteList( SID_NAVIGATOR_INIT, - SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, + nCall, { &aItem }); + } SfxViewShell* pViewShell = GetViewShell(); OSL_ASSERT (pViewShell!=nullptr); diff --git a/sfx2/source/control/request.cxx b/sfx2/source/control/request.cxx index 5da3517df107..8e73cf2cd7f0 100644 --- a/sfx2/source/control/request.cxx +++ b/sfx2/source/control/request.cxx @@ -71,6 +71,7 @@ struct SfxRequest_Impl: public SfxListener std::unique_ptr<SfxAllItemSet> pInternalArgs; SfxViewFrame* pViewFrame; + int m_nLokViewId = -1; css::uno::Reference< css::frame::XDispatchRecorder > xRecorder; css::uno::Reference< css::util::XURLTransformer > xTransform; @@ -746,4 +747,14 @@ void SfxRequest::ReleaseArgs() pImpl->pInternalArgs.reset(); } +void SfxRequest::SetLokViewId(int nId) +{ + pImpl->m_nLokViewId = nId; +} + +int SfxRequest::GetLokViewId() const +{ + return pImpl->m_nLokViewId; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notify/hintpost.cxx b/sfx2/source/notify/hintpost.cxx index aa125d212943..78c8c0499099 100644 --- a/sfx2/source/notify/hintpost.cxx +++ b/sfx2/source/notify/hintpost.cxx @@ -20,8 +20,10 @@ #include <hintpost.hxx> #include <sfx2/request.hxx> +#include <sfx2/lokhelper.hxx> #include <utility> #include <vcl/svapp.hxx> +#include <comphelper/lok.hxx> SfxHintPoster::SfxHintPoster(std::function<void(std::unique_ptr<SfxRequest>)> aLink) : m_Link(std::move(aLink)) @@ -32,6 +34,19 @@ SfxHintPoster::~SfxHintPoster() {} void SfxHintPoster::Post(std::unique_ptr<SfxRequest> pHintToPost) { + if (comphelper::LibreOfficeKit::isActive()) + { + // Store the LOK view at the time of posting, so we can restore it later. + if (SfxLokHelper::isSettingView()) + { + // This would be bad, setView() should not trigger new posted hints, otherwise this will + // never end if the view doesn't match when we execute the posted hint. + SAL_WARN("sfx.notify", "SfxHintPoster::Post: posting new hint during setting a view"); + } + + pHintToPost->SetLokViewId(SfxLokHelper::getView()); + } + Application::PostUserEvent((LINK(this, SfxHintPoster, DoEvent_Impl)), pHintToPost.release()); AddFirstRef(); } @@ -40,7 +55,29 @@ IMPL_LINK(SfxHintPoster, DoEvent_Impl, void*, pPostedHint, void) { auto pRequest = static_cast<SfxRequest*>(pPostedHint); if (m_Link) + { + bool bSetView = false; + int nOldId = -1; + if (comphelper::LibreOfficeKit::isActive()) + { + int nNewId = pRequest->GetLokViewId(); + nOldId = SfxLokHelper::getView(); + if (nNewId != -1 && nNewId != nOldId) + { + // The current view ID is not the one that was active when posting the hint, switch + // to it. + SfxLokHelper::setView(nNewId); + bSetView = true; + } + } + m_Link(std::unique_ptr<SfxRequest>(pRequest)); + + if (bSetView) + { + SfxLokHelper::setView(nOldId); + } + } else delete pRequest; ReleaseRef(); diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 6ef68f2e42ec..2e3674f7d287 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -36,12 +36,15 @@ #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <comphelper/lok.hxx> #include <sfx2/msgpool.hxx> +#include <comphelper/scopeguard.hxx> #include <boost/property_tree/json_parser.hpp> using namespace com::sun::star; namespace { +bool g_bSettingView(false); + /// Used to disable callbacks. /// Needed to avoid recursion when switching views, /// which can cause clients to invoke LOKit API and @@ -163,8 +166,16 @@ void SfxLokHelper::destroyView(int nId) } } +bool SfxLokHelper::isSettingView() +{ + return g_bSettingView; +} + void SfxLokHelper::setView(int nId) { + g_bSettingView = true; + comphelper::ScopeGuard g([] { g_bSettingView = false; }); + SfxApplication* pApp = SfxApplication::Get(); if (pApp == nullptr) return; |