bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / customize / selector.cxx
blob781ddbfbefaa233132539dbb283aa698336bfa36
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 <vcl/builderfactory.hxx>
25 #include "selector.hxx"
26 #include <dialmgr.hxx>
27 #include <svx/fmresids.hrc>
28 #include <svx/dialmgr.hxx>
29 #include <cuires.hrc>
30 #include <sfx2/app.hxx>
31 #include <sfx2/msg.hxx>
32 #include <sfx2/msgpool.hxx>
33 #include <sfx2/minfitem.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/dispatch.hxx>
37 #include <comphelper/documentinfo.hxx>
38 #include <comphelper/processfactory.hxx>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <com/sun/star/container/XEnumerationAccess.hpp>
43 #include <com/sun/star/container/XEnumeration.hpp>
44 #include <com/sun/star/document/XEmbeddedScripts.hpp>
45 #include <com/sun/star/document/XScriptInvocationContext.hpp>
46 #include <com/sun/star/frame/ModuleManager.hpp>
47 #include <com/sun/star/frame/Desktop.hpp>
48 #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
49 #include <com/sun/star/frame/DispatchInformation.hpp>
50 #include <com/sun/star/frame/theUICommandDescription.hpp>
51 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
52 #include <com/sun/star/script/provider/XScriptProvider.hpp>
53 #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
54 #include <com/sun/star/script/browse/XBrowseNode.hpp>
55 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
56 #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
57 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
58 #include <com/sun/star/ui/theUICategoryDescription.hpp>
61 using namespace ::com::sun::star;
62 using namespace ::com::sun::star::uno;
63 using namespace ::com::sun::star::script;
64 using namespace ::com::sun::star::frame;
65 using namespace ::com::sun::star::document;
66 using namespace ::com::sun::star::container;
68 #include <svtools/imagemgr.hxx>
69 #include "svtools/treelistentry.hxx"
70 #include <tools/urlobj.hxx>
71 #include <tools/diagnose_ex.h>
74 * The implementations of SvxConfigFunctionListBox and
75 * SvxConfigGroupListBox are copied from sfx2/source/dialog/cfg.cxx
77 SvxConfigFunctionListBox::SvxConfigFunctionListBox(vcl::Window* pParent, WinBits nStyle)
78 : SvTreeListBox(pParent, nStyle | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT | WB_TABSTOP)
79 , pCurEntry(0)
80 , m_pDraggingEntry(0)
82 GetModel()->SetSortMode( SortAscending );
84 // Timer for the BallonHelp
85 aTimer.SetTimeout( 200 );
86 aTimer.SetTimeoutHdl(
87 LINK( this, SvxConfigFunctionListBox, TimerHdl ) );
90 VCL_BUILDER_DECL_FACTORY(SvxConfigFunctionListBox)
92 WinBits nWinBits = WB_TABSTOP;
94 OString sBorder = VclBuilder::extractCustomProperty(rMap);
95 if (!sBorder.isEmpty())
96 nWinBits |= WB_BORDER;
98 rRet = VclPtr<SvxConfigFunctionListBox>::Create(pParent, nWinBits);
101 SvxConfigFunctionListBox::~SvxConfigFunctionListBox()
103 disposeOnce();
106 void SvxConfigFunctionListBox::dispose()
108 ClearAll();
109 SvTreeListBox::dispose();
112 SvTreeListEntry* SvxConfigFunctionListBox::GetLastSelectedEntry()
114 if ( m_pDraggingEntry != NULL )
116 return m_pDraggingEntry;
118 else
120 return FirstSelected();
124 void SvxConfigFunctionListBox::MouseMove( const MouseEvent& rMEvt )
126 Point aMousePos = rMEvt.GetPosPixel();
127 pCurEntry = GetCurEntry();
129 if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
130 aTimer.Start();
131 else
133 Help::ShowBalloon( this, aMousePos, OUString() );
134 aTimer.Stop();
139 IMPL_LINK_NOARG_TYPED(SvxConfigFunctionListBox, TimerHdl, Timer *, void)
141 aTimer.Stop();
142 Point aMousePos = GetPointerPosPixel();
143 SvTreeListEntry *pEntry = GetCurEntry();
144 if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
145 Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) );
148 void SvxConfigFunctionListBox::ClearAll()
150 aArr.clear();
151 Clear();
154 OUString SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry *pEntry )
156 SvxGroupInfo_Impl *pInfo =
157 pEntry ? static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData()): 0;
159 if ( pInfo )
161 if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT )
163 OUString aCmdURL( pInfo->sURL );
165 OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this );
167 return aHelpText;
169 else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT )
171 return pInfo->sHelpText;
175 return OUString();
178 void SvxConfigFunctionListBox::FunctionSelected()
180 Help::ShowBalloon( this, Point(), OUString() );
183 // drag and drop support
184 DragDropMode SvxConfigFunctionListBox::NotifyStartDrag(
185 TransferDataContainer& /*aTransferDataContainer*/, SvTreeListEntry* pEntry )
187 m_pDraggingEntry = pEntry;
188 return GetDragDropMode();
191 void SvxConfigFunctionListBox::DragFinished( sal_Int8 /*nDropAction*/ )
193 m_pDraggingEntry = NULL;
196 sal_Int8
197 SvxConfigFunctionListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
199 return DND_ACTION_NONE;
202 SvxConfigGroupListBox::SvxConfigGroupListBox(vcl::Window* pParent, WinBits nStyle)
203 : SvTreeListBox(pParent, nStyle |
204 WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_TABSTOP)
205 , m_bShowSlots(false)
206 , pFunctionListBox(NULL)
207 , m_pImageProvider(NULL)
208 , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK))
209 , m_libImage(CUI_RES(RID_CUIIMG_LIB))
210 , m_macImage(CUI_RES(RID_CUIIMG_MACRO))
211 , m_docImage(CUI_RES(RID_CUIIMG_DOC))
212 , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS))
213 , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS))
215 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
217 SetNodeBitmaps(
218 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
219 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE )
223 VCL_BUILDER_DECL_FACTORY(SvxConfigGroupListBox)
225 WinBits nWinBits = WB_TABSTOP;
227 OString sBorder = VclBuilder::extractCustomProperty(rMap);
228 if (!sBorder.isEmpty())
229 nWinBits |= WB_BORDER;
231 rRet = VclPtr<SvxConfigGroupListBox>::Create(pParent, nWinBits);
234 SvxConfigGroupListBox::~SvxConfigGroupListBox()
236 disposeOnce();
239 void SvxConfigGroupListBox::dispose()
241 ClearAll();
242 pFunctionListBox.clear();
243 SvTreeListBox::dispose();
246 void SvxConfigGroupListBox::ClearAll()
248 aArr.clear();
249 Clear();
253 namespace
256 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
257 component by implementing XScriptInvocationContext.
258 @return
259 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
260 model
262 static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
264 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
265 if ( !xScripts.is() )
267 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
268 if ( xContext.is() )
269 xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
272 return Reference< XModel >( xScripts, UNO_QUERY );
276 static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
278 Reference< XModel > xDocument;
280 // examine our associated frame
283 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
284 if ( _rxFrame.is() )
286 // first try the model in the frame
287 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
288 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
290 if ( !xDocument.is() )
292 // if there is no suitable document in the frame, try the controller
293 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
297 catch( const Exception& )
299 DBG_UNHANDLED_EXCEPTION();
302 return xDocument;
306 void SvxConfigGroupListBox::fillScriptList( const Reference< browse::XBrowseNode >& _rxRootNode, SvTreeListEntry* _pParentEntry, bool _bCheapChildrenOnDemand )
308 OSL_PRECOND( _rxRootNode.is(), "SvxConfigGroupListBox::fillScriptList: invalid root node!" );
309 if ( !_rxRootNode.is() )
310 return;
314 if ( _rxRootNode->hasChildNodes() )
316 Sequence< Reference< browse::XBrowseNode > > children =
317 _rxRootNode->getChildNodes();
319 bool bIsRootNode = _rxRootNode->getName() == "Root";
321 /* To mimic current starbasic behaviour we
322 need to make sure that only the current document
323 is displayed in the config tree. Tests below
324 set the bDisplay flag to sal_False if the current
325 node is a first level child of the Root and is NOT
326 either the current document, user or share */
327 OUString sCurrentDocTitle;
328 Reference< XModel > xWorkingDocument = lcl_getScriptableDocument_nothrow( m_xFrame );
329 if ( xWorkingDocument.is() )
331 sCurrentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument );
334 for ( long n = 0; n < children.getLength(); ++n )
336 Reference< browse::XBrowseNode >& theChild = children[n];
337 //#139111# some crash reports show that it might be unset
338 if ( !theChild.is() )
339 continue;
340 OUString sUIName = theChild->getName();
341 bool bDisplay = true;
343 if ( bIsRootNode
344 || ( m_bShowSlots && _pParentEntry && ( GetModel()->GetDepth( _pParentEntry ) == 0 ) )
345 // if we show slots (as in the customize dialog)
346 // then the user & share are added at depth=1
349 if ( sUIName == "user" )
351 sUIName = m_sMyMacros;
352 bIsRootNode = true;
354 else if ( sUIName == "share" )
356 sUIName = m_sProdMacros;
357 bIsRootNode = true;
359 else if ( !sUIName.equals( sCurrentDocTitle ) )
361 bDisplay = false;
365 if ( !bDisplay )
366 continue;
368 if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT )
369 continue;
371 SvTreeListEntry* pNewEntry = InsertEntry( sUIName, _pParentEntry );
373 Image aImage = GetImage( theChild, comphelper::getProcessComponentContext(), bIsRootNode );
374 SetExpandedEntryBmp( pNewEntry, aImage );
375 SetCollapsedEntryBmp( pNewEntry, aImage );
377 SvxGroupInfo_Impl* pInfo =
378 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, theChild );
379 pNewEntry->SetUserData( pInfo );
380 aArr.push_back( pInfo );
382 if ( _bCheapChildrenOnDemand )
384 /* i30923 - Would be nice if there was a better
385 * way to determine if a basic lib had children
386 * without having to ask for them (which forces
387 * the library to be loaded */
388 pNewEntry->EnableChildrenOnDemand( true );
390 else
392 // if there are granchildren we're interested in, display the '+' before
393 // the entry, but do not yet expand
394 Sequence< Reference< browse::XBrowseNode > > grandchildren =
395 children[n]->getChildNodes();
397 for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
399 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
401 pNewEntry->EnableChildrenOnDemand( true );
402 break;
409 catch (const Exception&)
411 DBG_UNHANDLED_EXCEPTION();
415 void SvxConfigGroupListBox::Init(bool bShowSlots, const Reference< frame::XFrame >& xFrame)
417 m_bShowSlots = bShowSlots;
418 m_xFrame.set(xFrame);
420 SetUpdateMode(false);
421 ClearAll();
423 Reference< XComponentContext > xContext(
424 comphelper::getProcessComponentContext() );
426 // are we showing builtin commands?
427 if ( m_bShowSlots && m_xFrame.is() )
429 Reference< frame::XDispatchInformationProvider > xDIP(
430 m_xFrame, UNO_QUERY );
432 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
434 OUString aModuleId;
435 try{
436 aModuleId = xModuleManager->identify( m_xFrame );
437 }catch(const uno::Exception&)
438 { aModuleId.clear(); }
440 Reference< container::XNameAccess > const xNameAccess(
441 frame::theUICommandDescription::get(xContext) );
442 xNameAccess->getByName( aModuleId ) >>= m_xModuleCommands;
444 Reference< container::XNameAccess > xAllCategories =
445 ui::theUICategoryDescription::get( xContext );
447 Reference< container::XNameAccess > xModuleCategories;
448 if ( !aModuleId.isEmpty() )
452 xModuleCategories = Reference< container::XNameAccess >(
453 xAllCategories->getByName( aModuleId ), UNO_QUERY );
455 catch ( container::NoSuchElementException& )
460 if ( !xModuleCategories.is() )
462 xModuleCategories = xAllCategories;
465 if ( xModuleCategories.is() )
467 Sequence< sal_Int16 > gids =
468 xDIP->getSupportedCommandGroups();
470 for ( sal_Int32 i = 0; i < gids.getLength(); ++i )
472 Sequence< frame::DispatchInformation > commands;
475 commands =
476 xDIP->getConfigurableDispatchInformation( gids[i] );
478 catch ( container::NoSuchElementException& )
480 continue;
483 if ( commands.getLength() == 0 )
485 continue;
488 sal_Int32 gid = gids[i];
489 OUString idx = OUString::number( gid );
490 OUString group = idx;
493 xModuleCategories->getByName( idx ) >>= group;
495 catch ( container::NoSuchElementException& )
499 SvTreeListEntry *pEntry = InsertEntry( group, NULL );
501 SvxGroupInfo_Impl *pInfo =
502 new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION, gids[i] );
503 aArr.push_back( pInfo );
505 pEntry->SetUserData( pInfo );
510 // Add Scripting Framework entries
511 Reference< browse::XBrowseNode > rootNode;
515 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( xContext );
516 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
518 catch( const Exception& )
520 DBG_UNHANDLED_EXCEPTION();
523 if ( rootNode.is() )
525 if ( m_bShowSlots )
527 SvxGroupInfo_Impl *pInfo =
528 new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, rootNode );
530 OUString aTitle = CUI_RESSTR(RID_SVXSTR_PRODMACROS);
532 SvTreeListEntry *pNewEntry = InsertEntry( aTitle, NULL );
533 pNewEntry->SetUserData( pInfo );
534 pNewEntry->EnableChildrenOnDemand( true );
535 aArr.push_back( pInfo );
537 else
539 fillScriptList( rootNode, NULL, false );
542 MakeVisible( GetEntry( 0,0 ) );
543 SetUpdateMode( true );
546 Image SvxConfigGroupListBox::GetImage(
547 Reference< browse::XBrowseNode > node,
548 Reference< XComponentContext > xCtx,
549 bool bIsRootNode
552 Image aImage;
553 if ( bIsRootNode )
555 if ( node->getName() == "user" || node->getName() == "share" )
557 aImage = m_hdImage;
559 else
561 OUString factoryURL;
562 OUString nodeName = node->getName();
563 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
564 if ( xDocumentModel.is() )
566 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
567 // get the long name of the document:
568 OUString appModule( xModuleManager->identify(
569 xDocumentModel ) );
570 Sequence<beans::PropertyValue> moduleDescr;
571 Any aAny = xModuleManager->getByName(appModule);
572 if( !( aAny >>= moduleDescr ) )
574 throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
576 beans::PropertyValue const * pmoduleDescr =
577 moduleDescr.getConstArray();
578 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
580 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
582 pmoduleDescr[ pos ].Value >>= factoryURL;
583 break;
587 if( !factoryURL.isEmpty() )
589 aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
591 else
593 aImage = m_docImage;
597 else
599 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
600 aImage = m_macImage;
601 else
602 aImage = m_libImage;
604 return aImage;
607 Reference< XInterface >
608 SvxConfigGroupListBox::getDocumentModel(
609 Reference< XComponentContext >& xCtx, OUString& docName )
611 Reference< XInterface > xModel;
612 Reference< frame::XDesktop2 > desktop = Desktop::create(xCtx);
614 Reference< container::XEnumerationAccess > componentsAccess =
615 desktop->getComponents();
616 Reference< container::XEnumeration > components =
617 componentsAccess->createEnumeration();
618 while (components->hasMoreElements())
620 Reference< frame::XModel > model(
621 components->nextElement(), UNO_QUERY );
622 if ( model.is() )
624 OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
625 if( sTdocUrl.equals( docName ) )
627 xModel = model;
628 break;
632 return xModel;
635 void SvxConfigGroupListBox::GroupSelected()
637 SvTreeListEntry *pEntry = FirstSelected();
638 SvxGroupInfo_Impl *pInfo = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
639 pFunctionListBox->SetUpdateMode(false);
640 pFunctionListBox->ClearAll();
641 if ( pInfo->nKind != SVX_CFGGROUP_FUNCTION &&
642 pInfo->nKind != SVX_CFGGROUP_SCRIPTCONTAINER )
644 pFunctionListBox->SetUpdateMode(true);
645 return;
648 switch ( pInfo->nKind )
650 case SVX_CFGGROUP_FUNCTION :
652 SvTreeListEntry *_pEntry = FirstSelected();
653 if ( _pEntry != NULL )
655 SvxGroupInfo_Impl *_pInfo =
656 static_cast<SvxGroupInfo_Impl*>(_pEntry->GetUserData());
658 Reference< frame::XDispatchInformationProvider > xDIP(
659 m_xFrame, UNO_QUERY );
661 Sequence< frame::DispatchInformation > commands;
664 commands = xDIP->getConfigurableDispatchInformation(
665 _pInfo->nOrd );
667 catch ( container::NoSuchElementException& )
671 for ( sal_Int32 i = 0; i < commands.getLength(); ++i )
673 if ( commands[i].Command.isEmpty() )
675 continue;
678 Image aImage;
680 OUString aCmdURL( commands[i].Command );
682 if ( m_pImageProvider )
684 aImage = m_pImageProvider->GetImage( aCmdURL );
687 OUString aLabel;
690 Any a = m_xModuleCommands->getByName( aCmdURL );
691 Sequence< beans::PropertyValue > aPropSeq;
693 if ( a >>= aPropSeq )
695 for ( sal_Int32 k = 0; k < aPropSeq.getLength(); ++k )
697 if ( aPropSeq[k].Name == "Name" )
699 aPropSeq[k].Value >>= aLabel;
700 break;
705 catch ( container::NoSuchElementException& )
709 if ( aLabel.isEmpty() )
711 aLabel = commands[i].Command;
714 SvTreeListEntry* pFuncEntry = NULL;
715 if ( !!aImage )
717 pFuncEntry = pFunctionListBox->InsertEntry(
718 aLabel, aImage, aImage );
720 else
722 pFuncEntry = pFunctionListBox->InsertEntry(
723 aLabel, NULL );
726 SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl(
727 SVX_CFGFUNCTION_SLOT, 123, aCmdURL, OUString() );
729 pFunctionListBox->aArr.push_back( _pGroupInfo );
731 pFuncEntry->SetUserData( _pGroupInfo );
734 break;
737 case SVX_CFGGROUP_SCRIPTCONTAINER:
739 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode );
741 try {
742 if ( rootNode->hasChildNodes() )
744 Sequence< Reference< browse::XBrowseNode > > children =
745 rootNode->getChildNodes();
747 for ( sal_Int32 n = 0; n < children.getLength(); ++n )
749 if (!children[n].is())
750 continue;
751 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
753 OUString uri;
754 OUString description;
756 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
757 if (!xPropSet.is())
759 continue;
762 Any value = xPropSet->getPropertyValue(
763 OUString("URI"));
764 value >>= uri;
768 value = xPropSet->getPropertyValue(
769 OUString("Description"));
770 value >>= description;
772 catch (Exception &) {
773 // do nothing, the description will be empty
776 SvxGroupInfo_Impl* _pGroupInfo =
777 new SvxGroupInfo_Impl(
778 SVX_CFGFUNCTION_SCRIPT, 123, uri, description );
780 Image aImage = GetImage( children[n], Reference< XComponentContext >(), false );
781 SvTreeListEntry* pNewEntry =
782 pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
783 pFunctionListBox->SetExpandedEntryBmp( pNewEntry, aImage );
784 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage );
786 pNewEntry->SetUserData( _pGroupInfo );
788 pFunctionListBox->aArr.push_back( _pGroupInfo );
794 catch (const Exception&)
796 DBG_UNHANDLED_EXCEPTION();
798 break;
801 default:
803 return;
807 if ( pFunctionListBox->GetEntryCount() )
808 pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
810 pFunctionListBox->SetUpdateMode(true);
813 bool SvxConfigGroupListBox::Expand( SvTreeListEntry* pParent )
815 bool bRet = SvTreeListBox::Expand( pParent );
816 if ( bRet )
818 sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
820 sal_uLong nChildCount = GetVisibleChildCount( pParent );
822 if ( nChildCount+1 > nEntries )
824 MakeVisible( pParent, true );
826 else
828 SvTreeListEntry *pEntry = GetFirstEntryInView();
829 sal_uLong nParentPos = 0;
830 while ( pEntry && pEntry != pParent )
832 ++nParentPos;
833 pEntry = GetNextEntryInView( pEntry );
836 if ( nParentPos + nChildCount + 1 > nEntries )
837 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
841 return bRet;
844 void SvxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
846 SvxGroupInfo_Impl *pInfo = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
847 pInfo->bWasOpened = true;
848 switch ( pInfo->nKind )
850 case SVX_CFGGROUP_SCRIPTCONTAINER:
852 if ( !GetChildCount( pEntry ) )
854 Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ) ;
855 fillScriptList( rootNode, pEntry, true /* i30923 */ );
857 break;
860 default:
861 OSL_FAIL( "Falscher Gruppentyp!" );
862 break;
867 * Implementation of SvxScriptSelectorDialog
869 * This dialog is used for selecting Slot API commands
870 * and Scripting Framework Scripts.
873 SvxScriptSelectorDialog::SvxScriptSelectorDialog(
874 vcl::Window* pParent, bool bShowSlots, const Reference< frame::XFrame >& xFrame)
875 : ModelessDialog(pParent, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
876 , m_bShowSlots(bShowSlots)
878 get<FixedText>("libraryft")->Show(!m_bShowSlots);
879 get<FixedText>("categoryft")->Show(m_bShowSlots);
880 get<FixedText>("macronameft")->Show(!m_bShowSlots);
881 get<FixedText>("commandsft")->Show(m_bShowSlots);
882 get(m_pDescriptionText, "description");
883 get(m_pCommands, "commands");
884 if (m_bShowSlots)
886 // If we are showing Slot API commands update labels in the UI, and
887 // enable drag'n'drop
888 SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_ADD_COMMANDS));
889 m_pCommands->SetDragDropMode( DragDropMode::APP_COPY );
891 get(m_pCancelButton, "close");
892 get(m_pDialogDescription, "helptoolbar");
893 get(m_pOKButton, "add");
895 else
897 get(m_pCancelButton, "cancel");
898 get(m_pDialogDescription, "helpmacro");
899 get(m_pOKButton, "ok");
901 m_pCancelButton->Show();
902 m_pDialogDescription->Show();
903 m_pOKButton->Show();
905 get(m_pCategories, "categories");
906 m_pCategories->SetFunctionListBox(m_pCommands);
907 m_pCategories->Init(bShowSlots, xFrame);
909 m_pCategories->SetSelectHdl(
910 LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
911 m_pCommands->SetSelectHdl( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
912 m_pCommands->SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
914 m_pOKButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
915 m_pCancelButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
917 m_sDefaultDesc = m_pDescriptionText->GetText();
919 UpdateUI();
922 SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
924 disposeOnce();
927 void SvxScriptSelectorDialog::dispose()
929 m_pDialogDescription.clear();
930 m_pCategories.clear();
931 m_pCommands.clear();
932 m_pOKButton.clear();
933 m_pCancelButton.clear();
934 m_pDescriptionText.clear();
935 ModelessDialog::dispose();
938 IMPL_LINK( SvxScriptSelectorDialog, SelectHdl, Control*, pCtrl )
940 if (pCtrl == m_pCategories)
942 m_pCategories->GroupSelected();
944 else if (pCtrl == m_pCommands)
946 m_pCommands->FunctionSelected();
948 UpdateUI();
949 return 0;
952 IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl )
954 (void)pCtrl;
955 if (m_pOKButton->IsEnabled())
956 return ClickHdl(m_pOKButton);
957 return 0;
960 // Check if command is selected and enable the OK button accordingly
961 // Grab the help text for this id if available and update the description field
962 void
963 SvxScriptSelectorDialog::UpdateUI()
965 OUString url = GetScriptURL();
966 if ( url != NULL && !url.isEmpty() )
968 OUString sMessage =
969 m_pCommands->GetHelpText(m_pCommands->FirstSelected());
970 m_pDescriptionText->SetText(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
972 m_pOKButton->Enable( true );
974 else
976 m_pDescriptionText->SetText(m_sDefaultDesc);
977 m_pOKButton->Enable( false );
981 IMPL_LINK( SvxScriptSelectorDialog, ClickHdl, Button *, pButton )
983 if (pButton == m_pCancelButton)
985 // If we are displaying Slot API commands then the dialog is being
986 // run from Tools/Configure and we should not close it, just hide it
987 if ( !m_bShowSlots )
989 EndDialog( RET_CANCEL );
991 else
993 Hide();
996 else if (pButton == m_pOKButton)
998 GetAddHdl().Call( this );
1000 // If we are displaying Slot API commands then this the dialog is being
1001 // run from Tools/Configure and we should not close it
1002 if ( !m_bShowSlots )
1004 EndDialog( RET_OK );
1006 else
1008 // Select the next entry in the list if possible
1009 SvTreeListEntry* current = m_pCommands->FirstSelected();
1010 SvTreeListEntry* next = SvTreeListBox::NextSibling( current );
1012 if ( next != NULL )
1014 m_pCommands->Select( next );
1019 return 0;
1022 void
1023 SvxScriptSelectorDialog::SetRunLabel()
1025 m_pOKButton->SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_RUN));
1028 void
1029 SvxScriptSelectorDialog::SetDialogDescription( const OUString& rDescription )
1031 m_pDialogDescription->SetText( rDescription );
1034 OUString
1035 SvxScriptSelectorDialog::GetScriptURL() const
1037 OUString result;
1039 SvTreeListEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->m_pCommands->GetLastSelectedEntry();
1040 if ( pEntry )
1042 SvxGroupInfo_Impl *pData = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
1043 if ( ( pData->nKind == SVX_CFGFUNCTION_SLOT )
1044 || ( pData->nKind == SVX_CFGFUNCTION_SCRIPT )
1047 result = pData->sURL;
1051 return result;
1054 OUString
1055 SvxScriptSelectorDialog::GetSelectedDisplayName()
1057 return m_pCommands->GetEntryText( m_pCommands->GetLastSelectedEntry() );
1060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */