xref: /aoo41x/main/cui/source/customize/selector.cxx (revision cdf0e10c)
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