summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/lokhelper.hxx2
-rw-r--r--include/sfx2/request.hxx5
-rw-r--r--sc/source/core/data/global.cxx11
-rw-r--r--sd/source/ui/view/viewshel.cxx15
-rw-r--r--sfx2/source/control/request.cxx11
-rw-r--r--sfx2/source/notify/hintpost.cxx37
-rw-r--r--sfx2/source/view/lokhelper.cxx11
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;