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 
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 {
53     SetBackground(Wallpaper());
54     SetPaintTransparent(true);
55 
56     if (rxFrame.is())
57     {
58         const sal_uInt16 nItemCount (GetItemCount());
59         if (nItemCount == 1)
60         {
61             // When there is only one item then make that as wide as
62             // the tool box.
63             CreateController(GetItemId(0), rxFrame, GetSizePixel().Width());
64         }
65         else
66             for (sal_uInt16 nItemIndex=0; nItemIndex<nItemCount; ++nItemIndex)
67                 CreateController(GetItemId(nItemIndex), rxFrame, 0);
68         UpdateIcons(rxFrame);
69 
70         SetSizePixel(CalcWindowSizePixel());
71 
72         SetDropdownClickHdl(LINK(this, SidebarToolBox, DropDownClickHandler));
73         SetClickHdl(LINK(this, SidebarToolBox, ClickHandler));
74         SetDoubleClickHdl(LINK(this, SidebarToolBox, DoubleClickHandler));
75         SetSelectHdl(LINK(this, SidebarToolBox, SelectHandler));
76         SetActivateHdl(LINK(this, SidebarToolBox, Activate));
77         SetDeactivateHdl(LINK(this, SidebarToolBox, Deactivate));
78     }
79 
80 #ifdef DEBUG
81     SetText(A2S("SidebarToolBox"));
82 #endif
83 }
84 
85 
86 
87 
88 SidebarToolBox::~SidebarToolBox (void)
89 {
90     ControllerContainer aControllers;
91     aControllers.swap(maControllers);
92     for (ControllerContainer::iterator iController(aControllers.begin()), iEnd(aControllers.end());
93          iController!=iEnd;
94          ++iController)
95     {
96         Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY);
97         if (xComponent.is())
98             xComponent->dispose();
99     }
100 
101     SetDropdownClickHdl(Link());
102     SetClickHdl(Link());
103     SetDoubleClickHdl(Link());
104     SetSelectHdl(Link());
105 	SetActivateHdl(Link());
106 	SetDeactivateHdl(Link());
107 
108 }
109 
110 
111 
112 
113 void SidebarToolBox::SetBorderWindow (const Window* pBorderWindow)
114 {
115     if (pBorderWindow != GetParent())
116     {
117         OSL_ASSERT("SetBorderWindow can only handle parent as border window");
118         return;
119     }
120 
121     if ( ! mbParentIsBorder)
122     {
123         mbParentIsBorder = true;
124 
125         SetPosSizePixel (
126             GetPosPixel().X(),
127             GetPosPixel().Y(),
128             GetSizePixel().Width(),
129             GetSizePixel().Height(),
130             WINDOW_POSSIZE_ALL);
131     }
132 }
133 
134 
135 
136 
137 void SidebarToolBox::Paint (const Rectangle& rRect)
138 {
139     ToolBox::Paint(rRect);
140 
141     if (Theme::GetBoolean(Theme::Bool_UseToolBoxItemSeparator))
142     {
143         const sal_Int32 nSeparatorY ((GetSizePixel().Height() - maItemSeparator.GetSizePixel().Height())/2);
144         const sal_uInt16 nItemCount (GetItemCount());
145         int nLastRight (-1);
146         for (sal_uInt16 nIndex=0; nIndex<nItemCount; ++nIndex)
147         {
148             const Rectangle aItemBoundingBox (GetItemPosRect(nIndex));
149             if (nLastRight >= 0)
150             {
151                 const int nSeparatorX ((nLastRight + aItemBoundingBox.Left() - 1) / 2);
152                 DrawImage(Point(nSeparatorX,nSeparatorY), maItemSeparator);
153             }
154 
155             nLastRight = aItemBoundingBox.Right();
156         }
157     }
158 }
159 
160 
161 
162 
163 Point SidebarToolBox::GetPosPixel (void) const
164 {
165     if (mbParentIsBorder)
166     {
167         const Point aParentPoint (GetParent()->GetPosPixel());
168         const Point aChildPoint (ToolBox::GetPosPixel());
169         return Point(
170             aParentPoint.X() + aChildPoint.X(),
171             aParentPoint.Y() + aChildPoint.Y());
172     }
173     else
174         return ToolBox::GetPosPixel();
175 }
176 
177 
178 
179 
180 void SidebarToolBox::SetPosSizePixel (
181     long nX,
182     long nY,
183     long nWidth,
184     long nHeight,
185     sal_uInt16 nFlags)
186 {
187     if (mbParentIsBorder)
188     {
189         const Point aRelativePosition (static_cast<ToolBoxBackground*>(GetParent())->SetToolBoxChild(
190                 this,
191                 nX,
192                 nY,
193                 nWidth,
194                 nHeight,
195                 nFlags));
196         ToolBox::SetPosSizePixel(
197             aRelativePosition.X(),
198             aRelativePosition.Y(),
199             nWidth,
200             nHeight,
201             nFlags);
202     }
203     else
204         ToolBox::SetPosSizePixel(nX, nY, nWidth, nHeight, nFlags);
205 }
206 
207 
208 
209 
210 long SidebarToolBox::Notify (NotifyEvent& rEvent)
211 {
212     if (rEvent.GetType() == EVENT_KEYINPUT)
213     {
214         if (rEvent.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB)
215         {
216             // Special handling for transferring handling of KEY_TAB
217             // that becomes necessary because of our parent that is
218             // not the dialog but a background control.
219             return DockingWindow::Notify(rEvent);
220         }
221     }
222     return ToolBox::Notify(rEvent);
223 }
224 
225 
226 
227 
228 void SidebarToolBox::CreateController (
229     const sal_uInt16 nItemId,
230     const cssu::Reference<css::frame::XFrame>& rxFrame,
231     const sal_Int32 nItemWidth)
232 {
233     ItemDescriptor aDescriptor;
234 
235     const OUString sCommandName (GetItemCommand(nItemId));
236 
237     aDescriptor.mxController = sfx2::sidebar::ControllerFactory::CreateToolBoxController(
238         this,
239         nItemId,
240         sCommandName,
241         rxFrame,
242         VCLUnoHelper::GetInterface(this),
243         nItemWidth);
244     if (aDescriptor.mxController.is())
245     {
246         aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName);
247         aDescriptor.msCurrentCommand = sCommandName;
248 
249         maControllers.insert(::std::make_pair(nItemId, aDescriptor));
250     }
251 }
252 
253 
254 
255 
256 Reference<frame::XToolbarController> SidebarToolBox::GetControllerForItemId (const sal_uInt16 nItemId) const
257 {
258     ControllerContainer::const_iterator iController (maControllers.find(nItemId));
259     if (iController != maControllers.end())
260         return iController->second.mxController;
261     else
262         return NULL;
263 }
264 
265 
266 
267 
268 void SidebarToolBox::UpdateIcons (const Reference<frame::XFrame>& rxFrame)
269 {
270     const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());
271     const bool bIsHighContrastActive (sfx2::sidebar::Theme::IsHighContrastMode());
272 
273     for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end());
274          iController!=iEnd;
275          ++iController)
276     {
277         const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand);
278         Image aImage (framework::GetImageFromURL(rxFrame, sCommandURL, bBigImages, bIsHighContrastActive));
279         SetItemImage(iController->first, aImage);
280     }
281 }
282 
283 
284 
285 
286 sal_uInt16 SidebarToolBox::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const
287 {
288     for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end());
289          iController!=iEnd;
290          ++iController)
291     {
292         Reference<frame::XToolbarController> xController (iController->second.mxController);
293         Reference<frame::XSubToolbarController> xSubToolbarController (xController, UNO_QUERY);
294         if (xSubToolbarController.is())
295         {
296             const OUString sName (xSubToolbarController->getSubToolbarName());
297             if (sName.equals(rsSubToolbarName))
298                 return iController->first;
299         }
300     }
301     return 0;
302 }
303 
304 
305 
306 IMPL_LINK(SidebarToolBox, DropDownClickHandler, ToolBox*, pToolBox)
307 {
308     if (pToolBox != NULL)
309     {
310         Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
311         if (xController.is())
312         {
313             Reference<awt::XWindow> xWindow = xController->createPopupWindow();
314             if (xWindow.is() )
315                 xWindow->setFocus();
316         }
317     }
318     return 1;
319 }
320 
321 
322 
323 
324 IMPL_LINK(SidebarToolBox, ClickHandler, ToolBox*, pToolBox)
325 {
326     if (pToolBox == NULL)
327         return 0;
328 
329     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
330     if (xController.is())
331         xController->click();
332 
333     return 1;
334 }
335 
336 
337 
338 
339 IMPL_LINK(SidebarToolBox, DoubleClickHandler, ToolBox*, pToolBox)
340 {
341     if (pToolBox == NULL)
342         return 0;
343 
344     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
345     if (xController.is())
346         xController->doubleClick();
347 
348     return 1;
349 }
350 
351 
352 
353 
354 IMPL_LINK(SidebarToolBox, SelectHandler, ToolBox*, pToolBox)
355 {
356     if (pToolBox == NULL)
357         return 0;
358 
359     Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
360     if (xController.is())
361         xController->execute((sal_Int16)pToolBox->GetModifier());
362 
363     return 1;
364 }
365 
366 
367 
368 
369 IMPL_LINK(SidebarToolBox, Activate, ToolBox*, EMPTYARG)
370 {
371     return 1;
372 }
373 
374 
375 
376 
377 IMPL_LINK(SidebarToolBox, Deactivate, ToolBox*, EMPTYARG)
378 {
379     return 1;
380 }
381 
382 
383 
384 } } // end of namespace sfx2::sidebar
385