1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_sfx2.hxx"
23 
24 #include "sfx2/sidebar/SidebarToolBox.hxx"
25 #include "ToolBoxBackground.hxx"
26 #include "sfx2/sidebar/ControllerFactory.hxx"
27 #include "sfx2/sidebar/Theme.hxx"
28 #include "sfx2/sidebar/Tools.hxx"
29 
30 #include <vcl/gradient.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <svtools/miscopt.hxx>
33 #include <framework/imageproducer.hxx>
34 #include <com/sun/star/frame/XSubToolbarController.hpp>
35 
36 
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using ::rtl::OUString;
40 
41 
42 namespace sfx2 { namespace sidebar {
43 
44 
SidebarToolBox(Window * pParentWindow,const ResId & rResId,const cssu::Reference<css::frame::XFrame> & rxFrame)45 SidebarToolBox::SidebarToolBox (
46     Window* pParentWindow,
47     const ResId& rResId,
48     const cssu::Reference<css::frame::XFrame>& rxFrame)
49     : ToolBox(pParentWindow, rResId),
50       mbParentIsBorder(false),
51       maItemSeparator(Theme::GetImage(Theme::Image_ToolBoxItemSeparator)),
52       maControllers(),
53       mbAreHandlersRegistered(false)
54 {
55     SetBackground(Wallpaper());
56     SetPaintTransparent(true);
57 
58     if (rxFrame.is())
59     {
60         const sal_uInt16 nItemCount (GetItemCount());
61         if (nItemCount == 1)
62         {
63             // When there is only one item then make that as wide as
64             // the tool box.
65             CreateController(GetItemId(0), rxFrame, GetSizePixel().Width());
66         }
67         else
68             for (sal_uInt16 nItemIndex=0; nItemIndex<nItemCount; ++nItemIndex)
69                 CreateController(GetItemId(nItemIndex), rxFrame, 0);
70         UpdateIcons(rxFrame);
71 
72         SetSizePixel(CalcWindowSizePixel());
73 
74         RegisterHandlers();
75     }
76 
77 #ifdef DEBUG
78     SetText(A2S("SidebarToolBox"));
79 #endif
80 }
81 
82 
83 
84 
SidebarToolBox(Window * pParentWindow)85 SidebarToolBox::SidebarToolBox (Window* pParentWindow)
86     : ToolBox(pParentWindow, 0),
87       mbParentIsBorder(false),
88       maItemSeparator(Theme::GetImage(Theme::Image_ToolBoxItemSeparator)),
89       maControllers(),
90       mbAreHandlersRegistered(false)
91 {
92     SetBackground(Wallpaper());
93     SetPaintTransparent(true);
94 
95 #ifdef DEBUG
96     SetText(A2S("SidebarToolBox"));
97 #endif
98 }
99 
100 
101 
102 
~SidebarToolBox(void)103 SidebarToolBox::~SidebarToolBox (void)
104 {
105     ControllerContainer aControllers;
106     aControllers.swap(maControllers);
107     for (ControllerContainer::iterator iController(aControllers.begin()), iEnd(aControllers.end());
108          iController!=iEnd;
109          ++iController)
110     {
111         Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY);
112         if (xComponent.is())
113             xComponent->dispose();
114     }
115 
116     if (mbAreHandlersRegistered)
117     {
118         SetDropdownClickHdl(Link());
119         SetClickHdl(Link());
120         SetDoubleClickHdl(Link());
121         SetSelectHdl(Link());
122         SetActivateHdl(Link());
123         SetDeactivateHdl(Link());
124     }
125 }
126 
127 
128 
129 
SetBorderWindow(const Window * pBorderWindow)130 void SidebarToolBox::SetBorderWindow (const Window* pBorderWindow)
131 {
132     if (pBorderWindow != GetParent())
133     {
134         OSL_ASSERT("SetBorderWindow can only handle parent as border window");
135         return;
136     }
137 
138     if ( ! mbParentIsBorder)
139     {
140         mbParentIsBorder = true;
141 
142         SetPosSizePixel (
143             GetPosPixel().X(),
144             GetPosPixel().Y(),
145             GetSizePixel().Width(),
146             GetSizePixel().Height(),
147             WINDOW_POSSIZE_ALL);
148     }
149 }
150 
151 
152 
153 
Paint(const Rectangle & rRect)154 void SidebarToolBox::Paint (const Rectangle& rRect)
155 {
156     ToolBox::Paint(rRect);
157 
158     if (Theme::GetBoolean(Theme::Bool_UseToolBoxItemSeparator))
159     {
160         const sal_Int32 nSeparatorY ((GetSizePixel().Height() - maItemSeparator.GetSizePixel().Height())/2);
161         const sal_uInt16 nItemCount (GetItemCount());
162         int nLastRight (-1);
163         for (sal_uInt16 nIndex=0; nIndex<nItemCount; ++nIndex)
164         {
165             const Rectangle aItemBoundingBox (GetItemPosRect(nIndex));
166             if (nLastRight >= 0)
167             {
168                 const int nSeparatorX ((nLastRight + aItemBoundingBox.Left() - 1) / 2);
169                 DrawImage(Point(nSeparatorX,nSeparatorY), maItemSeparator);
170             }
171 
172             nLastRight = aItemBoundingBox.Right();
173         }
174     }
175 }
176 
177 
178 
179 
GetPosPixel(void) const180 Point SidebarToolBox::GetPosPixel (void) const
181 {
182     if (mbParentIsBorder)
183     {
184         const Point aParentPoint (GetParent()->GetPosPixel());
185         const Point aChildPoint (ToolBox::GetPosPixel());
186         return Point(
187             aParentPoint.X() + aChildPoint.X(),
188             aParentPoint.Y() + aChildPoint.Y());
189     }
190     else
191         return ToolBox::GetPosPixel();
192 }
193 
194 
195 
196 
SetPosSizePixel(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)197 void SidebarToolBox::SetPosSizePixel (
198     long nX,
199     long nY,
200     long nWidth,
201     long nHeight,
202     sal_uInt16 nFlags)
203 {
204     if (mbParentIsBorder)
205     {
206         const Point aRelativePosition (static_cast<ToolBoxBackground*>(GetParent())->SetToolBoxChild(
207                 this,
208                 nX,
209                 nY,
210                 nWidth,
211                 nHeight,
212                 nFlags));
213         ToolBox::SetPosSizePixel(
214             aRelativePosition.X(),
215             aRelativePosition.Y(),
216             nWidth,
217             nHeight,
218             nFlags);
219     }
220     else
221         ToolBox::SetPosSizePixel(nX, nY, nWidth, nHeight, nFlags);
222 }
223 
224 
225 
226 
Notify(NotifyEvent & rEvent)227 long SidebarToolBox::Notify (NotifyEvent& rEvent)
228 {
229     if (rEvent.GetType() == EVENT_KEYINPUT)
230     {
231         if (rEvent.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB)
232         {
233             // Special handling for transferring handling of KEY_TAB
234             // that becomes necessary because of our parent that is
235             // not the dialog but a background control.
236             return DockingWindow::Notify(rEvent);
237         }
238     }
239     return ToolBox::Notify(rEvent);
240 }
241 
242 
243 
244 
CreateController(const sal_uInt16 nItemId,const cssu::Reference<css::frame::XFrame> & rxFrame,const sal_Int32 nItemWidth)245 void SidebarToolBox::CreateController (
246     const sal_uInt16 nItemId,
247     const cssu::Reference<css::frame::XFrame>& rxFrame,
248     const sal_Int32 nItemWidth)
249 {
250     ItemDescriptor aDescriptor;
251 
252     const OUString sCommandName (GetItemCommand(nItemId));
253 
254     aDescriptor.mxController = sfx2::sidebar::ControllerFactory::CreateToolBoxController(
255         this,
256         nItemId,
257         sCommandName,
258         rxFrame,
259         VCLUnoHelper::GetInterface(this),
260         nItemWidth);
261     if (aDescriptor.mxController.is())
262     {
263         aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName);
264         aDescriptor.msCurrentCommand = sCommandName;
265 
266         maControllers.insert(::std::make_pair(nItemId, aDescriptor));
267     }
268 }
269 
270 
271 
272 
GetControllerForItemId(const sal_uInt16 nItemId) const273 Reference<frame::XToolbarController> SidebarToolBox::GetControllerForItemId (const sal_uInt16 nItemId) const
274 {
275     ControllerContainer::const_iterator iController (maControllers.find(nItemId));
276     if (iController != maControllers.end())
277         return iController->second.mxController;
278     else
279         return NULL;
280 }
281 
282 
283 
284 
SetController(const sal_uInt16 nItemId,const cssu::Reference<css::frame::XToolbarController> & rxController,const::rtl::OUString & rsCommandName)285 void SidebarToolBox::SetController(
286     const sal_uInt16 nItemId,
287     const cssu::Reference<css::frame::XToolbarController>& rxController,
288     const ::rtl::OUString& rsCommandName)
289 {
290     ItemDescriptor aDescriptor;
291     aDescriptor.mxController = rxController;
292     aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(rsCommandName);
293     aDescriptor.msCurrentCommand = rsCommandName;
294 
295     ControllerContainer::iterator iController (maControllers.find(nItemId));
296     if (iController != maControllers.end())
297     {
298         Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY);
299         if (xComponent.is())
300             xComponent->dispose();
301 
302         iController->second = aDescriptor;
303     }
304     else
305     {
306         maControllers[nItemId] = aDescriptor;
307     }
308 
309     if (rxController.is())
310         RegisterHandlers();
311 }
312 
313 
314 
315 
UpdateIcons(const Reference<frame::XFrame> & rxFrame)316 void SidebarToolBox::UpdateIcons (const Reference<frame::XFrame>& rxFrame)
317 {
318     const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());
319     const bool bIsHighContrastActive (sfx2::sidebar::Theme::IsHighContrastMode());
320 
321     for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end());
322          iController!=iEnd;
323          ++iController)
324     {
325         const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand);
326         Image aImage (framework::GetImageFromURL(rxFrame, sCommandURL, bBigImages, bIsHighContrastActive));
327         SetItemImage(iController->first, aImage);
328     }
329 }
330 
331 
332 
333 
GetItemIdForSubToolbarName(const OUString & rsSubToolbarName) const334 sal_uInt16 SidebarToolBox::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const
335 {
336     for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end());
337          iController!=iEnd;
338          ++iController)
339     {
340         Reference<frame::XToolbarController> xController (iController->second.mxController);
341         Reference<frame::XSubToolbarController> xSubToolbarController (xController, UNO_QUERY);
342         if (xSubToolbarController.is())
343         {
344             const OUString sName (xSubToolbarController->getSubToolbarName());
345             if (sName.equals(rsSubToolbarName))
346                 return iController->first;
347         }
348     }
349     return 0;
350 }
351 
352 
353 
354 
RegisterHandlers(void)355 void SidebarToolBox::RegisterHandlers (void)
356 {
357     if ( ! mbAreHandlersRegistered)
358     {
359         mbAreHandlersRegistered = true;
360         SetDropdownClickHdl(LINK(this, SidebarToolBox, DropDownClickHandler));
361         SetClickHdl(LINK(this, SidebarToolBox, ClickHandler));
362         SetDoubleClickHdl(LINK(this, SidebarToolBox, DoubleClickHandler));
363         SetSelectHdl(LINK(this, SidebarToolBox, SelectHandler));
364         SetActivateHdl(LINK(this, SidebarToolBox, Activate));
365         SetDeactivateHdl(LINK(this, SidebarToolBox, Deactivate));
366     }
367 }
368 
369 
370 
371 
IMPL_LINK(SidebarToolBox,DropDownClickHandler,ToolBox *,pToolBox)372 IMPL_LINK(SidebarToolBox, DropDownClickHandler, ToolBox*, pToolBox)
373 {
374     if (pToolBox != NULL)
375     {
376         Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
377         if (xController.is())
378         {
379             Reference<awt::XWindow> xWindow = xController->createPopupWindow();
380             if (xWindow.is() )
381                 xWindow->setFocus();
382         }
383     }
384     return 1;
385 }
386 
387 
388 
389 
IMPL_LINK(SidebarToolBox,ClickHandler,ToolBox *,pToolBox)390 IMPL_LINK(SidebarToolBox, ClickHandler, ToolBox*, pToolBox)
391 {
392     if (pToolBox == NULL)
393         return 0;
394 
395     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
396     if (xController.is())
397         xController->click();
398 
399     return 1;
400 }
401 
402 
403 
404 
IMPL_LINK(SidebarToolBox,DoubleClickHandler,ToolBox *,pToolBox)405 IMPL_LINK(SidebarToolBox, DoubleClickHandler, ToolBox*, pToolBox)
406 {
407     if (pToolBox == NULL)
408         return 0;
409 
410     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
411     if (xController.is())
412         xController->doubleClick();
413 
414     return 1;
415 }
416 
417 
418 
419 
IMPL_LINK(SidebarToolBox,SelectHandler,ToolBox *,pToolBox)420 IMPL_LINK(SidebarToolBox, SelectHandler, ToolBox*, pToolBox)
421 {
422     if (pToolBox == NULL)
423         return 0;
424 
425     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
426     if (xController.is())
427         xController->execute((sal_Int16)pToolBox->GetModifier());
428 
429     return 1;
430 }
431 
432 
433 
434 
IMPL_LINK(SidebarToolBox,Activate,ToolBox *,EMPTYARG)435 IMPL_LINK(SidebarToolBox, Activate, ToolBox*, EMPTYARG)
436 {
437     return 1;
438 }
439 
440 
441 
442 
IMPL_LINK(SidebarToolBox,Deactivate,ToolBox *,EMPTYARG)443 IMPL_LINK(SidebarToolBox, Deactivate, ToolBox*, EMPTYARG)
444 {
445     return 1;
446 }
447 
448 
449 
450 } } // end of namespace sfx2::sidebar
451