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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_cui.hxx" 26 #include <vcl/help.hxx> 27 #include <vcl/msgbox.hxx> 28 #include <vcl/metric.hxx> 29 #include "selector.hxx" 30 #include <dialmgr.hxx> 31 #include "selector.hrc" 32 #include <svx/fmresids.hrc> // for RID_SVXIMG_... 33 #include <svx/dialmgr.hxx> // for RID_SVXIMG_... 34 #include <cuires.hrc> 35 #include <sfx2/app.hxx> 36 #include <sfx2/msg.hxx> 37 #include <sfx2/msgpool.hxx> 38 #include <sfx2/minfitem.hxx> 39 #include <sfx2/objsh.hxx> 40 #include <sfx2/dispatch.hxx> 41 42 #include <comphelper/documentinfo.hxx> 43 #include <comphelper/processfactory.hxx> 44 #include <comphelper/componentcontext.hxx> 45 46 #include <com/sun/star/beans/XPropertySet.hpp> 47 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp> 48 #include <com/sun/star/script/provider/XScriptProvider.hpp> 49 #include <com/sun/star/script/browse/XBrowseNode.hpp> 50 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp> 51 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp> 52 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp> 53 #include <com/sun/star/frame/XModuleManager.hpp> 54 #include <com/sun/star/frame/XDesktop.hpp> 55 #include <com/sun/star/container/XEnumerationAccess.hpp> 56 #include <com/sun/star/container/XEnumeration.hpp> 57 #include <com/sun/star/document/XEmbeddedScripts.hpp> 58 #include <com/sun/star/document/XScriptInvocationContext.hpp> 59 #include <com/sun/star/frame/XDispatchInformationProvider.hpp> 60 #include <com/sun/star/frame/DispatchInformation.hpp> 61 #include <com/sun/star/container/XChild.hpp> 62 63 using ::rtl::OUString; 64 using namespace ::com::sun::star; 65 using namespace ::com::sun::star::uno; 66 using namespace ::com::sun::star::script; 67 using namespace ::com::sun::star::frame; 68 using namespace ::com::sun::star::document; 69 using namespace ::com::sun::star::container; 70 71 #define _SVSTDARR_STRINGSDTOR 72 #include <svl/svstdarr.hxx> 73 #include <svtools/imagemgr.hxx> 74 #include <tools/urlobj.hxx> 75 #include <tools/diagnose_ex.h> 76 77 SV_IMPL_PTRARR(SvxGroupInfoArr_Impl, SvxGroupInfoPtr); 78 79 /* 80 * The implementations of SvxConfigFunctionListBox_Impl and 81 * SvxConfigGroupListBox_Impl are copied from sfx2/source/dialog/cfg.cxx 82 */ 83 SvxConfigFunctionListBox_Impl::SvxConfigFunctionListBox_Impl( Window* pParent, const ResId& rResId) 84 : SvTreeListBox( pParent, rResId ) 85 , pCurEntry( 0 ) 86 , m_pDraggingEntry( 0 ) 87 { 88 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT ); 89 GetModel()->SetSortMode( SortAscending ); 90 91 // Timer f"ur die BallonHelp 92 aTimer.SetTimeout( 200 ); 93 aTimer.SetTimeoutHdl( 94 LINK( this, SvxConfigFunctionListBox_Impl, TimerHdl ) ); 95 } 96 97 SvxConfigFunctionListBox_Impl::~SvxConfigFunctionListBox_Impl() 98 { 99 ClearAll(); 100 } 101 102 SvLBoxEntry* SvxConfigFunctionListBox_Impl::GetLastSelectedEntry() 103 { 104 if ( m_pDraggingEntry != NULL ) 105 { 106 return m_pDraggingEntry; 107 } 108 else 109 { 110 return FirstSelected(); 111 } 112 } 113 114 void SvxConfigFunctionListBox_Impl::MouseMove( const MouseEvent& rMEvt ) 115 { 116 Point aMousePos = rMEvt.GetPosPixel(); 117 pCurEntry = GetCurEntry(); 118 119 if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry ) 120 aTimer.Start(); 121 else 122 { 123 Help::ShowBalloon( this, aMousePos, String() ); 124 aTimer.Stop(); 125 } 126 } 127 128 129 IMPL_LINK( SvxConfigFunctionListBox_Impl, TimerHdl, Timer*, EMPTYARG) 130 { 131 aTimer.Stop(); 132 Point aMousePos = GetPointerPosPixel(); 133 SvLBoxEntry *pEntry = GetCurEntry(); 134 if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry ) 135 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) ); 136 return 0L; 137 } 138 139 void SvxConfigFunctionListBox_Impl::ClearAll() 140 { 141 sal_uInt16 nCount = aArr.Count(); 142 for ( sal_uInt16 i=0; i<nCount; i++ ) 143 { 144 SvxGroupInfo_Impl *pData = aArr[i]; 145 delete pData; 146 } 147 148 aArr.Remove( 0, nCount ); 149 Clear(); 150 } 151 152 String SvxConfigFunctionListBox_Impl::GetHelpText( SvLBoxEntry *pEntry ) 153 { 154 // Information zum selektierten Entry aus den Userdaten holen 155 SvxGroupInfo_Impl *pInfo = 156 pEntry ? (SvxGroupInfo_Impl*) pEntry->GetUserData(): 0; 157 158 if ( pInfo ) 159 { 160 if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT ) 161 { 162 OUString aCmdURL( pInfo->sURL ); 163 164 OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this ); 165 166 return aHelpText; 167 } 168 else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT ) 169 { 170 return pInfo->sHelpText; 171 } 172 } 173 174 return String(); 175 } 176 177 void SvxConfigFunctionListBox_Impl::FunctionSelected() 178 { 179 Help::ShowBalloon( this, Point(), String() ); 180 } 181 182 // drag and drop support 183 DragDropMode SvxConfigFunctionListBox_Impl::NotifyStartDrag( 184 TransferDataContainer& /*aTransferDataContainer*/, SvLBoxEntry* pEntry ) 185 { 186 m_pDraggingEntry = pEntry; 187 return GetDragDropMode(); 188 } 189 190 void SvxConfigFunctionListBox_Impl::DragFinished( sal_Int8 /*nDropAction*/ ) 191 { 192 m_pDraggingEntry = NULL; 193 } 194 195 sal_Int8 196 SvxConfigFunctionListBox_Impl::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) 197 { 198 return DND_ACTION_NONE; 199 } 200 201 SvxConfigGroupListBox_Impl::SvxConfigGroupListBox_Impl( 202 Window* pParent, const ResId& rResId, 203 bool _bShowSlots, const Reference< frame::XFrame >& xFrame ) 204 : SvTreeListBox( pParent, rResId ) 205 , m_bShowSlots( _bShowSlots ), 206 m_hdImage(ResId(IMG_HARDDISK,*rResId.GetResMgr())), 207 m_hdImage_hc(ResId(IMG_HARDDISK_HC,*rResId.GetResMgr())), 208 m_libImage(ResId(IMG_LIB,*rResId.GetResMgr())), 209 m_libImage_hc(ResId(IMG_LIB_HC,*rResId.GetResMgr())), 210 m_macImage(ResId(IMG_MACRO,*rResId.GetResMgr())), 211 m_macImage_hc(ResId(IMG_MACRO_HC,*rResId.GetResMgr())), 212 m_docImage(ResId(IMG_DOC,*rResId.GetResMgr())), 213 m_docImage_hc(ResId(IMG_DOC_HC,*rResId.GetResMgr())), 214 m_sMyMacros(String(ResId(STR_MYMACROS,*rResId.GetResMgr()))), 215 m_sProdMacros(String(ResId(STR_PRODMACROS,*rResId.GetResMgr()))) 216 { 217 FreeResource(); 218 219 if ( xFrame != NULL ) 220 { 221 m_xFrame.set( xFrame ); 222 } 223 224 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ); 225 226 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) ); 227 228 SetNodeBitmaps( 229 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ), 230 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ), 231 BMP_COLOR_NORMAL ); 232 233 SetNodeBitmaps( 234 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ), 235 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ), 236 BMP_COLOR_HIGHCONTRAST ); 237 } 238 239 240 SvxConfigGroupListBox_Impl::~SvxConfigGroupListBox_Impl() 241 { 242 ClearAll(); 243 } 244 245 void SvxConfigGroupListBox_Impl::ClearAll() 246 { 247 sal_uInt16 nCount = aArr.Count(); 248 for ( sal_uInt16 i=0; i<nCount; i++ ) 249 { 250 SvxGroupInfo_Impl *pData = aArr[i]; 251 delete pData; 252 } 253 254 aArr.Remove( 0, nCount ); 255 Clear(); 256 } 257 258 //----------------------------------------------- 259 namespace 260 { 261 //........................................... 262 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a 263 component by implementing XScriptInvocationContext. 264 @return 265 the model which supports the embedded scripts, or <NULL/> if it cannot find such a 266 model 267 */ 268 static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent ) 269 { 270 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY ); 271 if ( !xScripts.is() ) 272 { 273 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY ); 274 if ( xContext.is() ) 275 xScripts.set( xContext->getScriptContainer(), UNO_QUERY ); 276 } 277 278 return Reference< XModel >( xScripts, UNO_QUERY ); 279 } 280 281 //........................................... 282 static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame ) 283 { 284 Reference< XModel > xDocument; 285 286 // examine our associated frame 287 try 288 { 289 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" ); 290 if ( _rxFrame.is() ) 291 { 292 // first try the model in the frame 293 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW ); 294 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() ); 295 296 if ( !xDocument.is() ) 297 { 298 // if there is no suitable document in the frame, try the controller 299 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() ); 300 } 301 } 302 } 303 catch( const Exception& ) 304 { 305 DBG_UNHANDLED_EXCEPTION(); 306 } 307 308 return xDocument; 309 } 310 } 311 312 void SvxConfigGroupListBox_Impl::fillScriptList( const Reference< browse::XBrowseNode >& _rxRootNode, SvLBoxEntry* _pParentEntry, bool _bCheapChildsOnDemand ) 313 { 314 OSL_PRECOND( _rxRootNode.is(), "SvxConfigGroupListBox_Impl::fillScriptList: invalid root node!" ); 315 if ( !_rxRootNode.is() ) 316 return; 317 318 try 319 { 320 if ( _rxRootNode->hasChildNodes() ) 321 { 322 Sequence< Reference< browse::XBrowseNode > > children = 323 _rxRootNode->getChildNodes(); 324 325 sal_Bool bIsRootNode = _rxRootNode->getName().equalsAscii("Root"); 326 327 /* To mimic current starbasic behaviour we 328 need to make sure that only the current document 329 is displayed in the config tree. Tests below 330 set the bDisplay flag to sal_False if the current 331 node is a first level child of the Root and is NOT 332 either the current document, user or share */ 333 OUString sCurrentDocTitle; 334 Reference< XModel > xWorkingDocument = lcl_getScriptableDocument_nothrow( m_xFrame ); 335 if ( xWorkingDocument.is() ) 336 { 337 sCurrentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument ); 338 } 339 340 for ( long n = 0; n < children.getLength(); n++ ) 341 { 342 Reference< browse::XBrowseNode >& theChild = children[n]; 343 //#139111# some crash reports show that it might be unset 344 if ( !theChild.is() ) 345 continue; 346 ::rtl::OUString sUIName = theChild->getName(); 347 sal_Bool bDisplay = sal_True; 348 349 if ( bIsRootNode 350 || ( m_bShowSlots && _pParentEntry && ( GetModel()->GetDepth( _pParentEntry ) == 0 ) ) 351 // if we show slots (as in the customize dialog) 352 // then the user & share are added at depth=1 353 ) 354 { 355 if ( sUIName.equalsAscii( "user" ) ) 356 { 357 sUIName = m_sMyMacros; 358 bIsRootNode = sal_True; 359 } 360 else if ( sUIName.equalsAscii( "share" ) ) 361 { 362 sUIName = m_sProdMacros; 363 bIsRootNode = sal_True; 364 } 365 else if ( !sUIName.equals( sCurrentDocTitle ) ) 366 { 367 bDisplay = sal_False; 368 } 369 } 370 371 if ( !bDisplay ) 372 continue; 373 374 if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT ) 375 continue; 376 377 SvLBoxEntry* pNewEntry = InsertEntry( sUIName, _pParentEntry ); 378 379 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 380 Image aImage = GetImage( theChild, aContext.getUNOContext(), bIsRootNode, BMP_COLOR_NORMAL ); 381 SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); 382 SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); 383 384 aImage = GetImage( theChild, aContext.getUNOContext(), bIsRootNode, BMP_COLOR_HIGHCONTRAST ); 385 SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST ); 386 SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST ); 387 388 SvxGroupInfo_Impl* pInfo = 389 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, theChild ); 390 pNewEntry->SetUserData( pInfo ); 391 aArr.Insert( pInfo, aArr.Count() ); 392 393 if ( _bCheapChildsOnDemand ) 394 { 395 /* i30923 - Would be nice if there was a better 396 * way to determine if a basic lib had children 397 * without having to ask for them (which forces 398 * the library to be loaded */ 399 pNewEntry->EnableChildsOnDemand( sal_True ); 400 } 401 else 402 { 403 // if there are granchildren we're interested in, display the '+' before 404 // the entry, but do not yet expand 405 Sequence< Reference< browse::XBrowseNode > > grandchildren = 406 children[n]->getChildNodes(); 407 408 for ( sal_Int32 m = 0; m < grandchildren.getLength(); m++ ) 409 { 410 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER ) 411 { 412 pNewEntry->EnableChildsOnDemand( sal_True ); 413 break; 414 } 415 } 416 } 417 } 418 } 419 } 420 catch (const Exception&) 421 { 422 DBG_UNHANDLED_EXCEPTION(); 423 } 424 } 425 426 void SvxConfigGroupListBox_Impl::Init() 427 { 428 SetUpdateMode(sal_False); 429 ClearAll(); 430 431 Reference< XComponentContext > xContext; 432 Reference < beans::XPropertySet > xProps( 433 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); 434 435 xContext.set( xProps->getPropertyValue( 436 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), 437 UNO_QUERY ); 438 439 // are we showing builtin commands? 440 if ( m_bShowSlots && xContext.is() && m_xFrame.is() ) 441 { 442 Reference< lang::XMultiComponentFactory > xMCF = 443 xContext->getServiceManager(); 444 445 Reference< frame::XDispatchInformationProvider > xDIP( 446 m_xFrame, UNO_QUERY ); 447 448 Reference< ::com::sun::star::frame::XModuleManager > 449 xModuleManager( xMCF->createInstanceWithContext( 450 OUString::createFromAscii( 451 "com.sun.star.frame.ModuleManager" ), 452 xContext ), 453 UNO_QUERY ); 454 455 OUString aModuleId; 456 try{ 457 aModuleId = xModuleManager->identify( m_xFrame ); 458 }catch(const uno::Exception&) 459 { aModuleId = ::rtl::OUString(); } 460 461 Reference< container::XNameAccess > xNameAccess( 462 xMCF->createInstanceWithContext( 463 OUString::createFromAscii( 464 "com.sun.star.frame.UICommandDescription" ), 465 xContext ), 466 UNO_QUERY ); 467 468 if ( xNameAccess.is() ) 469 { 470 xNameAccess->getByName( aModuleId ) >>= m_xModuleCommands; 471 } 472 473 Reference< container::XNameAccess > xAllCategories( 474 xMCF->createInstanceWithContext( 475 OUString::createFromAscii( 476 "com.sun.star.ui.UICategoryDescription" ), 477 xContext ), 478 UNO_QUERY ); 479 480 Reference< container::XNameAccess > xModuleCategories; 481 if ( xAllCategories.is() ) 482 { 483 if ( aModuleId.getLength() != 0 ) 484 { 485 try 486 { 487 xModuleCategories = Reference< container::XNameAccess >( 488 xAllCategories->getByName( aModuleId ), UNO_QUERY ); 489 } 490 catch ( container::NoSuchElementException& ) 491 { 492 } 493 } 494 495 if ( !xModuleCategories.is() ) 496 { 497 xModuleCategories = xAllCategories; 498 } 499 } 500 501 if ( xModuleCategories.is() ) 502 { 503 Sequence< sal_Int16 > gids = 504 xDIP->getSupportedCommandGroups(); 505 506 for ( sal_Int32 i = 0; i < gids.getLength(); i++ ) 507 { 508 Sequence< frame::DispatchInformation > commands; 509 try 510 { 511 commands = 512 xDIP->getConfigurableDispatchInformation( gids[i] ); 513 } 514 catch ( container::NoSuchElementException& ) 515 { 516 continue; 517 } 518 519 if ( commands.getLength() == 0 ) 520 { 521 continue; 522 } 523 524 sal_Int32 gid = gids[i]; 525 OUString idx = OUString::valueOf( gid ); 526 OUString group = idx; 527 try 528 { 529 xModuleCategories->getByName( idx ) >>= group; 530 } 531 catch ( container::NoSuchElementException& ) 532 { 533 } 534 535 SvLBoxEntry *pEntry = InsertEntry( group, NULL ); 536 537 SvxGroupInfo_Impl *pInfo = 538 new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION, gids[i] ); 539 aArr.Insert( pInfo, aArr.Count() ); 540 541 pEntry->SetUserData( pInfo ); 542 } 543 } 544 } 545 546 if ( xContext.is() ) 547 { 548 // Add Scripting Framework entries 549 Reference< browse::XBrowseNode > rootNode; 550 Reference< XComponentContext> xCtx; 551 552 try 553 { 554 Reference < beans::XPropertySet > _xProps( 555 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); 556 xCtx.set( _xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW ); 557 Reference< browse::XBrowseNodeFactory > xFac( xCtx->getValueByName( 558 OUString::createFromAscii( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory") ), UNO_QUERY_THROW ); 559 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) ); 560 } 561 catch( const Exception& ) 562 { 563 DBG_UNHANDLED_EXCEPTION(); 564 } 565 566 if ( rootNode.is() ) 567 { 568 if ( m_bShowSlots ) 569 { 570 SvxGroupInfo_Impl *pInfo = 571 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, rootNode ); 572 573 String aTitle = 574 String( CUI_RES( STR_SELECTOR_MACROS ) ); 575 576 SvLBoxEntry *pNewEntry = InsertEntry( aTitle, NULL ); 577 pNewEntry->SetUserData( pInfo ); 578 pNewEntry->EnableChildsOnDemand( sal_True ); 579 aArr.Insert( pInfo, aArr.Count() ); 580 } 581 else 582 { 583 fillScriptList( rootNode, NULL, false ); 584 } 585 } 586 } 587 MakeVisible( GetEntry( 0,0 ) ); 588 SetUpdateMode( sal_True ); 589 } 590 591 Image SvxConfigGroupListBox_Impl::GetImage( Reference< browse::XBrowseNode > node, Reference< XComponentContext > xCtx, bool bIsRootNode, bool bHighContrast ) 592 { 593 Image aImage; 594 if ( bIsRootNode ) 595 { 596 if ( node->getName().equalsAscii( "user" ) || node->getName().equalsAscii( "share" ) ) 597 { 598 if( bHighContrast == BMP_COLOR_NORMAL ) 599 aImage = m_hdImage; 600 else 601 aImage = m_hdImage_hc; 602 } 603 else 604 { 605 OUString factoryURL; 606 OUString nodeName = node->getName(); 607 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName ); 608 if ( xDocumentModel.is() ) 609 { 610 Reference< ::com::sun::star::frame::XModuleManager > 611 xModuleManager( 612 xCtx->getServiceManager() 613 ->createInstanceWithContext( 614 OUString::createFromAscii("com.sun.star.frame.ModuleManager"), 615 xCtx ), 616 UNO_QUERY_THROW ); 617 Reference<container::XNameAccess> xModuleConfig( 618 xModuleManager, UNO_QUERY_THROW ); 619 // get the long name of the document: 620 OUString appModule( xModuleManager->identify( 621 xDocumentModel ) ); 622 Sequence<beans::PropertyValue> moduleDescr; 623 Any aAny = xModuleConfig->getByName(appModule); 624 if( sal_True != ( aAny >>= moduleDescr ) ) 625 { 626 throw RuntimeException(OUString::createFromAscii("SFTreeListBox::Init: failed to get PropertyValue"), Reference< XInterface >()); 627 } 628 beans::PropertyValue const * pmoduleDescr = 629 moduleDescr.getConstArray(); 630 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; ) 631 { 632 if (pmoduleDescr[ pos ].Name.equalsAsciiL( 633 RTL_CONSTASCII_STRINGPARAM( 634 "ooSetupFactoryEmptyDocumentURL") )) 635 { 636 pmoduleDescr[ pos ].Value >>= factoryURL; 637 break; 638 } 639 } 640 } 641 if( factoryURL.getLength() > 0 ) 642 { 643 if( bHighContrast == BMP_COLOR_NORMAL ) 644 aImage = SvFileInformationManager::GetFileImage( 645 INetURLObject(factoryURL), false, 646 BMP_COLOR_NORMAL ); 647 else 648 aImage = SvFileInformationManager::GetFileImage( 649 INetURLObject(factoryURL), false, 650 BMP_COLOR_HIGHCONTRAST ); 651 } 652 else 653 { 654 if( bHighContrast == BMP_COLOR_NORMAL ) 655 aImage = m_docImage; 656 else 657 aImage = m_docImage_hc; 658 } 659 } 660 } 661 else 662 { 663 if( node->getType() == browse::BrowseNodeTypes::SCRIPT ) 664 { 665 if( bHighContrast == BMP_COLOR_NORMAL ) 666 aImage = m_macImage; 667 else 668 aImage = m_macImage_hc; 669 } 670 else 671 { 672 if( bHighContrast == BMP_COLOR_NORMAL ) 673 aImage = m_libImage; 674 else 675 aImage = m_libImage_hc; 676 } 677 } 678 return aImage; 679 } 680 681 Reference< XInterface > 682 SvxConfigGroupListBox_Impl::getDocumentModel( 683 Reference< XComponentContext >& xCtx, OUString& docName ) 684 { 685 Reference< XInterface > xModel; 686 Reference< lang::XMultiComponentFactory > mcf = 687 xCtx->getServiceManager(); 688 Reference< frame::XDesktop > desktop ( 689 mcf->createInstanceWithContext( 690 OUString::createFromAscii("com.sun.star.frame.Desktop"), xCtx ), 691 UNO_QUERY ); 692 693 Reference< container::XEnumerationAccess > componentsAccess = 694 desktop->getComponents(); 695 Reference< container::XEnumeration > components = 696 componentsAccess->createEnumeration(); 697 while (components->hasMoreElements()) 698 { 699 Reference< frame::XModel > model( 700 components->nextElement(), UNO_QUERY ); 701 if ( model.is() ) 702 { 703 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model ); 704 if( sTdocUrl.equals( docName ) ) 705 { 706 xModel = model; 707 break; 708 } 709 } 710 } 711 return xModel; 712 } 713 714 void SvxConfigGroupListBox_Impl::GroupSelected() 715 { 716 SvLBoxEntry *pEntry = FirstSelected(); 717 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData(); 718 pFunctionListBox->SetUpdateMode(sal_False); 719 pFunctionListBox->ClearAll(); 720 if ( pInfo->nKind != SVX_CFGGROUP_FUNCTION && 721 pInfo->nKind != SVX_CFGGROUP_SCRIPTCONTAINER ) 722 { 723 pFunctionListBox->SetUpdateMode(sal_True); 724 return; 725 } 726 727 switch ( pInfo->nKind ) 728 { 729 case SVX_CFGGROUP_FUNCTION : 730 { 731 SvLBoxEntry *_pEntry = FirstSelected(); 732 if ( _pEntry != NULL ) 733 { 734 SvxGroupInfo_Impl *_pInfo = 735 (SvxGroupInfo_Impl*) _pEntry->GetUserData(); 736 737 Reference< frame::XDispatchInformationProvider > xDIP( 738 m_xFrame, UNO_QUERY ); 739 740 Sequence< frame::DispatchInformation > commands; 741 try 742 { 743 commands = xDIP->getConfigurableDispatchInformation( 744 _pInfo->nOrd ); 745 } 746 catch ( container::NoSuchElementException& ) 747 { 748 } 749 750 for ( sal_Int32 i = 0; i < commands.getLength(); i++ ) 751 { 752 if ( commands[i].Command.getLength() == 0 ) 753 { 754 continue; 755 } 756 757 Image aImage; 758 759 OUString aCmdURL( commands[i].Command ); 760 761 if ( m_pImageProvider ) 762 { 763 aImage = m_pImageProvider->GetImage( aCmdURL ); 764 } 765 766 OUString aLabel; 767 try 768 { 769 Any a = m_xModuleCommands->getByName( aCmdURL ); 770 Sequence< beans::PropertyValue > aPropSeq; 771 772 if ( a >>= aPropSeq ) 773 { 774 for ( sal_Int32 k = 0; k < aPropSeq.getLength(); k++ ) 775 { 776 if ( aPropSeq[k].Name.equalsAscii( "Name" ) ) 777 { 778 aPropSeq[k].Value >>= aLabel; 779 break; 780 } 781 } 782 } 783 } 784 catch ( container::NoSuchElementException& ) 785 { 786 } 787 788 if ( aLabel.getLength() == 0 ) 789 { 790 aLabel = commands[i].Command; 791 } 792 793 SvLBoxEntry* pFuncEntry = NULL; 794 if ( !!aImage ) 795 { 796 pFuncEntry = pFunctionListBox->InsertEntry( 797 aLabel, aImage, aImage ); 798 } 799 else 800 { 801 pFuncEntry = pFunctionListBox->InsertEntry( 802 aLabel, NULL ); 803 } 804 805 SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl( 806 SVX_CFGFUNCTION_SLOT, 123, aCmdURL, ::rtl::OUString() ); 807 808 pFunctionListBox->aArr.Insert( 809 _pGroupInfo, pFunctionListBox->aArr.Count() ); 810 811 pFuncEntry->SetUserData( _pGroupInfo ); 812 } 813 } 814 break; 815 } 816 817 case SVX_CFGGROUP_SCRIPTCONTAINER: 818 { 819 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ); 820 821 try { 822 if ( rootNode->hasChildNodes() ) 823 { 824 Sequence< Reference< browse::XBrowseNode > > children = 825 rootNode->getChildNodes(); 826 827 for ( long n = 0; n < children.getLength(); n++ ) 828 { 829 if (!children[n].is()) 830 continue; 831 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT) 832 { 833 OUString uri; 834 OUString description; 835 836 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY ); 837 if (!xPropSet.is()) 838 { 839 continue; 840 } 841 842 Any value = 843 xPropSet->getPropertyValue( String::CreateFromAscii( "URI" ) ); 844 value >>= uri; 845 846 try 847 { 848 value = xPropSet->getPropertyValue( 849 String::CreateFromAscii( "Description" ) ); 850 value >>= description; 851 } 852 catch (Exception &) { 853 // do nothing, the description will be empty 854 } 855 856 SvxGroupInfo_Impl* _pGroupInfo = 857 new SvxGroupInfo_Impl( 858 SVX_CFGFUNCTION_SCRIPT, 123, uri, description ); 859 860 Image aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_NORMAL ); 861 SvLBoxEntry* pNewEntry = 862 pFunctionListBox->InsertEntry( children[n]->getName(), NULL ); 863 pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL); 864 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL); 865 aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_HIGHCONTRAST ); 866 pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST); 867 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST); 868 869 pNewEntry->SetUserData( _pGroupInfo ); 870 871 pFunctionListBox->aArr.Insert( 872 _pGroupInfo, pFunctionListBox->aArr.Count() ); 873 874 } 875 } 876 } 877 } 878 catch (const Exception&) 879 { 880 DBG_UNHANDLED_EXCEPTION(); 881 } 882 break; 883 } 884 885 default: 886 { 887 return; 888 } 889 } 890 891 if ( pFunctionListBox->GetEntryCount() ) 892 pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) ); 893 894 pFunctionListBox->SetUpdateMode(sal_True); 895 } 896 897 sal_Bool SvxConfigGroupListBox_Impl::Expand( SvLBoxEntry* pParent ) 898 { 899 sal_Bool bRet = SvTreeListBox::Expand( pParent ); 900 if ( bRet ) 901 { 902 // Wieviele Entries k"onnen angezeigt werden ? 903 sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight(); 904 905 // Wieviele Kinder sollen angezeigt werden ? 906 sal_uLong nChildCount = GetVisibleChildCount( pParent ); 907 908 // Passen alle Kinder und der parent gleichzeitig in die View ? 909 if ( nChildCount+1 > nEntries ) 910 { 911 // Wenn nicht, wenigstens parent ganz nach oben schieben 912 MakeVisible( pParent, sal_True ); 913 } 914 else 915 { 916 // An welcher relativen ViewPosition steht der aufzuklappende parent 917 SvLBoxEntry *pEntry = GetFirstEntryInView(); 918 sal_uLong nParentPos = 0; 919 while ( pEntry && pEntry != pParent ) 920 { 921 nParentPos++; 922 pEntry = GetNextEntryInView( pEntry ); 923 } 924 925 // Ist unter dem parent noch genug Platz f"ur alle Kinder ? 926 if ( nParentPos + nChildCount + 1 > nEntries ) 927 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) ); 928 } 929 } 930 931 return bRet; 932 } 933 934 void SvxConfigGroupListBox_Impl::RequestingChilds( SvLBoxEntry *pEntry ) 935 { 936 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData(); 937 pInfo->bWasOpened = sal_True; 938 switch ( pInfo->nKind ) 939 { 940 case SVX_CFGGROUP_SCRIPTCONTAINER: 941 { 942 if ( !GetChildCount( pEntry ) ) 943 { 944 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ) ; 945 fillScriptList( rootNode, pEntry, true /* i30923 */ ); 946 } 947 break; 948 } 949 950 default: 951 DBG_ERROR( "Falscher Gruppentyp!" ); 952 break; 953 } 954 } 955 956 /* 957 * Implementation of SvxScriptSelectorDialog 958 * 959 * This dialog is used for selecting Slot API commands 960 * and Scripting Framework Scripts. 961 */ 962 963 SvxScriptSelectorDialog::SvxScriptSelectorDialog( 964 Window* pParent, sal_Bool bShowSlots, const Reference< frame::XFrame >& xFrame ) 965 : 966 ModelessDialog( pParent, CUI_RES( RID_DLG_SCRIPTSELECTOR ) ), 967 aDialogDescription( this, CUI_RES( TXT_SELECTOR_DIALOG_DESCRIPTION ) ), 968 aGroupText( this, CUI_RES( TXT_SELECTOR_CATEGORIES ) ), 969 aCategories( this, CUI_RES( BOX_SELECTOR_CATEGORIES ), bShowSlots, xFrame ), 970 aFunctionText( this, CUI_RES( TXT_SELECTOR_COMMANDS ) ), 971 aCommands( this, CUI_RES( BOX_SELECTOR_COMMANDS ) ), 972 aOKButton( this, CUI_RES( BTN_SELECTOR_OK ) ), 973 aCancelButton( this, CUI_RES( BTN_SELECTOR_CANCEL ) ), 974 aHelpButton( this, CUI_RES( BTN_SELECTOR_HELP ) ), 975 aDescription( this, CUI_RES( GRP_SELECTOR_DESCRIPTION ) ), 976 aDescriptionText( this, CUI_RES( TXT_SELECTOR_DESCRIPTION ) ), 977 m_bShowSlots( bShowSlots ) 978 { 979 980 ResMgr& rMgr = CUI_MGR(); 981 982 // If we are showing Slot API commands update labels in the UI, and 983 // enable drag'n'drop 984 if ( m_bShowSlots ) 985 { 986 aGroupText.SetText( String( ResId( STR_SELECTOR_CATEGORIES, rMgr ) ) ); 987 aOKButton.SetText( String( ResId( STR_SELECTOR_ADD, rMgr ) ) ); 988 aCancelButton.SetText( String( ResId( STR_SELECTOR_CLOSE, rMgr ) ) ); 989 aFunctionText.SetText( String( ResId( STR_SELECTOR_COMMANDS, rMgr ) ) ); 990 SetDialogDescription( 991 String( ResId( STR_SELECTOR_ADD_COMMANDS_DESCRIPTION, rMgr ) ) ); 992 SetText( String( ResId( STR_SELECTOR_ADD_COMMANDS, rMgr ) ) ); 993 994 aCommands.SetDragDropMode( SV_DRAGDROP_APP_COPY ); 995 } 996 997 ResizeControls(); 998 999 aCategories.SetFunctionListBox( &aCommands ); 1000 aCategories.Init(); 1001 // aCategories.Select( aCategories.GetEntry( 0, 0 ) ); 1002 1003 aCategories.SetSelectHdl( 1004 LINK( this, SvxScriptSelectorDialog, SelectHdl ) ); 1005 aCommands.SetSelectHdl( LINK( this, SvxScriptSelectorDialog, SelectHdl ) ); 1006 aCommands.SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) ); 1007 1008 aOKButton.SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) ); 1009 aCancelButton.SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) ); 1010 1011 UpdateUI(); 1012 FreeResource(); 1013 } 1014 1015 void SvxScriptSelectorDialog::ResizeControls() 1016 { 1017 Point p, newp; 1018 Size s, news; 1019 long gap; 1020 1021 sal_uInt16 style = TEXT_DRAW_MULTILINE | TEXT_DRAW_TOP | 1022 TEXT_DRAW_LEFT | TEXT_DRAW_WORDBREAK; 1023 1024 // get dimensions of dialog instructions control 1025 p = aDialogDescription.GetPosPixel(); 1026 s = aDialogDescription.GetSizePixel(); 1027 1028 // get dimensions occupied by text in the control 1029 Rectangle rect = 1030 GetTextRect( Rectangle( p, s ), aDialogDescription.GetText(), style ); 1031 news = rect.GetSize(); 1032 1033 // the gap is the difference between the control height and its text height 1034 gap = s.Height() - news.Height(); 1035 1036 // resize the dialog instructions control 1037 news = Size( s.Width(), s.Height() - gap ); 1038 aDialogDescription.SetSizePixel( news ); 1039 1040 // resize other controls to fill the gap 1041 p = aGroupText.GetPosPixel(); 1042 newp = Point( p.X(), p.Y() - gap ); 1043 aGroupText.SetPosPixel( newp ); 1044 1045 p = aCategories.GetPosPixel(); 1046 newp = Point( p.X(), p.Y() - gap ); 1047 aCategories.SetPosPixel( newp ); 1048 s = aCategories.GetSizePixel(); 1049 news = Size( s.Width(), s.Height() + gap ); 1050 aCategories.SetSizePixel( news ); 1051 1052 p = aFunctionText.GetPosPixel(); 1053 newp = Point( p.X(), p.Y() - gap ); 1054 aFunctionText.SetPosPixel( newp ); 1055 1056 p = aCommands.GetPosPixel(); 1057 newp = Point( p.X(), p.Y() - gap ); 1058 aCommands.SetPosPixel( newp ); 1059 s = aCommands.GetSizePixel(); 1060 news = Size( s.Width(), s.Height() + gap ); 1061 aCommands.SetSizePixel( news ); 1062 1063 p = aOKButton.GetPosPixel(); 1064 newp = Point( p.X(), p.Y() - gap ); 1065 aOKButton.SetPosPixel( newp ); 1066 1067 p = aCancelButton.GetPosPixel(); 1068 newp = Point( p.X(), p.Y() - gap ); 1069 aCancelButton.SetPosPixel( newp ); 1070 1071 p = aHelpButton.GetPosPixel(); 1072 newp = Point( p.X(), p.Y() - gap ); 1073 aHelpButton.SetPosPixel( newp ); 1074 } 1075 1076 SvxScriptSelectorDialog::~SvxScriptSelectorDialog() 1077 { 1078 } 1079 1080 IMPL_LINK( SvxScriptSelectorDialog, SelectHdl, Control*, pCtrl ) 1081 { 1082 if ( pCtrl == &aCategories ) 1083 { 1084 aCategories.GroupSelected(); 1085 } 1086 else if ( pCtrl == &aCommands ) 1087 { 1088 aCommands.FunctionSelected(); 1089 } 1090 UpdateUI(); 1091 return 0; 1092 } 1093 1094 IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl ) 1095 { 1096 (void)pCtrl; 1097 if ( aOKButton.IsEnabled() ) 1098 return ClickHdl( &aOKButton ); 1099 return 0; 1100 } 1101 1102 // Check if command is selected and enable the OK button accordingly 1103 // Grab the help text for this id if available and update the description field 1104 void 1105 SvxScriptSelectorDialog::UpdateUI() 1106 { 1107 OUString url = GetScriptURL(); 1108 if ( url != NULL && url.getLength() != 0 ) 1109 { 1110 String rMessage = 1111 aCommands.GetHelpText( aCommands.FirstSelected() ); 1112 aDescriptionText.SetText( rMessage ); 1113 1114 aOKButton.Enable( sal_True ); 1115 } 1116 else 1117 { 1118 aDescriptionText.SetText( String() ); 1119 aOKButton.Enable( sal_False ); 1120 } 1121 } 1122 1123 IMPL_LINK( SvxScriptSelectorDialog, ClickHdl, Button *, pButton ) 1124 { 1125 if ( pButton == &aCancelButton ) 1126 { 1127 // If we are displaying Slot API commands then the dialog is being 1128 // run from Tools/Configure and we should not close it, just hide it 1129 if ( m_bShowSlots == sal_False ) 1130 { 1131 EndDialog( RET_CANCEL ); 1132 } 1133 else 1134 { 1135 Hide(); 1136 } 1137 } 1138 else if ( pButton == &aOKButton ) 1139 { 1140 GetAddHdl().Call( this ); 1141 1142 // If we are displaying Slot API commands then this the dialog is being 1143 // run from Tools/Configure and we should not close it 1144 if ( m_bShowSlots == sal_False ) 1145 { 1146 EndDialog( RET_OK ); 1147 } 1148 else 1149 { 1150 // Select the next entry in the list if possible 1151 SvLBoxEntry* current = aCommands.FirstSelected(); 1152 SvLBoxEntry* next = aCommands.NextSibling( current ); 1153 1154 if ( next != NULL ) 1155 { 1156 aCommands.Select( next ); 1157 } 1158 } 1159 } 1160 1161 return 0; 1162 } 1163 1164 void 1165 SvxScriptSelectorDialog::SetRunLabel() 1166 { 1167 aOKButton.SetText( String( CUI_RES( STR_SELECTOR_RUN ) ) ); 1168 } 1169 1170 void 1171 SvxScriptSelectorDialog::SetDialogDescription( const String& rDescription ) 1172 { 1173 aDialogDescription.SetText( rDescription ); 1174 } 1175 1176 String 1177 SvxScriptSelectorDialog::GetScriptURL() const 1178 { 1179 OUString result; 1180 1181 SvLBoxEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->aCommands.GetLastSelectedEntry(); 1182 if ( pEntry ) 1183 { 1184 SvxGroupInfo_Impl *pData = (SvxGroupInfo_Impl*) pEntry->GetUserData(); 1185 if ( ( pData->nKind == SVX_CFGFUNCTION_SLOT ) 1186 || ( pData->nKind == SVX_CFGFUNCTION_SCRIPT ) 1187 ) 1188 { 1189 result = pData->sURL; 1190 } 1191 } 1192 1193 return result; 1194 } 1195 1196 String 1197 SvxScriptSelectorDialog::GetSelectedDisplayName() 1198 { 1199 return aCommands.GetEntryText( aCommands.GetLastSelectedEntry() ); 1200 } 1201 1202 String 1203 SvxScriptSelectorDialog::GetSelectedHelpText() 1204 { 1205 return aCommands.GetHelpText( aCommands.GetLastSelectedEntry() ); 1206 } 1207