Updated core
[LibreOffice.git] / cui / source / customize / selector.cxx
blob1f2105ce28d27fe5461adbbc1b60015564799798
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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_...
28 #include <cuires.hrc>
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)
78 , pCurEntry(0)
79 , m_pDraggingEntry(0)
81 GetModel()->SetSortMode( SortAscending );
83 // Timer for the BallonHelp
84 aTimer.SetTimeout( 200 );
85 aTimer.SetTimeoutHdl(
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()
96 ClearAll();
99 SvTreeListEntry* SvxConfigFunctionListBox::GetLastSelectedEntry()
101 if ( m_pDraggingEntry != NULL )
103 return m_pDraggingEntry;
105 else
107 return FirstSelected();
111 void SvxConfigFunctionListBox::MouseMove( const MouseEvent& rMEvt )
113 Point aMousePos = rMEvt.GetPosPixel();
114 pCurEntry = GetCurEntry();
116 if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
117 aTimer.Start();
118 else
120 Help::ShowBalloon( this, aMousePos, String() );
121 aTimer.Stop();
126 IMPL_LINK_NOARG(SvxConfigFunctionListBox, TimerHdl)
128 aTimer.Stop();
129 Point aMousePos = GetPointerPosPixel();
130 SvTreeListEntry *pEntry = GetCurEntry();
131 if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
132 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) );
133 return 0L;
136 void SvxConfigFunctionListBox::ClearAll()
138 aArr.clear();
139 Clear();
142 String SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry *pEntry )
144 SvxGroupInfo_Impl *pInfo =
145 pEntry ? (SvxGroupInfo_Impl*) pEntry->GetUserData(): 0;
147 if ( pInfo )
149 if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT )
151 OUString aCmdURL( pInfo->sURL );
153 OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this );
155 return aHelpText;
157 else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT )
159 return pInfo->sHelpText;
163 return String();
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;
184 sal_Int8
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 ) );
203 SetNodeBitmaps(
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()
216 ClearAll();
219 void SvxConfigGroupListBox::ClearAll()
221 aArr.clear();
222 Clear();
225 //-----------------------------------------------
226 namespace
228 //...........................................
229 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
230 component by implementing XScriptInvocationContext.
231 @return
232 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
233 model
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 );
241 if ( xContext.is() )
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!" );
257 if ( _rxFrame.is() )
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();
275 return xDocument;
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() )
283 return;
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() )
312 continue;
313 OUString sUIName = theChild->getName();
314 sal_Bool bDisplay = sal_True;
316 if ( bIsRootNode
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;
338 if ( !bDisplay )
339 continue;
341 if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT )
342 continue;
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 );
363 else
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 );
375 break;
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);
394 ClearAll();
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) );
407 OUString aModuleId;
408 try{
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;
448 commands =
449 xDIP->getConfigurableDispatchInformation( gids[i] );
451 catch ( container::NoSuchElementException& )
453 continue;
456 if ( commands.getLength() == 0 )
458 continue;
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();
496 if ( rootNode.is() )
498 if ( m_bShowSlots )
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 );
510 else
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,
522 bool bIsRootNode
525 Image aImage;
526 if ( bIsRootNode )
528 if ( node->getName() == "user" || node->getName() == "share" )
530 aImage = m_hdImage;
532 else
534 OUString factoryURL;
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(
542 xDocumentModel ) );
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;
556 break;
560 if( !factoryURL.isEmpty() )
562 aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
564 else
566 aImage = m_docImage;
570 else
572 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
573 aImage = m_macImage;
574 else
575 aImage = m_libImage;
577 return aImage;
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 );
595 if ( model.is() )
597 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
598 if( sTdocUrl.equals( docName ) )
600 xModel = model;
601 break;
605 return xModel;
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);
618 return;
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(
638 _pInfo->nOrd );
640 catch ( container::NoSuchElementException& )
644 for ( sal_Int32 i = 0; i < commands.getLength(); ++i )
646 if ( commands[i].Command.isEmpty() )
648 continue;
651 Image aImage;
653 OUString aCmdURL( commands[i].Command );
655 if ( m_pImageProvider )
657 aImage = m_pImageProvider->GetImage( aCmdURL );
660 OUString aLabel;
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;
673 break;
678 catch ( container::NoSuchElementException& )
682 if ( aLabel.isEmpty() )
684 aLabel = commands[i].Command;
687 SvTreeListEntry* pFuncEntry = NULL;
688 if ( !!aImage )
690 pFuncEntry = pFunctionListBox->InsertEntry(
691 aLabel, aImage, aImage );
693 else
695 pFuncEntry = pFunctionListBox->InsertEntry(
696 aLabel, NULL );
699 SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl(
700 SVX_CFGFUNCTION_SLOT, 123, aCmdURL, OUString() );
702 pFunctionListBox->aArr.push_back( _pGroupInfo );
704 pFuncEntry->SetUserData( _pGroupInfo );
707 break;
710 case SVX_CFGGROUP_SCRIPTCONTAINER:
712 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode );
714 try {
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())
723 continue;
724 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
726 OUString uri;
727 OUString description;
729 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
730 if (!xPropSet.is())
732 continue;
735 Any value = xPropSet->getPropertyValue(
736 OUString("URI"));
737 value >>= uri;
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();
771 break;
774 default:
776 return;
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 );
789 if ( bRet )
791 sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
793 sal_uLong nChildCount = GetVisibleChildCount( pParent );
795 if ( nChildCount+1 > nEntries )
797 MakeVisible( pParent, sal_True );
799 else
801 SvTreeListEntry *pEntry = GetFirstEntryInView();
802 sal_uLong nParentPos = 0;
803 while ( pEntry && pEntry != pParent )
805 ++nParentPos;
806 pEntry = GetNextEntryInView( pEntry );
809 if ( nParentPos + nChildCount + 1 > nEntries )
810 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
814 return bRet;
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 */ );
830 break;
833 default:
834 OSL_FAIL( "Falscher Gruppentyp!" );
835 break;
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");
857 if (m_bShowSlots)
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");
868 else
870 get(m_pCancelButton, "cancel");
871 get(m_pDialogDescription, "helpmacro");
872 get(m_pOKButton, "ok");
874 m_pCancelButton->Show();
875 m_pDialogDescription->Show();
876 m_pOKButton->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();
892 UpdateUI();
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();
909 UpdateUI();
910 return 0;
913 IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl )
915 (void)pCtrl;
916 if (m_pOKButton->IsEnabled())
917 return ClickHdl(m_pOKButton);
918 return 0;
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
923 void
924 SvxScriptSelectorDialog::UpdateUI()
926 OUString url = GetScriptURL();
927 if ( url != NULL && !url.isEmpty() )
929 OUString sMessage =
930 m_pCommands->GetHelpText(m_pCommands->FirstSelected());
931 m_pDescriptionText->SetText(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
933 m_pOKButton->Enable( sal_True );
935 else
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 );
952 else
954 Hide();
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 )
965 EndDialog( RET_OK );
967 else
969 // Select the next entry in the list if possible
970 SvTreeListEntry* current = m_pCommands->FirstSelected();
971 SvTreeListEntry* next = m_pCommands->NextSibling( current );
973 if ( next != NULL )
975 m_pCommands->Select( next );
980 return 0;
983 void
984 SvxScriptSelectorDialog::SetRunLabel()
986 m_pOKButton->SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_RUN));
989 void
990 SvxScriptSelectorDialog::SetDialogDescription( const String& rDescription )
992 m_pDialogDescription->SetText( rDescription );
995 String
996 SvxScriptSelectorDialog::GetScriptURL() const
998 OUString result;
1000 SvTreeListEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->m_pCommands->GetLastSelectedEntry();
1001 if ( pEntry )
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;
1012 return result;
1015 String
1016 SvxScriptSelectorDialog::GetSelectedDisplayName()
1018 return m_pCommands->GetEntryText( m_pCommands->GetLastSelectedEntry() );
1021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */