xref: /trunk/main/cui/source/customize/selector.cxx (revision 2ee96f1c)
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  */
SvxConfigFunctionListBox_Impl(Window * pParent,const ResId & rResId)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 
~SvxConfigFunctionListBox_Impl()97 SvxConfigFunctionListBox_Impl::~SvxConfigFunctionListBox_Impl()
98 {
99 	ClearAll();
100 }
101 
GetLastSelectedEntry()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 
MouseMove(const MouseEvent & rMEvt)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 
IMPL_LINK(SvxConfigFunctionListBox_Impl,TimerHdl,Timer *,EMPTYARG)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 
ClearAll()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 
GetHelpText(SvLBoxEntry * pEntry)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 
FunctionSelected()177 void SvxConfigFunctionListBox_Impl::FunctionSelected()
178 {
179 	Help::ShowBalloon( this, Point(), String() );
180 }
181 
182 // drag and drop support
NotifyStartDrag(TransferDataContainer &,SvLBoxEntry * pEntry)183 DragDropMode SvxConfigFunctionListBox_Impl::NotifyStartDrag(
184     TransferDataContainer& /*aTransferDataContainer*/, SvLBoxEntry* pEntry )
185 {
186 	m_pDraggingEntry = pEntry;
187 	return GetDragDropMode();
188 }
189 
DragFinished(sal_Int8)190 void SvxConfigFunctionListBox_Impl::DragFinished( sal_Int8 /*nDropAction*/ )
191 {
192 	m_pDraggingEntry = NULL;
193 }
194 
195 sal_Int8
AcceptDrop(const AcceptDropEvent &)196 SvxConfigFunctionListBox_Impl::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
197 {
198 	return DND_ACTION_NONE;
199 }
200 
SvxConfigGroupListBox_Impl(Window * pParent,const ResId & rResId,bool _bShowSlots,const Reference<frame::XFrame> & xFrame)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 
~SvxConfigGroupListBox_Impl()240 SvxConfigGroupListBox_Impl::~SvxConfigGroupListBox_Impl()
241 {
242 	ClearAll();
243 }
244 
ClearAll()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     */
lcl_getDocumentWithScripts_throw(const Reference<XInterface> & _rxComponent)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     //...........................................
lcl_getScriptableDocument_nothrow(const Reference<XFrame> & _rxFrame)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 
fillScriptList(const Reference<browse::XBrowseNode> & _rxRootNode,SvLBoxEntry * _pParentEntry,bool _bCheapChildsOnDemand)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 
Init()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 
GetImage(Reference<browse::XBrowseNode> node,Reference<XComponentContext> xCtx,bool bIsRootNode,bool bHighContrast)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  >
getDocumentModel(Reference<XComponentContext> & xCtx,OUString & docName)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 
GroupSelected()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 
Expand(SvLBoxEntry * pParent)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 
RequestingChilds(SvLBoxEntry * pEntry)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 
SvxScriptSelectorDialog(Window * pParent,sal_Bool bShowSlots,const Reference<frame::XFrame> & xFrame)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 
ResizeControls()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 
~SvxScriptSelectorDialog()1076 SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
1077 {
1078 }
1079 
IMPL_LINK(SvxScriptSelectorDialog,SelectHdl,Control *,pCtrl)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 
IMPL_LINK(SvxScriptSelectorDialog,FunctionDoubleClickHdl,Control *,pCtrl)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
UpdateUI()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 
IMPL_LINK(SvxScriptSelectorDialog,ClickHdl,Button *,pButton)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
SetRunLabel()1165 SvxScriptSelectorDialog::SetRunLabel()
1166 {
1167 	aOKButton.SetText( String( CUI_RES( STR_SELECTOR_RUN ) ) );
1168 }
1169 
1170 void
SetDialogDescription(const String & rDescription)1171 SvxScriptSelectorDialog::SetDialogDescription( const String& rDescription )
1172 {
1173 	aDialogDescription.SetText( rDescription );
1174 }
1175 
1176 String
GetScriptURL() const1177 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
GetSelectedDisplayName()1197 SvxScriptSelectorDialog::GetSelectedDisplayName()
1198 {
1199 	return aCommands.GetEntryText( aCommands.GetLastSelectedEntry() );
1200 }
1201 
1202 String
GetSelectedHelpText()1203 SvxScriptSelectorDialog::GetSelectedHelpText()
1204 {
1205 	return aCommands.GetHelpText( aCommands.GetLastSelectedEntry() );
1206 }
1207