lok: Properly update sidebar context in Math

Change-Id: I830c0d9bdeaa6340283eafc3e91251d02602d7aa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137247
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
index a4bd7a3..54c91a6 100644
--- a/chart2/source/controller/main/ChartController.cxx
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -379,7 +379,7 @@ void SAL_CALL ChartController::attachFrame(
    {
        auto pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get());
        assert(pSidebar);
        sfx2::sidebar::SidebarController::registerSidebarForFrame(pSidebar, this);
        pSidebar->registerSidebarForFrame(this);
        pSidebar->updateModel(getChartModel());
        css::lang::EventObject aEvent;
        mpSelectionChangeHandler->selectionChanged(aEvent);
@@ -745,7 +745,7 @@ void SAL_CALL ChartController::dispose()
        uno::Reference<ui::XSidebar> xSidebar = getSidebarFromModel(getChartModel());
        if (sfx2::sidebar::SidebarController* pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get()))
        {
            sfx2::sidebar::SidebarController::unregisterSidebarForFrame(pSidebar, this);
            pSidebar->unregisterSidebarForFrame(this);
        }
    }

diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx
index e996c85..208af98 100644
--- a/include/sfx2/sidebar/SidebarController.hxx
+++ b/include/sfx2/sidebar/SidebarController.hxx
@@ -78,9 +78,9 @@ public:
    static SidebarController* GetSidebarControllerForFrame (
        const css::uno::Reference<css::frame::XFrame>& rxFrame);

    static void registerSidebarForFrame(SidebarController* pController, const css::uno::Reference<css::frame::XController>& xFrame);
    void registerSidebarForFrame(const css::uno::Reference<css::frame::XController>& xFrame);

    static void unregisterSidebarForFrame(SidebarController* pController, const css::uno::Reference<css::frame::XController>& xFrame);
    void unregisterSidebarForFrame(const css::uno::Reference<css::frame::XController>& xFrame);

    // ui::XContextChangeEventListener
    virtual void SAL_CALL notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent) override;
@@ -170,6 +170,7 @@ public:

    void SyncUpdate();

    // Used to avoid wrong context update when an embedded object activation is in progress
    bool hasChartOrMathContextCurrently() const;

    static SidebarController* GetSidebarControllerForView(const SfxViewShell* pViewShell);
diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx
index 6909f5c..4384482 100644
--- a/sfx2/source/sidebar/SidebarController.cxx
+++ b/sfx2/source/sidebar/SidebarController.cxx
@@ -120,6 +120,7 @@ SidebarController::SidebarController (
                     const ::std::vector<TabBar::DeckMenuData>& rMenuData) { return this->ShowPopupMenu(rMainMenu, rSubMenu, rMenuData); },
              this)),
      maCurrentContext(OUString(), OUString()),
      maRequestedContext(OUString(), OUString()),
      mnRequestedForceFlags(SwitchFlag_NoForce),
      mbMinimumSidebarWidth(officecfg::Office::UI::Sidebar::General::MinimumWidth::get()),
      msCurrentDeckId(gsDefaultDeckId),
@@ -143,7 +144,7 @@ rtl::Reference<SidebarController> SidebarController::create(SidebarDockingWindow
    rtl::Reference<SidebarController> instance(new SidebarController(pParentWindow, pViewFrame));

    const css::uno::Reference<css::frame::XFrame>& rxFrame = pViewFrame->GetFrame().GetFrameInterface();
    registerSidebarForFrame(instance.get(), rxFrame->getController());
    instance->registerSidebarForFrame(rxFrame->getController());
    rxFrame->addFrameActionListener(instance);
    // Listen for window events.
    instance->mpParentWindow->AddEventListener(LINK(instance.get(), SidebarController, WindowEventHandler));
@@ -190,27 +191,27 @@ SidebarController* SidebarController::GetSidebarControllerForFrame (
    return dynamic_cast<SidebarController*>(xListener.get());
}

void SidebarController::registerSidebarForFrame(SidebarController* pController, const css::uno::Reference<css::frame::XController>& xController)
void SidebarController::registerSidebarForFrame(const css::uno::Reference<css::frame::XController>& xController)
{
    // Listen for context change events.
    css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
        css::ui::ContextChangeEventMultiplexer::get(
            ::comphelper::getProcessComponentContext()));
    xMultiplexer->addContextChangeEventListener(
        static_cast<css::ui::XContextChangeEventListener*>(pController),
        static_cast<css::ui::XContextChangeEventListener*>(this),
        xController);
}

