Bump version to 4.3-4
[LibreOffice.git] / cui / source / customize / selector.cxx
blob4dbbac23a3cb872ad582d6747a87dccb654416e4
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>
27 #include <svx/dialmgr.hxx>
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/theUICommandDescription.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/theUICategoryDescription.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, WinBits nStyle)
77 : SvTreeListBox(pParent, nStyle | 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 &rMap)
91 WinBits nWinBits = WB_TABSTOP;
93 OString sBorder = VclBuilder::extractCustomProperty(rMap);
94 if (!sBorder.isEmpty())
95 nWinBits |= WB_BORDER;
97 return new SvxConfigFunctionListBox(pParent, nWinBits);
100 SvxConfigFunctionListBox::~SvxConfigFunctionListBox()
102 ClearAll();
105 SvTreeListEntry* SvxConfigFunctionListBox::GetLastSelectedEntry()
107 if ( m_pDraggingEntry != NULL )
109 return m_pDraggingEntry;
111 else
113 return FirstSelected();
117 void SvxConfigFunctionListBox::MouseMove( const MouseEvent& rMEvt )
119 Point aMousePos = rMEvt.GetPosPixel();
120 pCurEntry = GetCurEntry();
122 if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
123 aTimer.Start();
124 else
126 Help::ShowBalloon( this, aMousePos, OUString() );
127 aTimer.Stop();
132 IMPL_LINK_NOARG(SvxConfigFunctionListBox, TimerHdl)
134 aTimer.Stop();
135 Point aMousePos = GetPointerPosPixel();
136 SvTreeListEntry *pEntry = GetCurEntry();
137 if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
138 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) );
139 return 0L;
142 void SvxConfigFunctionListBox::ClearAll()
144 aArr.clear();
145 Clear();
148 OUString SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry *pEntry )
150 SvxGroupInfo_Impl *pInfo =
151 pEntry ? (SvxGroupInfo_Impl*) pEntry->GetUserData(): 0;
153 if ( pInfo )
155 if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT )
157 OUString aCmdURL( pInfo->sURL );
159 OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this );
161 return aHelpText;
163 else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT )
165 return pInfo->sHelpText;
169 return OUString();
172 void SvxConfigFunctionListBox::FunctionSelected()
174 Help::ShowBalloon( this, Point(), OUString() );
177 // drag and drop support
178 DragDropMode SvxConfigFunctionListBox::NotifyStartDrag(
179 TransferDataContainer& /*aTransferDataContainer*/, SvTreeListEntry* pEntry )
181 m_pDraggingEntry = pEntry;
182 return GetDragDropMode();
185 void SvxConfigFunctionListBox::DragFinished( sal_Int8 /*nDropAction*/ )
187 m_pDraggingEntry = NULL;
190 sal_Int8
191 SvxConfigFunctionListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
193 return DND_ACTION_NONE;
196 SvxConfigGroupListBox::SvxConfigGroupListBox(Window* pParent, WinBits nStyle)
197 : SvTreeListBox(pParent, nStyle |
198 WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_TABSTOP)
199 , m_bShowSlots(false)
200 , pFunctionListBox(NULL)
201 , m_pImageProvider(NULL)
202 , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK))
203 , m_libImage(CUI_RES(RID_CUIIMG_LIB))
204 , m_macImage(CUI_RES(RID_CUIIMG_MACRO))
205 , m_docImage(CUI_RES(RID_CUIIMG_DOC))
206 , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS))
207 , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS))
209 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
211 SetNodeBitmaps(
212 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
213 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE )
217 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvxConfigGroupListBox(Window *pParent, VclBuilder::stringmap &rMap)
219 WinBits nWinBits = WB_TABSTOP;
221 OString sBorder = VclBuilder::extractCustomProperty(rMap);
222 if (!sBorder.isEmpty())
223 nWinBits |= WB_BORDER;
225 return new SvxConfigGroupListBox(pParent, nWinBits);
228 SvxConfigGroupListBox::~SvxConfigGroupListBox()
230 ClearAll();
233 void SvxConfigGroupListBox::ClearAll()
235 aArr.clear();
236 Clear();
240 namespace
243 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
244 component by implementing XScriptInvocationContext.
245 @return
246 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
247 model
249 static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
251 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
252 if ( !xScripts.is() )
254 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
255 if ( xContext.is() )
256 xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
259 return Reference< XModel >( xScripts, UNO_QUERY );
263 static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
265 Reference< XModel > xDocument;
267 // examine our associated frame
270 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
271 if ( _rxFrame.is() )
273 // first try the model in the frame
274 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
275 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
277 if ( !xDocument.is() )
279 // if there is no suitable document in the frame, try the controller
280 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
284 catch( const Exception& )
286 DBG_UNHANDLED_EXCEPTION();
289 return xDocument;
293 void SvxConfigGroupListBox::fillScriptList( const Reference< browse::XBrowseNode >& _rxRootNode, SvTreeListEntry* _pParentEntry, bool _bCheapChildrenOnDemand )
295 OSL_PRECOND( _rxRootNode.is(), "SvxConfigGroupListBox::fillScriptList: invalid root node!" );
296 if ( !_rxRootNode.is() )
297 return;
301 if ( _rxRootNode->hasChildNodes() )
303 Sequence< Reference< browse::XBrowseNode > > children =
304 _rxRootNode->getChildNodes();
306 bool bIsRootNode = _rxRootNode->getName() == "Root";
308 /* To mimic current starbasic behaviour we
309 need to make sure that only the current document
310 is displayed in the config tree. Tests below
311 set the bDisplay flag to sal_False if the current
312 node is a first level child of the Root and is NOT
313 either the current document, user or share */
314 OUString sCurrentDocTitle;
315 Reference< XModel > xWorkingDocument = lcl_getScriptableDocument_nothrow( m_xFrame );
316 if ( xWorkingDocument.is() )
318 sCurrentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument );
321 for ( long n = 0; n < children.getLength(); ++n )
323 Reference< browse::XBrowseNode >& theChild = children[n];
324 //#139111# some crash reports show that it might be unset
325 if ( !theChild.is() )
326 continue;
327 OUString sUIName = theChild->getName();
328 bool bDisplay = true;
330 if ( bIsRootNode
331 || ( m_bShowSlots && _pParentEntry && ( GetModel()->GetDepth( _pParentEntry ) == 0 ) )
332 // if we show slots (as in the customize dialog)
333 // then the user & share are added at depth=1
336 if ( sUIName == "user" )
338 sUIName = m_sMyMacros;
339 bIsRootNode = true;
341 else if ( sUIName == "share" )
343 sUIName = m_sProdMacros;
344 bIsRootNode = true;
346 else if ( !sUIName.equals( sCurrentDocTitle ) )
348 bDisplay = false;
352 if ( !bDisplay )
353 continue;
355 if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT )
356 continue;
358 SvTreeListEntry* pNewEntry = InsertEntry( sUIName, _pParentEntry );
360 Image aImage = GetImage( theChild, comphelper::getProcessComponentContext(), bIsRootNode );
361 SetExpandedEntryBmp( pNewEntry, aImage );
362 SetCollapsedEntryBmp( pNewEntry, aImage );
364 SvxGroupInfo_Impl* pInfo =
365 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, theChild );
366 pNewEntry->SetUserData( pInfo );
367 aArr.push_back( pInfo );
369 if ( _bCheapChildrenOnDemand )
371 /* i30923 - Would be nice if there was a better
372 * way to determine if a basic lib had children
373 * without having to ask for them (which forces
374 * the library to be loaded */
375 pNewEntry->EnableChildrenOnDemand( true );
377 else
379 // if there are granchildren we're interested in, display the '+' before
380 // the entry, but do not yet expand
381 Sequence< Reference< browse::XBrowseNode > > grandchildren =
382 children[n]->getChildNodes();
384 for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
386 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
388 pNewEntry->EnableChildrenOnDemand( true );
389 break;
396 catch (const Exception&)
398 DBG_UNHANDLED_EXCEPTION();
402 void SvxConfigGroupListBox::Init(bool bShowSlots, const Reference< frame::XFrame >& xFrame)
404 m_bShowSlots = bShowSlots;
405 m_xFrame.set(xFrame);
407 SetUpdateMode(false);
408 ClearAll();
410 Reference< XComponentContext > xContext(
411 comphelper::getProcessComponentContext() );
413 // are we showing builtin commands?
414 if ( m_bShowSlots && m_xFrame.is() )
416 Reference< frame::XDispatchInformationProvider > xDIP(
417 m_xFrame, UNO_QUERY );
419 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
421 OUString aModuleId;
422 try{
423 aModuleId = xModuleManager->identify( m_xFrame );
424 }catch(const uno::Exception&)
425 { aModuleId = OUString(); }
427 Reference< container::XNameAccess > const xNameAccess(
428 frame::theUICommandDescription::get(xContext) );
429 xNameAccess->getByName( aModuleId ) >>= m_xModuleCommands;
431 Reference< container::XNameAccess > xAllCategories =
432 ui::theUICategoryDescription::get( xContext );
434 Reference< container::XNameAccess > xModuleCategories;
435 if ( !aModuleId.isEmpty() )
439 xModuleCategories = Reference< container::XNameAccess >(
440 xAllCategories->getByName( aModuleId ), UNO_QUERY );
442 catch ( container::NoSuchElementException& )
447 if ( !xModuleCategories.is() )
449 xModuleCategories = xAllCategories;
452 if ( xModuleCategories.is() )
454 Sequence< sal_Int16 > gids =
455 xDIP->getSupportedCommandGroups();
457 for ( sal_Int32 i = 0; i < gids.getLength(); ++i )
459 Sequence< frame::DispatchInformation > commands;
462 commands =
463 xDIP->getConfigurableDispatchInformation( gids[i] );
465 catch ( container::NoSuchElementException& )
467 continue;
470 if ( commands.getLength() == 0 )
472 continue;
475 sal_Int32 gid = gids[i];
476 OUString idx = OUString::number( gid );
477 OUString group = idx;
480 xModuleCategories->getByName( idx ) >>= group;
482 catch ( container::NoSuchElementException& )
486 SvTreeListEntry *pEntry = InsertEntry( group, NULL );
488 SvxGroupInfo_Impl *pInfo =
489 new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION, gids[i] );
490 aArr.push_back( pInfo );
492 pEntry->SetUserData( pInfo );
497 // Add Scripting Framework entries
498 Reference< browse::XBrowseNode > rootNode;
502 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( xContext );
503 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
505 catch( const Exception& )
507 DBG_UNHANDLED_EXCEPTION();
510 if ( rootNode.is() )
512 if ( m_bShowSlots )
514 SvxGroupInfo_Impl *pInfo =
515 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, rootNode );
517 OUString aTitle = CUI_RESSTR(RID_SVXSTR_PRODMACROS);
519 SvTreeListEntry *pNewEntry = InsertEntry( aTitle, NULL );
520 pNewEntry->SetUserData( pInfo );
521 pNewEntry->EnableChildrenOnDemand( true );
522 aArr.push_back( pInfo );
524 else
526 fillScriptList( rootNode, NULL, false );
529 MakeVisible( GetEntry( 0,0 ) );
530 SetUpdateMode( true );
533 Image SvxConfigGroupListBox::GetImage(
534 Reference< browse::XBrowseNode > node,
535 Reference< XComponentContext > xCtx,
536 bool bIsRootNode
539 Image aImage;
540 if ( bIsRootNode )
542 if ( node->getName() == "user" || node->getName() == "share" )
544 aImage = m_hdImage;
546 else
548 OUString factoryURL;
549 OUString nodeName = node->getName();
550 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
551 if ( xDocumentModel.is() )
553 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
554 // get the long name of the document:
555 OUString appModule( xModuleManager->identify(
556 xDocumentModel ) );
557 Sequence<beans::PropertyValue> moduleDescr;
558 Any aAny = xModuleManager->getByName(appModule);
559 if( !( aAny >>= moduleDescr ) )
561 throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue", Reference< XInterface >());
563 beans::PropertyValue const * pmoduleDescr =
564 moduleDescr.getConstArray();
565 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
567 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
569 pmoduleDescr[ pos ].Value >>= factoryURL;
570 break;
574 if( !factoryURL.isEmpty() )
576 aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
578 else
580 aImage = m_docImage;
584 else
586 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
587 aImage = m_macImage;
588 else
589 aImage = m_libImage;
591 return aImage;
594 Reference< XInterface >
595 SvxConfigGroupListBox::getDocumentModel(
596 Reference< XComponentContext >& xCtx, OUString& docName )
598 Reference< XInterface > xModel;
599 Reference< frame::XDesktop2 > desktop = Desktop::create(xCtx);
601 Reference< container::XEnumerationAccess > componentsAccess =
602 desktop->getComponents();
603 Reference< container::XEnumeration > components =
604 componentsAccess->createEnumeration();
605 while (components->hasMoreElements())
607 Reference< frame::XModel > model(
608 components->nextElement(), UNO_QUERY );
609 if ( model.is() )
611 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
612 if( sTdocUrl.equals( docName ) )
614 xModel = model;
615 break;
619 return xModel;
622 void SvxConfigGroupListBox::GroupSelected()
624 SvTreeListEntry *pEntry = FirstSelected();
625 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData();
626 pFunctionListBox->SetUpdateMode(false);
627 pFunctionListBox->ClearAll();
628 if ( pInfo->nKind != SVX_CFGGROUP_FUNCTION &&
629 pInfo->nKind != SVX_CFGGROUP_SCRIPTCONTAINER )
631 pFunctionListBox->SetUpdateMode(true);
632 return;
635 switch ( pInfo->nKind )
637 case SVX_CFGGROUP_FUNCTION :
639 SvTreeListEntry *_pEntry = FirstSelected();
640 if ( _pEntry != NULL )
642 SvxGroupInfo_Impl *_pInfo =
643 (SvxGroupInfo_Impl*) _pEntry->GetUserData();
645 Reference< frame::XDispatchInformationProvider > xDIP(
646 m_xFrame, UNO_QUERY );
648 Sequence< frame::DispatchInformation > commands;
651 commands = xDIP->getConfigurableDispatchInformation(
652 _pInfo->nOrd );
654 catch ( container::NoSuchElementException& )
658 for ( sal_Int32 i = 0; i < commands.getLength(); ++i )
660 if ( commands[i].Command.isEmpty() )
662 continue;
665 Image aImage;
667 OUString aCmdURL( commands[i].Command );
669 if ( m_pImageProvider )
671 aImage = m_pImageProvider->GetImage( aCmdURL );
674 OUString aLabel;
677 Any a = m_xModuleCommands->getByName( aCmdURL );
678 Sequence< beans::PropertyValue > aPropSeq;
680 if ( a >>= aPropSeq )
682 for ( sal_Int32 k = 0; k < aPropSeq.getLength(); ++k )
684 if ( aPropSeq[k].Name == "Name" )
686 aPropSeq[k].Value >>= aLabel;
687 break;
692 catch ( container::NoSuchElementException& )
696 if ( aLabel.isEmpty() )
698 aLabel = commands[i].Command;
701 SvTreeListEntry* pFuncEntry = NULL;
702 if ( !!aImage )
704 pFuncEntry = pFunctionListBox->InsertEntry(
705 aLabel, aImage, aImage );
707 else
709 pFuncEntry = pFunctionListBox->InsertEntry(
710 aLabel, NULL );
713 SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl(
714 SVX_CFGFUNCTION_SLOT, 123, aCmdURL, OUString() );
716 pFunctionListBox->aArr.push_back( _pGroupInfo );
718 pFuncEntry->SetUserData( _pGroupInfo );
721 break;
724 case SVX_CFGGROUP_SCRIPTCONTAINER:
726 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode );
728 try {
729 if ( rootNode->hasChildNodes() )
731 Sequence< Reference< browse::XBrowseNode > > children =
732 rootNode->getChildNodes();
734 for ( sal_Int32 n = 0; n < children.getLength(); ++n )
736 if (!children[n].is())
737 continue;
738 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
740 OUString uri;
741 OUString description;
743 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
744 if (!xPropSet.is())
746 continue;
749 Any value = xPropSet->getPropertyValue(
750 OUString("URI"));
751 value >>= uri;
755 value = xPropSet->getPropertyValue(
756 OUString("Description"));
757 value >>= description;
759 catch (Exception &) {
760 // do nothing, the description will be empty
763 SvxGroupInfo_Impl* _pGroupInfo =
764 new SvxGroupInfo_Impl(
765 SVX_CFGFUNCTION_SCRIPT, 123, uri, description );
767 Image aImage = GetImage( children[n], Reference< XComponentContext >(), false );
768 SvTreeListEntry* pNewEntry =
769 pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
770 pFunctionListBox->SetExpandedEntryBmp( pNewEntry, aImage );
771 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage );
773 pNewEntry->SetUserData( _pGroupInfo );
775 pFunctionListBox->aArr.push_back( _pGroupInfo );
781 catch (const Exception&)
783 DBG_UNHANDLED_EXCEPTION();
785 break;
788 default:
790 return;
794 if ( pFunctionListBox->GetEntryCount() )
795 pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
797 pFunctionListBox->SetUpdateMode(true);
800 bool SvxConfigGroupListBox::Expand( SvTreeListEntry* pParent )
802 bool bRet = SvTreeListBox::Expand( pParent );
803 if ( bRet )
805 sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
807 sal_uLong nChildCount = GetVisibleChildCount( pParent );
809 if ( nChildCount+1 > nEntries )
811 MakeVisible( pParent, true );
813 else
815 SvTreeListEntry *pEntry = GetFirstEntryInView();
816 sal_uLong nParentPos = 0;
817 while ( pEntry && pEntry != pParent )
819 ++nParentPos;
820 pEntry = GetNextEntryInView( pEntry );
823 if ( nParentPos + nChildCount + 1 > nEntries )
824 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
828 return bRet;
831 void SvxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
833 SvxGroupInfo_Impl *pInfo = (SvxGroupInfo_Impl*) pEntry->GetUserData();
834 pInfo->bWasOpened = true;
835 switch ( pInfo->nKind )
837 case SVX_CFGGROUP_SCRIPTCONTAINER:
839 if ( !GetChildCount( pEntry ) )
841 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ) ;
842 fillScriptList( rootNode, pEntry, true /* i30923 */ );
844 break;
847 default:
848 OSL_FAIL( "Falscher Gruppentyp!" );
849 break;
854 * Implementation of SvxScriptSelectorDialog
856 * This dialog is used for selecting Slot API commands
857 * and Scripting Framework Scripts.
860 SvxScriptSelectorDialog::SvxScriptSelectorDialog(
861 Window* pParent, bool bShowSlots, const Reference< frame::XFrame >& xFrame)
862 : ModelessDialog(pParent, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
863 , m_bShowSlots(bShowSlots)
865 get<FixedText>("libraryft")->Show(!m_bShowSlots);
866 get<FixedText>("categoryft")->Show(m_bShowSlots);
867 get<FixedText>("macronameft")->Show(!m_bShowSlots);
868 get<FixedText>("commandsft")->Show(m_bShowSlots);
869 get(m_pDescriptionText, "description");
870 get(m_pCommands, "commands");
871 if (m_bShowSlots)
873 // If we are showing Slot API commands update labels in the UI, and
874 // enable drag'n'drop
875 SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_ADD_COMMANDS));
876 m_pCommands->SetDragDropMode( SV_DRAGDROP_APP_COPY );
878 get(m_pCancelButton, "close");
879 get(m_pDialogDescription, "helptoolbar");
880 get(m_pOKButton, "add");
882 else
884 get(m_pCancelButton, "cancel");
885 get(m_pDialogDescription, "helpmacro");
886 get(m_pOKButton, "ok");
888 m_pCancelButton->Show();
889 m_pDialogDescription->Show();
890 m_pOKButton->Show();
892 get(m_pCategories, "categories");
893 m_pCategories->SetFunctionListBox(m_pCommands);
894 m_pCategories->Init(bShowSlots, xFrame);
896 m_pCategories->SetSelectHdl(
897 LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
898 m_pCommands->SetSelectHdl( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
899 m_pCommands->SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
901 m_pOKButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
902 m_pCancelButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
904 m_sDefaultDesc = m_pDescriptionText->GetText();
906 UpdateUI();
909 SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
913 IMPL_LINK( SvxScriptSelectorDialog, SelectHdl, Control*, pCtrl )
915 if (pCtrl == m_pCategories)
917 m_pCategories->GroupSelected();
919 else if (pCtrl == m_pCommands)
921 m_pCommands->FunctionSelected();
923 UpdateUI();
924 return 0;
927 IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl )
929 (void)pCtrl;
930 if (m_pOKButton->IsEnabled())
931 return ClickHdl(m_pOKButton);
932 return 0;
935 // Check if command is selected and enable the OK button accordingly
936 // Grab the help text for this id if available and update the description field
937 void
938 SvxScriptSelectorDialog::UpdateUI()
940 OUString url = GetScriptURL();
941 if ( url != NULL && !url.isEmpty() )
943 OUString sMessage =
944 m_pCommands->GetHelpText(m_pCommands->FirstSelected());
945 m_pDescriptionText->SetText(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
947 m_pOKButton->Enable( true );
949 else
951 m_pDescriptionText->SetText(m_sDefaultDesc);
952 m_pOKButton->Enable( false );
956 IMPL_LINK( SvxScriptSelectorDialog, ClickHdl, Button *, pButton )
958 if (pButton == m_pCancelButton)
960 // If we are displaying Slot API commands then the dialog is being
961 // run from Tools/Configure and we should not close it, just hide it
962 if ( m_bShowSlots == false )
964 EndDialog( RET_CANCEL );
966 else
968 Hide();
971 else if (pButton == m_pOKButton)
973 GetAddHdl().Call( this );
975 // If we are displaying Slot API commands then this the dialog is being
976 // run from Tools/Configure and we should not close it
977 if ( m_bShowSlots == false )
979 EndDialog( RET_OK );
981 else
983 // Select the next entry in the list if possible
984 SvTreeListEntry* current = m_pCommands->FirstSelected();
985 SvTreeListEntry* next = m_pCommands->NextSibling( current );
987 if ( next != NULL )
989 m_pCommands->Select( next );
994 return 0;
997 void
998 SvxScriptSelectorDialog::SetRunLabel()
1000 m_pOKButton->SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_RUN));
1003 void
1004 SvxScriptSelectorDialog::SetDialogDescription( const OUString& rDescription )
1006 m_pDialogDescription->SetText( rDescription );
1009 OUString
1010 SvxScriptSelectorDialog::GetScriptURL() const
1012 OUString result;
1014 SvTreeListEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->m_pCommands->GetLastSelectedEntry();
1015 if ( pEntry )
1017 SvxGroupInfo_Impl *pData = (SvxGroupInfo_Impl*) pEntry->GetUserData();
1018 if ( ( pData->nKind == SVX_CFGFUNCTION_SLOT )
1019 || ( pData->nKind == SVX_CFGFUNCTION_SCRIPT )
1022 result = pData->sURL;
1026 return result;
1029 OUString
1030 SvxScriptSelectorDialog::GetSelectedDisplayName()
1032 return m_pCommands->GetEntryText( m_pCommands->GetLastSelectedEntry() );
1035 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */