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