void SidebarController::unregisterSidebarForFrame(SidebarController* pController, const css::uno::Reference<css::frame::XController>& xController)
void SidebarController::unregisterSidebarForFrame(const css::uno::Reference<css::frame::XController>& xController)
{
    pController->saveDeckState();
    pController->disposeDecks();
    saveDeckState();
    disposeDecks();

    css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
        css::ui::ContextChangeEventMultiplexer::get(
            ::comphelper::getProcessComponentContext()));
    xMultiplexer->removeContextChangeEventListener(
        static_cast<css::ui::XContextChangeEventListener*>(pController),
        static_cast<css::ui::XContextChangeEventListener*>(this),
        xController);
}

@@ -328,7 +329,7 @@ void SidebarController::disposing(std::unique_lock<std::mutex>&)
    if (!xController.is())
        xController = mxCurrentController;

    unregisterSidebarForFrame(this, xController);
    unregisterSidebarForFrame(xController);
}

void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
@@ -548,6 +549,8 @@ void SidebarController::UpdateConfigurations()
            (maCurrentContext.msApplication != maRequestedContext.msApplication))
    {
        OUString sLastActiveDeck = mpResourceManager->GetLastActiveDeck( maRequestedContext );
        if (comphelper::LibreOfficeKit::isActive() && sLastActiveDeck == "PropertyDeck" && maRequestedContext.msApplication == "com.sun.star.formula.FormulaProperties")
            sLastActiveDeck = "ElementsDeck"; // Manual override for lok
        if (!sLastActiveDeck.isEmpty())
            msCurrentDeckId = sLastActiveDeck;
    }
@@ -1591,9 +1594,9 @@ void SidebarController::frameAction(const css::frame::FrameActionEvent& rEvent)
    if (rEvent.Frame == mxFrame)
    {
        if (rEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING)
            unregisterSidebarForFrame(this, mxFrame->getController());
            unregisterSidebarForFrame(mxFrame->getController());
        else if (rEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED)
            registerSidebarForFrame(this, mxFrame->getController());
            registerSidebarForFrame(mxFrame->getController());
    }
}

@@ -1609,10 +1612,18 @@ void SidebarController::saveDeckState()
    }
}

static bool isChartOrMathContext(const Context& context)
{
    return context.msApplication == "com.sun.star.chart2.ChartDocument"
           || context.msApplication == "com.sun.star.formula.FormulaProperties";
}

bool SidebarController::hasChartOrMathContextCurrently() const
{
    return GetCurrentContext().msApplication == "com.sun.star.chart2.ChartDocument"
           || GetCurrentContext().msApplication == "com.sun.star.formula.FormulaProperties";
    if ((maRequestedContext != maCurrentContext) && isChartOrMathContext(maRequestedContext))
        return true; // We are not yet changed, but in the process

    return isChartOrMathContext(maCurrentContext);
}

sfx2::sidebar::SidebarController* SidebarController::GetSidebarControllerForView(const SfxViewShell* pViewShell)
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
index 56896a0..71dd3bc 100644
--- a/starmath/source/view.cxx
+++ b/starmath/source/view.cxx
@@ -2099,29 +2099,6 @@ void SmViewShell::GetState(SfxItemSet &rSet)

namespace
{
css::uno::Reference<css::ui::XSidebar>
getSidebarFromModel(const css::uno::Reference<css::frame::XModel>& xModel)
{
    css::uno::Reference<css::container::XChild> xChild(xModel, css::uno::UNO_QUERY);
    if (!xChild.is())
        return nullptr;

    css::uno::Reference<css::frame::XModel> xParent(xChild->getParent(), css::uno::UNO_QUERY);
    if (!xParent.is())
        return nullptr;

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

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

    return xSidebarProvider->getSidebar();
}

class SmController : public SfxBaseController
{
public:
@@ -2141,14 +2118,7 @@ public:
        SfxBaseController::attachFrame(xFrame);

        // No need to call mpSelectionChangeHandler->Connect() unless SmController implements XSelectionSupplier
        if (auto xSidebar = getSidebarFromModel(getModel()))
        {
            auto pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get());
            assert(pSidebar);
            sfx2::sidebar::SidebarController::registerSidebarForFrame(pSidebar, this);
            pSidebar->updateModel(getModel());
            mpSelectionChangeHandler->selectionChanged({}); // Installs the correct context
        }
        mpSelectionChangeHandler->selectionChanged({}); // Installs the correct context
    }

private: