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