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