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>
diff --git a/include/sfx2/shell.hxx b/include/sfx2/shell.hxx
index 420c8d5..566241c 100644
--- a/include/sfx2/shell.hxx
+++ b/include/sfx2/shell.hxx
@@ -455,7 +455,7 @@ public:
            defined with an earlier call to SetContextName().
            When <FALSE/> then broadcast the 'default' context.
    */
    void BroadcastContextForActivation (const bool bIsActivated);
    virtual void BroadcastContextForActivation (const bool bIsActivated);

    /** Enabled or disable the context broadcaster.  Returns the old state.
    */
diff --git a/sd/sdi/NotesPanelView.sdi b/sd/sdi/NotesPanelView.sdi
index b54addb..2fca90c 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 de7f3e5..cf3fd88 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 bf0c017..f245e88 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 d6d79d1..7de135d 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 da5325c..a5cebb3 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 b848593..8b1292e 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 b56335a..1ad4f13 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 122ac73..5e20b9c 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 45d2974..45c2c41 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>
@@ -193,7 +194,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 0b19042..a13daeb 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 c8f40b9..89a8f9c 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 db2ee5f..f158e32 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 7310b2e..4bdc074 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 b945695..8fcd132 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 2f2cecf..11f7a18 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 ();