Update ooo320-m1
[ooovba.git] / svx / source / cui / selector.cxx
blob83e0e33bd8805e9098b8c8aa7214abb20b3ffbda
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: selector.cxx,v $
10 * $Revision: 1.28 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <vcl/help.hxx>
34 #ifndef _MSGBOX_HXX //autogen
35 #include <vcl/msgbox.hxx>
36 #endif
37 #include <vcl/metric.hxx>
39 #include "selector.hxx"
40 #include <svx/dialmgr.hxx>
42 #include "selector.hrc"
43 #include "fmresids.hrc"
44 #include <svx/dialogs.hrc>
46 #include <sfx2/app.hxx>
47 #include <sfx2/msg.hxx>
48 #include <sfx2/msgpool.hxx>
49 #include <sfx2/macrconf.hxx>
50 #include <sfx2/minfitem.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <sfx2/dispatch.hxx>
54 #include <comphelper/documentinfo.hxx>
55 #include <comphelper/processfactory.hxx>
56 #include <comphelper/componentcontext.hxx>
58 /** === begin UNO includes === **/
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
61 #include <com/sun/star/script/provider/XScriptProvider.hpp>
62 #include <com/sun/star/script/browse/XBrowseNode.hpp>
63 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
64 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
65 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
66 #include <com/sun/star/frame/XModuleManager.hpp>
67 #include <com/sun/star/frame/XDesktop.hpp>
68 #include <com/sun/star/container/XEnumerationAccess.hpp>
69 #include <com/sun/star/container/XEnumeration.hpp>
70 #include <com/sun/star/document/XEmbeddedScripts.hpp>
71 #include <com/sun/star/document/XScriptInvocationContext.hpp>
72 #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
73 #include <com/sun/star/frame/DispatchInformation.hpp>
74 #include <com/sun/star/container/XChild.hpp>
75 /** === end UNO includes === **/
77 using ::rtl::OUString;
78 using namespace ::com::sun::star;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::script;
81 using namespace ::com::sun::star::frame;
82 using namespace ::com::sun::star::document;
83 using namespace ::com::sun::star::container;
85 #define _SVSTDARR_STRINGSDTOR
86 #include <svtools/svstdarr.hxx>
87 #include <svtools/imagemgr.hxx>
88 #include <tools/urlobj.hxx>
89 #include <tools/diagnose_ex.h>
91 SV_IMPL_PTRARR(SvxGroupInfoArr_Impl, SvxGroupInfoPtr);
94 * The implementations of SvxConfigFunctionListBox_Impl and
95 * SvxConfigGroupListBox_Impl are copied from sfx2/source/dialog/cfg.cxx
97 SvxConfigFunctionListBox_Impl::SvxConfigFunctionListBox_Impl( Window* pParent, const ResId& rResId)
98 : SvTreeListBox( pParent, rResId )
99 , pCurEntry( 0 )
100 , m_pDraggingEntry( 0 )
102 SetWindowBits( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT );
103 GetModel()->SetSortMode( SortAscending );
105 // Timer f"ur die BallonHelp
106 aTimer.SetTimeout( 200 );
107 aTimer.SetTimeoutHdl(
108 LINK( this, SvxConfigFunctionListBox_Impl, TimerHdl ) );
111 SvxConfigFunctionListBox_Impl::~SvxConfigFunctionListBox_Impl()
113 ClearAll();
116 SvLBoxEntry* SvxConfigFunctionListBox_Impl::GetLastSelectedEntry()
118 if ( m_pDraggingEntry != NULL )
120 return m_pDraggingEntry;
122 else
124 return FirstSelected();
128 void SvxConfigFunctionListBox_Impl::MouseMove( const MouseEvent& rMEvt )
130 Point aMousePos = rMEvt.GetPosPixel();
131 pCurEntry = GetCurEntry();
133 if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
134 aTimer.Start();
135 else
137 Help::ShowBalloon( this, aMousePos, String() );
138 aTimer.Stop();
143 IMPL_LINK( SvxConfigFunctionListBox_Impl, TimerHdl, Timer*, EMPTYARG)
145 aTimer.Stop();
146 Point aMousePos = GetPointerPosPixel();
147 SvLBoxEntry *pEntry = GetCurEntry();
148 if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
149 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) );
150 return 0L;
153 void SvxConfigFunctionListBox_Impl::ClearAll()
155 USHORT nCount = aArr.Count();
156 for ( USHORT i=0; i<nCount; i++ )
158 SvxGroupInfo_Impl *pData = aArr[i];
159 delete pData;
162 aArr.Remove( 0, nCount );
163 Clear();
166 SvLBoxEntry* SvxConfigFunctionListBox_Impl::GetEntry_Impl( const String& rName )
168 SvLBoxEntry *pEntry = First();
169 while ( pEntry )
171 if ( GetEntryText( pEntry ) == rName )
172 return pEntry;
173 pEntry = Next( pEntry );
176 return NULL;
179 SvLBoxEntry* SvxConfigFunctionListBox_Impl::GetEntry_Impl( USHORT nId )
181 SvLBoxEntry *pEntry = First();
182 while ( pEntry )
184 SvxGroupInfo_Impl *pData = (SvxGroupInfo_Impl*) pEntry->GetUserData();
185 if ( pData && pData->nOrd == nId )
186 return pEntry;
187 pEntry = Next( pEntry );
190 return NULL;
193 USHORT SvxConfigFunctionListBox_Impl::GetId( SvLBoxEntry *pEntry )
195 SvxGroupInfo_Impl *pData = pEntry ?
196 (SvxGroupInfo_Impl*) pEntry->GetUserData() : 0;
197 if ( pData )
198 return pData->nOrd;
199 return 0;
202 String SvxConfigFunctionListBox_Impl::GetHelpText( SvLBoxEntry *pEntry )
204 // Information zum selektierten Entry aus den Userdaten holen
205 SvxGroupInfo_Impl *pInfo =
206 pEntry ? (SvxGroupInfo_Impl*) pEntry->GetUserData(): 0;
208 if ( pInfo )
210 if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT )
212 OUString aCmdURL( pInfo->sURL );
214 OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this );
216 return aHelpText;
218 else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT )
220 return pInfo->sHelpText;
224 return String();
227 void SvxConfigFunctionListBox_Impl::FunctionSelected()
229 Help::ShowBalloon( this, Point(), String() );
232 // drag and drop support
233 DragDropMode SvxConfigFunctionListBox_Impl::NotifyStartDrag(
234 TransferDataContainer& /*aTransferDataContainer*/, SvLBoxEntry* pEntry )
236 m_pDraggingEntry = pEntry;
237 return GetDragDropMode();
240 void SvxConfigFunctionListBox_Impl::DragFinished( sal_Int8 /*nDropAction*/ )
242 m_pDraggingEntry = NULL;
245 sal_Int8
246 SvxConfigFunctionListBox_Impl::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
248 return DND_ACTION_NONE;
251 SvxConfigGroupListBox_Impl::SvxConfigGroupListBox_Impl(
252 Window* pParent, const ResId& rResId,
253 bool _bShowSlots, const Reference< frame::XFrame >& xFrame )
254 : SvTreeListBox( pParent, rResId )
255 , m_bShowSlots( _bShowSlots ),
256 m_hdImage(ResId(IMG_HARDDISK,*rResId.GetResMgr())),
257 m_hdImage_hc(ResId(IMG_HARDDISK_HC,*rResId.GetResMgr())),
258 m_libImage(ResId(IMG_LIB,*rResId.GetResMgr())),
259 m_libImage_hc(ResId(IMG_LIB_HC,*rResId.GetResMgr())),
260 m_macImage(ResId(IMG_MACRO,*rResId.GetResMgr())),
261 m_macImage_hc(ResId(IMG_MACRO_HC,*rResId.GetResMgr())),
262 m_docImage(ResId(IMG_DOC,*rResId.GetResMgr())),
263 m_docImage_hc(ResId(IMG_DOC_HC,*rResId.GetResMgr())),
264 m_sMyMacros(String(ResId(STR_MYMACROS,*rResId.GetResMgr()))),
265 m_sProdMacros(String(ResId(STR_PRODMACROS,*rResId.GetResMgr())))
267 FreeResource();
269 if ( xFrame != NULL )
271 m_xFrame.set( xFrame );
274 SetWindowBits( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT );
276 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
278 SetNodeBitmaps(
279 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
280 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
281 BMP_COLOR_NORMAL );
283 SetNodeBitmaps(
284 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
285 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
286 BMP_COLOR_HIGHCONTRAST );
290 SvxConfigGroupListBox_Impl::~SvxConfigGroupListBox_Impl()
292 ClearAll();
295 void SvxConfigGroupListBox_Impl::ClearAll()
297 USHORT nCount = aArr.Count();
298 for ( USHORT i=0; i<nCount; i++ )
300 SvxGroupInfo_Impl *pData = aArr[i];
301 delete pData;
304 aArr.Remove( 0, nCount );
305 Clear();
308 //-----------------------------------------------
309 namespace
311 //...........................................
312 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
313 component by implementing XScriptInvocationContext.
314 @return
315 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
316 model
318 static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
320 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
321 if ( !xScripts.is() )
323 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
324 if ( xContext.is() )
325 xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
328 return Reference< XModel >( xScripts, UNO_QUERY );
331 //...........................................
332 static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
334 Reference< XModel > xDocument;
336 // examine our associated frame
339 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
340 if ( _rxFrame.is() )
342 // first try the model in the frame
343 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
344 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
346 if ( !xDocument.is() )
348 // if there is no suitable document in the frame, try the controller
349 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
353 catch( const Exception& )
355 DBG_UNHANDLED_EXCEPTION();
358 return xDocument;
362 void SvxConfigGroupListBox_Impl::fillScriptList( const Reference< browse::XBrowseNode >& _rxRootNode, SvLBoxEntry* _pParentEntry, bool _bCheapChildsOnDemand )
364 OSL_PRECOND( _rxRootNode.is(), "SvxConfigGroupListBox_Impl::fillScriptList: invalid root node!" );
365 if ( !_rxRootNode.is() )
366 return;
370 if ( _rxRootNode->hasChildNodes() )
372 Sequence< Reference< browse::XBrowseNode > > children =
373 _rxRootNode->getChildNodes();
375 BOOL bIsRootNode = _rxRootNode->getName().equalsAscii("Root");
377 /* To mimic current starbasic behaviour we
378 need to make sure that only the current document
379 is displayed in the config tree. Tests below
380 set the bDisplay flag to FALSE if the current
381 node is a first level child of the Root and is NOT
382 either the current document, user or share */
383 OUString sCurrentDocTitle;
384 Reference< XModel > xWorkingDocument = lcl_getScriptableDocument_nothrow( m_xFrame );
385 if ( xWorkingDocument.is() )
387 sCurrentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument );
390 for ( long n = 0; n < children.getLength(); n++ )
392 Reference< browse::XBrowseNode >& theChild = children[n];
393 //#139111# some crash reports show that it might be unset
394 if ( !theChild.is() )
395 continue;
396 ::rtl::OUString sUIName = theChild->getName();
397 BOOL bDisplay = TRUE;
399 if ( bIsRootNode
400 || ( m_bShowSlots && _pParentEntry && ( GetModel()->GetDepth( _pParentEntry ) == 0 ) )
401 // if we show slots (as in the customize dialog)
402 // then the user & share are added at depth=1
405 if ( sUIName.equalsAscii( "user" ) )
407 sUIName = m_sMyMacros;
408 bIsRootNode = sal_True;
410 else if ( sUIName.equalsAscii( "share" ) )
412 sUIName = m_sProdMacros;
413 bIsRootNode = sal_True;
415 else if ( !sUIName.equals( sCurrentDocTitle ) )
417 bDisplay = FALSE;
421 if ( !bDisplay )
422 continue;
424 if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT )
425 continue;
427 SvLBoxEntry* pNewEntry = InsertEntry( sUIName, _pParentEntry );
429 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
430 Image aImage = GetImage( theChild, aContext.getUNOContext(), bIsRootNode, BMP_COLOR_NORMAL );
431 SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL );
432 SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL );
434 aImage = GetImage( theChild, aContext.getUNOContext(), bIsRootNode, BMP_COLOR_HIGHCONTRAST );
435 SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST );
436 SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST );
438 SvxGroupInfo_Impl* pInfo =
439 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, theChild );
440 pNewEntry->SetUserData( pInfo );
441 aArr.Insert( pInfo, aArr.Count() );
443 if ( _bCheapChildsOnDemand )
445 /* i30923 - Would be nice if there was a better
446 * way to determine if a basic lib had children
447 * without having to ask for them (which forces
448 * the library to be loaded */
449 pNewEntry->EnableChildsOnDemand( TRUE );
451 else
453 // if there are granchildren we're interested in, display the '+' before
454 // the entry, but do not yet expand
455 Sequence< Reference< browse::XBrowseNode > > grandchildren =
456 children[n]->getChildNodes();
458 for ( sal_Int32 m = 0; m < grandchildren.getLength(); m++ )
460 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
462 pNewEntry->EnableChildsOnDemand( TRUE );
463 break;
470 catch (const Exception&)
472 DBG_UNHANDLED_EXCEPTION();
476 void SvxConfigGroupListBox_Impl::Init()
478 SetUpdateMode(FALSE);
479 ClearAll();
481 Reference< XComponentContext > xContext;
482 Reference < beans::XPropertySet > xProps(
483 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
485 xContext.set( xProps->getPropertyValue(
486 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))),
487 UNO_QUERY );
489 // are we showing builtin commands?
490 if ( m_bShowSlots && xContext.is() && m_xFrame.is() )
492 Reference< lang::XMultiComponentFactory > xMCF =
493 xContext->getServiceManager();
495 Reference< frame::XDispatchInformationProvider > xDIP(
496 m_xFrame, UNO_QUERY );
498 Reference< ::com::sun::star::frame::XModuleManager >
499 xModuleManager( xMCF->createInstanceWithContext(
500 OUString::createFromAscii(
501 "com.sun.star.frame.ModuleManager" ),
502 xContext ),
503 UNO_QUERY );
505 OUString aModuleId;
506 try{
507 aModuleId = xModuleManager->identify( m_xFrame );
508 }catch(const uno::Exception&)
509 { aModuleId = ::rtl::OUString(); }
511 Reference< container::XNameAccess > xNameAccess(
512 xMCF->createInstanceWithContext(
513 OUString::createFromAscii(
514 "com.sun.star.frame.UICommandDescription" ),
515 xContext ),
516 UNO_QUERY );
518 if ( xNameAccess.is() )
520 xNameAccess->getByName( aModuleId ) >>= m_xModuleCommands;
523 Reference< container::XNameAccess > xAllCategories(
524 xMCF->createInstanceWithContext(
525 OUString::createFromAscii(
526 "com.sun.star.ui.UICategoryDescription" ),
527 xContext ),
528 UNO_QUERY );
530 Reference< container::XNameAccess > xModuleCategories;
531 if ( xAllCategories.is() )
533 if ( aModuleId.getLength() != 0 )
537 xModuleCategories = Reference< container::XNameAccess >(
538 xAllCategories->getByName( aModuleId ), UNO_QUERY );
540 catch ( container::NoSuchElementException& )
545 if ( !xModuleCategories.is() )
547 xModuleCategories = xAllCategories;
551 if ( xModuleCategories.is() )
553 Sequence< sal_Int16 > gids =
554 xDIP->getSupportedCommandGroups();
556 for ( sal_Int32 i = 0; i < gids.getLength(); i++ )
558 Sequence< frame::DispatchInformation > commands;
561 commands =
562 xDIP->getConfigurableDispatchInformation( gids[i] );
564 catch ( container::NoSuchElementException& )
566 continue;
569 if ( commands.getLength() == 0 )
571 continue;
574 sal_Int32 gid = gids[i];
575 OUString idx = OUString::valueOf( gid );
576 OUString group = idx;
579 xModuleCategories->getByName( idx ) >>= group;
581 catch ( container::NoSuchElementException& )
585 SvLBoxEntry *pEntry = InsertEntry( group, NULL );
587 SvxGroupInfo_Impl *pInfo =
588 new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION, gids[i] );
589 aArr.Insert( pInfo, aArr.Count() );
591 pEntry->SetUserData( pInfo );
596 if ( xContext.is() )
598 // Add Scripting Framework entries
599 Reference< browse::XBrowseNode > rootNode;
600 Reference< XComponentContext> xCtx;
604 Reference < beans::XPropertySet > _xProps(
605 ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
606 xCtx.set( _xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
607 Reference< browse::XBrowseNodeFactory > xFac( xCtx->getValueByName(
608 OUString::createFromAscii( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory") ), UNO_QUERY_THROW );
609 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
611 catch( const Exception& )
613 DBG_UNHANDLED_EXCEPTION();
616 if ( rootNode.is() )
618 if ( m_bShowSlots )
620 SvxGroupInfo_Impl *pInfo =
621 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, rootNode );
623 String aTitle =
624 String( SVX_RES( STR_SELECTOR_MACROS ) );
626 SvLBoxEntry *pNewEntry = InsertEntry( aTitle, NULL );
627 pNewEntry->SetUserData( pInfo );
628 pNewEntry->EnableChildsOnDemand( TRUE );
629 aArr.Insert( pInfo, aArr.Count() );
631 else
633 fillScriptList( rootNode, NULL, false );
637 MakeVisible( GetEntry( 0,0 ) );
638 SetUpdateMode( TRUE );
641 Image SvxConfigGroupListBox_Impl::GetImage( Reference< browse::XBrowseNode > node, Reference< XComponentContext > xCtx, bool bIsRootNode, bool bHighContrast )
643 Image aImage;
644 if ( bIsRootNode )
646 if ( node->getName().equalsAscii( "user" ) || node->getName().equalsAscii( "share" ) )
648 if( bHighContrast == BMP_COLOR_NORMAL )
649 aImage = m_hdImage;
650 else
651 aImage = m_hdImage_hc;
653 else
655 OUString factoryURL;
656 OUString nodeName = node->getName();
657 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
658 if ( xDocumentModel.is() )
660 Reference< ::com::sun::star::frame::XModuleManager >
661 xModuleManager(
662 xCtx->getServiceManager()
663 ->createInstanceWithContext(
664 OUString::createFromAscii("com.sun.star.frame.ModuleManager"),
665 xCtx ),
666 UNO_QUERY_THROW );
667 Reference<container::XNameAccess> xModuleConfig(
668 xModuleManager, UNO_QUERY_THROW );
669 // get the long name of the document:
670 OUString appModule( xModuleManager->identify(
671 xDocumentModel ) );
672 Sequence<beans::PropertyValue> moduleDescr;
673 Any aAny = xModuleConfig->getByName(appModule);
674 if( sal_True != ( aAny >>= moduleDescr ) )
676 throw RuntimeException(OUString::createFromAscii("SFTreeListBox::Init: failed to get PropertyValue"), Reference< XInterface >());
678 beans::PropertyValue const * pmoduleDescr =
679 moduleDescr.getConstArray();
680 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
682 if (pmoduleDescr[ pos ].Name.equalsAsciiL(
683 RTL_CONSTASCII_STRINGPARAM(
684 "ooSetupFactoryEmptyDocumentURL") ))
686 pmoduleDescr[ pos ].Value >>= factoryURL;
687 break;
691 if( factoryURL.getLength() > 0 )
693 if( bHighContrast == BMP_COLOR_NORMAL )
694 aImage = SvFileInformationManager::GetFileImage(
695 INetURLObject(factoryURL), false,
696 BMP_COLOR_NORMAL );
697 else
698 aImage = SvFileInformationManager::GetFileImage(
699 INetURLObject(factoryURL), false,
700 BMP_COLOR_HIGHCONTRAST );
702 else
704 if( bHighContrast == BMP_COLOR_NORMAL )
705 aImage = m_docImage;
706 else
707 aImage = m_docImage_hc;
711 else
713 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
715 if( bHighContrast == BMP_COLOR_NORMAL )
716 aImage = m_macImage;
717 else
718 aImage = m_macImage_hc;
720 else
722 if( bHighContrast == BMP_COLOR_NORMAL )
723 aImage = m_libImage;
724 else
725 aImage = m_libImage_hc;
728 return aImage;
731 Reference< XInterface >
732 SvxConfigGroupListBox_Impl::getDocumentModel(
733 Reference< XComponentContext >& xCtx, OUString& docName )
735 Reference< XInterface > xModel;
736 Reference< lang::XMultiComponentFactory > mcf =
737 xCtx->getServiceManager();
738 Reference< frame::XDesktop > desktop (
739 mcf->createInstanceWithContext(
740 OUString::createFromAscii("com.sun.star.frame.Desktop"), xCtx ),
741 UNO_QUERY );
743 Reference< container::XEnumerationAccess > componentsAccess =
744 desktop->getComponents();
745 Reference< container::XEnumeration > components =
746 componentsAccess->createEnumeration();
747 while (components->hasMoreElements())
749 Reference< frame::XModel > model(
750 components->nextElement(), UNO_QUERY );
751 if ( model.is() )
753 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
754 if( sTdocUrl.equals( docName ) )
756 xModel = model;
757 break;
761 return xModel;
764 void SvxConfigGroupListBox_Impl::GroupSelected()
766 SvLBoxEntry *pEntry = FirstSelected();
767 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData();
768 pFunctionListBox->SetUpdateMode(FALSE);
769 pFunctionListBox->ClearAll();
770 if ( pInfo->nKind != SVX_CFGGROUP_FUNCTION &&
771 pInfo->nKind != SVX_CFGGROUP_SCRIPTCONTAINER )
773 pFunctionListBox->SetUpdateMode(TRUE);
774 return;
777 switch ( pInfo->nKind )
779 case SVX_CFGGROUP_FUNCTION :
781 SvLBoxEntry *_pEntry = FirstSelected();
782 if ( _pEntry != NULL )
784 SvxGroupInfo_Impl *_pInfo =
785 (SvxGroupInfo_Impl*) _pEntry->GetUserData();
787 Reference< frame::XDispatchInformationProvider > xDIP(
788 m_xFrame, UNO_QUERY );
790 Sequence< frame::DispatchInformation > commands;
793 commands = xDIP->getConfigurableDispatchInformation(
794 _pInfo->nOrd );
796 catch ( container::NoSuchElementException& )
800 for ( sal_Int32 i = 0; i < commands.getLength(); i++ )
802 if ( commands[i].Command.getLength() == 0 )
804 continue;
807 Image aImage;
809 OUString aCmdURL( commands[i].Command );
811 if ( m_pImageProvider )
813 aImage = m_pImageProvider->GetImage( aCmdURL );
816 OUString aLabel;
819 Any a = m_xModuleCommands->getByName( aCmdURL );
820 Sequence< beans::PropertyValue > aPropSeq;
822 if ( a >>= aPropSeq )
824 for ( sal_Int32 k = 0; k < aPropSeq.getLength(); k++ )
826 if ( aPropSeq[k].Name.equalsAscii( "Name" ) )
828 aPropSeq[k].Value >>= aLabel;
829 break;
834 catch ( container::NoSuchElementException& )
838 if ( aLabel.getLength() == 0 )
840 aLabel = commands[i].Command;
843 SvLBoxEntry* pFuncEntry = NULL;
844 if ( !!aImage )
846 pFuncEntry = pFunctionListBox->InsertEntry(
847 aLabel, aImage, aImage );
849 else
851 pFuncEntry = pFunctionListBox->InsertEntry(
852 aLabel, NULL );
855 SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl(
856 SVX_CFGFUNCTION_SLOT, 123, aCmdURL, ::rtl::OUString() );
858 pFunctionListBox->aArr.Insert(
859 _pGroupInfo, pFunctionListBox->aArr.Count() );
861 pFuncEntry->SetUserData( _pGroupInfo );
864 break;
867 case SVX_CFGGROUP_SCRIPTCONTAINER:
869 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode );
871 try {
872 if ( rootNode->hasChildNodes() )
874 Sequence< Reference< browse::XBrowseNode > > children =
875 rootNode->getChildNodes();
877 for ( long n = 0; n < children.getLength(); n++ )
879 if (!children[n].is())
880 continue;
881 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
883 OUString uri;
884 OUString description;
886 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
887 if (!xPropSet.is())
889 continue;
892 Any value =
893 xPropSet->getPropertyValue( String::CreateFromAscii( "URI" ) );
894 value >>= uri;
898 value = xPropSet->getPropertyValue(
899 String::CreateFromAscii( "Description" ) );
900 value >>= description;
902 catch (Exception &) {
903 // do nothing, the description will be empty
906 SvxGroupInfo_Impl* _pGroupInfo =
907 new SvxGroupInfo_Impl(
908 SVX_CFGFUNCTION_SCRIPT, 123, uri, description );
910 Image aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_NORMAL );
911 SvLBoxEntry* pNewEntry =
912 pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
913 pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
914 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
915 aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_HIGHCONTRAST );
916 pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
917 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
919 pNewEntry->SetUserData( _pGroupInfo );
921 pFunctionListBox->aArr.Insert(
922 _pGroupInfo, pFunctionListBox->aArr.Count() );
928 catch (const Exception&)
930 DBG_UNHANDLED_EXCEPTION();
932 break;
935 default:
937 return;
941 if ( pFunctionListBox->GetEntryCount() )
942 pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
944 pFunctionListBox->SetUpdateMode(TRUE);
947 BOOL SvxConfigGroupListBox_Impl::Expand( SvLBoxEntry* pParent )
949 BOOL bRet = SvTreeListBox::Expand( pParent );
950 if ( bRet )
952 // Wieviele Entries k"onnen angezeigt werden ?
953 ULONG nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
955 // Wieviele Kinder sollen angezeigt werden ?
956 ULONG nChildCount = GetVisibleChildCount( pParent );
958 // Passen alle Kinder und der parent gleichzeitig in die View ?
959 if ( nChildCount+1 > nEntries )
961 // Wenn nicht, wenigstens parent ganz nach oben schieben
962 MakeVisible( pParent, TRUE );
964 else
966 // An welcher relativen ViewPosition steht der aufzuklappende parent
967 SvLBoxEntry *pEntry = GetFirstEntryInView();
968 ULONG nParentPos = 0;
969 while ( pEntry && pEntry != pParent )
971 nParentPos++;
972 pEntry = GetNextEntryInView( pEntry );
975 // Ist unter dem parent noch genug Platz f"ur alle Kinder ?
976 if ( nParentPos + nChildCount + 1 > nEntries )
977 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
981 return bRet;
984 void SvxConfigGroupListBox_Impl::RequestingChilds( SvLBoxEntry *pEntry )
986 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData();
987 pInfo->bWasOpened = TRUE;
988 switch ( pInfo->nKind )
990 case SVX_CFGGROUP_SCRIPTCONTAINER:
992 if ( !GetChildCount( pEntry ) )
994 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ) ;
995 fillScriptList( rootNode, pEntry, true /* i30923 */ );
997 break;
1000 default:
1001 DBG_ERROR( "Falscher Gruppentyp!" );
1002 break;
1007 * Implementation of SvxScriptSelectorDialog
1009 * This dialog is used for selecting Slot API commands
1010 * and Scripting Framework Scripts.
1013 SvxScriptSelectorDialog::SvxScriptSelectorDialog(
1014 Window* pParent, BOOL bShowSlots, const Reference< frame::XFrame >& xFrame )
1016 ModelessDialog( pParent, SVX_RES( RID_DLG_SCRIPTSELECTOR ) ),
1017 aDialogDescription( this, SVX_RES( TXT_SELECTOR_DIALOG_DESCRIPTION ) ),
1018 aGroupText( this, SVX_RES( TXT_SELECTOR_CATEGORIES ) ),
1019 aCategories( this, SVX_RES( BOX_SELECTOR_CATEGORIES ), bShowSlots, xFrame ),
1020 aFunctionText( this, SVX_RES( TXT_SELECTOR_COMMANDS ) ),
1021 aCommands( this, SVX_RES( BOX_SELECTOR_COMMANDS ) ),
1022 aOKButton( this, SVX_RES( BTN_SELECTOR_OK ) ),
1023 aCancelButton( this, SVX_RES( BTN_SELECTOR_CANCEL ) ),
1024 aHelpButton( this, SVX_RES( BTN_SELECTOR_HELP ) ),
1025 aDescription( this, SVX_RES( GRP_SELECTOR_DESCRIPTION ) ),
1026 aDescriptionText( this, SVX_RES( TXT_SELECTOR_DESCRIPTION ) ),
1027 m_bShowSlots( bShowSlots )
1030 ResMgr& rMgr = DIALOG_MGR();
1032 // If we are showing Slot API commands update labels in the UI, and
1033 // enable drag'n'drop
1034 if ( m_bShowSlots )
1036 aGroupText.SetText( String( ResId( STR_SELECTOR_CATEGORIES, rMgr ) ) );
1037 aOKButton.SetText( String( ResId( STR_SELECTOR_ADD, rMgr ) ) );
1038 aCancelButton.SetText( String( ResId( STR_SELECTOR_CLOSE, rMgr ) ) );
1039 aFunctionText.SetText( String( ResId( STR_SELECTOR_COMMANDS, rMgr ) ) );
1040 SetDialogDescription(
1041 String( ResId( STR_SELECTOR_ADD_COMMANDS_DESCRIPTION, rMgr ) ) );
1042 SetText( String( ResId( STR_SELECTOR_ADD_COMMANDS, rMgr ) ) );
1044 aCommands.SetDragDropMode( SV_DRAGDROP_APP_COPY );
1047 ResizeControls();
1049 aCategories.SetFunctionListBox( &aCommands );
1050 aCategories.Init();
1051 // aCategories.Select( aCategories.GetEntry( 0, 0 ) );
1053 aCategories.SetSelectHdl(
1054 LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1055 aCommands.SetSelectHdl( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
1056 aCommands.SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
1058 aOKButton.SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1059 aCancelButton.SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
1061 UpdateUI();
1062 FreeResource();
1065 void SvxScriptSelectorDialog::ResizeControls()
1067 Point p, newp;
1068 Size s, news;
1069 long gap;
1071 USHORT style = TEXT_DRAW_MULTILINE | TEXT_DRAW_TOP |
1072 TEXT_DRAW_LEFT | TEXT_DRAW_WORDBREAK;
1074 // get dimensions of dialog instructions control
1075 p = aDialogDescription.GetPosPixel();
1076 s = aDialogDescription.GetSizePixel();
1078 // get dimensions occupied by text in the control
1079 Rectangle rect =
1080 GetTextRect( Rectangle( p, s ), aDialogDescription.GetText(), style );
1081 news = rect.GetSize();
1083 // the gap is the difference between the control height and its text height
1084 gap = s.Height() - news.Height();
1086 // resize the dialog instructions control
1087 news = Size( s.Width(), s.Height() - gap );
1088 aDialogDescription.SetSizePixel( news );
1090 // resize other controls to fill the gap
1091 p = aGroupText.GetPosPixel();
1092 newp = Point( p.X(), p.Y() - gap );
1093 aGroupText.SetPosPixel( newp );
1095 p = aCategories.GetPosPixel();
1096 newp = Point( p.X(), p.Y() - gap );
1097 aCategories.SetPosPixel( newp );
1098 s = aCategories.GetSizePixel();
1099 news = Size( s.Width(), s.Height() + gap );
1100 aCategories.SetSizePixel( news );
1102 p = aFunctionText.GetPosPixel();
1103 newp = Point( p.X(), p.Y() - gap );
1104 aFunctionText.SetPosPixel( newp );
1106 p = aCommands.GetPosPixel();
1107 newp = Point( p.X(), p.Y() - gap );
1108 aCommands.SetPosPixel( newp );
1109 s = aCommands.GetSizePixel();
1110 news = Size( s.Width(), s.Height() + gap );
1111 aCommands.SetSizePixel( news );
1113 p = aOKButton.GetPosPixel();
1114 newp = Point( p.X(), p.Y() - gap );
1115 aOKButton.SetPosPixel( newp );
1117 p = aCancelButton.GetPosPixel();
1118 newp = Point( p.X(), p.Y() - gap );
1119 aCancelButton.SetPosPixel( newp );
1121 p = aHelpButton.GetPosPixel();
1122 newp = Point( p.X(), p.Y() - gap );
1123 aHelpButton.SetPosPixel( newp );
1126 SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
1130 IMPL_LINK( SvxScriptSelectorDialog, SelectHdl, Control*, pCtrl )
1132 if ( pCtrl == &aCategories )
1134 aCategories.GroupSelected();
1136 else if ( pCtrl == &aCommands )
1138 aCommands.FunctionSelected();
1140 UpdateUI();
1141 return 0;
1144 IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl )
1146 (void)pCtrl;
1147 if ( aOKButton.IsEnabled() )
1148 return ClickHdl( &aOKButton );
1149 return 0;
1152 // Check if command is selected and enable the OK button accordingly
1153 // Grab the help text for this id if available and update the description field
1154 void
1155 SvxScriptSelectorDialog::UpdateUI()
1157 OUString url = GetScriptURL();
1158 if ( url != NULL && url.getLength() != 0 )
1160 String rMessage =
1161 aCommands.GetHelpText( aCommands.FirstSelected() );
1162 aDescriptionText.SetText( rMessage );
1164 aOKButton.Enable( TRUE );
1166 else
1168 aDescriptionText.SetText( String() );
1169 aOKButton.Enable( FALSE );
1173 IMPL_LINK( SvxScriptSelectorDialog, ClickHdl, Button *, pButton )
1175 if ( pButton == &aCancelButton )
1177 // If we are displaying Slot API commands then the dialog is being
1178 // run from Tools/Configure and we should not close it, just hide it
1179 if ( m_bShowSlots == FALSE )
1181 EndDialog( RET_CANCEL );
1183 else
1185 Hide();
1188 else if ( pButton == &aOKButton )
1190 GetAddHdl().Call( this );
1192 // If we are displaying Slot API commands then this the dialog is being
1193 // run from Tools/Configure and we should not close it
1194 if ( m_bShowSlots == FALSE )
1196 EndDialog( RET_OK );
1198 else
1200 // Select the next entry in the list if possible
1201 SvLBoxEntry* current = aCommands.FirstSelected();
1202 SvLBoxEntry* next = aCommands.NextSibling( current );
1204 if ( next != NULL )
1206 aCommands.Select( next );
1211 return 0;
1214 void
1215 SvxScriptSelectorDialog::SetRunLabel()
1217 aOKButton.SetText( String( SVX_RES( STR_SELECTOR_RUN ) ) );
1220 void
1221 SvxScriptSelectorDialog::SetDialogDescription( const String& rDescription )
1223 aDialogDescription.SetText( rDescription );
1226 USHORT
1227 SvxScriptSelectorDialog::GetSelectedId()
1229 return aCommands.GetId( aCommands.GetLastSelectedEntry() );
1232 String
1233 SvxScriptSelectorDialog::GetScriptURL() const
1235 OUString result;
1237 SvLBoxEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->aCommands.GetLastSelectedEntry();
1238 if ( pEntry )
1240 SvxGroupInfo_Impl *pData = (SvxGroupInfo_Impl*) pEntry->GetUserData();
1241 if ( ( pData->nKind == SVX_CFGFUNCTION_SLOT )
1242 || ( pData->nKind == SVX_CFGFUNCTION_SCRIPT )
1245 result = pData->sURL;
1249 return result;
1252 String
1253 SvxScriptSelectorDialog::GetSelectedDisplayName()
1255 return aCommands.GetEntryText( aCommands.GetLastSelectedEntry() );
1258 String
1259 SvxScriptSelectorDialog::GetSelectedHelpText()
1261 return aCommands.GetHelpText( aCommands.GetLastSelectedEntry() );