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