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 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 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 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 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 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 180 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 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 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 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 273 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 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 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 334 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 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 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 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 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 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 435 IMPL_LINK(SidebarToolBox, Activate, ToolBox*, EMPTYARG) 436 { 437 return 1; 438 } 439 440 441 442 443 IMPL_LINK(SidebarToolBox, Deactivate, ToolBox*, EMPTYARG) 444 { 445 return 1; 446 } 447 448 449 450 } } // end of namespace sfx2::sidebar 451