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