bump product version to 4.1.6.2
[LibreOffice.git] / sfx2 / source / sidebar / TabBar.cxx
blob52e06756af7f0f77446a6948f820b7791efa908f
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "TabBar.hxx"
20 #include "TabItem.hxx"
21 #include "sidebar/ControlFactory.hxx"
22 #include "DeckDescriptor.hxx"
23 #include "Paint.hxx"
24 #include "sfx2/sidebar/Theme.hxx"
25 #include "sfx2/sidebar/Tools.hxx"
26 #include "FocusManager.hxx"
28 #include <vcl/gradient.hxx>
29 #include <vcl/image.hxx>
30 #include <vcl/wrkwin.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <comphelper/componentcontext.hxx>
33 #include <tools/svborder.hxx>
35 #include <com/sun/star/graphic/XGraphicProvider.hpp>
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
44 namespace sfx2 { namespace sidebar {
46 TabBar::TabBar (
47 Window* pParentWindow,
48 const Reference<frame::XFrame>& rxFrame,
49 const ::boost::function<void(const ::rtl::OUString&)>& rDeckActivationFunctor,
50 const PopupMenuProvider& rPopupMenuProvider)
51 : Window(pParentWindow, WB_DIALOGCONTROL),
52 mxFrame(rxFrame),
53 mpMenuButton(ControlFactory::CreateMenuButton(this)),
54 maItems(),
55 maDeckActivationFunctor(rDeckActivationFunctor),
56 maPopupMenuProvider(rPopupMenuProvider)
58 SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
60 mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu));
61 mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
62 Layout();
64 #ifdef DEBUG
65 SetText(A2S("TabBar"));
66 #endif
72 TabBar::~TabBar (void)
79 void TabBar::Paint (const Rectangle& rUpdateArea)
81 Window::Paint(rUpdateArea);
83 const sal_Int32 nHorizontalPadding (Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
84 SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
85 DrawLine(
86 Point(nHorizontalPadding, mnMenuSeparatorY),
87 Point(GetSizePixel().Width()-nHorizontalPadding, mnMenuSeparatorY));
93 sal_Int32 TabBar::GetDefaultWidth (void)
95 return Theme::GetInteger(Theme::Int_TabItemWidth)
96 + Theme::GetInteger(Theme::Int_TabBarLeftPadding)
97 + Theme::GetInteger(Theme::Int_TabBarRightPadding);
103 void TabBar::SetDecks (
104 const ResourceManager::DeckContextDescriptorContainer& rDecks)
106 // Remove the current buttons.
108 for(ItemContainer::iterator
109 iItem(maItems.begin()), iEnd(maItems.end());
110 iItem!=iEnd;
111 ++iItem)
113 iItem->mpButton.reset();
115 maItems.clear();
118 maItems.resize(rDecks.size());
119 sal_Int32 nIndex (0);
120 for (ResourceManager::DeckContextDescriptorContainer::const_iterator
121 iDeck(rDecks.begin()),
122 iEnd(rDecks.end());
123 iDeck!=iEnd;
124 ++iDeck)
126 const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(iDeck->msId);
127 if (pDescriptor == NULL)
129 OSL_ASSERT(pDescriptor!=NULL);
130 continue;
133 Item& rItem (maItems[nIndex++]);
134 rItem.msDeckId = pDescriptor->msId;
135 rItem.mpButton.reset(CreateTabItem(*pDescriptor));
136 rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
137 rItem.maDeckActivationFunctor = maDeckActivationFunctor;
138 rItem.mbIsHiddenByDefault = false;
139 rItem.mbIsHidden = ! pDescriptor->mbIsEnabled;
141 rItem.mpButton->Enable(iDeck->mbIsEnabled);
144 UpdateButtonIcons();
145 Layout();
151 void TabBar::UpdateButtonIcons (void)
153 mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu));
155 for(ItemContainer::const_iterator
156 iItem(maItems.begin()), iEnd(maItems.end());
157 iItem!=iEnd;
158 ++iItem)
160 const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
161 if (pDeckDescriptor != NULL)
162 iItem->mpButton->SetModeImage(GetItemImage(*pDeckDescriptor));
165 Invalidate();
171 void TabBar::Layout (void)
173 const SvBorder aPadding (
174 Theme::GetInteger(Theme::Int_TabBarLeftPadding),
175 Theme::GetInteger(Theme::Int_TabBarTopPadding),
176 Theme::GetInteger(Theme::Int_TabBarRightPadding),
177 Theme::GetInteger(Theme::Int_TabBarBottomPadding));
178 sal_Int32 nX (aPadding.Top());
179 sal_Int32 nY (aPadding.Left());
180 const Size aTabItemSize (
181 Theme::GetInteger(Theme::Int_TabItemWidth),
182 Theme::GetInteger(Theme::Int_TabItemHeight));
184 // Place the menu button and the separator.
185 if (mpMenuButton != NULL)
187 mpMenuButton->SetPosSizePixel(
188 Point(nX,nY),
189 aTabItemSize);
190 mpMenuButton->Show();
191 nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
192 mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
195 // Place the deck selection buttons.
196 for(ItemContainer::const_iterator
197 iItem(maItems.begin()), iEnd(maItems.end());
198 iItem!=iEnd;
199 ++iItem)
201 Button& rButton (*iItem->mpButton);
202 rButton.Show( ! iItem->mbIsHidden);
204 if (iItem->mbIsHidden)
205 continue;
207 // Place and size the icon.
208 rButton.SetPosSizePixel(
209 Point(nX,nY),
210 aTabItemSize);
211 rButton.Show();
213 nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
215 Invalidate();
221 void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId)
223 Item* pItem = GetItemForId(rsDeckId);
224 if (pItem != NULL)
225 pItem->mpButton->Check();
231 TabBar::Item* TabBar::GetItemForId (const ::rtl::OUString& rsDeckId)
233 for (ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
234 iItem!=iEnd;
235 ++iItem)
237 if (iItem->msDeckId.equals(rsDeckId))
238 return &*iItem;
240 return NULL;
246 void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
248 SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
249 UpdateButtonIcons();
251 Window::DataChanged(rDataChangedEvent);
257 long TabBar::Notify (NotifyEvent&)
259 return sal_False;
265 RadioButton* TabBar::CreateTabItem (const DeckDescriptor& rDeckDescriptor)
267 RadioButton* pItem = ControlFactory::CreateTabItem(this);
268 pItem->SetHelpText(rDeckDescriptor.msHelpText);
269 pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
271 return pItem;
276 Image TabBar::GetItemImage (const DeckDescriptor& rDeckDescriptor) const
278 return Tools::GetImage(
279 rDeckDescriptor.msIconURL,
280 rDeckDescriptor.msHighContrastIconURL,
281 mxFrame);
288 IMPL_LINK(TabBar::Item, HandleClick, Button*, EMPTYARG)
292 maDeckActivationFunctor(msDeckId);
294 catch( const ::com::sun::star::uno::Exception&) {} // workaround for #i123198#
296 return 1;
302 const ::rtl::OUString TabBar::GetDeckIdForIndex (const sal_Int32 nIndex) const
304 if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
305 throw RuntimeException();
306 else
307 return maItems[nIndex].msDeckId;
313 void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
315 if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
316 throw RuntimeException();
317 else
319 maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
320 ResourceManager::Instance().SetIsDeckEnabled(
321 maItems[nIndex].msDeckId,
322 maItems[nIndex].mbIsHidden);
323 Layout();
330 void TabBar::RestoreHideFlags (void)
332 bool bNeedsLayout (false);
333 for(ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
334 iItem!=iEnd;
335 ++iItem)
337 if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
339 iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
340 bNeedsLayout = true;
343 if (bNeedsLayout)
344 Layout();
350 void TabBar::UpdateFocusManager (FocusManager& rFocusManager)
352 ::std::vector<Button*> aButtons;
353 aButtons.reserve(maItems.size()+1);
355 aButtons.push_back(mpMenuButton.get());
356 for(ItemContainer::const_iterator
357 iItem(maItems.begin()), iEnd(maItems.end());
358 iItem!=iEnd;
359 ++iItem)
361 aButtons.push_back(iItem->mpButton.get());
363 rFocusManager.SetButtons(aButtons);
369 IMPL_LINK(TabBar, OnToolboxClicked, void*, EMPTYARG)
371 if ( ! mpMenuButton)
372 return 0;
374 ::std::vector<DeckMenuData> aMenuData;
376 for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
377 iItem!=iEnd;
378 ++iItem)
380 const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
381 if (pDeckDescriptor != NULL)
383 DeckMenuData aData;
384 aData.msDisplayName = pDeckDescriptor->msTitle;
385 aData.msDeckId = pDeckDescriptor->msId;
386 aData.mbIsCurrentDeck = iItem->mpButton->IsChecked();
387 aData.mbIsActive = !iItem->mbIsHidden;
388 aData.mbIsEnabled = iItem->mpButton->IsEnabled();
390 aMenuData.push_back(aData);
394 maPopupMenuProvider(
395 Rectangle(
396 mpMenuButton->GetPosPixel(),
397 mpMenuButton->GetSizePixel()),
398 aMenuData);
399 mpMenuButton->Check(sal_False);
401 return 0;
406 } } // end of namespace sfx2::sidebar