Resolves: #i122095# React asynchronously to context changes

In order to avoid problems in SFX2

(cherry picked from commit 61ed9eac0583e34a9b69f0a1adcc208509e336a1)

Change-Id: I375603a28e788ce9257be308dc09a589240d0e58
diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx
index 887e245..969cc04 100644
--- a/sfx2/source/sidebar/SidebarController.cxx
+++ b/sfx2/source/sidebar/SidebarController.cxx
@@ -91,6 +91,7 @@ SidebarController::SidebarController (
      maCurrentContext(OUString(), OUString()),
      msCurrentDeckId(A2S("PropertyDeck")),
      maPropertyChangeForwarder(::boost::bind(&SidebarController::BroadcastPropertyChange, this)),
      maContextChangeUpdate(::boost::bind(&SidebarController::UpdateConfigurations, this)),
      mbIsDeckClosed(false),
      mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width())
{
@@ -167,10 +168,14 @@ void SAL_CALL SidebarController::disposing (void)
void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
    throw(cssu::RuntimeException)
{
    UpdateConfigurations(
        Context(
            rEvent.ApplicationName,
            rEvent.ContextName));
    // Update to the requested new context asynchronously to avoid
    // subtle errors caused by SFX2 which in rare cases can not
    // properly handle a synchronous update.
    maRequestedContext = Context(
        rEvent.ApplicationName,
        rEvent.ContextName);
    if (maRequestedContext != maCurrentContext)
        maContextChangeUpdate.RequestCall();
}


@@ -277,17 +282,17 @@ void SidebarController::NotifyResize (void)



void SidebarController::UpdateConfigurations (const Context& rContext)
void SidebarController::UpdateConfigurations (void)
{
    if (maCurrentContext != rContext)
    if (maCurrentContext != maRequestedContext)
    {
        maCurrentContext = rContext;
        maCurrentContext = maRequestedContext;

        // Notify the tab bar about the updated set of decks.
        ResourceManager::IdContainer aDeckIds;
        ResourceManager::Instance().GetMatchingDecks (
            aDeckIds,
            rContext,
            maCurrentContext,
            mxFrame);
        mpTabBar->SetDecks(aDeckIds);

@@ -308,13 +313,13 @@ void SidebarController::UpdateConfigurations (const Context& rContext)

        DeckDescriptor const* pDeckDescriptor = NULL;
        if ( ! bCurrentDeckMatches)
            pDeckDescriptor = ResourceManager::Instance().GetBestMatchingDeck(rContext, mxFrame);
            pDeckDescriptor = ResourceManager::Instance().GetBestMatchingDeck(maCurrentContext, mxFrame);
        else
            pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(msCurrentDeckId);
        if (pDeckDescriptor != NULL)
        {
            msCurrentDeckId = pDeckDescriptor->msId;
            SwitchToDeck(*pDeckDescriptor, rContext);
            SwitchToDeck(*pDeckDescriptor, maCurrentContext);

            // Tell the tab bar to highlight the button associated
            // with the deck.
@@ -327,7 +332,7 @@ void SidebarController::UpdateConfigurations (const Context& rContext)
        {
            DeckTitleBar* pTitleBar = mpCurrentDeck->GetTitleBar();
            if (pTitleBar != NULL)
                pTitleBar->SetTitle(msCurrentDeckTitle+A2S(" (")+rContext.msContext+A2S(")"));
                pTitleBar->SetTitle(msCurrentDeckTitle+A2S(" (")+maCurrentContext.msContext+A2S(")"));
        }
#endif
    }
@@ -861,7 +866,6 @@ bool SidebarController::CanModifyChildWindowWidth (void) const
    SfxSplitWindow* pSplitWindow = dynamic_cast<SfxSplitWindow*>(mpParentWindow->GetParent());
    if (pSplitWindow == NULL)
    {
        OSL_ASSERT(pSplitWindow!=NULL);
        return 0;
    }

diff --git a/sfx2/source/sidebar/SidebarController.hxx b/sfx2/source/sidebar/SidebarController.hxx
index 38ce50b..4ae0f7d 100644
--- a/sfx2/source/sidebar/SidebarController.hxx
+++ b/sfx2/source/sidebar/SidebarController.hxx
@@ -107,9 +107,11 @@ private:
    ::boost::scoped_ptr<TabBar> mpTabBar;
    cssu::Reference<css::frame::XFrame> mxFrame;
    Context maCurrentContext;
    Context maRequestedContext;
    ::rtl::OUString msCurrentDeckId;
    ::rtl::OUString msCurrentDeckTitle;
    AsynchronousCall maPropertyChangeForwarder;
    AsynchronousCall maContextChangeUpdate;
    bool mbIsDeckClosed;
    /** Before the deck is closed the sidebar width is saved into this variable,
        so that it can be restored when the deck is reopended.
@@ -118,7 +120,9 @@ private:
    FocusManager maFocusManager;

    DECL_LINK(WindowEventHandler, VclWindowEvent*);
    void UpdateConfigurations (const Context& rContext);
    /** Make maRequestedContext the current context.
    */
    void UpdateConfigurations (void);
    bool ArePanelSetsEqual (
        const SharedPanelContainer& rCurrentPanels,
        const ResourceManager::PanelContextDescriptorContainer& rRequestedPanels);