From 603c089e4261a028d9ea70012cb5b1f4effcb545 Mon Sep 17 00:00:00 2001 From: Andre Fischer Date: Mon, 29 Apr 2013 07:44:43 +0000 Subject: Resolves: #i122082# Hide sidebar panels for read only documents (cherry picked from commit aae247a34cd6f3bf421e57bbec08837d73ddf258) Conflicts: sfx2/inc/sfx2/sidebar/SidebarChildWindow.hxx sfx2/inc/sfx2/sidebar/Theme.hxx sfx2/source/sidebar/SidebarChildWindow.cxx sfx2/source/sidebar/SidebarController.cxx sfx2/source/sidebar/SidebarDockingWindow.cxx Change-Id: Ib59132d6d5e177d5a02ee24973b0fb07114db60a --- include/sfx2/sidebar/SidebarChildWindow.hxx | 2 + include/sfx2/sidebar/Theme.hxx | 1 + .../data/org/openoffice/Office/UI/Sidebar.xcu | 9 + .../schema/org/openoffice/Office/UI/Sidebar.xcs | 6 + sfx2/source/sidebar/PanelDescriptor.hxx | 1 + sfx2/source/sidebar/ResourceManager.cxx | 107 +++-- sfx2/source/sidebar/ResourceManager.hxx | 23 +- sfx2/source/sidebar/SidebarChildWindow.cxx | 23 +- sfx2/source/sidebar/SidebarController.cxx | 448 +++++++++++++++------ sfx2/source/sidebar/SidebarController.hxx | 60 ++- sfx2/source/sidebar/SidebarDockingWindow.cxx | 6 +- sfx2/source/sidebar/TabBar.cxx | 36 +- sfx2/source/sidebar/TabBar.hxx | 3 +- sfx2/source/sidebar/TabItem.cxx | 5 +- sfx2/source/sidebar/Theme.cxx | 8 + 15 files changed, 535 insertions(+), 203 deletions(-) diff --git a/include/sfx2/sidebar/SidebarChildWindow.hxx b/include/sfx2/sidebar/SidebarChildWindow.hxx index 23f9194dba32..194f09893bac 100644 --- a/include/sfx2/sidebar/SidebarChildWindow.hxx +++ b/include/sfx2/sidebar/SidebarChildWindow.hxx @@ -40,6 +40,8 @@ public: SfxChildWinInfo* pInfo); SFX_DECL_CHILDWINDOW_WITHID(SidebarChildWindow); + + static sal_Int32 GetDefaultWidth (Window* pWindow); }; diff --git a/include/sfx2/sidebar/Theme.hxx b/include/sfx2/sidebar/Theme.hxx index d34866b7b179..0b75123ae35b 100644 --- a/include/sfx2/sidebar/Theme.hxx +++ b/include/sfx2/sidebar/Theme.hxx @@ -77,6 +77,7 @@ public: Image_PanelMenu, Image_ToolBoxItemSeparator, Image_Closer, + Image_CloseIndicator, __Image_Color, diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu index b435c9a7bbd5..9c9ff6365f28 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu @@ -831,6 +831,9 @@ true + + true + SwNavigatorPanel @@ -857,6 +860,9 @@ true + + true + ScNavigatorPanel @@ -883,6 +889,9 @@ true + + true + SdNavigatorPanel diff --git a/officecfg/registry/schema/org/openoffice/Office/UI/Sidebar.xcs b/officecfg/registry/schema/org/openoffice/Office/UI/Sidebar.xcs index f7a35a364a52..8d096b3a69c8 100644 --- a/officecfg/registry/schema/org/openoffice/Office/UI/Sidebar.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/UI/Sidebar.xcs @@ -201,6 +201,12 @@ 10000 + + + This flag controls whether the panel is shown when the document in the edit view is read only. + + false + Experimental: Set to true when panel wants to paint its content via a XCanvas. diff --git a/sfx2/source/sidebar/PanelDescriptor.hxx b/sfx2/source/sidebar/PanelDescriptor.hxx index cb39dbbc598f..d06fb0388fe9 100644 --- a/sfx2/source/sidebar/PanelDescriptor.hxx +++ b/sfx2/source/sidebar/PanelDescriptor.hxx @@ -38,6 +38,7 @@ public: ContextList maContextList; ::rtl::OUString msImplementationURL; sal_Int32 mnOrderIndex; + bool mbShowForReadOnlyDocuments; bool mbWantsCanvas; PanelDescriptor (void); diff --git a/sfx2/source/sidebar/ResourceManager.cxx b/sfx2/source/sidebar/ResourceManager.cxx index 070bb1c7ddd1..725471a27195 100644 --- a/sfx2/source/sidebar/ResourceManager.cxx +++ b/sfx2/source/sidebar/ResourceManager.cxx @@ -81,25 +81,6 @@ ResourceManager::~ResourceManager (void) -const DeckDescriptor* ResourceManager::GetBestMatchingDeck ( - const Context& rContext, - const Reference& rxFrame) -{ - ReadLegacyAddons(rxFrame); - - for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd(maDecks.end()); - iDeck!=iEnd; - ++iDeck) - { - if (iDeck->maContextList.GetMatch(rContext) != NULL) - return &*iDeck; - } - return NULL; -} - - - - const DeckDescriptor* ResourceManager::GetDeckDescriptor ( const ::rtl::OUString& rsDeckId) const { @@ -157,14 +138,15 @@ void ResourceManager::SetIsDeckEnabled ( -const ResourceManager::IdContainer& ResourceManager::GetMatchingDecks ( - IdContainer& rDeckIds, +const ResourceManager::DeckContextDescriptorContainer& ResourceManager::GetMatchingDecks ( + DeckContextDescriptorContainer& rDecks, const Context& rContext, + const bool bIsDocumentReadOnly, const Reference& rxFrame) { ReadLegacyAddons(rxFrame); - ::std::multimap aOrderedIds; + ::std::multimap aOrderedIds; for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd (maDecks.end()); @@ -172,22 +154,28 @@ const ResourceManager::IdContainer& ResourceManager::GetMatchingDecks ( ++iDeck) { const DeckDescriptor& rDeckDescriptor (*iDeck); - if (rDeckDescriptor.maContextList.GetMatch(rContext) != NULL) - aOrderedIds.insert(::std::multimap::value_type( - rDeckDescriptor.mnOrderIndex, - rDeckDescriptor.msId)); + if (rDeckDescriptor.maContextList.GetMatch(rContext) == NULL) + continue; + DeckContextDescriptor aDeckContextDescriptor; + aDeckContextDescriptor.msId = rDeckDescriptor.msId; + aDeckContextDescriptor.mbIsEnabled = + ! bIsDocumentReadOnly + || IsDeckEnabled(rDeckDescriptor.msId, rContext, rxFrame); + aOrderedIds.insert(::std::multimap::value_type( + rDeckDescriptor.mnOrderIndex, + aDeckContextDescriptor)); } - for (::std::multimap::const_iterator + for (::std::multimap::const_iterator iId(aOrderedIds.begin()), iEnd(aOrderedIds.end()); iId!=iEnd; ++iId) { - rDeckIds.push_back(iId->second); + rDecks.push_back(iId->second); } - return rDeckIds; + return rDecks; } @@ -209,20 +197,21 @@ const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatc ++iPanel) { const PanelDescriptor& rPanelDescriptor (*iPanel); - if (rPanelDescriptor.msDeckId.equals(rsDeckId)) - { - const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext); - if (pEntry != NULL) - { - PanelContextDescriptor aPanelContextDescriptor; - aPanelContextDescriptor.msId = rPanelDescriptor.msId; - aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand; - aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible; - aOrderedIds.insert(::std::multimap::value_type( - rPanelDescriptor.mnOrderIndex, - aPanelContextDescriptor)); - } - } + if ( ! rPanelDescriptor.msDeckId.equals(rsDeckId)) + continue; + + const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext); + if (pEntry == NULL) + continue; + + PanelContextDescriptor aPanelContextDescriptor; + aPanelContextDescriptor.msId = rPanelDescriptor.msId; + aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand; + aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible; + aPanelContextDescriptor.mbShowForReadOnlyDocuments = rPanelDescriptor.mbShowForReadOnlyDocuments; + aOrderedIds.insert(::std::multimap::value_type( + rPanelDescriptor.mnOrderIndex, + aPanelContextDescriptor)); } for (::std::multimap::const_iterator @@ -334,6 +323,8 @@ void ResourceManager::ReadPanelList (void) aPanelNode.getNodeValue("ImplementationURL")); rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32( aPanelNode.getNodeValue("OrderIndex")); + rPanelDescriptor.mbShowForReadOnlyDocuments = ::comphelper::getBOOL( + aPanelNode.getNodeValue("ShowForReadOnlyDocument")); rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL( aPanelNode.getNodeValue("WantsCanvas")); const OUString sDefaultMenuCommand (::comphelper::getString( @@ -555,6 +546,7 @@ void ResourceManager::ReadLegacyAddons (const Reference& rxFrame) rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL")); rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString()); rPanelDescriptor.msImplementationURL = rsNodeName; + rPanelDescriptor.mbShowForReadOnlyDocuments = false; } // When there where invalid nodes then we have to adapt the size @@ -641,4 +633,33 @@ void ResourceManager::GetToolPanelNodeNames ( + +bool ResourceManager::IsDeckEnabled ( + const OUString& rsDeckId, + const Context& rContext, + const Reference& rxFrame) const +{ + // Check if any panel that matches the current context can be + // displayed. + ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors; + ResourceManager::Instance().GetMatchingPanels( + aPanelContextDescriptors, + rContext, + rsDeckId, + rxFrame); + + for (ResourceManager::PanelContextDescriptorContainer::const_iterator + iPanel(aPanelContextDescriptors.begin()), + iEnd(aPanelContextDescriptors.end()); + iPanel!=iEnd; + ++iPanel) + { + if (iPanel->mbShowForReadOnlyDocuments) + return true; + } + + return false; +} + + } } // end of namespace sfx2::sidebar diff --git a/sfx2/source/sidebar/ResourceManager.hxx b/sfx2/source/sidebar/ResourceManager.hxx index cc9093c34b92..80c0b0b25c97 100644 --- a/sfx2/source/sidebar/ResourceManager.hxx +++ b/sfx2/source/sidebar/ResourceManager.hxx @@ -44,10 +44,6 @@ class ResourceManager public: static ResourceManager& Instance (void); - const DeckDescriptor* GetBestMatchingDeck ( - const Context& rContext, - const cssu::Reference& rxFrame); - const DeckDescriptor* GetDeckDescriptor ( const ::rtl::OUString& rsDeckId) const; const PanelDescriptor* GetPanelDescriptor ( @@ -64,19 +60,28 @@ public: const ::rtl::OUString& rsDeckId, const bool bIsEnabled); - typedef ::std::vector IdContainer; + class DeckContextDescriptor + { + public: + ::rtl::OUString msId; + bool mbIsEnabled; + }; + typedef ::std::vector DeckContextDescriptorContainer; + class PanelContextDescriptor { public: ::rtl::OUString msId; ::rtl::OUString msMenuCommand; bool mbIsInitiallyVisible; + bool mbShowForReadOnlyDocuments; }; typedef ::std::vector PanelContextDescriptorContainer; - const IdContainer& GetMatchingDecks ( - IdContainer& rDeckDescriptors, + const DeckContextDescriptorContainer& GetMatchingDecks ( + DeckContextDescriptorContainer& rDeckDescriptors, const Context& rContext, + const bool bIsDocumentReadOnly, const cssu::Reference& rxFrame); const PanelContextDescriptorContainer& GetMatchingPanels ( @@ -113,6 +118,10 @@ private: void GetToolPanelNodeNames ( ::std::vector& rMatchingNames, const ::utl::OConfigurationTreeRoot aRoot) const; + bool IsDeckEnabled ( + const ::rtl::OUString& rsDeckId, + const Context& rContext, + const cssu::Reference& rxFrame) const; }; diff --git a/sfx2/source/sidebar/SidebarChildWindow.cxx b/sfx2/source/sidebar/SidebarChildWindow.cxx index f02b37c54b40..cb001ceaf4c5 100644 --- a/sfx2/source/sidebar/SidebarChildWindow.cxx +++ b/sfx2/source/sidebar/SidebarChildWindow.cxx @@ -15,6 +15,8 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ + +#include "TabBar.hxx" #include "sfx2/sidebar/SidebarChildWindow.hxx" #include "SidebarDockingWindow.hxx" #include "sfx2/sfxsids.hrc" @@ -44,9 +46,9 @@ SidebarChildWindow::SidebarChildWindow ( eChildAlignment = SFX_ALIGN_RIGHT; this->pWindow->SetHelpId(HID_SIDEBAR_WINDOW); - this->pWindow->SetOutputSizePixel(Size(300, 450)); + this->pWindow->SetOutputSizePixel(Size(GetDefaultWidth(this->pWindow), 450)); - SfxDockingWindow* pDockingParent = dynamic_cast(pParentWindow); + SfxDockingWindow* pDockingParent = dynamic_cast(this->pWindow); if (pDockingParent != NULL) pDockingParent->Initialize(pInfo); SetHideNotDelete(sal_True); @@ -55,4 +57,21 @@ SidebarChildWindow::SidebarChildWindow ( } + + +sal_Int32 SidebarChildWindow::GetDefaultWidth (Window* pWindow) +{ + if (pWindow != NULL) + { + // Width of the paragraph panel. + const static sal_Int32 nMaxPropertyPageWidth (115); + + return pWindow->LogicToPixel(Point(nMaxPropertyPageWidth,1), MAP_APPFONT).X() + + TabBar::GetDefaultWidth(); + } + else + return 0; +} + + } } // end of namespace sfx2::sidebar diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx index c4584422856c..7a6ef5e20192 100644 --- a/sfx2/source/sidebar/SidebarController.cxx +++ b/sfx2/source/sidebar/SidebarController.cxx @@ -23,6 +23,7 @@ #include "SidebarResource.hxx" #include "TabBar.hxx" #include "sfx2/sidebar/Theme.hxx" +#include "sfx2/sidebar/SidebarChildWindow.hxx" #include "SidebarDockingWindow.hxx" #include "Context.hxx" #include "Tools.hxx" @@ -32,6 +33,7 @@ #include "sfx2/titledockwin.hxx" #include "sfxlocal.hrc" #include +#include #include "splitwin.hxx" #include #include @@ -61,6 +63,15 @@ using ::rtl::OUString; #undef VERBOSE +namespace +{ + const static OUString gsReadOnlyCommandName (A2S(".uno:EditDoc")); + const static sal_Int32 gnMaximumSidebarWidth (400); + const static sal_Int32 gnWidthCloseThreshold (70); + const static sal_Int32 gnWidthOpenThreshold (40); +} + + namespace sfx2 { namespace sidebar { namespace { @@ -85,15 +96,22 @@ SidebarController::SidebarController ( mpTabBar(new TabBar( mpParentWindow, rxFrame, - ::boost::bind(&SidebarController::SwitchToDeck, this, _1), + ::boost::bind(&SidebarController::OpenThenSwitchToDeck, this, _1), ::boost::bind(&SidebarController::ShowPopupMenu, this, _1,_2,_3))), mxFrame(rxFrame), maCurrentContext(OUString(), OUString()), msCurrentDeckId(A2S("PropertyDeck")), maPropertyChangeForwarder(::boost::bind(&SidebarController::BroadcastPropertyChange, this)), maContextChangeUpdate(::boost::bind(&SidebarController::UpdateConfigurations, this)), - mbIsDeckClosed(false), - mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()) + mbIsDeckRequestedOpen(), + mbIsDeckOpen(), + mbCanDeckBeOpened(true), + mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()), + mxReadOnlyModeDispatch(), + mbIsDocumentReadOnly(false), + mpSplitWindow(NULL), + mnWidthOnSplitterButtonDown(0), + mpCloseIndicator() { if (pParentWindow == NULL) { @@ -118,6 +136,13 @@ SidebarController::SidebarController ( A2S(""), static_cast(this)); + // Get the dispatch object as preparation to listen for changes of + // the read-only state. + const util::URL aURL (GetURL(gsReadOnlyCommandName)); + mxReadOnlyModeDispatch = GetDispatch(aURL); + if (mxReadOnlyModeDispatch.is()) + mxReadOnlyModeDispatch->addStatusListener(this, aURL); + SwitchToDeck(A2S("default")); } @@ -142,6 +167,14 @@ void SAL_CALL SidebarController::disposing (void) xMultiplexer->removeAllContextChangeEventListeners( static_cast(this)); + if (mxReadOnlyModeDispatch.is()) + mxReadOnlyModeDispatch->removeStatusListener(this, GetURL(gsReadOnlyCommandName)); + if (mpSplitWindow != NULL) + { + mpSplitWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler)); + mpSplitWindow = NULL; + } + if (mpParentWindow != NULL) { mpParentWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler)); @@ -203,6 +236,25 @@ void SAL_CALL SidebarController::propertyChange (const css::beans::PropertyChang +void SAL_CALL SidebarController::statusChanged (const css::frame::FeatureStateEvent& rEvent) + throw(cssu::RuntimeException) +{ + bool bIsReadWrite (true); + if (rEvent.IsEnabled) + rEvent.State >>= bIsReadWrite; + + if (mbIsDocumentReadOnly != !bIsReadWrite) + { + mbIsDocumentReadOnly = !bIsReadWrite; + + // Force the current deck to update its panel list. + SwitchToDeck(msCurrentDeckId); + } +} + + + + void SAL_CALL SidebarController::requestLayout (void) throw(cssu::RuntimeException) { @@ -237,12 +289,36 @@ void SidebarController::NotifyResize (void) const sal_Int32 nWidth (pParentWindow->GetSizePixel().Width()); const sal_Int32 nHeight (pParentWindow->GetSizePixel().Height()); + mbIsDeckOpen = (nWidth > TabBar::GetDefaultWidth()); + + if (mnSavedSidebarWidth <= 0) + mnSavedSidebarWidth = nWidth; + + bool bIsDeckVisible; + if (mbCanDeckBeOpened) + { + const bool bIsOpening (nWidth > mnWidthOnSplitterButtonDown); + if (bIsOpening) + bIsDeckVisible = nWidth >= TabBar::GetDefaultWidth() + gnWidthOpenThreshold; + else + bIsDeckVisible = nWidth >= TabBar::GetDefaultWidth() + gnWidthCloseThreshold; + mbIsDeckRequestedOpen = bIsDeckVisible; + UpdateCloseIndicator(!bIsDeckVisible); + } + else + bIsDeckVisible = false; + // Place the deck. if (mpCurrentDeck) { - mpCurrentDeck->setPosSizePixel(0,0, nWidth-TabBar::GetDefaultWidth(), nHeight); - mpCurrentDeck->Show(); - mpCurrentDeck->RequestLayout(); + if (bIsDeckVisible) + { + mpCurrentDeck->setPosSizePixel(0,0, nWidth-TabBar::GetDefaultWidth(), nHeight); + mpCurrentDeck->Show(); + mpCurrentDeck->RequestLayout(); + } + else + mpCurrentDeck->Hide(); } // Place the tab bar. @@ -257,26 +333,34 @@ void SidebarController::NotifyResize (void) pTitleBar->SetCloserVisible(CanModifyChildWindowWidth()); } - if (nWidth > TabBar::GetDefaultWidth()) - mnSavedSidebarWidth = nWidth; - RestrictWidth(); -#ifdef VERBOSE - if (mpCurrentDeck) +} + + + + +void SidebarController::ProcessNewWidth (const sal_Int32 nNewWidth) +{ + if ( ! mbIsDeckRequestedOpen) + return; + + if (mbIsDeckRequestedOpen.get()) + { + // Deck became large enough to be shown. Show it. + mnSavedSidebarWidth = nNewWidth; + RequestOpenDeck(); + } + else { - mpCurrentDeck->PrintWindowTree(); - sal_Int32 nPanelIndex (0); - for (SharedPanelContainer::const_iterator - iPanel(mpCurrentDeck->GetPanels().begin()), - iEnd(mpCurrentDeck->GetPanels().end()); - iPanel!=iEnd; - ++iPanel,++nPanelIndex) - { - OSL_TRACE("panel %d:", nPanelIndex); - (*iPanel)->PrintWindowTree(); - } + // Deck became too small. Close it completely. + // If window is wider than the tab bar then mark the deck as being visible, even when it its not. + // This is to trigger an adjustment of the width to the width of the tab bar. + mbIsDeckOpen = true; + RequestCloseDeck(); + + if (mnWidthOnSplitterButtonDown > TabBar::GetDefaultWidth()) + mnSavedSidebarWidth = mnWidthOnSplitterButtonDown; } -#endif } @@ -288,44 +372,56 @@ void SidebarController::UpdateConfigurations (void) { maCurrentContext = maRequestedContext; - // Notify the tab bar about the updated set of decks. - ResourceManager::IdContainer aDeckIds; + // Find the set of decks that could be displayed for the new context. + ResourceManager::DeckContextDescriptorContainer aDecks; ResourceManager::Instance().GetMatchingDecks ( - aDeckIds, + aDecks, maCurrentContext, + mbIsDocumentReadOnly, mxFrame); - mpTabBar->SetDecks(aDeckIds); + mpTabBar->SetDecks(aDecks); - // Check if the current deck is among the matching decks. - bool bCurrentDeckMatches (false); - for (ResourceManager::IdContainer::const_iterator - iDeck(aDeckIds.begin()), - iEnd(aDeckIds.end()); + // Notify the tab bar about the updated set of decks. + mpTabBar->SetDecks(aDecks); + + // Find the new deck. By default that is the same as the old + // one. If that is not set or not enabled, then choose the + // first enabled deck. + OUString sNewDeckId; + for (ResourceManager::DeckContextDescriptorContainer::const_iterator + iDeck(aDecks.begin()), + iEnd(aDecks.end()); iDeck!=iEnd; ++iDeck) { - if (iDeck->equals(msCurrentDeckId)) + if (iDeck->mbIsEnabled) { - bCurrentDeckMatches = true; - break; + if (iDeck->msId.equals(msCurrentDeckId)) + { + sNewDeckId = msCurrentDeckId; + break; + } + else if (sNewDeckId.getLength() == 0) + sNewDeckId = iDeck->msId; } } - DeckDescriptor const* pDeckDescriptor = NULL; - if ( ! bCurrentDeckMatches) - pDeckDescriptor = ResourceManager::Instance().GetBestMatchingDeck(maCurrentContext, mxFrame); - else - pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(msCurrentDeckId); - if (pDeckDescriptor != NULL) + if (sNewDeckId.getLength() == 0) { - msCurrentDeckId = pDeckDescriptor->msId; - SwitchToDeck(*pDeckDescriptor, maCurrentContext); + // We did not find a valid deck. + RequestCloseDeck(); + return; // Tell the tab bar to highlight the button associated // with the deck. - mpTabBar->HighlightDeck(msCurrentDeckId); + mpTabBar->HighlightDeck(sNewDeckId); } + msCurrentDeckId = sNewDeckId; + SwitchToDeck( + *ResourceManager::Instance().GetDeckDescriptor(sNewDeckId), + maCurrentContext); + #ifdef DEBUG // Show the context name in the deck title bar. if (mpCurrentDeck) @@ -341,10 +437,20 @@ void SidebarController::UpdateConfigurations (void) +void SidebarController::OpenThenSwitchToDeck ( + const ::rtl::OUString& rsDeckId) +{ + RequestOpenDeck(); + SwitchToDeck(rsDeckId); +} + + + + void SidebarController::SwitchToDeck ( const ::rtl::OUString& rsDeckId) { - if ( ! msCurrentDeckId.equals(rsDeckId) || mbIsDeckClosed) + if ( ! msCurrentDeckId.equals(rsDeckId) || ! mbIsDeckOpen) { const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(rsDeckId); if (pDeckDescriptor != NULL) @@ -374,9 +480,6 @@ void SidebarController::SwitchToDeck ( msCurrentDeckId = rDeckDescriptor.msId; } - // Reopen the deck when necessary. - OpenDeck(); - // Determine the panels to display in the deck. ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors; ResourceManager::Instance().GetMatchingPanels( @@ -413,6 +516,12 @@ void SidebarController::SwitchToDeck ( return; } + // When the document is read-only, check if there are any panels that can still be displayed. + if (mbIsDocumentReadOnly) + { + } + + // Provide a configuration and Deck object. if ( ! mpCurrentDeck) { @@ -420,7 +529,7 @@ void SidebarController::SwitchToDeck ( new Deck( rDeckDescriptor, mpParentWindow, - ::boost::bind(&SidebarController::CloseDeck, this))); + ::boost::bind(&SidebarController::RequestCloseDeck, this))); msCurrentDeckTitle = rDeckDescriptor.msTitle; } if ( ! mpCurrentDeck) @@ -438,6 +547,11 @@ void SidebarController::SwitchToDeck ( const ResourceManager::PanelContextDescriptor& rPanelContexDescriptor ( aPanelContextDescriptors[nReadIndex]); + // Determine if the panel can be displayed. + const bool bIsPanelVisible (!mbIsDocumentReadOnly || rPanelContexDescriptor.mbShowForReadOnlyDocuments); + if ( ! bIsPanelVisible) + continue; + // Find the corresponding panel among the currently active // panels. SharedPanelContainer::const_iterator iPanel (::std::find_if( @@ -501,28 +615,6 @@ bool SidebarController::ArePanelSetsEqual ( const SharedPanelContainer& rCurrentPanels, const ResourceManager::PanelContextDescriptorContainer& rRequestedPanels) { -#ifdef VERBOSE - OSL_TRACE("current panel list:"); - for (SharedPanelContainer::const_iterator - iPanel(rCurrentPanels.begin()), - iEnd(rCurrentPanels.end()); - iPanel!=iEnd; - ++iPanel) - { - OSL_TRACE(" panel %s", S2A((*iPanel)->GetId())); - } - - OSL_TRACE("requested panels: "); - for (ResourceManager::PanelContextDescriptorContainer::const_iterator - iId(rRequestedPanels.begin()), - iEnd(rRequestedPanels.end()); - iId!=iEnd; - ++iId) - { - OSL_TRACE(" panel %s", S2A(iId->msId)); - } -#endif - if (rCurrentPanels.size() != rRequestedPanels.size()) return false; for (sal_Int32 nIndex=0,nCount=rCurrentPanels.size(); nIndexGetId().equals(rRequestedPanels[nIndex].msId)) return false; + + // Check if the panels still can be displayed. This may not be the case when + // the document just become rea-only. + if (mbIsDocumentReadOnly && ! rRequestedPanels[nIndex].mbShowForReadOnlyDocuments) + return false; } return true; } @@ -626,14 +723,13 @@ Reference SidebarController::CreateUIElement ( IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent*, pEvent) { - if (pEvent != NULL) + if (pEvent==NULL) + return sal_False; + + if (pEvent->GetWindow() == mpParentWindow) { switch (pEvent->GetId()) { - case VCLEVENT_WINDOW_GETFOCUS: - case VCLEVENT_WINDOW_LOSEFOCUS: - break; - case VCLEVENT_WINDOW_SHOW: case VCLEVENT_WINDOW_RESIZE: NotifyResize(); @@ -651,10 +747,34 @@ IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent*, pEvent) dispose(); break; + case VCLEVENT_WINDOW_PAINT: + OSL_TRACE("Paint"); + break; + default: break; } } + else if (pEvent->GetWindow()==mpSplitWindow && mpSplitWindow!=NULL) + { + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_MOUSEBUTTONDOWN: + mnWidthOnSplitterButtonDown = mpParentWindow->GetSizePixel().Width(); + break; + + case VCLEVENT_WINDOW_MOUSEBUTTONUP: + { + ProcessNewWidth(mpParentWindow->GetSizePixel().Width()); + mnWidthOnSplitterButtonDown = 0; + break; + } + + case SFX_HINT_DYING: + dispose(); + break; + } + } return sal_True; } @@ -683,16 +803,8 @@ void SidebarController::ShowDetailMenu (const ::rtl::OUString& rsMenuCommand) co { try { - util::URL aURL; - aURL.Complete = rsMenuCommand; - - const ::comphelper::ComponentContext aComponentContext (::comphelper::getProcessServiceFactory()); - const Reference xParser ( - aComponentContext.createComponent("com.sun.star.util.URLTransformer"), - UNO_QUERY_THROW); - xParser->parseStrict(aURL); - Reference xProvider (mxFrame, UNO_QUERY_THROW); - Reference xDispatch (xProvider->queryDispatch(aURL, OUString(), 0)); + const util::URL aURL (GetURL(rsMenuCommand)); + Reference xDispatch (GetDispatch(aURL)); if (xDispatch.is()) xDispatch->dispatch(aURL, Sequence()); } @@ -706,6 +818,33 @@ void SidebarController::ShowDetailMenu (const ::rtl::OUString& rsMenuCommand) co +util::URL SidebarController::GetURL (const ::rtl::OUString& rsCommand) const +{ + util::URL aURL; + aURL.Complete = rsCommand; + + const ::comphelper::ComponentContext aComponentContext (::comphelper::getProcessServiceFactory()); + const Reference xParser ( + aComponentContext.createComponent("com.sun.star.util.URLTransformer"), + UNO_QUERY_THROW); + xParser->parseStrict(aURL); + + return aURL; +} + + + + +Reference SidebarController::GetDispatch (const util::URL& rURL) const +{ + Reference xProvider (mxFrame, UNO_QUERY_THROW); + Reference xDispatch (xProvider->queryDispatch(rURL, OUString(), 0)); + return xDispatch; +} + + + + ::boost::shared_ptr SidebarController::CreatePopupMenu ( const ::std::vector& rDeckSelectionData, const ::std::vector& rDeckShowData) const @@ -819,35 +958,54 @@ IMPL_LINK(SidebarController, OnMenuItemSelected, Menu*, pMenu) -void SidebarController::CloseDeck (void) +void SidebarController::RequestCloseDeck (void) { - if ( ! mbIsDeckClosed) - { - mbIsDeckClosed = true; - if ( ! mpParentWindow->IsFloatingMode()) - mnSavedSidebarWidth = SetChildWindowWidth(TabBar::GetDefaultWidth()); - mpParentWindow->SetStyle(mpParentWindow->GetStyle() & ~WB_SIZEABLE); + mbIsDeckRequestedOpen = false; + UpdateDeckOpenState(); +} - if (mpCurrentDeck) - mpCurrentDeck->Hide(); - NotifyResize(); - } + + +void SidebarController::RequestOpenDeck (void) +{ + mbIsDeckRequestedOpen = true; + UpdateDeckOpenState(); } -void SidebarController::OpenDeck (void) +void SidebarController::UpdateDeckOpenState (void) { - if (mbIsDeckClosed) - { - mbIsDeckClosed = false; - SetChildWindowWidth(mnSavedSidebarWidth); + if ( ! mbIsDeckRequestedOpen) + // No state requested. + return; - if (mpCurrentDeck) - mpCurrentDeck->Show(); + // Update (change) the open state when it either has not yet been initialized + // or when its value differs from the requested state. + if ( ! mbIsDeckOpen + || mbIsDeckOpen.get() != mbIsDeckRequestedOpen.get()) + { + if (mbIsDeckRequestedOpen.get()) + { + if (mnSavedSidebarWidth <= TabBar::GetDefaultWidth()) + SetChildWindowWidth(SidebarChildWindow::GetDefaultWidth(mpParentWindow)); + else + SetChildWindowWidth(mnSavedSidebarWidth); + } + else + { + if ( ! mpParentWindow->IsFloatingMode()) + mnSavedSidebarWidth = SetChildWindowWidth(TabBar::GetDefaultWidth()); + if (mnWidthOnSplitterButtonDown > TabBar::GetDefaultWidth()) + mnSavedSidebarWidth = mnWidthOnSplitterButtonDown; + mpParentWindow->SetStyle(mpParentWindow->GetStyle() & ~WB_SIZEABLE); + } + mbIsDeckOpen = mbIsDeckRequestedOpen.get(); + if (mbIsDeckOpen.get() && mpCurrentDeck) + mpCurrentDeck->Show(mbIsDeckOpen.get()); NotifyResize(); } } @@ -863,13 +1021,11 @@ FocusManager& SidebarController::GetFocusManager (void) -bool SidebarController::CanModifyChildWindowWidth (void) const +bool SidebarController::CanModifyChildWindowWidth (void) { - SfxSplitWindow* pSplitWindow = dynamic_cast(mpParentWindow->GetParent()); + SfxSplitWindow* pSplitWindow = GetSplitWindow(); if (pSplitWindow == NULL) - { - return 0; - } + return false; sal_uInt16 nRow (0xffff); sal_uInt16 nColumn (0xffff); @@ -877,7 +1033,7 @@ bool SidebarController::CanModifyChildWindowWidth (void) const sal_uInt16 nRowCount (pSplitWindow->GetWindowCount(nColumn)); - return nRowCount == 1; + return nRowCount==1; } @@ -885,7 +1041,7 @@ bool SidebarController::CanModifyChildWindowWidth (void) const sal_Int32 SidebarController::SetChildWindowWidth (const sal_Int32 nNewWidth) { - SfxSplitWindow* pSplitWindow = dynamic_cast(mpParentWindow->GetParent()); + SfxSplitWindow* pSplitWindow = GetSplitWindow(); if (pSplitWindow == NULL) return 0; @@ -903,6 +1059,7 @@ sal_Int32 SidebarController::SetChildWindowWidth (const sal_Int32 nNewWidth) Size(nNewWidth, aWindowSize.Height()), nColumn, nRow); + static_cast(pSplitWindow)->Split(); return static_cast(nColumnWidth); } @@ -912,23 +1069,70 @@ sal_Int32 SidebarController::SetChildWindowWidth (const sal_Int32 nNewWidth) void SidebarController::RestrictWidth (void) { - SfxSplitWindow* pSplitWindow = dynamic_cast(mpParentWindow->GetParent()); + SfxSplitWindow* pSplitWindow = GetSplitWindow(); if (pSplitWindow != NULL) { const sal_uInt16 nId (pSplitWindow->GetItemId(mpParentWindow)); const sal_uInt16 nSetId (pSplitWindow->GetSet(nId)); - // Minimum width is always that of the tabbar. - const sal_Int32 nMinimumWidth (TabBar::GetDefaultWidth()); - // Maximum width depends on whether the deck is open or closed. - const sal_Int32 nMaximumWidth ( - mbIsDeckClosed - ? TabBar::GetDefaultWidth() - : 400); pSplitWindow->SetItemSizeRange( nSetId, - Range(nMinimumWidth, nMaximumWidth)); - if (nMinimumWidth == nMaximumWidth) - pSplitWindow->SetItemSize(nSetId, nMinimumWidth); + Range(TabBar::GetDefaultWidth(), gnMaximumSidebarWidth)); + } +} + + + + +SfxSplitWindow* SidebarController::GetSplitWindow (void) +{ + if (mpSplitWindow == NULL) + { + if (mpParentWindow != NULL) + { + mpSplitWindow = dynamic_cast(mpParentWindow->GetParent()); + if (mpSplitWindow != NULL) + mpSplitWindow->AddEventListener(LINK(this, SidebarController, WindowEventHandler)); + } + } + + return mpSplitWindow; +} + + + + +void SidebarController::UpdateCloseIndicator (const bool bCloseAfterDrag) +{ + if (mpParentWindow == NULL) + return; + + if (bCloseAfterDrag) + { + // Make sure that the indicator exists. + if ( ! mpCloseIndicator) + { + mpCloseIndicator.reset(new FixedImage(mpParentWindow)); + FixedImage* pFixedImage = static_cast(mpCloseIndicator.get()); + const Image aImage (Theme::GetImage(Theme::Image_CloseIndicator)); + pFixedImage->SetImage(aImage); + pFixedImage->SetSizePixel(aImage.GetSizePixel()); + pFixedImage->SetBackground(Theme::GetWallpaper(Theme::Paint_DeckBackground)); + } + + // Place and show the indicator. + const Size aWindowSize (mpParentWindow->GetSizePixel()); + const Size aImageSize (mpCloseIndicator->GetSizePixel()); + mpCloseIndicator->SetPosPixel( + Point( + aWindowSize.Width() - TabBar::GetDefaultWidth() - aImageSize.Width(), + (aWindowSize.Height() - aImageSize.Height())/2)); + mpCloseIndicator->Show(); + } + else + { + // Hide but don't delete the indicator. + if (mpCloseIndicator) + mpCloseIndicator->Hide(); } } diff --git a/sfx2/source/sidebar/SidebarController.hxx b/sfx2/source/sidebar/SidebarController.hxx index 2d2773690622..0aa088306ca5 100644 --- a/sfx2/source/sidebar/SidebarController.hxx +++ b/sfx2/source/sidebar/SidebarController.hxx @@ -29,12 +29,14 @@ #include #include +#include #include #include #include #include -#include +#include +#include #include namespace css = ::com::sun::star; @@ -43,13 +45,17 @@ namespace cssu = ::com::sun::star::uno; namespace { - typedef ::cppu::WeakComponentImplHelper3 < + typedef ::cppu::WeakComponentImplHelper4 < css::ui::XContextChangeEventListener, css::beans::XPropertyChangeListener, - css::ui::XSidebar + css::ui::XSidebar, + css::frame::XStatusListener > SidebarControllerInterfaceBase; } +class SfxSplitWindow; +class FixedBitmap; + namespace sfx2 { namespace sidebar { class ContentPanelDescriptor; @@ -82,6 +88,10 @@ public: virtual void SAL_CALL propertyChange (const css::beans::PropertyChangeEvent& rEvent) throw(cssu::RuntimeException); + // frame::XStatusListener + virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent) + throw(cssu::RuntimeException); + // ui::XSidebar virtual void SAL_CALL requestLayout (void) throw(cssu::RuntimeException); @@ -90,14 +100,16 @@ public: void SwitchToDeck ( const ::rtl::OUString& rsDeckId); + void OpenThenSwitchToDeck ( + const ::rtl::OUString& rsDeckId); /** Show only the tab bar, not the deck. */ - void CloseDeck (void); + void RequestCloseDeck (void); /** Open the deck area and restore the parent window to its old width. */ - void OpenDeck (void); + void RequestOpenDeck (void); FocusManager& GetFocusManager (void); @@ -112,12 +124,36 @@ private: ::rtl::OUString msCurrentDeckTitle; AsynchronousCall maPropertyChangeForwarder; AsynchronousCall maContextChangeUpdate; - bool mbIsDeckClosed; + + /** Two flags control whether the deck is displayed or if only the + tab bar remains visible. + The mbIsDeckOpen flag stores the current state while + mbIsDeckRequestedOpen stores how this state should be. User + actions like clicking on the deck closer affect the + mbIsDeckRequestedOpen. Normally both flags have the same + value. A document being read-only can prevent the deck from opening. + */ + ::boost::optional mbIsDeckRequestedOpen; + ::boost::optional mbIsDeckOpen; + bool mbCanDeckBeOpened; + /** Before the deck is closed the sidebar width is saved into this variable, so that it can be restored when the deck is reopended. */ sal_Int32 mnSavedSidebarWidth; FocusManager maFocusManager; + cssu::Reference mxReadOnlyModeDispatch; + bool mbIsDocumentReadOnly; + SfxSplitWindow* mpSplitWindow; + /** When the user moves the splitter then we remember the + width at that time. + */ + sal_Int32 mnWidthOnSplitterButtonDown; + /** Control that is temporarily used as replacement for the deck + to indicate that when the current mouse drag operation ends, the + sidebar will only show the tab bar. + */ + ::boost::scoped_ptr mpCloseIndicator; DECL_LINK(WindowEventHandler, VclWindowEvent*); /** Make maRequestedContext the current context. @@ -141,6 +177,8 @@ private: const ::std::vector& rDeckSelectionData, const ::std::vector& rDeckShowData) const; void ShowDetailMenu (const ::rtl::OUString& rsMenuCommand) const; + css::util::URL GetURL (const ::rtl::OUString& rsCommand) const; + cssu::Reference GetDispatch (const css::util::URL& rURL) const; ::boost::shared_ptr CreatePopupMenu ( const ::std::vector& rDeckSelectionData, const ::std::vector& rDeckShowData) const; @@ -151,21 +189,25 @@ private: That is only possible if there is no other docking window docked above or below the sidebar. Return whether the width of the child window can be modified. */ - bool CanModifyChildWindowWidth (void) const; + bool CanModifyChildWindowWidth (void); /** Set the child window container to a new width. Return the old width. */ sal_Int32 SetChildWindowWidth (const sal_Int32 nNewWidth); - void RestrictWidth (void); - /** Update the icons displayed in the title bars of the deck and the panels. This is called once when a deck is created and every time when a data change event is processed. */ void UpdateTitleBarIcons (void); + void UpdateDeckOpenState (void); + void RestrictWidth (void); + SfxSplitWindow* GetSplitWindow (void); + void ProcessNewWidth (const sal_Int32 nNewWidth); + void UpdateCloseIndicator (const bool bIsIndicatorVisible); + virtual void SAL_CALL disposing (void); }; diff --git a/sfx2/source/sidebar/SidebarDockingWindow.cxx b/sfx2/source/sidebar/SidebarDockingWindow.cxx index ccfdbaaa3705..1e01bb72b939 100644 --- a/sfx2/source/sidebar/SidebarDockingWindow.cxx +++ b/sfx2/source/sidebar/SidebarDockingWindow.cxx @@ -33,9 +33,9 @@ namespace sfx2 { namespace sidebar { SidebarDockingWindow::SidebarDockingWindow( SfxBindings* pSfxBindings, SidebarChildWindow& rChildWindow, - Window* pParent, + Window* pParentWindow, WinBits nBits) - : SfxDockingWindow(pSfxBindings, &rChildWindow, pParent, nBits), + : SfxDockingWindow(pSfxBindings, &rChildWindow, pParentWindow, nBits), mpSidebarController() { // Get the XFrame from the bindings. @@ -117,7 +117,7 @@ sal_Bool SidebarDockingWindow::Close (void) { // Do not close the floating window. // Dock it and close just the deck instead. - mpSidebarController->CloseDeck(); + mpSidebarController->RequestCloseDeck(); SetFloatingMode(sal_False); mpSidebarController->NotifyResize(); return sal_False; diff --git a/sfx2/source/sidebar/TabBar.cxx b/sfx2/source/sidebar/TabBar.cxx index c30953bbdd94..feebb14ec223 100644 --- a/sfx2/source/sidebar/TabBar.cxx +++ b/sfx2/source/sidebar/TabBar.cxx @@ -101,7 +101,7 @@ sal_Int32 TabBar::GetDefaultWidth (void) void TabBar::SetDecks ( - const ResourceManager::IdContainer& rDeckIds) + const ResourceManager::DeckContextDescriptorContainer& rDecks) { // Remove the current buttons. { @@ -115,15 +115,15 @@ void TabBar::SetDecks ( maItems.clear(); } - maItems.resize(rDeckIds.size()); + maItems.resize(rDecks.size()); sal_Int32 nIndex (0); - for (ResourceManager::IdContainer::const_iterator - iDeckId(rDeckIds.begin()), - iEnd(rDeckIds.end()); - iDeckId!=iEnd; - ++iDeckId) + for (ResourceManager::DeckContextDescriptorContainer::const_iterator + iDeck(rDecks.begin()), + iEnd(rDecks.end()); + iDeck!=iEnd; + ++iDeck) { - const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(*iDeckId); + const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(iDeck->msId); if (pDescriptor == NULL) { OSL_ASSERT(pDescriptor!=NULL); @@ -137,6 +137,8 @@ void TabBar::SetDecks ( rItem.maDeckActivationFunctor = maDeckActivationFunctor; rItem.mbIsHiddenByDefault = false; rItem.mbIsHidden = ! pDescriptor->mbIsEnabled; + + rItem.mpButton->Enable(iDeck->mbIsEnabled); } UpdateButtonIcons(); @@ -218,16 +220,24 @@ void TabBar::Layout (void) void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId) { - for (ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end()); + Item* pItem = GetItemForId(rsDeckId); + if (pItem != NULL) + pItem->mpButton->Check(); +} + + + + +TabBar::Item* TabBar::GetItemForId (const ::rtl::OUString& rsDeckId) +{ + for (ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end()); iItem!=iEnd; ++iItem) { if (iItem->msDeckId.equals(rsDeckId)) - { - iItem->mpButton->Check(); - break; - } + return &*iItem; } + return NULL; } diff --git a/sfx2/source/sidebar/TabBar.hxx b/sfx2/source/sidebar/TabBar.hxx index 50ea6f3537d0..2f158cb6ea7a 100644 --- a/sfx2/source/sidebar/TabBar.hxx +++ b/sfx2/source/sidebar/TabBar.hxx @@ -70,7 +70,7 @@ public: static sal_Int32 GetDefaultWidth (void); void SetDecks ( - const ResourceManager::IdContainer& rDeckIds); + const ResourceManager::DeckContextDescriptorContainer& rDecks); void HighlightDeck (const ::rtl::OUString& rsDeckId); void AddPopupMenuEntries ( PopupMenu& rMenu, @@ -104,6 +104,7 @@ private: PopupMenuProvider maPopupMenuProvider; RadioButton* CreateTabItem (const DeckDescriptor& rDeckDescriptor); + Item* GetItemForId (const ::rtl::OUString& rsId); Image GetItemImage (const DeckDescriptor& rDeskDescriptor) const; void Layout (void); void UpdateButtonIcons (void); diff --git a/sfx2/source/sidebar/TabItem.cxx b/sfx2/source/sidebar/TabItem.cxx index 059fabdf6d7b..8bc0fd9fdb74 100644 --- a/sfx2/source/sidebar/TabItem.cxx +++ b/sfx2/source/sidebar/TabItem.cxx @@ -55,7 +55,6 @@ TabItem::~TabItem (void) void TabItem::Paint (const Rectangle& rUpdateArea) { - OSL_TRACE("TabItem::Paint"); switch(mePaintType) { case PT_Theme: @@ -81,12 +80,12 @@ void TabItem::Paint (const Rectangle& rUpdateArea) (GetSizePixel().Height() - aIconSize.Height())/2); DrawImage( aIconLocation, - aIcon); + aIcon, + IsEnabled() ? 0 : IMAGE_DRAW_DISABLE); break; } case PT_Native: Button::Paint(rUpdateArea); - // DrawImage(maIconPosition, maIcon); break; } } diff --git a/sfx2/source/sidebar/Theme.cxx b/sfx2/source/sidebar/Theme.cxx index b7ef8b5896c5..81d951731f74 100644 --- a/sfx2/source/sidebar/Theme.cxx +++ b/sfx2/source/sidebar/Theme.cxx @@ -361,6 +361,12 @@ void Theme::UpdateTheme (void) setPropertyValue( maPropertyIdToNameMap[Image_Closer], Any(A2S("private:graphicrepository/sfx2/res/closedoc.png"))); + setPropertyValue( + maPropertyIdToNameMap[Image_CloseIndicator], + Any( + mbIsHighContrastMode + ? A2S("private:graphicrepository/res/commandimagelist/lch_decrementlevel.png") + : A2S("private:graphicrepository/res/commandimagelist/lc_decrementlevel.png"))); setPropertyValue( maPropertyIdToNameMap[Image_ToolBoxItemSeparator], Any( @@ -778,6 +784,7 @@ void Theme::SetupPropertyMaps (void) AddEntry(Image_PanelMenu); AddEntry(Image_ToolBoxItemSeparator); AddEntry(Image_Closer); + AddEntry(Image_CloseIndicator); AddEntry(Color_DeckTitleFont); AddEntry(Color_PanelTitleFont); @@ -847,6 +854,7 @@ Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem) case Image_PanelMenu: case Image_ToolBoxItemSeparator: case Image_Closer: + case Image_CloseIndicator: return PT_Image; case Color_DeckTitleFont: -- cgit v1.2.3