LCOV - code coverage report
Current view: top level - sfx2/source/sidebar - SidebarController.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 269 492 54.7 %
Date: 2014-04-11 Functions: 22 40 55.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include "SidebarController.hxx"
      20             : #include "Deck.hxx"
      21             : #include "DeckTitleBar.hxx"
      22             : #include "Panel.hxx"
      23             : #include "PanelTitleBar.hxx"
      24             : #include "SidebarPanel.hxx"
      25             : #include "SidebarResource.hxx"
      26             : #include "TabBar.hxx"
      27             : #include <sfx2/sidebar/Theme.hxx>
      28             : #include <sfx2/sidebar/SidebarChildWindow.hxx>
      29             : #include <sfx2/sidebar/Tools.hxx>
      30             : #include "SidebarDockingWindow.hxx"
      31             : #include "Context.hxx"
      32             : 
      33             : #include <sfx2/sfxresid.hxx>
      34             : #include <sfx2/sfxsids.hrc>
      35             : #include <sfx2/titledockwin.hxx>
      36             : #include "sfxlocal.hrc"
      37             : #include <vcl/floatwin.hxx>
      38             : #include <vcl/fixed.hxx>
      39             : #include "splitwin.hxx"
      40             : #include <svl/smplhint.hxx>
      41             : #include <tools/link.hxx>
      42             : #include <toolkit/helper/vclunohelper.hxx>
      43             : #include <comphelper/processfactory.hxx>
      44             : #include <comphelper/namedvaluecollection.hxx>
      45             : 
      46             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      47             : #include <com/sun/star/lang/XInitialization.hpp>
      48             : #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
      49             : #include <com/sun/star/ui/ContextChangeEventObject.hpp>
      50             : #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
      51             : #include <com/sun/star/util/XURLTransformer.hpp>
      52             : #include <com/sun/star/util/URL.hpp>
      53             : #include <com/sun/star/rendering/XSpriteCanvas.hpp>
      54             : 
      55             : #include <boost/bind.hpp>
      56             : #include <boost/function.hpp>
      57             : #include <boost/scoped_array.hpp>
      58             : 
      59             : 
      60             : using namespace css;
      61             : using namespace cssu;
      62             : using ::rtl::OUString;
      63             : 
      64             : 
      65             : #undef VERBOSE
      66             : 
      67             : namespace
      68             : {
      69             :     const static char gsReadOnlyCommandName[] = ".uno:EditDoc";
      70             :     const static sal_Int32 gnMaximumSidebarWidth (400);
      71             :     const static sal_Int32 gnWidthCloseThreshold (70);
      72             :     const static sal_Int32 gnWidthOpenThreshold (40);
      73             : }
      74             : 
      75             : 
      76             : namespace sfx2 { namespace sidebar {
      77             : 
      78         149 : SidebarController::SidebarControllerContainer SidebarController::maSidebarControllerContainer;
      79             : 
      80             : namespace {
      81             :     enum MenuId
      82             :     {
      83             :         MID_UNLOCK_TASK_PANEL = 1,
      84             :         MID_LOCK_TASK_PANEL,
      85             :         MID_CUSTOMIZATION,
      86             :         MID_RESTORE_DEFAULT,
      87             :         MID_FIRST_PANEL,
      88             :         MID_FIRST_HIDE = 1000
      89             :     };
      90             : 
      91             :     /** When in doubt, show this deck.
      92             :     */
      93             :     static const char gsDefaultDeckId[] = "PropertyDeck";
      94             : }
      95             : 
      96             : 
      97          17 : SidebarController::SidebarController (
      98             :     SidebarDockingWindow* pParentWindow,
      99             :     const cssu::Reference<css::frame::XFrame>& rxFrame)
     100             :     : SidebarControllerInterfaceBase(m_aMutex),
     101             :       mpCurrentDeck(),
     102             :       mpParentWindow(pParentWindow),
     103             :       mpTabBar(new TabBar(
     104             :               mpParentWindow,
     105             :               rxFrame,
     106             :               ::boost::bind(&SidebarController::OpenThenSwitchToDeck, this, _1),
     107          17 :               ::boost::bind(&SidebarController::ShowPopupMenu, this, _1,_2))),
     108             :       mxFrame(rxFrame),
     109             :       maCurrentContext(OUString(), OUString()),
     110             :       maRequestedContext(),
     111             :       mnRequestedForceFlags(SwitchFlag_NoForce),
     112             :       msCurrentDeckId(gsDefaultDeckId),
     113             :       msCurrentDeckTitle(),
     114             :       maPropertyChangeForwarder(::boost::bind(&SidebarController::BroadcastPropertyChange, this)),
     115             :       maContextChangeUpdate(::boost::bind(&SidebarController::UpdateConfigurations, this)),
     116             :       maAsynchronousDeckSwitch(),
     117             :       mbIsDeckRequestedOpen(),
     118             :       mbIsDeckOpen(),
     119             :       mbCanDeckBeOpened(true),
     120          34 :       mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()),
     121             :       maFocusManager(::boost::bind(&SidebarController::ShowPanel, this, _1)),
     122             :       mxReadOnlyModeDispatch(),
     123             :       mbIsDocumentReadOnly(false),
     124             :       mpSplitWindow(NULL),
     125             :       mnWidthOnSplitterButtonDown(0),
     126          68 :       mpCloseIndicator()
     127             : {
     128          17 :     if (pParentWindow == NULL)
     129             :     {
     130             :         OSL_ASSERT(pParentWindow!=NULL);
     131          17 :             return;
     132             :     }
     133             : 
     134             :     // Listen for context change events.
     135             :     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
     136             :         css::ui::ContextChangeEventMultiplexer::get(
     137          17 :             ::comphelper::getProcessComponentContext()));
     138          17 :     if (xMultiplexer.is())
     139          17 :         xMultiplexer->addContextChangeEventListener(
     140             :             static_cast<css::ui::XContextChangeEventListener*>(this),
     141          17 :             mxFrame->getController());
     142             : 
     143             :     // Listen for window events.
     144          17 :     mpParentWindow->AddEventListener(LINK(this, SidebarController, WindowEventHandler));
     145             : 
     146             :     // Listen for theme property changes.
     147          34 :     Theme::GetPropertySet()->addPropertyChangeListener(
     148             :         OUString(""),
     149          17 :         static_cast<css::beans::XPropertyChangeListener*>(this));
     150             : 
     151             :     // Get the dispatch object as preparation to listen for changes of
     152             :     // the read-only state.
     153          34 :     const util::URL aURL (Tools::GetURL(gsReadOnlyCommandName));
     154          17 :     mxReadOnlyModeDispatch = Tools::GetDispatch(mxFrame, aURL);
     155          17 :     if (mxReadOnlyModeDispatch.is())
     156          17 :         mxReadOnlyModeDispatch->addStatusListener(this, aURL);
     157             : 
     158          17 :     SwitchToDeck(OUString("default"));
     159             : 
     160          34 :     WeakReference<SidebarController> xWeakController (this);
     161             :     maSidebarControllerContainer.insert(
     162             :         SidebarControllerContainer::value_type(
     163             :             rxFrame,
     164          34 :             xWeakController));
     165             : }
     166             : 
     167             : 
     168             : 
     169             : 
     170          34 : SidebarController::~SidebarController (void)
     171             : {
     172          34 : }
     173             : 
     174             : 
     175             : 
     176             : 
     177           0 : SidebarController* SidebarController::GetSidebarControllerForFrame (
     178             :     const cssu::Reference<css::frame::XFrame>& rxFrame)
     179             : {
     180           0 :     SidebarControllerContainer::iterator iEntry (maSidebarControllerContainer.find(rxFrame));
     181           0 :     if (iEntry == maSidebarControllerContainer.end())
     182           0 :         return NULL;
     183             : 
     184           0 :     cssu::Reference<XInterface> xController (iEntry->second.get());
     185           0 :     if ( ! xController.is())
     186           0 :         return NULL;
     187             : 
     188           0 :     return dynamic_cast<SidebarController*>(xController.get());
     189             : }
     190             : 
     191             : 
     192             : 
     193             : 
     194          17 : void SAL_CALL SidebarController::disposing (void)
     195             : {
     196          17 :     SidebarControllerContainer::iterator iEntry (maSidebarControllerContainer.find(mxFrame));
     197          17 :     if (iEntry != maSidebarControllerContainer.end())
     198          17 :         maSidebarControllerContainer.erase(iEntry);
     199             : 
     200          17 :     maFocusManager.Clear();
     201             : 
     202             :     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
     203             :         css::ui::ContextChangeEventMultiplexer::get(
     204          17 :             ::comphelper::getProcessComponentContext()));
     205          17 :     if (xMultiplexer.is())
     206          17 :         xMultiplexer->removeAllContextChangeEventListeners(
     207          17 :             static_cast<css::ui::XContextChangeEventListener*>(this));
     208             : 
     209          17 :     if (mxReadOnlyModeDispatch.is())
     210          17 :         mxReadOnlyModeDispatch->removeStatusListener(this, Tools::GetURL(gsReadOnlyCommandName));
     211          17 :     if (mpSplitWindow != NULL)
     212             :     {
     213          17 :         mpSplitWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler));
     214          17 :         mpSplitWindow = NULL;
     215             :     }
     216             : 
     217          17 :     if (mpParentWindow != NULL)
     218             :     {
     219          17 :         mpParentWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler));
     220          17 :         mpParentWindow = NULL;
     221             :     }
     222             : 
     223          17 :     if (mpCurrentDeck)
     224             :     {
     225          11 :         mpCurrentDeck->Dispose();
     226          11 :         mpCurrentDeck->PrintWindowTree();
     227          11 :         mpCurrentDeck.reset();
     228             :     }
     229             : 
     230          17 :     mpTabBar.reset();
     231             : 
     232          34 :     Theme::GetPropertySet()->removePropertyChangeListener(
     233             :         OUString(""),
     234          17 :         static_cast<css::beans::XPropertyChangeListener*>(this));
     235             : 
     236          17 :     maContextChangeUpdate.CancelRequest();
     237          17 :     maAsynchronousDeckSwitch.CancelRequest();
     238          17 : }
     239             : 
     240             : 
     241             : 
     242             : 
     243          67 : void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
     244             :     throw(cssu::RuntimeException, std::exception)
     245             : {
     246             :     // Update to the requested new context asynchronously to avoid
     247             :     // subtle errors caused by SFX2 which in rare cases can not
     248             :     // properly handle a synchronous update.
     249         134 :     maRequestedContext = Context(
     250             :         rEvent.ApplicationName,
     251          67 :         rEvent.ContextName);
     252          67 :     if (maRequestedContext != maCurrentContext)
     253             :     {
     254          50 :         maAsynchronousDeckSwitch.CancelRequest();
     255          50 :         maContextChangeUpdate.RequestCall();
     256             :     }
     257          67 : }
     258             : 
     259             : 
     260             : 
     261             : 
     262           0 : void SAL_CALL SidebarController::disposing (const css::lang::EventObject& rEventObject)
     263             :     throw(cssu::RuntimeException, std::exception)
     264             : {
     265             :     (void)rEventObject;
     266             : 
     267           0 :     dispose();
     268           0 : }
     269             : 
     270             : 
     271             : 
     272             : 
     273           0 : void SAL_CALL SidebarController::propertyChange (const css::beans::PropertyChangeEvent& rEvent)
     274             :     throw(cssu::RuntimeException, std::exception)
     275             : {
     276             :     (void)rEvent;
     277             : 
     278           0 :     maPropertyChangeForwarder.RequestCall();
     279           0 : }
     280             : 
     281             : 
     282             : 
     283             : 
     284          26 : void SAL_CALL SidebarController::statusChanged (const css::frame::FeatureStateEvent& rEvent)
     285             :     throw(cssu::RuntimeException, std::exception)
     286             : {
     287          26 :     bool bIsReadWrite (true);
     288          26 :     if (rEvent.IsEnabled)
     289           2 :         rEvent.State >>= bIsReadWrite;
     290             : 
     291          26 :     if (mbIsDocumentReadOnly != !bIsReadWrite)
     292             :     {
     293           0 :         mbIsDocumentReadOnly = !bIsReadWrite;
     294             : 
     295             :         // Force the current deck to update its panel list.
     296           0 :         if ( ! mbIsDocumentReadOnly)
     297           0 :             msCurrentDeckId = gsDefaultDeckId;
     298           0 :         mnRequestedForceFlags |= SwitchFlag_ForceSwitch;
     299           0 :         maAsynchronousDeckSwitch.CancelRequest();
     300           0 :         maContextChangeUpdate.RequestCall();
     301             :     }
     302          26 : }
     303             : 
     304             : 
     305             : 
     306             : 
     307          28 : void SAL_CALL SidebarController::requestLayout (void)
     308             :     throw(cssu::RuntimeException, std::exception)
     309             : {
     310          28 :     sal_Int32 nMinimalWidth = 0;
     311          28 :     if (mpCurrentDeck)
     312             :     {
     313          28 :         mpCurrentDeck->RequestLayout();
     314          28 :         nMinimalWidth = mpCurrentDeck->GetMinimalWidth();
     315             :     }
     316          28 :     RestrictWidth(nMinimalWidth);
     317          28 : }
     318             : 
     319             : 
     320             : 
     321             : 
     322           0 : void SidebarController::BroadcastPropertyChange (void)
     323             : {
     324           0 :     DataChangedEvent aEvent (DATACHANGED_USER);
     325           0 :     mpParentWindow->NotifyAllChildren(aEvent);
     326           0 :     mpParentWindow->Invalidate(INVALIDATE_CHILDREN);
     327           0 : }
     328             : 
     329             : 
     330             : 
     331             : 
     332          88 : void SidebarController::NotifyResize (void)
     333             : {
     334          88 :     if (mpTabBar == 0)
     335             :     {
     336             :         OSL_ASSERT(mpTabBar!=0);
     337          88 :         return;
     338             :     }
     339             : 
     340          88 :     Window* pParentWindow = mpTabBar->GetParent();
     341          88 :     sal_Int32 nTabBarDefaultWidth = TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor();
     342             : 
     343          88 :     const sal_Int32 nWidth (pParentWindow->GetSizePixel().Width());
     344          88 :     const sal_Int32 nHeight (pParentWindow->GetSizePixel().Height());
     345             : 
     346          88 :     mbIsDeckOpen = (nWidth > nTabBarDefaultWidth);
     347             : 
     348          88 :     if (mnSavedSidebarWidth <= 0)
     349          17 :         mnSavedSidebarWidth = nWidth;
     350             : 
     351             :     bool bIsDeckVisible;
     352          88 :     if (mbCanDeckBeOpened)
     353             :     {
     354          88 :         const bool bIsOpening (nWidth > mnWidthOnSplitterButtonDown);
     355          88 :         if (bIsOpening)
     356          88 :             bIsDeckVisible = nWidth >= nTabBarDefaultWidth + gnWidthOpenThreshold;
     357             :         else
     358           0 :             bIsDeckVisible = nWidth >= nTabBarDefaultWidth + gnWidthCloseThreshold;
     359          88 :         mbIsDeckRequestedOpen = bIsDeckVisible;
     360          88 :         UpdateCloseIndicator(!bIsDeckVisible);
     361             :     }
     362             :     else
     363           0 :         bIsDeckVisible = false;
     364             : 
     365          88 :     SfxSplitWindow* pSplitWindow = GetSplitWindow();
     366          88 :     if ( mpCurrentDeck && pSplitWindow )
     367             :     {
     368             :         // Find out that which side of the Window do we need to attach the Sidebar?
     369          16 :         if ( pSplitWindow->GetAlign() == WINDOWALIGN_RIGHT )        // attach the Sidebar towards the right-side of screen
     370             :         {
     371             :             // Place the deck first.
     372             :             {
     373          16 :                 if (bIsDeckVisible)
     374             :                 {
     375          16 :                     mpCurrentDeck->setPosSizePixel(0,0, nWidth-nTabBarDefaultWidth, nHeight);
     376          16 :                     mpCurrentDeck->Show();
     377          16 :                     mpCurrentDeck->RequestLayout();
     378             :                 }
     379             :                 else
     380           0 :                     mpCurrentDeck->Hide();
     381             :             }
     382             : 
     383             :             // Now place the tab bar.
     384          16 :             mpTabBar->setPosSizePixel(nWidth-nTabBarDefaultWidth,0,nTabBarDefaultWidth,nHeight);
     385          16 :             mpTabBar->Show();
     386             :         }
     387           0 :         else if ( pSplitWindow->GetAlign() == WINDOWALIGN_LEFT)     // attach the Sidebar towards the left-side of screen
     388             :         {
     389             :             // Place the tab bar first.
     390           0 :             mpTabBar->setPosSizePixel(0,0,nTabBarDefaultWidth,nHeight);
     391           0 :             mpTabBar->Show();
     392             : 
     393             :             // Now place the deck.
     394           0 :             if (bIsDeckVisible)
     395             :             {
     396           0 :                 mpCurrentDeck->setPosSizePixel(nTabBarDefaultWidth,0, nWidth-nTabBarDefaultWidth, nHeight);
     397           0 :                 mpCurrentDeck->Show();
     398           0 :                 mpCurrentDeck->RequestLayout();
     399             :             }
     400             :             else
     401           0 :                 mpCurrentDeck->Hide();
     402             :         }
     403             :     }
     404             : 
     405             :     // Determine if the closer of the deck can be shown.
     406          88 :     sal_Int32 nMinimalWidth = 0;
     407          88 :     if (mpCurrentDeck)
     408             :     {
     409          16 :         DeckTitleBar* pTitleBar = mpCurrentDeck->GetTitleBar();
     410          16 :         if (pTitleBar != NULL && pTitleBar->IsVisible())
     411          16 :             pTitleBar->SetCloserVisible(CanModifyChildWindowWidth());
     412          16 :         nMinimalWidth = mpCurrentDeck->GetMinimalWidth();
     413             :     }
     414             : 
     415          88 :     RestrictWidth(nMinimalWidth);
     416             : }
     417             : 
     418             : 
     419             : 
     420             : 
     421           0 : void SidebarController::ProcessNewWidth (const sal_Int32 nNewWidth)
     422             : {
     423           0 :     if ( ! mbIsDeckRequestedOpen)
     424           0 :         return;
     425             : 
     426           0 :     if (mbIsDeckRequestedOpen.get())
     427             :      {
     428             :         // Deck became large enough to be shown.  Show it.
     429           0 :         mnSavedSidebarWidth = nNewWidth;
     430           0 :         RequestOpenDeck();
     431             :     }
     432             :     else
     433             :     {
     434             :         // Deck became too small.  Close it completely.
     435             :         // If window is wider than the tab bar then mark the deck as being visible, even when it its not.
     436             :         // This is to trigger an adjustment of the width to the width of the tab bar.
     437           0 :         mbIsDeckOpen = true;
     438           0 :         RequestCloseDeck();
     439             : 
     440           0 :         if (mnWidthOnSplitterButtonDown > TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor())
     441           0 :             mnSavedSidebarWidth = mnWidthOnSplitterButtonDown;
     442             :     }
     443             : }
     444             : 
     445             : 
     446             : 
     447             : 
     448          11 : void SidebarController::UpdateConfigurations (void)
     449             : {
     450          22 :     if (maCurrentContext != maRequestedContext
     451          11 :         || mnRequestedForceFlags!=SwitchFlag_NoForce)
     452             :     {
     453          11 :         maCurrentContext = maRequestedContext;
     454             : 
     455             :         // Find the set of decks that could be displayed for the new context.
     456          11 :         ResourceManager::DeckContextDescriptorContainer aDecks;
     457          11 :         ResourceManager::Instance().GetMatchingDecks (
     458             :             aDecks,
     459             :             maCurrentContext,
     460             :             mbIsDocumentReadOnly,
     461          22 :             mxFrame);
     462             : 
     463             :         // Notify the tab bar about the updated set of decks.
     464          11 :         mpTabBar->SetDecks(aDecks);
     465             : 
     466             :         // Find the new deck.  By default that is the same as the old
     467             :         // one.  If that is not set or not enabled, then choose the
     468             :         // first enabled deck.
     469          22 :         OUString sNewDeckId;
     470          11 :         for (ResourceManager::DeckContextDescriptorContainer::const_iterator
     471          11 :                  iDeck(aDecks.begin()),
     472          11 :                  iEnd(aDecks.end());
     473             :              iDeck!=iEnd;
     474             :              ++iDeck)
     475             :         {
     476          11 :             if (iDeck->mbIsEnabled)
     477             :             {
     478          11 :                 if (iDeck->msId.equals(msCurrentDeckId))
     479             :                 {
     480          11 :                     sNewDeckId = msCurrentDeckId;
     481          11 :                     break;
     482             :                 }
     483           0 :                 else if (sNewDeckId.getLength() == 0)
     484           0 :                     sNewDeckId = iDeck->msId;
     485             :             }
     486             :         }
     487             : 
     488          11 :         if (sNewDeckId.getLength() == 0)
     489             :         {
     490             :             // We did not find a valid deck.
     491           0 :             RequestCloseDeck();
     492          11 :             return;
     493             :         }
     494             : 
     495             :         // Tell the tab bar to highlight the button associated
     496             :         // with the deck.
     497          11 :         mpTabBar->HighlightDeck(sNewDeckId);
     498             : 
     499             :         const DeckDescriptor* pDescriptor =
     500          11 :             ResourceManager::Instance().GetDeckDescriptor(sNewDeckId);
     501             : 
     502          11 :         if (pDescriptor)
     503             :         {
     504             :             SwitchToDeck(
     505             :                 *pDescriptor,
     506          11 :                 maCurrentContext);
     507          11 :         }
     508             :     }
     509             : }
     510             : 
     511             : 
     512             : 
     513             : 
     514           0 : void SidebarController::OpenThenSwitchToDeck (
     515             :     const ::rtl::OUString& rsDeckId)
     516             : {
     517           0 :     RequestOpenDeck();
     518           0 :     SwitchToDeck(rsDeckId);
     519           0 :     mpTabBar->Invalidate();
     520           0 : }
     521             : 
     522             : 
     523             : 
     524             : 
     525           0 : void SidebarController::RequestSwitchToDeck (
     526             :     const ::rtl::OUString& rsDeckId)
     527             : {
     528           0 :     maContextChangeUpdate.CancelRequest();
     529             :     maAsynchronousDeckSwitch.RequestCall(
     530           0 :         ::boost::bind(&SidebarController::OpenThenSwitchToDeck, this, rsDeckId));
     531           0 : }
     532             : 
     533             : 
     534             : 
     535             : 
     536          17 : void SidebarController::SwitchToDeck (
     537             :     const ::rtl::OUString& rsDeckId)
     538             : {
     539          34 :     if ( ! msCurrentDeckId.equals(rsDeckId)
     540           0 :         || ! mbIsDeckOpen
     541          17 :         || mnRequestedForceFlags!=SwitchFlag_NoForce)
     542             :     {
     543          17 :         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(rsDeckId);
     544          17 :         if (pDeckDescriptor != NULL)
     545           0 :             SwitchToDeck(*pDeckDescriptor, maCurrentContext);
     546             :     }
     547          17 : }
     548             : 
     549             : 
     550             : 
     551             : 
     552          11 : void SidebarController::SwitchToDeck (
     553             :     const DeckDescriptor& rDeckDescriptor,
     554             :     const Context& rContext)
     555             : {
     556          11 :     maFocusManager.Clear();
     557             : 
     558          11 :     const bool bForceNewDeck ((mnRequestedForceFlags&SwitchFlag_ForceNewDeck)!=0);
     559          11 :     const bool bForceNewPanels ((mnRequestedForceFlags&SwitchFlag_ForceNewPanels)!=0);
     560          11 :     mnRequestedForceFlags = SwitchFlag_NoForce;
     561             : 
     562          22 :     if ( ! msCurrentDeckId.equals(rDeckDescriptor.msId)
     563          11 :         || bForceNewDeck)
     564             :     {
     565             :         // When the deck changes then destroy the deck and all panels
     566             :         // and create everything new.
     567           0 :         if (mpCurrentDeck)
     568             :         {
     569           0 :             mpCurrentDeck->Dispose();
     570           0 :             mpCurrentDeck.reset();
     571             :         }
     572             : 
     573           0 :         msCurrentDeckId = rDeckDescriptor.msId;
     574             :     }
     575          11 :     mpTabBar->HighlightDeck(msCurrentDeckId);
     576             : 
     577             :     // Determine the panels to display in the deck.
     578          11 :     ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors;
     579          11 :     ResourceManager::Instance().GetMatchingPanels(
     580             :         aPanelContextDescriptors,
     581             :         rContext,
     582             :         rDeckDescriptor.msId,
     583          22 :         mxFrame);
     584             : 
     585          11 :     if (aPanelContextDescriptors.empty())
     586             :     {
     587             :         // There are no panels to be displayed in the current context.
     588           0 :         if (EnumContext::GetContextEnum(rContext.msContext) != EnumContext::Context_Empty)
     589             :         {
     590             :             // Switch to the "empty" context and try again.
     591             :             SwitchToDeck(
     592             :                 rDeckDescriptor,
     593             :                 Context(
     594             :                     rContext.msApplication,
     595           0 :                     EnumContext::GetContextName(EnumContext::Context_Empty)));
     596           0 :             return;
     597             :         }
     598             :         else
     599             :         {
     600             :             // This is already the "empty" context. Looks like we have
     601             :             // to live with an empty deck.
     602             :         }
     603             :     }
     604             : 
     605             :     // Provide a configuration and Deck object.
     606          11 :     if ( ! mpCurrentDeck)
     607             :     {
     608             :         mpCurrentDeck.reset(
     609             :             new Deck(
     610             :                 rDeckDescriptor,
     611             :                 mpParentWindow,
     612          11 :                 ::boost::bind(&SidebarController::RequestCloseDeck, this)));
     613          11 :         msCurrentDeckTitle = rDeckDescriptor.msTitle;
     614             : 
     615             :     }
     616          11 :     if ( ! mpCurrentDeck)
     617           0 :         return;
     618             : 
     619             : #ifdef DEBUG
     620             :     // Show the context name in the deck title bar.
     621             :     DeckTitleBar* pDebugTitleBar = mpCurrentDeck->GetTitleBar();
     622             :     if (pDebugTitleBar != NULL)
     623             :         pDebugTitleBar->SetTitle(rDeckDescriptor.msTitle + " (" + maCurrentContext.msContext + ")");
     624             : #endif
     625             : 
     626             :     // Update the panel list.
     627          11 :     const sal_Int32 nNewPanelCount (aPanelContextDescriptors.size());
     628          22 :     SharedPanelContainer aNewPanels;
     629          11 :     const SharedPanelContainer& rCurrentPanels (mpCurrentDeck->GetPanels());
     630          11 :     aNewPanels.resize(nNewPanelCount);
     631          11 :     sal_Int32 nWriteIndex (0);
     632          11 :     bool bHasPanelSetChanged (false);
     633          22 :     for (sal_Int32 nReadIndex=0; nReadIndex<nNewPanelCount; ++nReadIndex)
     634             :     {
     635             :         const ResourceManager::PanelContextDescriptor& rPanelContexDescriptor (
     636          11 :             aPanelContextDescriptors[nReadIndex]);
     637             : 
     638             :         // Determine if the panel can be displayed.
     639          11 :         const bool bIsPanelVisible (!mbIsDocumentReadOnly || rPanelContexDescriptor.mbShowForReadOnlyDocuments);
     640          11 :         if ( ! bIsPanelVisible)
     641           0 :             continue;
     642             : 
     643             :         // Find the corresponding panel among the currently active
     644             :         // panels.
     645          11 :         SharedPanelContainer::const_iterator iPanel;
     646          11 :         if (bForceNewPanels)
     647             :         {
     648             :             // All panels have to be created in any case.  There is no
     649             :             // point in searching already existing panels.
     650           0 :             iPanel = rCurrentPanels.end();
     651             :         }
     652             :         else
     653             :         {
     654             :             iPanel = ::std::find_if(
     655             :                 rCurrentPanels.begin(),
     656             :                 rCurrentPanels.end(),
     657          11 :                 ::boost::bind(&Panel::HasIdPredicate, _1, ::boost::cref(rPanelContexDescriptor.msId)));
     658             :         }
     659          11 :         if (iPanel != rCurrentPanels.end())
     660             :         {
     661             :             // Panel already exists in current deck.  Reuse it.
     662           0 :             aNewPanels[nWriteIndex] = *iPanel;
     663           0 :             aNewPanels[nWriteIndex]->SetExpanded(rPanelContexDescriptor.mbIsInitiallyVisible);
     664             :         }
     665             :         else
     666             :         {
     667             :             // Panel does not yet exist or creation of new panels is forced.
     668             :             // Create it.
     669          22 :             aNewPanels[nWriteIndex] = CreatePanel(
     670             :                 rPanelContexDescriptor.msId,
     671             :                 mpCurrentDeck->GetPanelParentWindow(),
     672             :                 rPanelContexDescriptor.mbIsInitiallyVisible,
     673          11 :                 rContext);
     674          11 :             bHasPanelSetChanged = true;
     675             :         }
     676          11 :         if (aNewPanels[nWriteIndex] != 0)
     677             :         {
     678             :             // Depending on the context we have to change the command
     679             :             // for the "more options" dialog.
     680          11 :             PanelTitleBar* pTitleBar = aNewPanels[nWriteIndex]->GetTitleBar();
     681          11 :             if (pTitleBar != NULL)
     682             :             {
     683             :                 pTitleBar->SetMoreOptionsCommand(
     684             :                     rPanelContexDescriptor.msMenuCommand,
     685          11 :                     mxFrame);
     686             :             }
     687             : 
     688          11 :             ++nWriteIndex;
     689             :         }
     690             : 
     691             :     }
     692          11 :     aNewPanels.resize(nWriteIndex);
     693             : 
     694             :     // Activate the deck and the new set of panels.
     695          11 :     mpCurrentDeck->setPosSizePixel(
     696             :         0,
     697             :         0,
     698          33 :         mpParentWindow->GetSizePixel().Width()-TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor(),
     699          44 :         mpParentWindow->GetSizePixel().Height());
     700             : 
     701          11 :     mpCurrentDeck->SetPanels(aNewPanels);
     702          11 :     mpCurrentDeck->Show();
     703             : 
     704          11 :     mpParentWindow->SetText(rDeckDescriptor.msTitle);
     705             : 
     706          11 :     if (bHasPanelSetChanged)
     707          11 :         NotifyResize();
     708             : 
     709             :     // Tell the focus manager about the new panels and tab bar
     710             :     // buttons.
     711          11 :     maFocusManager.SetDeckTitle(mpCurrentDeck->GetTitleBar());
     712          11 :     maFocusManager.SetPanels(aNewPanels);
     713          11 :     mpTabBar->UpdateFocusManager(maFocusManager);
     714          22 :     UpdateTitleBarIcons();
     715             : }
     716             : 
     717             : 
     718             : 
     719             : 
     720          11 : SharedPanel SidebarController::CreatePanel (
     721             :     const OUString& rsPanelId,
     722             :     ::Window* pParentWindow,
     723             :     const bool bIsInitiallyExpanded,
     724             :     const Context& rContext)
     725             : {
     726          11 :     const PanelDescriptor* pPanelDescriptor = ResourceManager::Instance().GetPanelDescriptor(rsPanelId);
     727          11 :     if (pPanelDescriptor == NULL)
     728           0 :         return SharedPanel();
     729             : 
     730             :     // Create the panel which is the parent window of the UIElement.
     731             :     SharedPanel pPanel (new Panel(
     732             :         *pPanelDescriptor,
     733             :         pParentWindow,
     734             :         bIsInitiallyExpanded,
     735             :         ::boost::bind(&Deck::RequestLayout, mpCurrentDeck.get()),
     736          11 :         ::boost::bind(&SidebarController::GetCurrentContext, this)));
     737             : 
     738             :     // Create the XUIElement.
     739             :     Reference<ui::XUIElement> xUIElement (CreateUIElement(
     740          22 :             pPanel->GetComponentInterface(),
     741             :             pPanelDescriptor->msImplementationURL,
     742             :             pPanelDescriptor->mbWantsCanvas,
     743          44 :             rContext));
     744          11 :     if (xUIElement.is())
     745             :     {
     746             :         // Initialize the panel and add it to the active deck.
     747          11 :         pPanel->SetUIElement(xUIElement);
     748             :     }
     749             :     else
     750             :     {
     751           0 :         pPanel.reset();
     752             :     }
     753             : 
     754          22 :     return pPanel;
     755             : }
     756             : 
     757             : 
     758             : 
     759             : 
     760          11 : Reference<ui::XUIElement> SidebarController::CreateUIElement (
     761             :     const Reference<awt::XWindowPeer>& rxWindow,
     762             :     const ::rtl::OUString& rsImplementationURL,
     763             :     const bool bWantsCanvas,
     764             :     const Context& rContext)
     765             : {
     766             :     try
     767             :     {
     768          11 :         const Reference<XComponentContext> xComponentContext (::comphelper::getProcessComponentContext() );
     769             :         const Reference<ui::XUIElementFactory> xUIElementFactory =
     770          22 :                ui::theUIElementFactoryManager::get( xComponentContext );
     771             : 
     772             :        // Create the XUIElement.
     773          22 :         ::comphelper::NamedValueCollection aCreationArguments;
     774          11 :         aCreationArguments.put("Frame", makeAny(mxFrame));
     775          11 :         aCreationArguments.put("ParentWindow", makeAny(rxWindow));
     776          11 :         SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(mpParentWindow);
     777          11 :         if (pSfxDockingWindow != NULL)
     778          11 :             aCreationArguments.put("SfxBindings", makeAny(sal_uInt64(&pSfxDockingWindow->GetBindings())));
     779          11 :         aCreationArguments.put("Theme", Theme::GetPropertySet());
     780          11 :         aCreationArguments.put("Sidebar", makeAny(Reference<ui::XSidebar>(static_cast<ui::XSidebar*>(this))));
     781          11 :         if (bWantsCanvas)
     782             :         {
     783           0 :             Reference<rendering::XSpriteCanvas> xCanvas (VCLUnoHelper::GetWindow(rxWindow)->GetSpriteCanvas());
     784           0 :             aCreationArguments.put("Canvas", makeAny(xCanvas));
     785             :         }
     786          11 :         aCreationArguments.put("ApplicationName", makeAny(rContext.msApplication));
     787          11 :         aCreationArguments.put("ContextName", makeAny(rContext.msContext));
     788             : 
     789             :         Reference<ui::XUIElement> xUIElement(
     790          11 :             xUIElementFactory->createUIElement(
     791             :                 rsImplementationURL,
     792          11 :                 Sequence<beans::PropertyValue>(aCreationArguments.getPropertyValues())),
     793          22 :             UNO_QUERY_THROW);
     794             : 
     795          22 :         return xUIElement;
     796             :     }
     797           0 :     catch(const Exception& rException)
     798             :     {
     799             :         SAL_WARN("sfx.sidebar", "Cannot create panel: " << rException.Message);
     800           0 :         return NULL;
     801             :     }
     802             : }
     803             : 
     804             : 
     805             : 
     806             : 
     807         576 : IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent*, pEvent)
     808             : {
     809         288 :     if (pEvent==NULL)
     810           0 :         return sal_False;
     811             : 
     812         288 :     if (pEvent->GetWindow() == mpParentWindow)
     813             :     {
     814         162 :         switch (pEvent->GetId())
     815             :         {
     816             :             case VCLEVENT_WINDOW_SHOW:
     817             :             case VCLEVENT_WINDOW_RESIZE:
     818          77 :                 NotifyResize();
     819          77 :                 break;
     820             : 
     821             :             case VCLEVENT_WINDOW_DATACHANGED:
     822             :                 // Force an update of deck and tab bar to reflect
     823             :                 // changes in theme (high contrast mode).
     824           0 :                 Theme::HandleDataChange();
     825           0 :                 UpdateTitleBarIcons();
     826           0 :                 mpParentWindow->Invalidate();
     827           0 :                 mnRequestedForceFlags |= SwitchFlag_ForceNewDeck | SwitchFlag_ForceNewPanels;
     828           0 :                 maAsynchronousDeckSwitch.CancelRequest();
     829           0 :                 maContextChangeUpdate.RequestCall();
     830           0 :                 break;
     831             : 
     832             :             case SFX_HINT_DYING:
     833           0 :                 dispose();
     834           0 :                 break;
     835             : 
     836             :             case VCLEVENT_WINDOW_PAINT:
     837             :                 OSL_TRACE("Paint");
     838           0 :                 break;
     839             : 
     840             :             default:
     841          85 :                 break;
     842             :         }
     843             :     }
     844         126 :     else if (pEvent->GetWindow()==mpSplitWindow && mpSplitWindow!=NULL)
     845             :     {
     846         126 :         switch (pEvent->GetId())
     847             :         {
     848             :             case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
     849           0 :                 mnWidthOnSplitterButtonDown = mpParentWindow->GetSizePixel().Width();
     850           0 :                 break;
     851             : 
     852             :             case VCLEVENT_WINDOW_MOUSEBUTTONUP:
     853             :             {
     854           0 :                 ProcessNewWidth(mpParentWindow->GetSizePixel().Width());
     855           0 :                 mnWidthOnSplitterButtonDown = 0;
     856           0 :                 break;
     857             :             }
     858             : 
     859             :             case SFX_HINT_DYING:
     860           0 :                 dispose();
     861           0 :                 break;
     862             :          }
     863             :     }
     864             : 
     865         288 :     return sal_True;
     866             : }
     867             : 
     868             : 
     869             : 
     870             : 
     871           0 : void SidebarController::ShowPopupMenu (
     872             :     const Rectangle& rButtonBox,
     873             :     const ::std::vector<TabBar::DeckMenuData>& rMenuData) const
     874             : {
     875           0 :     ::boost::shared_ptr<PopupMenu> pMenu = CreatePopupMenu(rMenuData);
     876           0 :     pMenu->SetSelectHdl(LINK(this, SidebarController, OnMenuItemSelected));
     877             : 
     878             :     // pass toolbox button rect so the menu can stay open on button up
     879           0 :     Rectangle aBox (rButtonBox);
     880           0 :     aBox.Move(mpTabBar->GetPosPixel().X(), 0);
     881           0 :     pMenu->Execute(mpParentWindow, aBox, POPUPMENU_EXECUTE_DOWN);
     882           0 : }
     883             : 
     884             : 
     885             : 
     886             : 
     887           0 : ::boost::shared_ptr<PopupMenu> SidebarController::CreatePopupMenu (
     888             :     const ::std::vector<TabBar::DeckMenuData>& rMenuData) const
     889             : {
     890             :     // Create the top level popup menu.
     891           0 :     ::boost::shared_ptr<PopupMenu> pMenu (new PopupMenu());
     892           0 :     FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
     893           0 :     if (pMenuWindow != NULL)
     894             :     {
     895           0 :         pMenuWindow->SetPopupModeFlags(pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
     896             :     }
     897             : 
     898             :     // Create sub menu for customization (hiding of deck tabs.)
     899           0 :     PopupMenu* pCustomizationMenu = new PopupMenu();
     900             : 
     901           0 :     SidebarResource aLocalResource;
     902             : 
     903             :     // Add one entry for every tool panel element to individually make
     904             :     // them visible or hide them.
     905           0 :     sal_Int32 nIndex (0);
     906           0 :     for(::std::vector<TabBar::DeckMenuData>::const_iterator
     907           0 :             iItem(rMenuData.begin()),
     908           0 :             iEnd(rMenuData.end());
     909             :         iItem!=iEnd;
     910             :         ++iItem,++nIndex)
     911             :     {
     912           0 :         const sal_Int32 nMenuIndex (nIndex+MID_FIRST_PANEL);
     913           0 :         pMenu->InsertItem(nMenuIndex, iItem->msDisplayName, MIB_RADIOCHECK);
     914           0 :         pMenu->CheckItem(nMenuIndex, iItem->mbIsCurrentDeck ? sal_True : sal_False);
     915           0 :         pMenu->EnableItem(nMenuIndex, (iItem->mbIsEnabled&&iItem->mbIsActive) ? sal_True : sal_False);
     916             : 
     917           0 :         const sal_Int32 nSubMenuIndex (nIndex+MID_FIRST_HIDE);
     918           0 :         if (iItem->mbIsCurrentDeck)
     919             :         {
     920             :             // Don't allow the currently visible deck to be disabled.
     921           0 :             pCustomizationMenu->InsertItem(nSubMenuIndex, iItem->msDisplayName, MIB_RADIOCHECK);
     922           0 :             pCustomizationMenu->CheckItem(nSubMenuIndex, true);
     923             :         }
     924             :         else
     925             :         {
     926           0 :             pCustomizationMenu->InsertItem(nSubMenuIndex, iItem->msDisplayName, MIB_CHECKABLE);
     927           0 :             pCustomizationMenu->CheckItem(nSubMenuIndex, iItem->mbIsActive ? sal_True : sal_False);
     928             :         }
     929             :     }
     930             : 
     931           0 :     pMenu->InsertSeparator();
     932             : 
     933             :     // Add entry for docking or un-docking the tool panel.
     934           0 :     if (mpParentWindow->IsFloatingMode())
     935           0 :         pMenu->InsertItem(MID_LOCK_TASK_PANEL, SFX2_RESSTR(STR_SFX_DOCK));
     936             :     else
     937           0 :         pMenu->InsertItem(MID_UNLOCK_TASK_PANEL, SFX2_RESSTR(STR_SFX_UNDOCK));
     938             : 
     939           0 :     pCustomizationMenu->InsertSeparator();
     940           0 :     pCustomizationMenu->InsertItem(MID_RESTORE_DEFAULT, SFX2_RESSTR(STRING_RESTORE));
     941             : 
     942           0 :     pMenu->InsertItem(MID_CUSTOMIZATION, SFX2_RESSTR(STRING_CUSTOMIZATION));
     943           0 :     pMenu->SetPopupMenu(MID_CUSTOMIZATION, pCustomizationMenu);
     944             : 
     945           0 :     pMenu->RemoveDisabledEntries(false, false);
     946             : 
     947           0 :     return pMenu;
     948             : }
     949             : 
     950             : 
     951             : 
     952             : 
     953           0 : IMPL_LINK(SidebarController, OnMenuItemSelected, Menu*, pMenu)
     954             : {
     955           0 :     if (pMenu == NULL)
     956             :     {
     957             :         OSL_ENSURE(pMenu!=NULL, "sfx2::sidebar::SidebarController::OnMenuItemSelected: illegal menu!");
     958           0 :         return 0;
     959             :     }
     960             : 
     961           0 :     pMenu->Deactivate();
     962           0 :     const sal_Int32 nIndex (pMenu->GetCurItemId());
     963           0 :     switch (nIndex)
     964             :     {
     965             :         case MID_UNLOCK_TASK_PANEL:
     966           0 :             mpParentWindow->SetFloatingMode(true);
     967           0 :             break;
     968             : 
     969             :         case MID_LOCK_TASK_PANEL:
     970           0 :             mpParentWindow->SetFloatingMode(false);
     971           0 :             break;
     972             : 
     973             :         case MID_RESTORE_DEFAULT:
     974           0 :             mpTabBar->RestoreHideFlags();
     975           0 :             break;
     976             : 
     977             :         default:
     978             :         {
     979             :             try
     980             :             {
     981           0 :                 if (nIndex >= MID_FIRST_PANEL && nIndex<MID_FIRST_HIDE)
     982           0 :                     SwitchToDeck(mpTabBar->GetDeckIdForIndex(nIndex - MID_FIRST_PANEL));
     983           0 :                 else if (nIndex >=MID_FIRST_HIDE)
     984           0 :                     if (pMenu->GetItemBits(nIndex) == MIB_CHECKABLE)
     985           0 :                         mpTabBar->ToggleHideFlag(nIndex-MID_FIRST_HIDE);
     986             :             }
     987           0 :             catch (RuntimeException&)
     988             :             {
     989             :             }
     990             :         }
     991           0 :         break;
     992             :     }
     993             : 
     994           0 :     return 1;
     995             : }
     996             : 
     997             : 
     998             : 
     999             : 
    1000           0 : void SidebarController::RequestCloseDeck (void)
    1001             : {
    1002           0 :     mbIsDeckRequestedOpen = false;
    1003           0 :     UpdateDeckOpenState();
    1004           0 : }
    1005             : 
    1006             : 
    1007             : 
    1008             : 
    1009           0 : void SidebarController::RequestOpenDeck (void)
    1010             : {
    1011           0 :     mbIsDeckRequestedOpen = true;
    1012           0 :     UpdateDeckOpenState();
    1013           0 : }
    1014             : 
    1015             : 
    1016             : 
    1017             : 
    1018           0 : void SidebarController::UpdateDeckOpenState (void)
    1019             : {
    1020           0 :     if ( ! mbIsDeckRequestedOpen)
    1021             :         // No state requested.
    1022           0 :         return;
    1023             : 
    1024           0 :     sal_Int32 nTabBarDefaultWidth = TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor();
    1025             : 
    1026             :     // Update (change) the open state when it either has not yet been initialized
    1027             :     // or when its value differs from the requested state.
    1028           0 :     if ( ! mbIsDeckOpen
    1029           0 :         || mbIsDeckOpen.get() != mbIsDeckRequestedOpen.get())
    1030             :     {
    1031           0 :         if (mbIsDeckRequestedOpen.get())
    1032             :         {
    1033           0 :             if (mnSavedSidebarWidth <= nTabBarDefaultWidth)
    1034           0 :                 SetChildWindowWidth(SidebarChildWindow::GetDefaultWidth(mpParentWindow));
    1035             :             else
    1036           0 :                 SetChildWindowWidth(mnSavedSidebarWidth);
    1037             :         }
    1038             :         else
    1039             :         {
    1040           0 :             if ( ! mpParentWindow->IsFloatingMode())
    1041           0 :                 mnSavedSidebarWidth = SetChildWindowWidth(nTabBarDefaultWidth);
    1042           0 :             if (mnWidthOnSplitterButtonDown > nTabBarDefaultWidth)
    1043           0 :                 mnSavedSidebarWidth = mnWidthOnSplitterButtonDown;
    1044           0 :             mpParentWindow->SetStyle(mpParentWindow->GetStyle() & ~WB_SIZEABLE);
    1045             :         }
    1046             : 
    1047           0 :         mbIsDeckOpen = mbIsDeckRequestedOpen.get();
    1048           0 :         if (mbIsDeckOpen.get() && mpCurrentDeck)
    1049           0 :             mpCurrentDeck->Show(mbIsDeckOpen.get());
    1050           0 :         NotifyResize();
    1051             :     }
    1052             : }
    1053             : 
    1054             : 
    1055             : 
    1056             : 
    1057           0 : FocusManager& SidebarController::GetFocusManager (void)
    1058             : {
    1059           0 :     return maFocusManager;
    1060             : }
    1061             : 
    1062             : 
    1063             : 
    1064             : 
    1065          16 : bool SidebarController::CanModifyChildWindowWidth (void)
    1066             : {
    1067          16 :     SfxSplitWindow* pSplitWindow = GetSplitWindow();
    1068          16 :     if (pSplitWindow == NULL)
    1069           0 :         return false;
    1070             : 
    1071          16 :     sal_uInt16 nRow (0xffff);
    1072          16 :     sal_uInt16 nColumn (0xffff);
    1073          16 :     if (pSplitWindow->GetWindowPos(mpParentWindow, nColumn, nRow))
    1074             :     {
    1075          16 :         sal_uInt16 nRowCount (pSplitWindow->GetWindowCount(nColumn));
    1076          16 :         return nRowCount==1;
    1077             :     }
    1078             :     else
    1079           0 :         return false;
    1080             : }
    1081             : 
    1082             : 
    1083             : 
    1084             : 
    1085           0 : sal_Int32 SidebarController::SetChildWindowWidth (const sal_Int32 nNewWidth)
    1086             : {
    1087           0 :     SfxSplitWindow* pSplitWindow = GetSplitWindow();
    1088           0 :     if (pSplitWindow == NULL)
    1089           0 :         return 0;
    1090             : 
    1091           0 :     sal_uInt16 nRow (0xffff);
    1092           0 :     sal_uInt16 nColumn (0xffff);
    1093           0 :     pSplitWindow->GetWindowPos(mpParentWindow, nColumn, nRow);
    1094           0 :     const long nColumnWidth (pSplitWindow->GetLineSize(nColumn));
    1095             : 
    1096           0 :     Window* pWindow = mpParentWindow;
    1097           0 :     const Size aWindowSize (pWindow->GetSizePixel());
    1098             : 
    1099             :     pSplitWindow->MoveWindow(
    1100             :         mpParentWindow,
    1101             :         Size(nNewWidth, aWindowSize.Height()),
    1102             :         nColumn,
    1103           0 :         nRow);
    1104           0 :     static_cast<SplitWindow*>(pSplitWindow)->Split();
    1105             : 
    1106           0 :     return static_cast<sal_Int32>(nColumnWidth);
    1107             : }
    1108             : 
    1109             : 
    1110             : 
    1111             : 
    1112         116 : void SidebarController::RestrictWidth (sal_Int32 nWidth)
    1113             : {
    1114         116 :     SfxSplitWindow* pSplitWindow = GetSplitWindow();
    1115         116 :     if (pSplitWindow != NULL)
    1116             :     {
    1117         116 :         const sal_uInt16 nId (pSplitWindow->GetItemId(mpParentWindow));
    1118         116 :         const sal_uInt16 nSetId (pSplitWindow->GetSet(nId));
    1119             :         pSplitWindow->SetItemSizeRange(
    1120             :             nSetId,
    1121         116 :             Range(TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor() + nWidth,
    1122         232 :                   gnMaximumSidebarWidth * mpTabBar->GetDPIScaleFactor()));
    1123             :     }
    1124         116 : }
    1125             : 
    1126             : 
    1127             : 
    1128             : 
    1129         220 : SfxSplitWindow* SidebarController::GetSplitWindow (void)
    1130             : {
    1131         220 :     if (mpParentWindow != NULL)
    1132             :     {
    1133         220 :         SfxSplitWindow* pSplitWindow = dynamic_cast<SfxSplitWindow*>(mpParentWindow->GetParent());
    1134         220 :         if (pSplitWindow != mpSplitWindow)
    1135             :         {
    1136          17 :             if (mpSplitWindow != NULL)
    1137           0 :                 mpSplitWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler));
    1138             : 
    1139          17 :             mpSplitWindow = pSplitWindow;
    1140             : 
    1141          17 :             if (mpSplitWindow != NULL)
    1142          17 :                 mpSplitWindow->AddEventListener(LINK(this, SidebarController, WindowEventHandler));
    1143             :         }
    1144         220 :         return mpSplitWindow;
    1145             :     }
    1146             :     else
    1147           0 :         return NULL;
    1148             : }
    1149             : 
    1150             : 
    1151             : 
    1152             : 
    1153          88 : void SidebarController::UpdateCloseIndicator (const bool bCloseAfterDrag)
    1154             : {
    1155          88 :     if (mpParentWindow == NULL)
    1156          88 :         return;
    1157             : 
    1158          88 :     if (bCloseAfterDrag)
    1159             :     {
    1160             :         // Make sure that the indicator exists.
    1161           0 :         if ( ! mpCloseIndicator)
    1162             :         {
    1163           0 :             mpCloseIndicator.reset(new FixedImage(mpParentWindow));
    1164           0 :             FixedImage* pFixedImage = static_cast<FixedImage*>(mpCloseIndicator.get());
    1165           0 :             const Image aImage (Theme::GetImage(Theme::Image_CloseIndicator));
    1166           0 :             pFixedImage->SetImage(aImage);
    1167           0 :             pFixedImage->SetSizePixel(aImage.GetSizePixel());
    1168           0 :             pFixedImage->SetBackground(Theme::GetWallpaper(Theme::Paint_DeckBackground));
    1169             :         }
    1170             : 
    1171             :         // Place and show the indicator.
    1172           0 :         const Size aWindowSize (mpParentWindow->GetSizePixel());
    1173           0 :         const Size aImageSize (mpCloseIndicator->GetSizePixel());
    1174           0 :         mpCloseIndicator->SetPosPixel(
    1175             :             Point(
    1176           0 :                 aWindowSize.Width() - TabBar::GetDefaultWidth() * mpTabBar->GetDPIScaleFactor() - aImageSize.Width(),
    1177           0 :                 (aWindowSize.Height() - aImageSize.Height())/2));
    1178           0 :         mpCloseIndicator->Show();
    1179             :     }
    1180             :     else
    1181             :     {
    1182             :         // Hide but don't delete the indicator.
    1183          88 :         if (mpCloseIndicator)
    1184           0 :             mpCloseIndicator->Hide();
    1185             :     }
    1186             : }
    1187             : 
    1188             : 
    1189             : 
    1190             : 
    1191          11 : void SidebarController::UpdateTitleBarIcons (void)
    1192             : {
    1193          11 :     if ( ! mpCurrentDeck)
    1194          11 :         return;
    1195             : 
    1196          11 :     const bool bIsHighContrastModeActive (Theme::IsHighContrastMode());
    1197          11 :     const ResourceManager& rResourceManager (ResourceManager::Instance());
    1198             : 
    1199             :     // Update the deck icon.
    1200          11 :     const DeckDescriptor* pDeckDescriptor = rResourceManager.GetDeckDescriptor(mpCurrentDeck->GetId());
    1201          11 :     if (pDeckDescriptor != NULL && mpCurrentDeck->GetTitleBar())
    1202             :     {
    1203             :         const OUString sIconURL(
    1204             :             bIsHighContrastModeActive
    1205             :                 ? pDeckDescriptor->msHighContrastTitleBarIconURL
    1206          11 :                 : pDeckDescriptor->msTitleBarIconURL);
    1207          11 :         mpCurrentDeck->GetTitleBar()->SetIcon(Tools::GetImage(sIconURL, mxFrame));
    1208             :     }
    1209             : 
    1210             :     // Update the panel icons.
    1211          11 :     const SharedPanelContainer& rPanels (mpCurrentDeck->GetPanels());
    1212          22 :     for (SharedPanelContainer::const_iterator
    1213          11 :              iPanel(rPanels.begin()), iEnd(rPanels.end());
    1214             :              iPanel!=iEnd;
    1215             :              ++iPanel)
    1216             :     {
    1217          11 :         if ( ! *iPanel)
    1218           0 :             continue;
    1219          11 :         if ((*iPanel)->GetTitleBar() == NULL)
    1220           0 :             continue;
    1221          11 :         const PanelDescriptor* pPanelDescriptor = rResourceManager.GetPanelDescriptor((*iPanel)->GetId());
    1222          11 :         if (pPanelDescriptor == NULL)
    1223           0 :             continue;
    1224             :         const OUString sIconURL (
    1225             :             bIsHighContrastModeActive
    1226             :                ? pPanelDescriptor->msHighContrastTitleBarIconURL
    1227          11 :                : pPanelDescriptor->msTitleBarIconURL);
    1228          11 :         (*iPanel)->GetTitleBar()->SetIcon(Tools::GetImage(sIconURL, mxFrame));
    1229          11 :     }
    1230             : }
    1231             : 
    1232             : 
    1233             : 
    1234             : 
    1235           0 : void SidebarController::ShowPanel (const Panel& rPanel)
    1236             : {
    1237           0 :     if (mpCurrentDeck)
    1238           0 :         mpCurrentDeck->ShowPanel(rPanel);
    1239           0 : }
    1240             : 
    1241             : 
    1242             : 
    1243             : 
    1244           0 : Context SidebarController::GetCurrentContext (void) const
    1245             : {
    1246           0 :     return maCurrentContext;
    1247             : }
    1248             : 
    1249             : 
    1250         447 : } } // end of namespace sfx2::sidebar
    1251             : 
    1252             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10