tdf#139830: keep the right sidebar context for chart after view switch (calc).

There is a general behavior to switch to the default sidebar context
by view deactivation and switch back to the right context by view
activation. See SfxShell::Activate() and SfxShell::Deactivate().
By activation, we use the selection to find out the right sidebar
context. See GetContextForSelection_SC() method for example. However,
for charts, this does not work, because the chart window is a separate
environment and the shell does not know what is selected inside the
chart window. So let's avoid context switches when we have a chart
window active. Let the chart controller handle sidebar context changes.

Change-Id: I272ee5c35ac30221eed2930201c4710a9a5877c4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109790
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109897
Tested-by: Jenkins
diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx
index 490367c..1c38211 100644
--- a/include/sfx2/sidebar/SidebarController.hxx
+++ b/include/sfx2/sidebar/SidebarController.hxx
@@ -52,6 +52,7 @@ typedef cppu::WeakComponentImplHelper <
    > SidebarControllerInterfaceBase;

class SfxSplitWindow;
class SfxViewShell;

namespace sfx2::sidebar {

@@ -171,6 +172,10 @@ public:

    void SyncUpdate();

    bool hasChartContextCurrently() const;

    static SidebarController* GetSidebarControllerForView(SfxViewShell* pViewShell);

private:
    SidebarController(SidebarDockingWindow* pParentWindow, const SfxViewFrame* pViewFrame);

diff --git a/sc/source/ui/drawfunc/chartsh.cxx b/sc/source/ui/drawfunc/chartsh.cxx
index 25b66b0..95b0638 100644
--- a/sc/source/ui/drawfunc/chartsh.cxx
+++ b/sc/source/ui/drawfunc/chartsh.cxx
@@ -29,14 +29,30 @@
#include <viewdata.hxx>
#include <drawview.hxx>
#include <gridwin.hxx>
#include <sfx2/sidebar/SidebarController.hxx>
#include <tabvwsh.hxx>

#define ShellClass_ScChartShell
#include <scslots.hxx>

using namespace css::uno;
using namespace sfx2::sidebar;

namespace drawing = com::sun::star::drawing;

namespace {

bool inChartContext(ScTabViewShell* pViewShell)
{
    SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(pViewShell);
    if (pSidebar)
        return pSidebar->hasChartContextCurrently();

    return false;
}

} // anonymous namespace

SFX_IMPL_INTERFACE(ScChartShell, ScDrawShell)

void ScChartShell::InitInterface_Impl()
@@ -48,6 +64,35 @@ void ScChartShell::InitInterface_Impl()
    GetStaticInterface()->RegisterPopupMenu("oleobject");
}

void ScChartShell::Activate(bool bMDI)
{
    if(!inChartContext(GetViewData().GetViewShell()))
        ScDrawShell::Activate(bMDI);
    else
    {
        // Avoid context changes for chart during activation / deactivation.
        const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));

        SfxShell::Activate(bMDI);

        SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
    }
}

void ScChartShell::Deactivate(bool bMDI)
{
    if(!inChartContext(GetViewData().GetViewShell()))
        ScDrawShell::Deactivate(bMDI);
    else
    {
        // Avoid context changes for chart during activation / deactivation.
        const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));

        SfxShell::Deactivate(bMDI);

        SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
    }
}

ScChartShell::ScChartShell(ScViewData& rData) :
    ScDrawShell(rData)
diff --git a/sc/source/ui/inc/chartsh.hxx b/sc/source/ui/inc/chartsh.hxx
index fc2ee32..44000af 100644
--- a/sc/source/ui/inc/chartsh.hxx
+++ b/sc/source/ui/inc/chartsh.hxx
@@ -36,6 +36,10 @@ private:
    /// SfxInterface initializer.
    static void InitInterface_Impl();

protected:
    virtual void Activate(bool bMDI) override;
    virtual void Deactivate(bool bMDI) override;

public:
    ScChartShell(ScViewData& rData);
    virtual ~ScChartShell() override;
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
index bb7ba06..cb13072 100644
--- a/sc/source/ui/view/tabvwsh4.cxx
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -83,8 +83,23 @@
#include <comphelper/flagguard.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <comphelper/lok.hxx>
#include <sfx2/sidebar/SidebarController.hxx>

using namespace com::sun::star;
using namespace sfx2::sidebar;

namespace {

bool inChartContext(ScTabViewShell* pViewShell)
{
    SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(pViewShell);
    if (pSidebar)
        return pSidebar->hasChartContextCurrently();

    return false;
}

} // anonymous namespace

void ScTabViewShell::Activate(bool bMDI)
{
@@ -201,9 +216,12 @@ void ScTabViewShell::Activate(bool bMDI)
    //  don't call CheckSelectionTransfer here - activating a view should not change the
    //  primary selection (may be happening just because the mouse was moved over the window)

    ContextChangeEventMultiplexer::NotifyContextChange(
        GetController(),
        vcl::EnumContext::Context::Default);
    if (!inChartContext(this))
    {
        ContextChangeEventMultiplexer::NotifyContextChange(
            GetController(),
            vcl::EnumContext::Context::Default);
    }
}

void ScTabViewShell::Deactivate(bool bMDI)
diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx
index 60013c9..e2e03e3 100644
--- a/sfx2/source/sidebar/SidebarController.cxx
+++ b/sfx2/source/sidebar/SidebarController.cxx
@@ -28,6 +28,8 @@
#include <sfx2/sidebar/SidebarChildWindow.hxx>
#include <sidebar/Tools.hxx>
#include <sfx2/sidebar/SidebarDockingWindow.hxx>
#include <com/sun/star/ui/XSidebarProvider.hpp>
#include <com/sun/star/frame/XController2.hpp>
#include <sfx2/sidebar/Context.hxx>
#include <sfx2/viewsh.hxx>

@@ -1585,6 +1587,35 @@ void SidebarController::saveDeckState()
    }
}

bool SidebarController::hasChartContextCurrently() const
{
    return GetCurrentContext().msApplication == "com.sun.star.chart2.ChartDocument";
}

sfx2::sidebar::SidebarController* SidebarController::GetSidebarControllerForView(SfxViewShell* pViewShell)
{
    if (!pViewShell)
        return nullptr;

    Reference<css::frame::XController2> xController(pViewShell->GetController(), UNO_QUERY);
    if (!xController.is())
        return nullptr;

    // Make sure there is a model behind the controller, otherwise getSidebar() can crash.
    if (!xController->getModel().is())
        return nullptr;

    Reference<css::ui::XSidebarProvider> xSidebarProvider = xController->getSidebar();
    if (!xSidebarProvider.is())
        return nullptr;

    Reference<css::ui::XSidebar> xSidebar = xSidebarProvider->getSidebar();
    if (!xSidebar.is())
        return nullptr;

    return dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get());
}

} // end of namespace sfx2::sidebar

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */