1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/help.hxx>
21 #include <vcl/msgbox.hxx>
22 #include <vcl/metric.hxx>
23 #include <vcl/vclmedit.hxx>
24 #include "selector.hxx"
25 #include <dialmgr.hxx>
26 #include <svx/fmresids.hrc> // for RID_SVXIMG_...
27 #include <svx/dialmgr.hxx> // for RID_SVXIMG_...
29 #include <sfx2/app.hxx>
30 #include <sfx2/msg.hxx>
31 #include <sfx2/msgpool.hxx>
32 #include <sfx2/minfitem.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <sfx2/dispatch.hxx>
36 #include <comphelper/documentinfo.hxx>
37 #include <comphelper/processfactory.hxx>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/container/XChild.hpp>
41 #include <com/sun/star/container/XEnumerationAccess.hpp>
42 #include <com/sun/star/container/XEnumeration.hpp>
43 #include <com/sun/star/document/XEmbeddedScripts.hpp>
44 #include <com/sun/star/document/XScriptInvocationContext.hpp>
45 #include <com/sun/star/frame/ModuleManager.hpp>
46 #include <com/sun/star/frame/Desktop.hpp>
47 #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
48 #include <com/sun/star/frame/DispatchInformation.hpp>
49 #include <com/sun/star/frame/UICommandDescription.hpp>
50 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
51 #include <com/sun/star/script/provider/XScriptProvider.hpp>
52 #include <com/sun/star/script/browse/theBrowseNodeFactory.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/ui/UICategoryDescription.hpp>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::script
;
63 using namespace ::com::sun::star::frame
;
64 using namespace ::com::sun::star::document
;
65 using namespace ::com::sun::star::container
;
67 #include <svtools/imagemgr.hxx>
68 #include "svtools/treelistentry.hxx"
69 #include <tools/urlobj.hxx>
70 #include <tools/diagnose_ex.h>
73 * The implementations of SvxConfigFunctionListBox and
74 * SvxConfigGroupListBox are copied from sfx2/source/dialog/cfg.cxx
76 SvxConfigFunctionListBox::SvxConfigFunctionListBox(Window
* pParent
)
77 : SvTreeListBox(pParent
, WB_CLIPCHILDREN
| WB_HSCROLL
| WB_SORT
| WB_TABSTOP
)
81 GetModel()->SetSortMode( SortAscending
);
83 // Timer for the BallonHelp
84 aTimer
.SetTimeout( 200 );
86 LINK( this, SvxConfigFunctionListBox
, TimerHdl
) );
89 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxConfigFunctionListBox(Window
*pParent
, VclBuilder::stringmap
&)
91 return new SvxConfigFunctionListBox(pParent
);
94 SvxConfigFunctionListBox::~SvxConfigFunctionListBox()
99 SvTreeListEntry
* SvxConfigFunctionListBox::GetLastSelectedEntry()
101 if ( m_pDraggingEntry
!= NULL
)
103 return m_pDraggingEntry
;
107 return FirstSelected();
111 void SvxConfigFunctionListBox::MouseMove( const MouseEvent
& rMEvt
)
113 Point aMousePos
= rMEvt
.GetPosPixel();
114 pCurEntry
= GetCurEntry();
116 if ( pCurEntry
&& GetEntry( aMousePos
) == pCurEntry
)
120 Help::ShowBalloon( this, aMousePos
, String() );
126 IMPL_LINK_NOARG(SvxConfigFunctionListBox
, TimerHdl
)
129 Point aMousePos
= GetPointerPosPixel();
130 SvTreeListEntry
*pEntry
= GetCurEntry();
131 if ( pEntry
&& GetEntry( aMousePos
) == pEntry
&& pCurEntry
== pEntry
)
132 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos
), GetHelpText( pEntry
) );
136 void SvxConfigFunctionListBox::ClearAll()
142 String
SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry
*pEntry
)
144 SvxGroupInfo_Impl
*pInfo
=
145 pEntry
? (SvxGroupInfo_Impl
*) pEntry
->GetUserData(): 0;
149 if ( pInfo
->nKind
== SVX_CFGFUNCTION_SLOT
)
151 OUString
aCmdURL( pInfo
->sURL
);
153 OUString aHelpText
= Application::GetHelp()->GetHelpText( aCmdURL
, this );
157 else if ( pInfo
->nKind
== SVX_CFGFUNCTION_SCRIPT
)
159 return pInfo
->sHelpText
;
166 void SvxConfigFunctionListBox::FunctionSelected()
168 Help::ShowBalloon( this, Point(), String() );
171 // drag and drop support
172 DragDropMode
SvxConfigFunctionListBox::NotifyStartDrag(
173 TransferDataContainer
& /*aTransferDataContainer*/, SvTreeListEntry
* pEntry
)
175 m_pDraggingEntry
= pEntry
;
176 return GetDragDropMode();
179 void SvxConfigFunctionListBox::DragFinished( sal_Int8
/*nDropAction*/ )
181 m_pDraggingEntry
= NULL
;
185 SvxConfigFunctionListBox::AcceptDrop( const AcceptDropEvent
& /*rEvt*/ )
187 return DND_ACTION_NONE
;
190 SvxConfigGroupListBox::SvxConfigGroupListBox(Window
* pParent
)
191 : SvTreeListBox(pParent
,
192 WB_CLIPCHILDREN
| WB_HSCROLL
| WB_HASBUTTONS
| WB_HASLINES
| WB_HASLINESATROOT
| WB_HASBUTTONSATROOT
| WB_TABSTOP
)
193 , m_bShowSlots(false)
194 , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK
))
195 , m_libImage(CUI_RES(RID_CUIIMG_LIB
))
196 , m_macImage(CUI_RES(RID_CUIIMG_MACRO
))
197 , m_docImage(CUI_RES(RID_CUIIMG_DOC
))
198 , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS
))
199 , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS
))
201 ImageList
aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL
) );
204 aNavigatorImages
.GetImage( RID_SVXIMG_COLLAPSEDNODE
),
205 aNavigatorImages
.GetImage( RID_SVXIMG_EXPANDEDNODE
)
209 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxConfigGroupListBox(Window
*pParent
, VclBuilder::stringmap
&)
211 return new SvxConfigGroupListBox(pParent
);
214 SvxConfigGroupListBox::~SvxConfigGroupListBox()
219 void SvxConfigGroupListBox::ClearAll()
225 //-----------------------------------------------
228 //...........................................
229 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
230 component by implementing XScriptInvocationContext.
232 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
235 static Reference
< XModel
> lcl_getDocumentWithScripts_throw( const Reference
< XInterface
>& _rxComponent
)
237 Reference
< XEmbeddedScripts
> xScripts( _rxComponent
, UNO_QUERY
);
238 if ( !xScripts
.is() )
240 Reference
< XScriptInvocationContext
> xContext( _rxComponent
, UNO_QUERY
);
242 xScripts
.set( xContext
->getScriptContainer(), UNO_QUERY
);
245 return Reference
< XModel
>( xScripts
, UNO_QUERY
);
248 //...........................................
249 static Reference
< XModel
> lcl_getScriptableDocument_nothrow( const Reference
< XFrame
>& _rxFrame
)
251 Reference
< XModel
> xDocument
;
253 // examine our associated frame
256 OSL_ENSURE( _rxFrame
.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
259 // first try the model in the frame
260 Reference
< XController
> xController( _rxFrame
->getController(), UNO_SET_THROW
);
261 xDocument
= lcl_getDocumentWithScripts_throw( xController
->getModel() );
263 if ( !xDocument
.is() )
265 // if there is no suitable document in the frame, try the controller
266 xDocument
= lcl_getDocumentWithScripts_throw( _rxFrame
->getController() );
270 catch( const Exception
& )
272 DBG_UNHANDLED_EXCEPTION();
279 void SvxConfigGroupListBox::fillScriptList( const Reference
< browse::XBrowseNode
>& _rxRootNode
, SvTreeListEntry
* _pParentEntry
, bool _bCheapChildrenOnDemand
)
281 OSL_PRECOND( _rxRootNode
.is(), "SvxConfigGroupListBox::fillScriptList: invalid root node!" );
282 if ( !_rxRootNode
.is() )
287 if ( _rxRootNode
->hasChildNodes() )
289 Sequence
< Reference
< browse::XBrowseNode
> > children
=
290 _rxRootNode
->getChildNodes();
292 sal_Bool bIsRootNode
= _rxRootNode
->getName() == "Root";
294 /* To mimic current starbasic behaviour we
295 need to make sure that only the current document
296 is displayed in the config tree. Tests below
297 set the bDisplay flag to sal_False if the current
298 node is a first level child of the Root and is NOT
299 either the current document, user or share */
300 OUString sCurrentDocTitle
;
301 Reference
< XModel
> xWorkingDocument
= lcl_getScriptableDocument_nothrow( m_xFrame
);
302 if ( xWorkingDocument
.is() )
304 sCurrentDocTitle
= ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument
);
307 for ( long n
= 0; n
< children
.getLength(); ++n
)
309 Reference
< browse::XBrowseNode
>& theChild
= children
[n
];
310 //#139111# some crash reports show that it might be unset
311 if ( !theChild
.is() )
313 OUString sUIName
= theChild
->getName();
314 sal_Bool bDisplay
= sal_True
;
317 || ( m_bShowSlots
&& _pParentEntry
&& ( GetModel()->GetDepth( _pParentEntry
) == 0 ) )
318 // if we show slots (as in the customize dialog)
319 // then the user & share are added at depth=1
322 if ( sUIName
== "user" )
324 sUIName
= m_sMyMacros
;
325 bIsRootNode
= sal_True
;
327 else if ( sUIName
== "share" )
329 sUIName
= m_sProdMacros
;
330 bIsRootNode
= sal_True
;
332 else if ( !sUIName
.equals( sCurrentDocTitle
) )
334 bDisplay
= sal_False
;
341 if ( children
[n
]->getType() == browse::BrowseNodeTypes::SCRIPT
)
344 SvTreeListEntry
* pNewEntry
= InsertEntry( sUIName
, _pParentEntry
);
346 Image aImage
= GetImage( theChild
, comphelper::getProcessComponentContext(), bIsRootNode
);
347 SetExpandedEntryBmp( pNewEntry
, aImage
);
348 SetCollapsedEntryBmp( pNewEntry
, aImage
);
350 SvxGroupInfo_Impl
* pInfo
=
351 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER
, 0, theChild
);
352 pNewEntry
->SetUserData( pInfo
);
353 aArr
.push_back( pInfo
);
355 if ( _bCheapChildrenOnDemand
)
357 /* i30923 - Would be nice if there was a better
358 * way to determine if a basic lib had children
359 * without having to ask for them (which forces
360 * the library to be loaded */
361 pNewEntry
->EnableChildrenOnDemand( sal_True
);
365 // if there are granchildren we're interested in, display the '+' before
366 // the entry, but do not yet expand
367 Sequence
< Reference
< browse::XBrowseNode
> > grandchildren
=
368 children
[n
]->getChildNodes();
370 for ( sal_Int32 m
= 0; m
< grandchildren
.getLength(); ++m
)
372 if ( grandchildren
[m
]->getType() == browse::BrowseNodeTypes::CONTAINER
)
374 pNewEntry
->EnableChildrenOnDemand( sal_True
);
382 catch (const Exception
&)
384 DBG_UNHANDLED_EXCEPTION();
388 void SvxConfigGroupListBox::Init(bool bShowSlots
, const Reference
< frame::XFrame
>& xFrame
)
390 m_bShowSlots
= bShowSlots
;
391 m_xFrame
.set(xFrame
);
393 SetUpdateMode(sal_False
);
396 Reference
< XComponentContext
> xContext(
397 comphelper::getProcessComponentContext() );
399 // are we showing builtin commands?
400 if ( m_bShowSlots
&& m_xFrame
.is() )
402 Reference
< frame::XDispatchInformationProvider
> xDIP(
403 m_xFrame
, UNO_QUERY
);
405 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xContext
) );
409 aModuleId
= xModuleManager
->identify( m_xFrame
);
410 }catch(const uno::Exception
&)
411 { aModuleId
= OUString(); }
413 Reference
< container::XNameAccess
> const xNameAccess(
414 frame::UICommandDescription::create(xContext
) );
415 xNameAccess
->getByName( aModuleId
) >>= m_xModuleCommands
;
417 Reference
< container::XNameAccess
> xAllCategories
=
418 ui::UICategoryDescription::create( xContext
);
420 Reference
< container::XNameAccess
> xModuleCategories
;
421 if ( !aModuleId
.isEmpty() )
425 xModuleCategories
= Reference
< container::XNameAccess
>(
426 xAllCategories
->getByName( aModuleId
), UNO_QUERY
);
428 catch ( container::NoSuchElementException
& )
433 if ( !xModuleCategories
.is() )
435 xModuleCategories
= xAllCategories
;
438 if ( xModuleCategories
.is() )
440 Sequence
< sal_Int16
> gids
=
441 xDIP
->getSupportedCommandGroups();
443 for ( sal_Int32 i
= 0; i
< gids
.getLength(); ++i
)
445 Sequence
< frame::DispatchInformation
> commands
;
449 xDIP
->getConfigurableDispatchInformation( gids
[i
] );
451 catch ( container::NoSuchElementException
& )
456 if ( commands
.getLength() == 0 )
461 sal_Int32 gid
= gids
[i
];
462 OUString idx
= OUString::valueOf( gid
);
463 OUString group
= idx
;
466 xModuleCategories
->getByName( idx
) >>= group
;
468 catch ( container::NoSuchElementException
& )
472 SvTreeListEntry
*pEntry
= InsertEntry( group
, NULL
);
474 SvxGroupInfo_Impl
*pInfo
=
475 new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION
, gids
[i
] );
476 aArr
.push_back( pInfo
);
478 pEntry
->SetUserData( pInfo
);
483 // Add Scripting Framework entries
484 Reference
< browse::XBrowseNode
> rootNode
;
488 Reference
< browse::XBrowseNodeFactory
> xFac
= browse::theBrowseNodeFactory::get( xContext
);
489 rootNode
.set( xFac
->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR
) );
491 catch( const Exception
& )
493 DBG_UNHANDLED_EXCEPTION();
500 SvxGroupInfo_Impl
*pInfo
=
501 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER
, 0, rootNode
);
503 String aTitle
= CUI_RESSTR(RID_SVXSTR_PRODMACROS
);
505 SvTreeListEntry
*pNewEntry
= InsertEntry( aTitle
, NULL
);
506 pNewEntry
->SetUserData( pInfo
);
507 pNewEntry
->EnableChildrenOnDemand( sal_True
);
508 aArr
.push_back( pInfo
);
512 fillScriptList( rootNode
, NULL
, false );
515 MakeVisible( GetEntry( 0,0 ) );
516 SetUpdateMode( sal_True
);
519 Image
SvxConfigGroupListBox::GetImage(
520 Reference
< browse::XBrowseNode
> node
,
521 Reference
< XComponentContext
> xCtx
,
528 if ( node
->getName() == "user" || node
->getName() == "share" )
535 OUString nodeName
= node
->getName();
536 Reference
<XInterface
> xDocumentModel
= getDocumentModel(xCtx
, nodeName
);
537 if ( xDocumentModel
.is() )
539 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xCtx
) );
540 // get the long name of the document:
541 OUString
appModule( xModuleManager
->identify(
543 Sequence
<beans::PropertyValue
> moduleDescr
;
544 Any aAny
= xModuleManager
->getByName(appModule
);
545 if( sal_True
!= ( aAny
>>= moduleDescr
) )
547 throw RuntimeException(OUString("SFTreeListBox::Init: failed to get PropertyValue"), Reference
< XInterface
>());
549 beans::PropertyValue
const * pmoduleDescr
=
550 moduleDescr
.getConstArray();
551 for ( sal_Int32 pos
= moduleDescr
.getLength(); pos
--; )
553 if ( pmoduleDescr
[ pos
].Name
== "ooSetupFactoryEmptyDocumentURL" )
555 pmoduleDescr
[ pos
].Value
>>= factoryURL
;
560 if( !factoryURL
.isEmpty() )
562 aImage
= SvFileInformationManager::GetFileImage( INetURLObject(factoryURL
), false );
572 if( node
->getType() == browse::BrowseNodeTypes::SCRIPT
)
580 Reference
< XInterface
>
581 SvxConfigGroupListBox::getDocumentModel(
582 Reference
< XComponentContext
>& xCtx
, OUString
& docName
)
584 Reference
< XInterface
> xModel
;
585 Reference
< frame::XDesktop2
> desktop
= Desktop::create(xCtx
);
587 Reference
< container::XEnumerationAccess
> componentsAccess
=
588 desktop
->getComponents();
589 Reference
< container::XEnumeration
> components
=
590 componentsAccess
->createEnumeration();
591 while (components
->hasMoreElements())
593 Reference
< frame::XModel
> model(
594 components
->nextElement(), UNO_QUERY
);
597 OUString sTdocUrl
= ::comphelper::DocumentInfo::getDocumentTitle( model
);
598 if( sTdocUrl
.equals( docName
) )
608 void SvxConfigGroupListBox::GroupSelected()
610 SvTreeListEntry
*pEntry
= FirstSelected();
611 SvxGroupInfo_Impl
*pInfo
= (SvxGroupInfo_Impl
*) pEntry
->GetUserData();
612 pFunctionListBox
->SetUpdateMode(sal_False
);
613 pFunctionListBox
->ClearAll();
614 if ( pInfo
->nKind
!= SVX_CFGGROUP_FUNCTION
&&
615 pInfo
->nKind
!= SVX_CFGGROUP_SCRIPTCONTAINER
)
617 pFunctionListBox
->SetUpdateMode(sal_True
);
621 switch ( pInfo
->nKind
)
623 case SVX_CFGGROUP_FUNCTION
:
625 SvTreeListEntry
*_pEntry
= FirstSelected();
626 if ( _pEntry
!= NULL
)
628 SvxGroupInfo_Impl
*_pInfo
=
629 (SvxGroupInfo_Impl
*) _pEntry
->GetUserData();
631 Reference
< frame::XDispatchInformationProvider
> xDIP(
632 m_xFrame
, UNO_QUERY
);
634 Sequence
< frame::DispatchInformation
> commands
;
637 commands
= xDIP
->getConfigurableDispatchInformation(
640 catch ( container::NoSuchElementException
& )
644 for ( sal_Int32 i
= 0; i
< commands
.getLength(); ++i
)
646 if ( commands
[i
].Command
.isEmpty() )
653 OUString
aCmdURL( commands
[i
].Command
);
655 if ( m_pImageProvider
)
657 aImage
= m_pImageProvider
->GetImage( aCmdURL
);
663 Any a
= m_xModuleCommands
->getByName( aCmdURL
);
664 Sequence
< beans::PropertyValue
> aPropSeq
;
666 if ( a
>>= aPropSeq
)
668 for ( sal_Int32 k
= 0; k
< aPropSeq
.getLength(); ++k
)
670 if ( aPropSeq
[k
].Name
== "Name" )
672 aPropSeq
[k
].Value
>>= aLabel
;
678 catch ( container::NoSuchElementException
& )
682 if ( aLabel
.isEmpty() )
684 aLabel
= commands
[i
].Command
;
687 SvTreeListEntry
* pFuncEntry
= NULL
;
690 pFuncEntry
= pFunctionListBox
->InsertEntry(
691 aLabel
, aImage
, aImage
);
695 pFuncEntry
= pFunctionListBox
->InsertEntry(
699 SvxGroupInfo_Impl
*_pGroupInfo
= new SvxGroupInfo_Impl(
700 SVX_CFGFUNCTION_SLOT
, 123, aCmdURL
, OUString() );
702 pFunctionListBox
->aArr
.push_back( _pGroupInfo
);
704 pFuncEntry
->SetUserData( _pGroupInfo
);
710 case SVX_CFGGROUP_SCRIPTCONTAINER
:
712 Reference
< browse::XBrowseNode
> rootNode( pInfo
->xBrowseNode
);
715 if ( rootNode
->hasChildNodes() )
717 Sequence
< Reference
< browse::XBrowseNode
> > children
=
718 rootNode
->getChildNodes();
720 for ( sal_Int32 n
= 0; n
< children
.getLength(); ++n
)
722 if (!children
[n
].is())
724 if (children
[n
]->getType() == browse::BrowseNodeTypes::SCRIPT
)
727 OUString description
;
729 Reference
< beans::XPropertySet
>xPropSet( children
[n
], UNO_QUERY
);
735 Any value
= xPropSet
->getPropertyValue(
741 value
= xPropSet
->getPropertyValue(
742 OUString("Description"));
743 value
>>= description
;
745 catch (Exception
&) {
746 // do nothing, the description will be empty
749 SvxGroupInfo_Impl
* _pGroupInfo
=
750 new SvxGroupInfo_Impl(
751 SVX_CFGFUNCTION_SCRIPT
, 123, uri
, description
);
753 Image aImage
= GetImage( children
[n
], Reference
< XComponentContext
>(), sal_False
);
754 SvTreeListEntry
* pNewEntry
=
755 pFunctionListBox
->InsertEntry( children
[n
]->getName(), NULL
);
756 pFunctionListBox
->SetExpandedEntryBmp( pNewEntry
, aImage
);
757 pFunctionListBox
->SetCollapsedEntryBmp(pNewEntry
, aImage
);
759 pNewEntry
->SetUserData( _pGroupInfo
);
761 pFunctionListBox
->aArr
.push_back( _pGroupInfo
);
767 catch (const Exception
&)
769 DBG_UNHANDLED_EXCEPTION();
780 if ( pFunctionListBox
->GetEntryCount() )
781 pFunctionListBox
->Select( pFunctionListBox
->GetEntry( 0, 0 ) );
783 pFunctionListBox
->SetUpdateMode(sal_True
);
786 sal_Bool
SvxConfigGroupListBox::Expand( SvTreeListEntry
* pParent
)
788 sal_Bool bRet
= SvTreeListBox::Expand( pParent
);
791 sal_uLong nEntries
= GetOutputSizePixel().Height() / GetEntryHeight();
793 sal_uLong nChildCount
= GetVisibleChildCount( pParent
);
795 if ( nChildCount
+1 > nEntries
)
797 MakeVisible( pParent
, sal_True
);
801 SvTreeListEntry
*pEntry
= GetFirstEntryInView();
802 sal_uLong nParentPos
= 0;
803 while ( pEntry
&& pEntry
!= pParent
)
806 pEntry
= GetNextEntryInView( pEntry
);
809 if ( nParentPos
+ nChildCount
+ 1 > nEntries
)
810 ScrollOutputArea( (short)( nEntries
- ( nParentPos
+ nChildCount
+ 1 ) ) );
817 void SvxConfigGroupListBox::RequestingChildren( SvTreeListEntry
*pEntry
)
819 SvxGroupInfo_Impl
*pInfo
= (SvxGroupInfo_Impl
*) pEntry
->GetUserData();
820 pInfo
->bWasOpened
= sal_True
;
821 switch ( pInfo
->nKind
)
823 case SVX_CFGGROUP_SCRIPTCONTAINER
:
825 if ( !GetChildCount( pEntry
) )
827 Reference
< browse::XBrowseNode
> rootNode( pInfo
->xBrowseNode
) ;
828 fillScriptList( rootNode
, pEntry
, true /* i30923 */ );
834 OSL_FAIL( "Falscher Gruppentyp!" );
840 * Implementation of SvxScriptSelectorDialog
842 * This dialog is used for selecting Slot API commands
843 * and Scripting Framework Scripts.
846 SvxScriptSelectorDialog::SvxScriptSelectorDialog(
847 Window
* pParent
, sal_Bool bShowSlots
, const Reference
< frame::XFrame
>& xFrame
)
848 : ModelessDialog(pParent
, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
849 , m_bShowSlots(bShowSlots
)
851 get
<FixedText
>("libraryft")->Show(!m_bShowSlots
);
852 get
<FixedText
>("categoryft")->Show(m_bShowSlots
);
853 get
<FixedText
>("macronameft")->Show(!m_bShowSlots
);
854 get
<FixedText
>("commandsft")->Show(m_bShowSlots
);
855 get(m_pDescriptionText
, "description");
856 get(m_pCommands
, "commands");
859 // If we are showing Slot API commands update labels in the UI, and
860 // enable drag'n'drop
861 SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_ADD_COMMANDS
));
862 m_pCommands
->SetDragDropMode( SV_DRAGDROP_APP_COPY
);
864 get(m_pCancelButton
, "close");
865 get(m_pDialogDescription
, "helptoolbar");
866 get(m_pOKButton
, "add");
870 get(m_pCancelButton
, "cancel");
871 get(m_pDialogDescription
, "helpmacro");
872 get(m_pOKButton
, "ok");
874 m_pCancelButton
->Show();
875 m_pDialogDescription
->Show();
878 get(m_pCategories
, "categories");
879 m_pCategories
->SetFunctionListBox(m_pCommands
);
880 m_pCategories
->Init(bShowSlots
, xFrame
);
882 m_pCategories
->SetSelectHdl(
883 LINK( this, SvxScriptSelectorDialog
, SelectHdl
) );
884 m_pCommands
->SetSelectHdl( LINK( this, SvxScriptSelectorDialog
, SelectHdl
) );
885 m_pCommands
->SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog
, FunctionDoubleClickHdl
) );
887 m_pOKButton
->SetClickHdl( LINK( this, SvxScriptSelectorDialog
, ClickHdl
) );
888 m_pCancelButton
->SetClickHdl( LINK( this, SvxScriptSelectorDialog
, ClickHdl
) );
890 m_sDefaultDesc
= m_pDescriptionText
->GetText();
895 SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
899 IMPL_LINK( SvxScriptSelectorDialog
, SelectHdl
, Control
*, pCtrl
)
901 if (pCtrl
== m_pCategories
)
903 m_pCategories
->GroupSelected();
905 else if (pCtrl
== m_pCommands
)
907 m_pCommands
->FunctionSelected();
913 IMPL_LINK( SvxScriptSelectorDialog
, FunctionDoubleClickHdl
, Control
*, pCtrl
)
916 if (m_pOKButton
->IsEnabled())
917 return ClickHdl(m_pOKButton
);
921 // Check if command is selected and enable the OK button accordingly
922 // Grab the help text for this id if available and update the description field
924 SvxScriptSelectorDialog::UpdateUI()
926 OUString url
= GetScriptURL();
927 if ( url
!= NULL
&& !url
.isEmpty() )
930 m_pCommands
->GetHelpText(m_pCommands
->FirstSelected());
931 m_pDescriptionText
->SetText(sMessage
.isEmpty() ? m_sDefaultDesc
: sMessage
);
933 m_pOKButton
->Enable( sal_True
);
937 m_pDescriptionText
->SetText(m_sDefaultDesc
);
938 m_pOKButton
->Enable( sal_False
);
942 IMPL_LINK( SvxScriptSelectorDialog
, ClickHdl
, Button
*, pButton
)
944 if (pButton
== m_pCancelButton
)
946 // If we are displaying Slot API commands then the dialog is being
947 // run from Tools/Configure and we should not close it, just hide it
948 if ( m_bShowSlots
== sal_False
)
950 EndDialog( RET_CANCEL
);
957 else if (pButton
== m_pOKButton
)
959 GetAddHdl().Call( this );
961 // If we are displaying Slot API commands then this the dialog is being
962 // run from Tools/Configure and we should not close it
963 if ( m_bShowSlots
== sal_False
)
969 // Select the next entry in the list if possible
970 SvTreeListEntry
* current
= m_pCommands
->FirstSelected();
971 SvTreeListEntry
* next
= m_pCommands
->NextSibling( current
);
975 m_pCommands
->Select( next
);
984 SvxScriptSelectorDialog::SetRunLabel()
986 m_pOKButton
->SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_RUN
));
990 SvxScriptSelectorDialog::SetDialogDescription( const String
& rDescription
)
992 m_pDialogDescription
->SetText( rDescription
);
996 SvxScriptSelectorDialog::GetScriptURL() const
1000 SvTreeListEntry
*pEntry
= const_cast< SvxScriptSelectorDialog
* >( this )->m_pCommands
->GetLastSelectedEntry();
1003 SvxGroupInfo_Impl
*pData
= (SvxGroupInfo_Impl
*) pEntry
->GetUserData();
1004 if ( ( pData
->nKind
== SVX_CFGFUNCTION_SLOT
)
1005 || ( pData
->nKind
== SVX_CFGFUNCTION_SCRIPT
)
1008 result
= pData
->sURL
;
1016 SvxScriptSelectorDialog::GetSelectedDisplayName()
1018 return m_pCommands
->GetEntryText( m_pCommands
->GetLastSelectedEntry() );
1021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */