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 "SimpleToolBoxController.hxx" 27 #include "sfx2/sidebar/CommandInfoProvider.hxx" 28 29 #include <sfx2/sidebar/Theme.hxx> 30 #include <sfx2/sidebar/Tools.hxx> 31 #include <sfx2/sidebar/ControlFactory.hxx> 32 33 #include <svx/dialmgr.hxx> 34 #include <svtools/miscopt.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 SimpleToolBoxController(mxFrame, *pToolBox, nItemId, sCommandName)), 285 UNO_QUERY); 286 if ( ! aDescriptor.mxController.is()) 287 return; 288 289 // Get dispatch object for the command. 290 aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName); 291 aDescriptor.msCurrentCommand = sCommandName; 292 aDescriptor.mxDispatch = sfx2::sidebar::Tools::GetDispatch(mxFrame, aDescriptor.maURL); 293 if ( ! aDescriptor.mxDispatch.is()) 294 return; 295 296 // Initialize the controller with eg a service factory. 297 Reference<lang::XInitialization> xInitialization (aDescriptor.mxController, UNO_QUERY); 298 if (xInitialization.is()) 299 { 300 beans::PropertyValue aPropValue; 301 std::vector<Any> aPropertyVector; 302 303 aPropValue.Name = A2S("Frame"); 304 aPropValue.Value <<= mxFrame; 305 aPropertyVector.push_back(makeAny(aPropValue)); 306 307 aPropValue.Name = A2S("ServiceManager"); 308 aPropValue.Value <<= ::comphelper::getProcessServiceFactory(); 309 aPropertyVector.push_back(makeAny(aPropValue)); 310 311 aPropValue.Name = A2S("CommandURL"); 312 aPropValue.Value <<= sCommandName; 313 aPropertyVector.push_back(makeAny(aPropValue)); 314 315 Sequence<Any> aArgs (comphelper::containerToSequence(aPropertyVector)); 316 xInitialization->initialize(aArgs); 317 } 318 319 Reference<util::XUpdatable> xUpdatable (aDescriptor.mxController, UNO_QUERY); 320 if (xUpdatable.is()) 321 xUpdatable->update(); 322 323 // Add label. 324 const OUString sLabel (sfx2::sidebar::CommandInfoProvider::Instance().GetLabelForCommand( 325 sCommandName, 326 mxFrame)); 327 pToolBox->SetQuickHelpText(nItemId, sLabel); 328 329 // Add item to toolbox. 330 pToolBox->EnableItem(nItemId); 331 maControllers.insert(::std::make_pair(nItemId, aDescriptor)); 332 } 333 } 334 335 336 337 338 ToolBox* InsertPropertyPanel::GetToolBoxForItemId (const sal_uInt16 nItemId) const 339 { 340 switch(nItemId) 341 { 342 case TBI_STANDARD_LINE: 343 case TBI_STANDARD_ARROW: 344 case TBI_STANDARD_RECTANGLE: 345 case TBI_STANDARD_ELLIPSE: 346 case TBI_STANDARD_TEXT: 347 case TBI_STANDARD_LINES: 348 case TBI_STANDARD_CONNECTORS: 349 case TBI_STANDARD_ARROWS: 350 return mpStandardShapesToolBox.get(); 351 352 case TBI_CUSTOM_BASICS: 353 case TBI_CUSTOM_SYMBOLS: 354 case TBI_CUSTOM_ARROWS: 355 case TBI_CUSTOM_FLOWCHARTS: 356 case TBI_CUSTOM_CALLOUTS: 357 case TBI_CUSTOM_STARS: 358 return mpCustomShapesToolBox.get(); 359 360 default: 361 return NULL; 362 } 363 } 364 365 366 367 368 Reference<frame::XToolbarController> InsertPropertyPanel::GetControllerForItemId (const sal_uInt16 nItemId) const 369 { 370 ControllerContainer::const_iterator iController (maControllers.find(nItemId)); 371 if (iController != maControllers.end()) 372 return iController->second.mxController; 373 else 374 return NULL; 375 } 376 377 378 379 380 sal_uInt16 InsertPropertyPanel::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const 381 { 382 for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end()); 383 iController!=iEnd; 384 ++iController) 385 { 386 Reference<frame::XSubToolbarController> xSubToolbarController (iController->second.mxController, UNO_QUERY); 387 if (xSubToolbarController.is()) 388 if (xSubToolbarController->getSubToolbarName().equals(rsSubToolbarName)) 389 return iController->first; 390 } 391 return NULL; 392 } 393 394 395 396 397 void InsertPropertyPanel::UpdateIcons (void) 398 { 399 const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge()); 400 const bool bIsHighContrastActive (sfx2::sidebar::Theme::IsHighContrastMode()); 401 402 for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end()); 403 iController!=iEnd; 404 ++iController) 405 { 406 const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand); 407 Image aImage (framework::GetImageFromURL(mxFrame, sCommandURL, bBigImages, bIsHighContrastActive)); 408 ToolBox* pToolBox = GetToolBoxForItemId(iController->first); 409 if (pToolBox != NULL) 410 pToolBox->SetItemImage(iController->first, aImage); 411 } 412 } 413 414 415 416 417 } } // end of namespace svx::sidebar 418