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_svx.hxx" 23 24 #include "InsertPropertyPanel.hxx" 25 #include "InsertPropertyPanel.hrc" 26 #include "sfx2/sidebar/CommandInfoProvider.hxx" 27 28 #include <sfx2/sidebar/Theme.hxx> 29 #include <sfx2/sidebar/Tools.hxx> 30 #include <sfx2/sidebar/ControlFactory.hxx> 31 32 #include <svx/dialmgr.hxx> 33 #include <svtools/miscopt.hxx> 34 #include <svtools/generictoolboxcontroller.hxx> 35 #include <vcl/toolbox.hxx> 36 #include <sfx2/tbxctrl.hxx> 37 #include <framework/sfxhelperfunctions.hxx> 38 #include <framework/imageproducer.hxx> 39 #include <comphelper/processfactory.hxx> 40 #include <cppuhelper/compbase1.hxx> 41 #include <cppuhelper/basemutex.hxx> 42 43 #include <com/sun/star/frame/XStatusListener.hpp> 44 45 using namespace css; 46 using namespace cssu; 47 using ::rtl::OUString; 48 49 namespace svx { namespace sidebar { 50 51 52 InsertPropertyPanel::InsertPropertyPanel ( 53 Window* pParent, 54 const cssu::Reference<css::frame::XFrame>& rxFrame) 55 : Control(pParent, SVX_RES(RID_SIDEBAR_INSERT_PANEL)), 56 mpStandardShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)), 57 mpStandardShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox( 58 mpStandardShapesBackground.get(), 59 SVX_RES(TB_INSERT_STANDARD))), 60 mpCustomShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)), 61 mpCustomShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox( 62 mpCustomShapesBackground.get(), 63 SVX_RES(TB_INSERT_CUSTOM))), 64 maControllers(), 65 mxFrame(rxFrame) 66 { 67 SetupToolBox(*mpStandardShapesToolBox); 68 SetupToolBox(*mpCustomShapesToolBox); 69 FreeResource(); 70 71 UpdateIcons(); 72 73 mpStandardShapesToolBox->Show(); 74 mpCustomShapesToolBox->Show(); 75 76 // Listen to all tool box selection events. 77 Window* pTopWindow = pParent; 78 while (pTopWindow->GetParent() != NULL) 79 pTopWindow = pTopWindow->GetParent(); 80 pTopWindow->AddChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener)); 81 } 82 83 84 85 86 InsertPropertyPanel::~InsertPropertyPanel (void) 87 { 88 ControllerContainer aControllers; 89 aControllers.swap(maControllers); 90 for (ControllerContainer::iterator iController(aControllers.begin()), iEnd(aControllers.end()); 91 iController!=iEnd; 92 ++iController) 93 { 94 Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY); 95 if (xComponent.is()) 96 xComponent->dispose(); 97 } 98 99 // Remove window child listener. 100 Window* pTopWindow = this; 101 while (pTopWindow->GetParent() != NULL) 102 pTopWindow = pTopWindow->GetParent(); 103 pTopWindow->RemoveChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener)); 104 105 mpStandardShapesToolBox.reset(); 106 mpCustomShapesToolBox.reset(); 107 mpStandardShapesBackground.reset(); 108 mpCustomShapesBackground.reset(); 109 } 110 111 112 113 114 void InsertPropertyPanel::SetupToolBox (ToolBox& rToolBox) 115 { 116 const sal_uInt16 nItemCount (rToolBox.GetItemCount()); 117 for (sal_uInt16 nItemIndex=0; nItemIndex<nItemCount; ++nItemIndex) 118 CreateController(rToolBox.GetItemId(nItemIndex)); 119 120 rToolBox.SetDropdownClickHdl(LINK(this, InsertPropertyPanel, DropDownClickHandler)); 121 rToolBox.SetClickHdl(LINK(this, InsertPropertyPanel, ClickHandler)); 122 rToolBox.SetDoubleClickHdl(LINK(this, InsertPropertyPanel, DoubleClickHandler)); 123 rToolBox.SetSelectHdl(LINK(this, InsertPropertyPanel, SelectHandler)); 124 rToolBox.SetActivateHdl(LINK(this, InsertPropertyPanel, Activate)); 125 rToolBox.SetDeactivateHdl(LINK(this, InsertPropertyPanel, Deactivate)); 126 127 rToolBox.SetSizePixel(rToolBox.CalcWindowSizePixel()); 128 } 129 130 131 132 133 IMPL_LINK(InsertPropertyPanel, DropDownClickHandler, ToolBox*, pToolBox) 134 { 135 if (pToolBox != NULL) 136 { 137 Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); 138 if (xController.is()) 139 { 140 Reference<awt::XWindow> xWindow = xController->createPopupWindow(); 141 if (xWindow.is() ) 142 xWindow->setFocus(); 143 } 144 } 145 return 1; 146 } 147 148 149 150 151 IMPL_LINK(InsertPropertyPanel, ClickHandler, ToolBox*, pToolBox) 152 { 153 if (pToolBox == NULL) 154 return 0; 155 156 Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); 157 if (xController.is()) 158 xController->click(); 159 160 return 1; 161 } 162 163 164 165 166 IMPL_LINK(InsertPropertyPanel, DoubleClickHandler, ToolBox*, pToolBox) 167 { 168 if (pToolBox == NULL) 169 return 0; 170 171 Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); 172 if (xController.is()) 173 xController->doubleClick(); 174 175 return 1; 176 } 177 178 179 180 181 IMPL_LINK(InsertPropertyPanel, SelectHandler, ToolBox*, pToolBox) 182 { 183 if (pToolBox == NULL) 184 return 0; 185 186 Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId())); 187 if (xController.is()) 188 xController->execute((sal_Int16)pToolBox->GetModifier()); 189 190 return 1; 191 } 192 193 194 195 196 IMPL_LINK(InsertPropertyPanel, WindowEventListener, VclSimpleEvent*, pEvent) 197 { 198 // We will be getting a lot of window events (well, basically all 199 // of them), so reject early everything that is not connected to 200 // toolbox selection. 201 if (pEvent == NULL) 202 return 1; 203 if ( ! pEvent->ISA(VclWindowEvent)) 204 return 1; 205 if (pEvent->GetId() != VCLEVENT_TOOLBOX_SELECT) 206 return 1; 207 208 ToolBox* pToolBox = dynamic_cast<ToolBox*>(dynamic_cast<VclWindowEvent*>(pEvent)->GetWindow()); 209 if (pToolBox == NULL) 210 return 1; 211 212 // Extract name of (sub)toolbar from help id. 213 OUString sToolbarName (rtl::OStringToOUString(pToolBox->GetHelpId(), RTL_TEXTENCODING_UTF8)); 214 if (sToolbarName.getLength() == 0) 215 return 1; 216 const util::URL aURL (sfx2::sidebar::Tools::GetURL(sToolbarName)); 217 if (aURL.Path.getLength() == 0) 218 return 1; 219 220 // Get item id. 221 sal_uInt16 nId = pToolBox->GetCurItemId(); 222 if (nId == 0) 223 return 1; 224 225 // Get toolbar controller. 226 const sal_uInt16 nItemId (GetItemIdForSubToolbarName(aURL.Path)); 227 Reference<frame::XSubToolbarController> xController (GetControllerForItemId(nItemId), UNO_QUERY); 228 if ( ! xController.is()) 229 return 1; 230 231 const OUString sCommand (pToolBox->GetItemCommand(nId)); 232 ControllerContainer::iterator iController (maControllers.find(nItemId)); 233 if (iController != maControllers.end()) 234 iController->second.msCurrentCommand = sCommand; 235 xController->functionSelected(sCommand); 236 237 const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge()); 238 const bool bIsHighContrastActive (sfx2::sidebar::Theme::IsHighContrastMode()); 239 Image aImage (framework::GetImageFromURL(mxFrame, sCommand, bBigImages, bIsHighContrastActive)); 240 pToolBox->SetItemImage(iController->first, aImage); 241 242 return 1; 243 } 244 245 246 247 248 IMPL_LINK(InsertPropertyPanel, Activate, ToolBox*, EMPTYARG) 249 { 250 return 1; 251 } 252 253 254 255 256 IMPL_LINK(InsertPropertyPanel, Deactivate, ToolBox*, EMPTYARG) 257 { 258 return 1; 259 } 260 261 262 263 264 void InsertPropertyPanel::CreateController ( 265 const sal_uInt16 nItemId) 266 { 267 ToolBox* pToolBox = GetToolBoxForItemId(nItemId); 268 if (pToolBox != NULL) 269 { 270 ItemDescriptor aDescriptor; 271 272 const OUString sCommandName (pToolBox->GetItemCommand(nItemId)); 273 274 // Create a controller for the new item. 275 aDescriptor.mxController.set( 276 static_cast<XWeak*>(::framework::CreateToolBoxController( 277 mxFrame, 278 pToolBox, 279 nItemId, 280 sCommandName)), 281 UNO_QUERY); 282 if ( ! aDescriptor.mxController.is()) 283 aDescriptor.mxController.set( 284 static_cast<XWeak*>(new svt::GenericToolboxController( 285 ::comphelper::getProcessServiceFactory(), 286 mxFrame, 287 pToolBox, 288 nItemId, 289 sCommandName)), 290 UNO_QUERY); 291 if ( ! aDescriptor.mxController.is()) 292 return; 293 294 // Get dispatch object for the command. 295 aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName); 296 aDescriptor.msCurrentCommand = sCommandName; 297 aDescriptor.mxDispatch = sfx2::sidebar::Tools::GetDispatch(mxFrame, aDescriptor.maURL); 298 if ( ! aDescriptor.mxDispatch.is()) 299 return; 300 301 // Initialize the controller with eg a service factory. 302 Reference<lang::XInitialization> xInitialization (aDescriptor.mxController, UNO_QUERY); 303 if (xInitialization.is()) 304 { 305 beans::PropertyValue aPropValue; 306 std::vector<Any> aPropertyVector; 307 308 aPropValue.Name = A2S("Frame"); 309 aPropValue.Value <<= mxFrame; 310 aPropertyVector.push_back(makeAny(aPropValue)); 311 312 aPropValue.Name = A2S("ServiceManager"); 313 aPropValue.Value <<= ::comphelper::getProcessServiceFactory(); 314 aPropertyVector.push_back(makeAny(aPropValue)); 315 316 aPropValue.Name = A2S("CommandURL"); 317 aPropValue.Value <<= sCommandName; 318 aPropertyVector.push_back(makeAny(aPropValue)); 319 320 Sequence<Any> aArgs (comphelper::containerToSequence(aPropertyVector)); 321 xInitialization->initialize(aArgs); 322 } 323 324 Reference<util::XUpdatable> xUpdatable (aDescriptor.mxController, UNO_QUERY); 325 if (xUpdatable.is()) 326 xUpdatable->update(); 327 328 // Add label. 329 const OUString sLabel (sfx2::sidebar::CommandInfoProvider::Instance().GetLabelForCommand( 330 sCommandName, 331 mxFrame)); 332 pToolBox->SetQuickHelpText(nItemId, sLabel); 333 334 // Add item to toolbox. 335 pToolBox->EnableItem(nItemId); 336 maControllers.insert(::std::make_pair(nItemId, aDescriptor)); 337 } 338 } 339 340 341 342 343 ToolBox* InsertPropertyPanel::GetToolBoxForItemId (const sal_uInt16 nItemId) const 344 { 345 switch(nItemId) 346 { 347 case TBI_STANDARD_LINE: 348 case TBI_STANDARD_ARROW: 349 case TBI_STANDARD_RECTANGLE: 350 case TBI_STANDARD_ELLIPSE: 351 case TBI_STANDARD_TEXT: 352 case TBI_STANDARD_LINES: 353 case TBI_STANDARD_CONNECTORS: 354 case TBI_STANDARD_ARROWS: 355 return mpStandardShapesToolBox.get(); 356 357 case TBI_CUSTOM_BASICS: 358 case TBI_CUSTOM_SYMBOLS: 359 case TBI_CUSTOM_ARROWS: 360 case TBI_CUSTOM_FLOWCHARTS: 361 case TBI_CUSTOM_CALLOUTS: 362 case TBI_CUSTOM_STARS: 363 return mpCustomShapesToolBox.get(); 364 365 default: 366 return NULL; 367 } 368 } 369 370 371 372 373 Reference<frame::XToolbarController> InsertPropertyPanel::GetControllerForItemId (const sal_uInt16 nItemId) const 374 { 375 ControllerContainer::const_iterator iController (maControllers.find(nItemId)); 376 if (iController != maControllers.end()) 377 return iController->second.mxController; 378 else 379 return NULL; 380 } 381 382 383 384 385 sal_uInt16 InsertPropertyPanel::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const 386 { 387 for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end()); 388 iController!=iEnd; 389 ++iController) 390 { 391 Reference<frame::XSubToolbarController> xSubToolbarController (iController->second.mxController, UNO_QUERY); 392 if (xSubToolbarController.is()) 393 if (xSubToolbarController->getSubToolbarName().equals(rsSubToolbarName)) 394 return iController->first; 395 } 396 return NULL; 397 } 398 399 400 401 402 void InsertPropertyPanel::UpdateIcons (void) 403 { 404 const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge()); 405 const bool bIsHighContrastActive (sfx2::sidebar::Theme::IsHighContrastMode()); 406 407 for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end()); 408 iController!=iEnd; 409 ++iController) 410 { 411 const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand); 412 Image aImage (framework::GetImageFromURL(mxFrame, sCommandURL, bBigImages, bIsHighContrastActive)); 413 ToolBox* pToolBox = GetToolBoxForItemId(iController->first); 414 if (pToolBox != NULL) 415 pToolBox->SetItemImage(iController->first, aImage); 416 } 417 } 418 419 420 421 422 } } // end of namespace svx::sidebar 423