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

Generated by: LCOV version 1.10