diff options
author | Sarper Akdemir <sarper.akdemir@allotropia.de> | 2024-06-07 21:14:44 +0200 |
---|---|---|
committer | Thorsten Behrens <thorsten.behrens@allotropia.de> | 2024-07-03 09:54:20 +0200 |
commit | 002f4214084718a98fca6799133150f6b37e00f0 (patch) | |
tree | 48db0610408e45437bd7f4f19f6fd12caa0498ff /sd | |
parent | 5a91d78c61805d6e71ab86705d921d4296dc1477 (diff) |
tdf#33603: fix notespane (side/tool)bar interactions
Introduces OverridingShells that when set, makes the view
act like the MainViewShell.
The main use case is having more then one ViewShell in a
single window, where context (toolbars, sidebars etc.) can
jump in between different ViewShells.
Uses OverridingShells to enable NotesPane to react
ToolBarShells. Accessing the functionality of ToolBarShells
without the previous hacks with slot forwarding.
Change-Id: Icc9721d7f54097025bc9dc7ef7069aed856e6d96
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169658
Tested-by: Jenkins
Reviewed-by: Sarper Akdemir <sarper.akdemir@allotropia.de>
(cherry picked from commit 5e143492320dac8cdf8b2956799ca366f3d8e72c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169679
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
Diffstat (limited to 'sd')
-rw-r--r-- | sd/sdi/NotesPanelView.sdi | 1 | ||||
-rw-r--r-- | sd/source/ui/framework/module/ToolBarModule.cxx | 118 | ||||
-rw-r--r-- | sd/source/ui/framework/module/ToolBarModule.hxx | 29 | ||||
-rw-r--r-- | sd/source/ui/inc/EventMultiplexer.hxx | 12 | ||||
-rw-r--r-- | sd/source/ui/inc/ToolBarManager.hxx | 5 | ||||
-rw-r--r-- | sd/source/ui/inc/ViewShell.hxx | 1 | ||||
-rw-r--r-- | sd/source/ui/inc/ViewShellManager.hxx | 4 | ||||
-rw-r--r-- | sd/source/ui/tools/EventMultiplexer.cxx | 24 | ||||
-rw-r--r-- | sd/source/ui/view/NotesPanelView.cxx | 6 | ||||
-rw-r--r-- | sd/source/ui/view/NotesPanelViewShell.cxx | 1 | ||||
-rw-r--r-- | sd/source/ui/view/ToolBarManager.cxx | 38 | ||||
-rw-r--r-- | sd/source/ui/view/ViewShellManager.cxx | 51 | ||||
-rw-r--r-- | sd/source/ui/view/drtxtob.cxx | 5 | ||||
-rw-r--r-- | sd/source/ui/view/outlnvsh.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/view/viewshel.cxx | 65 |
15 files changed, 317 insertions, 45 deletions
diff --git a/sd/sdi/NotesPanelView.sdi b/sd/sdi/NotesPanelView.sdi index b54addb52b8c..2fca90c56fdc 100644 --- a/sd/sdi/NotesPanelView.sdi +++ b/sd/sdi/NotesPanelView.sdi @@ -499,5 +499,4 @@ include "drtxtob.sdi" shell NotesPanelViewShell { import NotesPanelView; - import TextObjectBar; } diff --git a/sd/source/ui/framework/module/ToolBarModule.cxx b/sd/source/ui/framework/module/ToolBarModule.cxx index de7f3e583126..cf3fd880105e 100644 --- a/sd/source/ui/framework/module/ToolBarModule.cxx +++ b/sd/source/ui/framework/module/ToolBarModule.cxx @@ -18,10 +18,17 @@ */ #include "ToolBarModule.hxx" +#include <ViewShell.hxx> #include <ViewShellBase.hxx> +#include <ViewShellManager.hxx> #include <DrawController.hxx> +#include <EventMultiplexer.hxx> #include <comphelper/servicehelper.hxx> #include <framework/FrameworkHelper.hxx> +#include <vcl/EnumContext.hxx> + +#include <com/sun/star/frame/XController.hpp> +#include <comphelper/processfactory.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -76,6 +83,9 @@ ToolBarModule::ToolBarModule ( ToolBarModule::~ToolBarModule() { + if (mpBase && mbListeningEventMultiplexer) + mpBase->GetEventMultiplexer()->RemoveEventListener( + LINK(this, ToolBarModule, EventMultiplexerListener)); } void ToolBarModule::disposing(std::unique_lock<std::mutex>&) @@ -93,6 +103,16 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( if (!mxConfigurationController.is()) return; + // since EventMultiplexer isn't available when the ToolBarModule is + // initialized, subscribing the event listener hacked here. + if (!mbListeningEventMultiplexer && mpBase) + { + mpBase->GetEventMultiplexer()->AddEventListener( + LINK(this, ToolBarModule, EventMultiplexerListener)); + mbListeningEventMultiplexer = true; + } + + sal_Int32 nEventType = 0; rEvent.UserData >>= nEventType; switch (nEventType) @@ -123,6 +143,34 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( } } +void ToolBarModule::HandlePaneViewShellFocused(const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId) +{ + if(!mpBase) + return; + + std::shared_ptr<FrameworkHelper> pFrameworkHelper(FrameworkHelper::Instance(*mpBase)); + std::shared_ptr<ViewShell> pViewShell + = FrameworkHelper::GetViewShell(pFrameworkHelper->GetView(rxResourceId)); + + if(mpBase->GetMainViewShell() == pViewShell) + { + mpBase->GetViewShellManager()->RemoveOverridingMainShell(); + return; + } + + switch(pViewShell->GetShellType()) + { + // shells that override mainviewshell functionality when used in a pane + case ViewShell::ST_NOTESPANEL: + mpBase->GetViewShellManager()->SetOverridingMainShell(pViewShell); + UpdateToolbars(pViewShell.get()); + break; + default: + break; + } + mpToolBarManagerLock.reset(); +} + void ToolBarModule::HandleUpdateStart() { // Lock the ToolBarManager and tell it to lock the ViewShellManager as @@ -149,23 +197,11 @@ void ToolBarModule::HandleUpdateEnd() std::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); std::shared_ptr<FrameworkHelper> pFrameworkHelper ( FrameworkHelper::Instance(*mpBase)); - ViewShell* pViewShell - = pFrameworkHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get(); - if (pViewShell != nullptr) - { - pToolBarManager->MainViewShellChanged(*pViewShell); - pToolBarManager->SelectionHasChanged( - *pViewShell, - *pViewShell->GetView()); - pToolBarManager->PreUpdate(); - } - else - { - pToolBarManager->MainViewShellChanged(); - pToolBarManager->PreUpdate(); - } - } + auto pViewShell + = pFrameworkHelper->GetViewShell(FrameworkHelper::msCenterPaneURL); + UpdateToolbars(pViewShell.get()); + } // Releasing the update lock of the ToolBarManager will let the // ToolBarManager with the help of the ViewShellManager take care of // updating tool bars and view shell with the minimal amount of @@ -173,6 +209,35 @@ void ToolBarModule::HandleUpdateEnd() mpToolBarManagerLock.reset(); } +void ToolBarModule::UpdateToolbars(ViewShell* pViewShell) +{ + // Update the set of visible tool bars and deactivate those that are + // no longer visible. This is done before the old view shell is + // destroyed in order to avoid unnecessary updates of those tool + // bars. + if (!mpBase) + return; + + std::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); + + if(!pToolBarManager) + return; + + if (pViewShell) + { + pToolBarManager->MainViewShellChanged(*pViewShell); + pToolBarManager->SelectionHasChanged( + *pViewShell, + *pViewShell->GetView()); + pToolBarManager->PreUpdate(); + } + else + { + pToolBarManager->MainViewShellChanged(); + pToolBarManager->PreUpdate(); + } +} + void SAL_CALL ToolBarModule::disposing (const lang::EventObject& rEvent) { if (mxConfigurationController.is() @@ -184,6 +249,27 @@ void SAL_CALL ToolBarModule::disposing (const lang::EventObject& rEvent) } } +IMPL_LINK(ToolBarModule, EventMultiplexerListener, sd::tools::EventMultiplexerEvent&, rEvent, + void) +{ + if (!mpBase) + return; + + switch(rEvent.meEventId) + { + case EventMultiplexerEventId::FocusShifted: + { + uno::Reference<drawing::framework::XResourceId> xResourceId{ rEvent.mxUserData, + UNO_QUERY }; + if (xResourceId.is()) + HandlePaneViewShellFocused(xResourceId); + break; + } + default: + break; + } +} + } // end of namespace sd::framework /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolBarModule.hxx b/sd/source/ui/framework/module/ToolBarModule.hxx index bf0c017ef981..f245e88f8562 100644 --- a/sd/source/ui/framework/module/ToolBarModule.hxx +++ b/sd/source/ui/framework/module/ToolBarModule.hxx @@ -20,20 +20,34 @@ #pragma once #include <ToolBarManager.hxx> +#include <tools/link.hxx> #include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/ui/XContextChangeEventListener.hpp> #include <comphelper/compbase.hxx> #include <o3tl/deleter.hxx> #include <rtl/ref.hxx> #include <memory> -namespace com::sun::star::drawing::framework { class XConfigurationController; } -namespace com::sun::star::frame { class XController; } +namespace com::sun::star::drawing::framework +{ +class XConfigurationController; +class XResourceId; +} +namespace com::sun::star::frame +{ +class XController; +} namespace sd { class DrawController; class ViewShellBase; } +namespace sd::tools +{ +class EventMultiplexerEvent; +} + namespace sd::framework { typedef comphelper::WeakComponentImplHelper < @@ -73,9 +87,20 @@ private: ViewShellBase* mpBase; std::unique_ptr<ToolBarManager::UpdateLock, o3tl::default_delete<ToolBarManager::UpdateLock>> mpToolBarManagerLock; bool mbMainViewSwitchUpdatePending; + bool mbListeningEventMultiplexer = false; + + /** Update toolbars via ToolbarManager + + @param pViewShell may be nullptr + */ + void UpdateToolbars(ViewShell* pViewShell); void HandleUpdateStart(); void HandleUpdateEnd(); + void HandlePaneViewShellFocused( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId); + + DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent&, void); }; } // end of namespace sd::framework diff --git a/sd/source/ui/inc/EventMultiplexer.hxx b/sd/source/ui/inc/EventMultiplexer.hxx index d6d79d11b279..7de135d45fff 100644 --- a/sd/source/ui/inc/EventMultiplexer.hxx +++ b/sd/source/ui/inc/EventMultiplexer.hxx @@ -22,6 +22,7 @@ #include <sal/config.h> #include <rtl/ref.hxx> +#include <com/sun/star/uno/XInterface.hpp> template <typename Arg, typename Ret> class Link; @@ -112,6 +113,10 @@ enum class EventMultiplexerEventId /** Edit mode was (or is being) switched to master mode. */ EditModeMaster, + + /** Focus shifted between views. + */ + FocusShifted, }; namespace sd::tools @@ -121,8 +126,10 @@ class EventMultiplexerEvent public: EventMultiplexerEventId meEventId; const void* mpUserData; + css::uno::Reference<css::uno::XInterface> mxUserData; - EventMultiplexerEvent(EventMultiplexerEventId eEventId, const void* pUserData); + EventMultiplexerEvent(EventMultiplexerEventId eEventId, const void* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); }; /** This convenience class makes it easy to listen to various events that @@ -160,7 +167,8 @@ public: @param pUserData Some data sent to the listeners along with the event. */ - void MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData); + void MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); private: class Implementation; diff --git a/sd/source/ui/inc/ToolBarManager.hxx b/sd/source/ui/inc/ToolBarManager.hxx index da5325cf693c..a5cebb377f5c 100644 --- a/sd/source/ui/inc/ToolBarManager.hxx +++ b/sd/source/ui/inc/ToolBarManager.hxx @@ -178,10 +178,13 @@ public: The group is used for the actual tool bars. @param nToolBarId Id of the tool bar shell. + @param bAddBar + Add the toolbar itself with the shell. When false only adds the shell. */ void AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId); + ShellId nToolBarId, + bool bAddBar = true); /** Remove the tool bar with the given name from the specified group. If the tool bar is not visible then nothing happens. diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index b848593458a6..8b1292e554ad 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -522,6 +522,7 @@ protected: virtual void Activate(bool IsMDIActivate) override; virtual void Deactivate(bool IsMDIActivate) override; + virtual void BroadcastContextForActivation (const bool bIsActivated) override; virtual void SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY ); diff --git a/sd/source/ui/inc/ViewShellManager.hxx b/sd/source/ui/inc/ViewShellManager.hxx index b56335ad6170..1ad4f138d8ae 100644 --- a/sd/source/ui/inc/ViewShellManager.hxx +++ b/sd/source/ui/inc/ViewShellManager.hxx @@ -79,6 +79,10 @@ public: */ void ActivateViewShell(ViewShell* pViewShell); + void RemoveOverridingMainShell(); + void SetOverridingMainShell(std::shared_ptr<ViewShell> pViewShell); + std::shared_ptr<ViewShell> GetOverridingMainShell(); + /** Activate the given shell which is not a view shell. For view shells use the ActivateViewShell() method. */ diff --git a/sd/source/ui/tools/EventMultiplexer.cxx b/sd/source/ui/tools/EventMultiplexer.cxx index 122ac736a4e8..5e20b9cc1f33 100644 --- a/sd/source/ui/tools/EventMultiplexer.cxx +++ b/sd/source/ui/tools/EventMultiplexer.cxx @@ -132,7 +132,8 @@ private: void CallListeners ( EventMultiplexerEventId eId, - void const * pUserData = nullptr); + void const * pUserData = nullptr, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); DECL_LINK(SlideSorterSelectionChangeListener, LinkParamNone*, void); }; @@ -173,11 +174,10 @@ void EventMultiplexer::RemoveEventListener ( mpImpl->RemoveEventListener(rCallback); } -void EventMultiplexer::MultiplexEvent( - EventMultiplexerEventId eEventId, - void const * pUserData ) +void EventMultiplexer::MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) { - EventMultiplexerEvent aEvent(eEventId, pUserData); + EventMultiplexerEvent aEvent(eEventId, pUserData, xUserData); mpImpl->CallListeners(aEvent); } @@ -622,11 +622,11 @@ void EventMultiplexer::Implementation::Notify ( } } -void EventMultiplexer::Implementation::CallListeners ( - EventMultiplexerEventId eId, - void const * pUserData) +void EventMultiplexer::Implementation::CallListeners( + EventMultiplexerEventId eId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) { - EventMultiplexerEvent aEvent(eId, pUserData); + EventMultiplexerEvent aEvent(eId, pUserData, xUserData); CallListeners(aEvent); } @@ -648,9 +648,11 @@ IMPL_LINK_NOARG(EventMultiplexer::Implementation, SlideSorterSelectionChangeList EventMultiplexerEvent::EventMultiplexerEvent ( EventMultiplexerEventId eEventId, - const void* pUserData) + const void* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) : meEventId(eEventId), - mpUserData(pUserData) + mpUserData(pUserData), + mxUserData(xUserData) { } diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index f95284c25ade..0611873ce150 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -18,6 +18,7 @@ #include <sdpage.hxx> #include <DrawViewShell.hxx> #include <DrawDocShell.hxx> +#include <ToolBarManager.hxx> #include <Window.hxx> #include <drawdoc.hxx> #include <sdmod.hxx> @@ -194,7 +195,12 @@ void NotesPanelView::onUpdateStyleSettings() void NotesPanelView::onResize() { ::sd::Window* pWin = mrNotesPanelViewShell.GetActiveWindow(); + if (!pWin) + return; + OutlinerView* pOutlinerView = GetOutlinerView(); + if (!pOutlinerView) + return; Size aOutputSize = pWin->PixelToLogic(pWin->GetOutputSizePixel()); diff --git a/sd/source/ui/view/NotesPanelViewShell.cxx b/sd/source/ui/view/NotesPanelViewShell.cxx index 0b1904293b05..a13daeb9f6f0 100644 --- a/sd/source/ui/view/NotesPanelViewShell.cxx +++ b/sd/source/ui/view/NotesPanelViewShell.cxx @@ -308,7 +308,6 @@ void NotesPanelViewShell::Activate(bool bIsMDIActivate) } ViewShell::Activate(bIsMDIActivate); - SfxShell::BroadcastContextForActivation(true); if (bIsMDIActivate) { diff --git a/sd/source/ui/view/ToolBarManager.cxx b/sd/source/ui/view/ToolBarManager.cxx index c8f40b99a0ef..89a8f9cfba61 100644 --- a/sd/source/ui/view/ToolBarManager.cxx +++ b/sd/source/ui/view/ToolBarManager.cxx @@ -20,9 +20,11 @@ #include <ToolBarManager.hxx> #include <DrawViewShell.hxx> +#include <NotesPanelViewShell.hxx> #include <EventMultiplexer.hxx> #include <ViewShellBase.hxx> #include <ViewShellManager.hxx> +#include <framework/FrameworkHelper.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -178,6 +180,8 @@ private: things easier and does not waste too much memory. */ GroupedShellList maCurrentList; + + std::shared_ptr<ViewShell> pCurrentActiveShell; }; /** This class concentrates the knowledge about when to show what tool bars @@ -256,7 +260,7 @@ public: void ResetToolBars (ToolBarGroup eGroup); void ResetAllToolBars(); void AddToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName); - void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId); + void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId, bool bAddBar = true); void RemoveToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName); /** Release all tool bar shells and the associated framework tool bars. @@ -387,12 +391,13 @@ void ToolBarManager::AddToolBar ( void ToolBarManager::AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId) + ShellId nToolBarId, + bool bAddBar) { if (mpImpl != nullptr) { UpdateLock aLock (shared_from_this()); - mpImpl->AddToolBarShell(eGroup,nToolBarId); + mpImpl->AddToolBarShell(eGroup,nToolBarId,bAddBar); } } @@ -621,13 +626,23 @@ void ToolBarManager::Implementation::RemoveToolBar ( void ToolBarManager::Implementation::AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId) + ShellId nToolBarId, + bool bAddBar) { ViewShell* pMainViewShell = mrBase.GetMainViewShell().get(); if (pMainViewShell != nullptr) { maToolBarShellList.AddShellId(eGroup,nToolBarId); - GetToolBarRules().SubShellAdded(eGroup, nToolBarId); + if (bAddBar) + { + GetToolBarRules().SubShellAdded(eGroup, nToolBarId); + } + else + { + mbPostUpdatePending = true; + if (mnLockCount == 0) + PostUpdate(); + } } } @@ -958,6 +973,11 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) ToolBarManager::msViewerToolBar); break; + case ::sd::ViewShell::ST_NOTESPANEL: + mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Permanent, + ToolbarId::Draw_Text_Toolbox_Sd); + break; + case ::sd::ViewShell::ST_DRAW: mpToolBarManager->AddToolBar( ToolBarManager::ToolBarGroup::Permanent, @@ -993,7 +1013,6 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) ToolBarManager::msSlideSorterObjectBar); break; - case ViewShell::ST_NOTESPANEL: case ViewShell::ST_NONE: case ViewShell::ST_PRESENTATION: case ViewShell::ST_SIDEBAR: @@ -1347,6 +1366,9 @@ void ToolBarShellList::UpdateShells ( if (rpMainViewShell == nullptr) return; + const std::shared_ptr<ViewShell>& pCurrentMainViewShell + = rpManager->GetOverridingMainShell() ? rpManager->GetOverridingMainShell() : rpMainViewShell; + GroupedShellList aList; // Deactivate shells that are in maCurrentList, but not in @@ -1357,7 +1379,7 @@ void ToolBarShellList::UpdateShells ( for (const auto& rShell : aList) { SAL_INFO("sd.view", __func__ << ": deactivating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId)); - rpManager->DeactivateSubShell(*rpMainViewShell, rShell.mnId); + rpManager->DeactivateSubShell(*pCurrentMainViewShell, rShell.mnId); } // Activate shells that are in maNewList, but not in @@ -1369,7 +1391,7 @@ void ToolBarShellList::UpdateShells ( for (const auto& rShell : aList) { SAL_INFO("sd.view", __func__ << ": activating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId)); - rpManager->ActivateSubShell(*rpMainViewShell, rShell.mnId); + rpManager->ActivateSubShell(*pCurrentMainViewShell, rShell.mnId); } // The maNewList now reflects the current state and thus is made diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index db2ee5f8f158..f158e32e3296 100644 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -113,6 +113,9 @@ public: void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove); void ActivateSubShell (const SfxShell& rParentShell, ShellId nId); void DeactivateSubShell (const SfxShell& rParentShell, ShellId nId); + void RemoveOverridingMainShell(); + void SetOverridingShell(std::shared_ptr<ViewShell> pViewShell); + std::shared_ptr<ViewShell> GetOverridingShell(); void MoveToTop (const SfxShell& rParentShell); SfxShell* GetShell (ShellId nId) const; SfxShell* GetTopShell() const; @@ -189,6 +192,7 @@ private: SfxShell* mpTopShell; SfxShell* mpTopViewShell; + std::shared_ptr<ViewShell> mpOverridingShell; void UpdateShellStack(); @@ -260,6 +264,26 @@ void ViewShellManager::DeactivateViewShell (const ViewShell* pShell) mpImpl->DeactivateViewShell(*pShell); } + +void ViewShellManager::RemoveOverridingMainShell() +{ + if(mbValid) + mpImpl->RemoveOverridingMainShell(); +} + +void ViewShellManager::SetOverridingMainShell(std::shared_ptr<ViewShell> pViewShell) +{ + if(mbValid) + mpImpl->SetOverridingShell(pViewShell); +} + +std::shared_ptr<ViewShell> ViewShellManager::GetOverridingMainShell() +{ + if(mbValid) + return mpImpl->GetOverridingShell(); + return {}; +} + void ViewShellManager::SetFormShell ( const ViewShell* pParentShell, FmFormShell* pFormShell, @@ -570,6 +594,21 @@ void ViewShellManager::Implementation::DeactivateSubShell ( DestroySubShell(aDescriptor); } +std::shared_ptr<ViewShell> ViewShellManager::Implementation::GetOverridingShell() +{ + return mpOverridingShell; +} + +void ViewShellManager::Implementation::RemoveOverridingMainShell() +{ + mpOverridingShell.reset(); +} + +void ViewShellManager::Implementation::SetOverridingShell(std::shared_ptr<ViewShell> pViewShell) +{ + mpOverridingShell = pViewShell; +} + void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell) { ::osl::MutexGuard aGuard (maMutex); @@ -711,10 +750,12 @@ void ViewShellManager::Implementation::UpdateShellStack() // 1. Create the missing shells. CreateShells(); + SfxShell* pPreviousTopViewShell = mpTopViewShell; // Update the pointer to the top-most active view shell. mpTopViewShell = (maActiveViewShells.empty()) ? nullptr : maActiveViewShells.begin()->mpShell; + bool bTopViewShellChanged = mpTopViewShell != pPreviousTopViewShell; // 2. Create the internal target stack. ShellStack aTargetStack; @@ -776,6 +817,10 @@ void ViewShellManager::Implementation::UpdateShellStack() if (mpTopShell!=nullptr && pUndoManager!=nullptr && mpTopShell->GetUndoManager()==nullptr) mpTopShell->SetUndoManager(pUndoManager); + // Only broadcast context for activation on the top-most ViewShell + if (mpTopViewShell && bTopViewShellChanged) + mpTopViewShell->BroadcastContextForActivation(true); + // Finally tell an invocation of this method on a higher level that it can (has // to) abort and return immediately. mbShellStackIsUpToDate = true; @@ -1071,6 +1116,7 @@ void ViewShellManager::Implementation::Shutdown() mrBase.RemoveSubShell (); maShellFactories.clear(); + mpOverridingShell.reset(); } #if OSL_DEBUG_LEVEL >= 2 @@ -1113,9 +1159,12 @@ void ViewShellManager::Implementation::Deactivate (SfxShell* pShell) { pView->SdrEndTextEdit(); pView->UnmarkAll(); + + // dispatch synchronously, otherwise it might execute while another + // ViewShell is active! pViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT, - SfxCallMode::ASYNCHRON); + SfxCallMode::SYNCHRON); } } diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx index 7310b2e19e2b..4bdc074a0574 100644 --- a/sd/source/ui/view/drtxtob.cxx +++ b/sd/source/ui/view/drtxtob.cxx @@ -56,6 +56,7 @@ #include <DrawDocShell.hxx> #include <DrawViewShell.hxx> #include <OutlineViewShell.hxx> +#include <NotesPanelViewShell.hxx> #include <Window.hxx> #include <OutlineView.hxx> #include <Outliner.hxx> @@ -453,7 +454,9 @@ void TextObjectBar::GetAttrStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, rSet.Put( aAttrSet, false ); // <- sal_False, so DontCare-Status gets acquired // these are disabled in outline-mode - if (!mpViewShell || dynamic_cast< const DrawViewShell *>( mpViewShell ) == nullptr) + if (!mpViewShell + || !(dynamic_cast<const DrawViewShell*>(mpViewShell) + || dynamic_cast<const NotesPanelViewShell*>(mpViewShell))) { rSet.DisableItem( SID_ATTR_PARA_ADJUST_LEFT ); rSet.DisableItem( SID_ATTR_PARA_ADJUST_RIGHT ); diff --git a/sd/source/ui/view/outlnvsh.cxx b/sd/source/ui/view/outlnvsh.cxx index b945695d97de..8fcd132ff3de 100644 --- a/sd/source/ui/view/outlnvsh.cxx +++ b/sd/source/ui/view/outlnvsh.cxx @@ -317,7 +317,7 @@ void OutlineViewShell::Activate( bool bIsMDIActivate ) } ViewShell::Activate( bIsMDIActivate ); - SfxShell::BroadcastContextForActivation(true); + BroadcastContextForActivation(true); pOlView->SetLinks(); pOlView->ConnectToApplication(); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 2f2cecf7aabd..11f7a186f282 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <framework/FrameworkHelper.hxx> +#include <framework/ViewShellWrapper.hxx> #include <memory> #include <ViewShell.hxx> #include <ViewShellImplementation.hxx> @@ -58,6 +60,7 @@ #include <SlideSorterViewShell.hxx> #include <ViewShellManager.hxx> #include <FormShellManager.hxx> +#include <EventMultiplexer.hxx> #include <svx/extrusionbar.hxx> #include <svx/fontworkbar.hxx> #include <svx/svdoutl.hxx> @@ -90,6 +93,12 @@ #include <sdmod.hxx> #include <AccessibleDocumentViewBase.hxx> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/XView.hpp> +#include <com/sun/star/frame/XFrame.hpp> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::presentation; @@ -405,6 +414,62 @@ void ViewShell::Deactivate(bool bIsMDIActivate) SfxShell::Deactivate(bIsMDIActivate); } +void ViewShell::BroadcastContextForActivation(const bool bIsActivated) +{ + auto getFrameworkResourceIdForShell + = [&]() -> uno::Reference<drawing::framework::XResourceId> const + { + Reference<::css::drawing::framework::XControllerManager> xControllerManager( + GetViewShellBase().GetController(), UNO_QUERY); + if (!xControllerManager.is()) + return {}; + + Reference<::css::drawing::framework::XConfigurationController> xConfigurationController + = xControllerManager->getConfigurationController(); + if (!xConfigurationController.is()) + return {}; + + Reference<::css::drawing::framework::XConfiguration> xConfiguration + = xConfigurationController->getCurrentConfiguration(); + if (!xConfiguration.is()) + return {}; + + auto aResIdsIndirect + = xConfiguration->getResources({}, "", drawing::framework::AnchorBindingMode_INDIRECT); + + for (const uno::Reference<drawing::framework::XResourceId>& rResId : aResIdsIndirect) + { + auto pFrameworkHelper = framework::FrameworkHelper::Instance(GetViewShellBase()); + + uno::Reference<drawing::framework::XView> xView; + if (rResId->getResourceURL().match(framework::FrameworkHelper::msViewURLPrefix)) + { + xView.set(xConfigurationController->getResource(rResId), UNO_QUERY); + + if (xView.is()) + { + auto pViewShellWrapper + = dynamic_cast<framework::ViewShellWrapper*>(xView.get()); + if (pViewShellWrapper->GetViewShell().get() == this) + { + return rResId; + } + } + } + } + return {}; + }; + + if (bIsActivated) + { + GetViewShellBase().GetEventMultiplexer()->MultiplexEvent( + EventMultiplexerEventId::FocusShifted, nullptr, getFrameworkResourceIdForShell()); + } + + if (GetDispatcher()) + SfxShell::BroadcastContextForActivation(bIsActivated); +} + void ViewShell::Shutdown() { Exit (); |