LCOV - code coverage report
Current view: top level - sfx2/source/sidebar - TabBar.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 118 175 67.4 %
Date: 2015-06-13 12:38:46 Functions: 15 23 65.2 %
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             : 
      20             : #include "TabBar.hxx"
      21             : #include "TabItem.hxx"
      22             : #include <sfx2/sidebar/ControlFactory.hxx>
      23             : #include "DeckDescriptor.hxx"
      24             : #include "Paint.hxx"
      25             : #include <sfx2/sidebar/Theme.hxx>
      26             : #include <sfx2/sidebar/Tools.hxx>
      27             : #include "FocusManager.hxx"
      28             : 
      29             : #include <vcl/gradient.hxx>
      30             : #include <vcl/image.hxx>
      31             : #include <vcl/wrkwin.hxx>
      32             : #include <comphelper/processfactory.hxx>
      33             : #include <tools/svborder.hxx>
      34             : 
      35             : #include <com/sun/star/graphic/XGraphicProvider.hpp>
      36             : 
      37             : using namespace css;
      38             : using namespace css::uno;
      39             : 
      40             : namespace sfx2 { namespace sidebar {
      41             : 
      42        3155 : TabBar::TabBar(vcl::Window* pParentWindow,
      43             :                const Reference<frame::XFrame>& rxFrame,
      44             :                const boost::function<void(const OUString&)>& rDeckActivationFunctor,
      45             :                const PopupMenuProvider& rPopupMenuProvider)
      46             :     : Window(pParentWindow, WB_DIALOGCONTROL),
      47             :       mxFrame(rxFrame),
      48             :       mpMenuButton(ControlFactory::CreateMenuButton(this)),
      49             :       maItems(),
      50             :       maDeckActivationFunctor(rDeckActivationFunctor),
      51        3155 :       maPopupMenuProvider(rPopupMenuProvider)
      52             : {
      53        3155 :     SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
      54             : 
      55        3155 :     mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu));
      56        3155 :     mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
      57        3155 :     Layout();
      58             : 
      59             : #ifdef DEBUG
      60             :     SetText(OUString("TabBar"));
      61             : #endif
      62        3155 : }
      63             : 
      64        9465 : TabBar::~TabBar()
      65             : {
      66        3155 :     disposeOnce();
      67        6310 : }
      68             : 
      69        3155 : void TabBar::dispose()
      70             : {
      71        6056 :     for(ItemContainer::iterator
      72        3155 :             iItem(maItems.begin()), iEnd(maItems.end());
      73             :         iItem!=iEnd;
      74             :         ++iItem)
      75        2901 :         iItem->mpButton.disposeAndClear();
      76        3155 :     maItems.clear();
      77        3155 :     mpMenuButton.disposeAndClear();
      78        3155 :     vcl::Window::dispose();
      79        3155 : }
      80             : 
      81        6376 : void TabBar::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rUpdateArea)
      82             : {
      83        6376 :     Window::Paint(rRenderContext, rUpdateArea);
      84             : 
      85        6376 :     const sal_Int32 nHorizontalPadding(Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
      86        6376 :     rRenderContext.SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
      87             :     rRenderContext.DrawLine(Point(nHorizontalPadding, mnMenuSeparatorY),
      88        6376 :                             Point(GetSizePixel().Width() - nHorizontalPadding, mnMenuSeparatorY));
      89        6376 : }
      90             : 
      91       50149 : sal_Int32 TabBar::GetDefaultWidth()
      92             : {
      93       50149 :     return Theme::GetInteger(Theme::Int_TabItemWidth)
      94       50149 :         + Theme::GetInteger(Theme::Int_TabBarLeftPadding)
      95       50149 :         + Theme::GetInteger(Theme::Int_TabBarRightPadding);
      96             : }
      97             : 
      98         610 : void TabBar::SetDecks(const ResourceManager::DeckContextDescriptorContainer& rDecks)
      99             : {
     100             :     // Remove the current buttons.
     101             :     {
     102         729 :         for(ItemContainer::iterator iItem(maItems.begin()); iItem != maItems.end(); ++iItem)
     103             :         {
     104         119 :             iItem->mpButton.disposeAndClear();
     105             :         }
     106         610 :         maItems.clear();
     107             :     }
     108         610 :     maItems.resize(rDecks.size());
     109         610 :     sal_Int32 nIndex (0);
     110       10890 :     for (ResourceManager::DeckContextDescriptorContainer::const_iterator
     111        7870 :              iDeck(rDecks.begin()); iDeck != rDecks.end(); ++iDeck)
     112             :     {
     113        3020 :         const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(iDeck->msId);
     114        3020 :         if (pDescriptor == NULL)
     115             :         {
     116             :             OSL_ASSERT(pDescriptor!=NULL);
     117           0 :             continue;
     118             :         }
     119             : 
     120        3020 :         Item& rItem (maItems[nIndex++]);
     121        3020 :         rItem.msDeckId = pDescriptor->msId;
     122        3020 :         rItem.mpButton.disposeAndClear();
     123        3020 :         rItem.mpButton = CreateTabItem(*pDescriptor);
     124        3020 :         rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
     125        3020 :         rItem.maDeckActivationFunctor = maDeckActivationFunctor;
     126        3020 :         rItem.mbIsHiddenByDefault = false;
     127        3020 :         rItem.mbIsHidden = ! pDescriptor->mbIsEnabled;
     128             : 
     129        3020 :         rItem.mpButton->Enable(iDeck->mbIsEnabled);
     130             :     }
     131             : 
     132         610 :     UpdateButtonIcons();
     133         610 :     Layout();
     134         610 : }
     135             : 
     136         613 : void TabBar::UpdateButtonIcons()
     137             : {
     138         613 :     Image aImage = Theme::GetImage(Theme::Image_TabBarMenu);
     139         613 :     if ( mpMenuButton->GetDPIScaleFactor() > 1 )
     140             :     {
     141           0 :         BitmapEx b = aImage.GetBitmapEx();
     142           0 :         b.Scale(mpMenuButton->GetDPIScaleFactor(), mpMenuButton->GetDPIScaleFactor(), BmpScaleFlag::Fast);
     143           0 :         aImage = Image(b);
     144             :     }
     145         613 :     mpMenuButton->SetModeImage(aImage);
     146             : 
     147        3633 :     for(ItemContainer::const_iterator
     148         613 :             iItem(maItems.begin()), iEnd(maItems.end());
     149             :         iItem!=iEnd;
     150             :         ++iItem)
     151             :     {
     152        3020 :         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
     153        3020 :         if (pDeckDescriptor != NULL)
     154             :         {
     155        3020 :             aImage = GetItemImage(*pDeckDescriptor);
     156        3020 :             if ( mpMenuButton->GetDPIScaleFactor() > 1 )
     157             :             {
     158           0 :                 BitmapEx b = aImage.GetBitmapEx();
     159           0 :                 b.Scale(mpMenuButton->GetDPIScaleFactor(), mpMenuButton->GetDPIScaleFactor(), BmpScaleFlag::Fast);
     160           0 :                 aImage = Image(b);
     161             :             }
     162             : 
     163        3020 :             iItem->mpButton->SetModeImage(aImage);
     164             :         }
     165             :     }
     166             : 
     167         613 :     Invalidate();
     168         613 : }
     169             : 
     170        3765 : void TabBar::Layout()
     171             : {
     172             :     const SvBorder aPadding (
     173        3765 :         Theme::GetInteger(Theme::Int_TabBarLeftPadding),
     174        3765 :         Theme::GetInteger(Theme::Int_TabBarTopPadding),
     175        3765 :         Theme::GetInteger(Theme::Int_TabBarRightPadding),
     176       15060 :         Theme::GetInteger(Theme::Int_TabBarBottomPadding));
     177        3765 :     sal_Int32 nX (aPadding.Top());
     178        3765 :     sal_Int32 nY (aPadding.Left());
     179             :     const Size aTabItemSize (
     180        3765 :         Theme::GetInteger(Theme::Int_TabItemWidth) * GetDPIScaleFactor(),
     181        7530 :         Theme::GetInteger(Theme::Int_TabItemHeight) * GetDPIScaleFactor());
     182             : 
     183             :     // Place the menu button and the separator.
     184        3765 :     if (mpMenuButton != nullptr)
     185             :     {
     186        3765 :         mpMenuButton->SetPosSizePixel(
     187             :             Point(nX,nY),
     188        3765 :             aTabItemSize);
     189        3765 :         mpMenuButton->Show();
     190        3765 :         nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
     191        3765 :         mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
     192             :     }
     193             : 
     194             :     // Place the deck selection buttons.
     195        6785 :     for(ItemContainer::const_iterator
     196        3765 :             iItem(maItems.begin()), iEnd(maItems.end());
     197             :         iItem!=iEnd;
     198             :         ++iItem)
     199             :     {
     200        3020 :         Button& rButton (*iItem->mpButton);
     201        3020 :         rButton.Show( ! iItem->mbIsHidden);
     202             : 
     203        3020 :         if (iItem->mbIsHidden)
     204           0 :             continue;
     205             : 
     206             :         // Place and size the icon.
     207             :         rButton.SetPosSizePixel(
     208             :             Point(nX,nY),
     209        3020 :             aTabItemSize);
     210        3020 :         rButton.Show();
     211             : 
     212        3020 :         nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
     213             :     }
     214        3765 :     Invalidate();
     215        3765 : }
     216             : 
     217        7579 : void TabBar::HighlightDeck (const OUString& rsDeckId)
     218             : {
     219       13815 :     for (ItemContainer::iterator iItem(maItems.begin()); iItem != maItems.end(); ++iItem)
     220             :     {
     221        6236 :         if (iItem->msDeckId.equals(rsDeckId))
     222        1269 :             iItem->mpButton->Check(true);
     223             :         else
     224        4967 :             iItem->mpButton->Check(false);
     225             :     }
     226        7579 : }
     227             : 
     228           0 : void TabBar::RemoveDeckHighlight ()
     229             : {
     230           0 :     for (ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
     231             :          iItem!=iEnd;
     232             :          ++iItem)
     233             :     {
     234           0 :         iItem->mpButton->Check(false);
     235             :     }
     236           0 : }
     237             : 
     238           3 : void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
     239             : {
     240           3 :     SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
     241           3 :     UpdateButtonIcons();
     242             : 
     243           3 :     Window::DataChanged(rDataChangedEvent);
     244           3 : }
     245             : 
     246        6351 : bool TabBar::Notify (NotifyEvent&)
     247             : {
     248        6351 :     return false;
     249             : }
     250             : 
     251        3020 : VclPtr<RadioButton> TabBar::CreateTabItem(const DeckDescriptor& rDeckDescriptor)
     252             : {
     253        3020 :     VclPtr<RadioButton> pItem = ControlFactory::CreateTabItem(this);
     254        3020 :     pItem->SetAccessibleName(rDeckDescriptor.msTitle);
     255        3020 :     pItem->SetAccessibleDescription(rDeckDescriptor.msHelpText);
     256        3020 :     pItem->SetHelpText(rDeckDescriptor.msHelpText);
     257        3020 :     pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
     258        3020 :     return pItem;
     259             : }
     260             : 
     261        3020 : Image TabBar::GetItemImage(const DeckDescriptor& rDeckDescriptor) const
     262             : {
     263             :     return Tools::GetImage(
     264             :         rDeckDescriptor.msIconURL,
     265             :         rDeckDescriptor.msHighContrastIconURL,
     266        3020 :         mxFrame);
     267             : }
     268             : 
     269           0 : IMPL_LINK(TabBar::Item, HandleClick, Button*,)
     270             : {
     271             :     try
     272             :     {
     273           0 :         maDeckActivationFunctor(msDeckId);
     274             :     }
     275           0 :     catch(const css::uno::Exception&)
     276             :     {} // workaround for #i123198#
     277             : 
     278           0 :     return 1;
     279             : }
     280             : 
     281           0 : const ::rtl::OUString TabBar::GetDeckIdForIndex (const sal_Int32 nIndex) const
     282             : {
     283           0 :     if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
     284           0 :         throw RuntimeException();
     285             :     else
     286           0 :         return maItems[nIndex].msDeckId;
     287             : }
     288             : 
     289           0 : void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
     290             : {
     291           0 :     if (nIndex<0 || static_cast<size_t>(nIndex) >= maItems.size())
     292           0 :         throw RuntimeException();
     293             :     else
     294             :     {
     295           0 :         maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
     296           0 :         ResourceManager::Instance().SetIsDeckEnabled(
     297           0 :             maItems[nIndex].msDeckId,
     298           0 :             maItems[nIndex].mbIsHidden);
     299           0 :         Layout();
     300             :     }
     301           0 : }
     302             : 
     303           0 : void TabBar::RestoreHideFlags()
     304             : {
     305           0 :     bool bNeedsLayout(false);
     306           0 :     for (ItemContainer::iterator iItem(maItems.begin()); iItem != maItems.end(); ++iItem)
     307             :     {
     308           0 :         if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
     309             :         {
     310           0 :             iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
     311           0 :             bNeedsLayout = true;
     312             :         }
     313             :     }
     314           0 :     if (bNeedsLayout)
     315           0 :         Layout();
     316           0 : }
     317             : 
     318        3765 : void TabBar::UpdateFocusManager(FocusManager& rFocusManager)
     319             : {
     320        3765 :     std::vector<Button*> aButtons;
     321        3765 :     aButtons.reserve(maItems.size()+1);
     322             : 
     323        3765 :     aButtons.push_back(mpMenuButton.get());
     324        6785 :     for (ItemContainer::const_iterator iItem(maItems.begin()); iItem != maItems.end(); ++iItem)
     325             :     {
     326        3020 :         aButtons.push_back(iItem->mpButton.get());
     327             :     }
     328        3765 :     rFocusManager.SetButtons(aButtons);
     329        3765 : }
     330             : 
     331           0 : IMPL_LINK_NOARG(TabBar, OnToolboxClicked)
     332             : {
     333           0 :     if (!mpMenuButton)
     334           0 :         return 0;
     335             : 
     336           0 :     std::vector<DeckMenuData> aMenuData;
     337             : 
     338           0 :     for (ItemContainer::const_iterator iItem(maItems.begin()); iItem != maItems.end(); ++iItem)
     339             :     {
     340           0 :         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
     341           0 :         if (pDeckDescriptor != NULL)
     342             :         {
     343           0 :             DeckMenuData aData;
     344           0 :             aData.msDisplayName = pDeckDescriptor->msTitle;
     345           0 :             aData.msDeckId = pDeckDescriptor->msId;
     346           0 :             aData.mbIsCurrentDeck = iItem->mpButton->IsChecked();
     347           0 :             aData.mbIsActive = !iItem->mbIsHidden;
     348           0 :             aData.mbIsEnabled = iItem->mpButton->IsEnabled();
     349             : 
     350           0 :             aMenuData.push_back(aData);
     351             :         }
     352             :     }
     353             : 
     354             :     maPopupMenuProvider(
     355             :         Rectangle(
     356           0 :             mpMenuButton->GetPosPixel(),
     357           0 :             mpMenuButton->GetSizePixel()),
     358           0 :         aMenuData);
     359           0 :     mpMenuButton->Check(false);
     360             : 
     361           0 :     return 0;
     362             : }
     363             : 
     364             : } } // end of namespace sfx2::sidebar
     365             : 
     366             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11