Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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 "cfg.hxx"
27 : #include <dialmgr.hxx>
28 : #include <svx/fmresids.hrc>
29 : #include <svx/dialmgr.hxx>
30 : #include <cuires.hrc>
31 : #include <sfx2/app.hxx>
32 : #include <sfx2/msg.hxx>
33 : #include <sfx2/msgpool.hxx>
34 : #include <sfx2/minfitem.hxx>
35 : #include <sfx2/objsh.hxx>
36 : #include <sfx2/dispatch.hxx>
37 :
38 : #include <comphelper/documentinfo.hxx>
39 : #include <comphelper/processfactory.hxx>
40 :
41 : #include <com/sun/star/beans/XPropertySet.hpp>
42 : #include <com/sun/star/container/XChild.hpp>
43 : #include <com/sun/star/container/XEnumerationAccess.hpp>
44 : #include <com/sun/star/container/XEnumeration.hpp>
45 : #include <com/sun/star/document/XEmbeddedScripts.hpp>
46 : #include <com/sun/star/document/XScriptInvocationContext.hpp>
47 : #include <com/sun/star/frame/ModuleManager.hpp>
48 : #include <com/sun/star/frame/Desktop.hpp>
49 : #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
50 : #include <com/sun/star/frame/DispatchInformation.hpp>
51 : #include <com/sun/star/frame/theUICommandDescription.hpp>
52 : #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
53 : #include <com/sun/star/script/provider/XScriptProvider.hpp>
54 : #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
55 : #include <com/sun/star/script/browse/XBrowseNode.hpp>
56 : #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
57 : #include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
58 : #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
59 : #include <com/sun/star/ui/theUICategoryDescription.hpp>
60 :
61 :
62 : using namespace ::com::sun::star;
63 : using namespace ::com::sun::star::uno;
64 : using namespace ::com::sun::star::script;
65 : using namespace ::com::sun::star::frame;
66 : using namespace ::com::sun::star::document;
67 : using namespace ::com::sun::star::container;
68 :
69 : #include <svtools/imagemgr.hxx>
70 : #include "svtools/treelistentry.hxx"
71 : #include <tools/urlobj.hxx>
72 : #include <tools/diagnose_ex.h>
73 :
74 : /*
75 : * The implementations of SvxConfigFunctionListBox and
76 : * SvxConfigGroupListBox are copied from sfx2/source/dialog/cfg.cxx
77 : */
78 0 : SvxConfigFunctionListBox::SvxConfigFunctionListBox(vcl::Window* pParent, WinBits nStyle)
79 : : SvTreeListBox(pParent, nStyle | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT | WB_TABSTOP)
80 : , pCurEntry(0)
81 0 : , m_pDraggingEntry(0)
82 : {
83 0 : GetModel()->SetSortMode( SortAscending );
84 :
85 : // Timer for the BallonHelp
86 0 : aTimer.SetTimeout( 200 );
87 : aTimer.SetTimeoutHdl(
88 0 : LINK( this, SvxConfigFunctionListBox, TimerHdl ) );
89 0 : }
90 :
91 0 : VCL_BUILDER_DECL_FACTORY(SvxConfigFunctionListBox)
92 : {
93 0 : WinBits nWinBits = WB_TABSTOP;
94 :
95 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
96 0 : if (!sBorder.isEmpty())
97 0 : nWinBits |= WB_BORDER;
98 :
99 0 : rRet = VclPtr<SvxConfigFunctionListBox>::Create(pParent, nWinBits);
100 0 : }
101 :
102 0 : SvxConfigFunctionListBox::~SvxConfigFunctionListBox()
103 : {
104 0 : disposeOnce();
105 0 : }
106 :
107 0 : void SvxConfigFunctionListBox::dispose()
108 : {
109 0 : ClearAll();
110 0 : SvTreeListBox::dispose();
111 0 : }
112 :
113 0 : SvTreeListEntry* SvxConfigFunctionListBox::GetLastSelectedEntry()
114 : {
115 0 : if ( m_pDraggingEntry != NULL )
116 : {
117 0 : return m_pDraggingEntry;
118 : }
119 : else
120 : {
121 0 : return FirstSelected();
122 : }
123 : }
124 :
125 0 : void SvxConfigFunctionListBox::MouseMove( const MouseEvent& rMEvt )
126 : {
127 0 : Point aMousePos = rMEvt.GetPosPixel();
128 0 : pCurEntry = GetCurEntry();
129 :
130 0 : if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
131 0 : aTimer.Start();
132 : else
133 : {
134 0 : Help::ShowBalloon( this, aMousePos, OUString() );
135 0 : aTimer.Stop();
136 : }
137 0 : }
138 :
139 :
140 0 : IMPL_LINK_NOARG_TYPED(SvxConfigFunctionListBox, TimerHdl, Timer *, void)
141 : {
142 0 : aTimer.Stop();
143 0 : Point aMousePos = GetPointerPosPixel();
144 0 : SvTreeListEntry *pEntry = GetCurEntry();
145 0 : if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
146 0 : Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) );
147 0 : }
148 :
149 0 : void SvxConfigFunctionListBox::ClearAll()
150 : {
151 0 : aArr.clear();
152 0 : Clear();
153 0 : }
154 :
155 0 : OUString SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry *pEntry )
156 : {
157 : SvxGroupInfo_Impl *pInfo =
158 0 : pEntry ? static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData()): 0;
159 :
160 0 : if ( pInfo )
161 : {
162 0 : if ( pInfo->nKind == SVX_CFGFUNCTION_SLOT )
163 : {
164 0 : OUString aCmdURL( pInfo->sURL );
165 :
166 0 : OUString aHelpText = Application::GetHelp()->GetHelpText( aCmdURL, this );
167 :
168 0 : return aHelpText;
169 : }
170 0 : else if ( pInfo->nKind == SVX_CFGFUNCTION_SCRIPT )
171 : {
172 0 : return pInfo->sHelpText;
173 : }
174 : }
175 :
176 0 : return OUString();
177 : }
178 :
179 0 : void SvxConfigFunctionListBox::FunctionSelected()
180 : {
181 0 : Help::ShowBalloon( this, Point(), OUString() );
182 0 : }
183 :
184 : // drag and drop support
185 0 : DragDropMode SvxConfigFunctionListBox::NotifyStartDrag(
186 : TransferDataContainer& /*aTransferDataContainer*/, SvTreeListEntry* pEntry )
187 : {
188 0 : m_pDraggingEntry = pEntry;
189 0 : return GetDragDropMode();
190 : }
191 :
192 0 : void SvxConfigFunctionListBox::DragFinished( sal_Int8 /*nDropAction*/ )
193 : {
194 0 : m_pDraggingEntry = NULL;
195 0 : }
196 :
197 : sal_Int8
198 0 : SvxConfigFunctionListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
199 : {
200 0 : return DND_ACTION_NONE;
201 : }
202 :
203 0 : SvxConfigGroupListBox::SvxConfigGroupListBox(vcl::Window* pParent, WinBits nStyle)
204 : : SvTreeListBox(pParent, nStyle |
205 : WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_TABSTOP)
206 : , m_bShowSlots(false)
207 : , pFunctionListBox(NULL)
208 : , m_pImageProvider(NULL)
209 0 : , m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK))
210 0 : , m_libImage(CUI_RES(RID_CUIIMG_LIB))
211 0 : , m_macImage(CUI_RES(RID_CUIIMG_MACRO))
212 0 : , m_docImage(CUI_RES(RID_CUIIMG_DOC))
213 0 : , m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS))
214 0 : , m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS))
215 : {
216 0 : ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
217 :
218 : SetNodeBitmaps(
219 : aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
220 : aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE )
221 0 : );
222 0 : }
223 :
224 0 : VCL_BUILDER_DECL_FACTORY(SvxConfigGroupListBox)
225 : {
226 0 : WinBits nWinBits = WB_TABSTOP;
227 :
228 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
229 0 : if (!sBorder.isEmpty())
230 0 : nWinBits |= WB_BORDER;
231 :
232 0 : rRet = VclPtr<SvxConfigGroupListBox>::Create(pParent, nWinBits);
233 0 : }
234 :
235 0 : SvxConfigGroupListBox::~SvxConfigGroupListBox()
236 : {
237 0 : disposeOnce();
238 0 : }
239 :
240 0 : void SvxConfigGroupListBox::dispose()
241 : {
242 0 : ClearAll();
243 0 : pFunctionListBox.clear();
244 0 : SvTreeListBox::dispose();
245 0 : }
246 :
247 0 : void SvxConfigGroupListBox::ClearAll()
248 : {
249 0 : aArr.clear();
250 0 : Clear();
251 0 : }
252 :
253 :
254 : namespace
255 : {
256 :
257 : /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
258 : component by implementing XScriptInvocationContext.
259 : @return
260 : the model which supports the embedded scripts, or <NULL/> if it cannot find such a
261 : model
262 : */
263 0 : static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
264 : {
265 0 : Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
266 0 : if ( !xScripts.is() )
267 : {
268 0 : Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
269 0 : if ( xContext.is() )
270 0 : xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
271 : }
272 :
273 0 : return Reference< XModel >( xScripts, UNO_QUERY );
274 : }
275 :
276 :
277 0 : static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
278 : {
279 0 : Reference< XModel > xDocument;
280 :
281 : // examine our associated frame
282 : try
283 : {
284 : OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
285 0 : if ( _rxFrame.is() )
286 : {
287 : // first try the model in the frame
288 0 : Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
289 0 : xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
290 :
291 0 : if ( !xDocument.is() )
292 : {
293 : // if there is no suitable document in the frame, try the controller
294 0 : xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
295 0 : }
296 : }
297 : }
298 0 : catch( const Exception& )
299 : {
300 : DBG_UNHANDLED_EXCEPTION();
301 : }
302 :
303 0 : return xDocument;
304 : }
305 : }
306 :
307 0 : void SvxConfigGroupListBox::fillScriptList( const Reference< browse::XBrowseNode >& _rxRootNode, SvTreeListEntry* _pParentEntry, bool _bCheapChildrenOnDemand )
308 : {
309 : OSL_PRECOND( _rxRootNode.is(), "SvxConfigGroupListBox::fillScriptList: invalid root node!" );
310 0 : if ( !_rxRootNode.is() )
311 0 : return;
312 :
313 : try
314 : {
315 0 : if ( _rxRootNode->hasChildNodes() )
316 : {
317 : Sequence< Reference< browse::XBrowseNode > > children =
318 0 : _rxRootNode->getChildNodes();
319 :
320 0 : bool bIsRootNode = _rxRootNode->getName() == "Root";
321 :
322 : /* To mimic current starbasic behaviour we
323 : need to make sure that only the current document
324 : is displayed in the config tree. Tests below
325 : set the bDisplay flag to sal_False if the current
326 : node is a first level child of the Root and is NOT
327 : either the current document, user or share */
328 0 : OUString sCurrentDocTitle;
329 0 : Reference< XModel > xWorkingDocument = lcl_getScriptableDocument_nothrow( m_xFrame );
330 0 : if ( xWorkingDocument.is() )
331 : {
332 0 : sCurrentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xWorkingDocument );
333 : }
334 :
335 0 : for ( long n = 0; n < children.getLength(); ++n )
336 : {
337 0 : Reference< browse::XBrowseNode >& theChild = children[n];
338 : //#139111# some crash reports show that it might be unset
339 0 : if ( !theChild.is() )
340 0 : continue;
341 0 : OUString sUIName = theChild->getName();
342 0 : bool bDisplay = true;
343 :
344 0 : if ( bIsRootNode
345 0 : || ( m_bShowSlots && _pParentEntry && ( GetModel()->GetDepth( _pParentEntry ) == 0 ) )
346 : // if we show slots (as in the customize dialog)
347 : // then the user & share are added at depth=1
348 : )
349 : {
350 0 : if ( sUIName == "user" )
351 : {
352 0 : sUIName = m_sMyMacros;
353 0 : bIsRootNode = true;
354 : }
355 0 : else if ( sUIName == "share" )
356 : {
357 0 : sUIName = m_sProdMacros;
358 0 : bIsRootNode = true;
359 : }
360 0 : else if ( !sUIName.equals( sCurrentDocTitle ) )
361 : {
362 0 : bDisplay = false;
363 : }
364 : }
365 :
366 0 : if ( !bDisplay )
367 0 : continue;
368 :
369 0 : if ( children[n]->getType() == browse::BrowseNodeTypes::SCRIPT )
370 0 : continue;
371 :
372 0 : SvTreeListEntry* pNewEntry = InsertEntry( sUIName, _pParentEntry );
373 :
374 0 : Image aImage = GetImage( theChild, comphelper::getProcessComponentContext(), bIsRootNode );
375 0 : SetExpandedEntryBmp( pNewEntry, aImage );
376 0 : SetCollapsedEntryBmp( pNewEntry, aImage );
377 :
378 : SvxGroupInfo_Impl* pInfo =
379 0 : new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, theChild );
380 0 : pNewEntry->SetUserData( pInfo );
381 0 : aArr.push_back( pInfo );
382 :
383 0 : if ( _bCheapChildrenOnDemand )
384 : {
385 : /* i30923 - Would be nice if there was a better
386 : * way to determine if a basic lib had children
387 : * without having to ask for them (which forces
388 : * the library to be loaded */
389 0 : pNewEntry->EnableChildrenOnDemand( true );
390 : }
391 : else
392 : {
393 : // if there are granchildren we're interested in, display the '+' before
394 : // the entry, but do not yet expand
395 : Sequence< Reference< browse::XBrowseNode > > grandchildren =
396 0 : children[n]->getChildNodes();
397 :
398 0 : for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
399 : {
400 0 : if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
401 : {
402 0 : pNewEntry->EnableChildrenOnDemand( true );
403 0 : break;
404 : }
405 0 : }
406 : }
407 0 : }
408 : }
409 : }
410 0 : catch (const Exception&)
411 : {
412 : DBG_UNHANDLED_EXCEPTION();
413 : }
414 : }
415 :
416 0 : void SvxConfigGroupListBox::Init(bool bShowSlots, const Reference< frame::XFrame >& xFrame)
417 : {
418 0 : m_bShowSlots = bShowSlots;
419 0 : m_xFrame.set(xFrame);
420 :
421 0 : SetUpdateMode(false);
422 0 : ClearAll();
423 :
424 : Reference< XComponentContext > xContext(
425 0 : comphelper::getProcessComponentContext() );
426 :
427 : // are we showing builtin commands?
428 0 : if ( m_bShowSlots && m_xFrame.is() )
429 : {
430 : Reference< frame::XDispatchInformationProvider > xDIP(
431 0 : m_xFrame, UNO_QUERY );
432 :
433 0 : Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
434 :
435 0 : OUString aModuleId;
436 : try{
437 0 : aModuleId = xModuleManager->identify( m_xFrame );
438 0 : }catch(const uno::Exception&)
439 0 : { aModuleId.clear(); }
440 :
441 : Reference< container::XNameAccess > const xNameAccess(
442 0 : frame::theUICommandDescription::get(xContext) );
443 0 : xNameAccess->getByName( aModuleId ) >>= m_xModuleCommands;
444 :
445 : Reference< container::XNameAccess > xAllCategories =
446 0 : ui::theUICategoryDescription::get( xContext );
447 :
448 0 : Reference< container::XNameAccess > xModuleCategories;
449 0 : if ( !aModuleId.isEmpty() )
450 : {
451 : try
452 : {
453 0 : xModuleCategories = Reference< container::XNameAccess >(
454 0 : xAllCategories->getByName( aModuleId ), UNO_QUERY );
455 : }
456 0 : catch ( container::NoSuchElementException& )
457 : {
458 : }
459 : }
460 :
461 0 : if ( !xModuleCategories.is() )
462 : {
463 0 : xModuleCategories = xAllCategories;
464 : }
465 :
466 0 : if ( xModuleCategories.is() )
467 : {
468 : Sequence< sal_Int16 > gids =
469 0 : xDIP->getSupportedCommandGroups();
470 :
471 0 : for ( sal_Int32 i = 0; i < gids.getLength(); ++i )
472 : {
473 0 : Sequence< frame::DispatchInformation > commands;
474 : try
475 : {
476 0 : commands =
477 0 : xDIP->getConfigurableDispatchInformation( gids[i] );
478 : }
479 0 : catch ( container::NoSuchElementException& )
480 : {
481 0 : continue;
482 : }
483 :
484 0 : if ( commands.getLength() == 0 )
485 : {
486 0 : continue;
487 : }
488 :
489 0 : sal_Int32 gid = gids[i];
490 0 : OUString idx = OUString::number( gid );
491 0 : OUString group = idx;
492 : try
493 : {
494 0 : xModuleCategories->getByName( idx ) >>= group;
495 : }
496 0 : catch ( container::NoSuchElementException& )
497 : {
498 : }
499 :
500 0 : SvTreeListEntry *pEntry = InsertEntry( group, NULL );
501 :
502 : SvxGroupInfo_Impl *pInfo =
503 0 : new SvxGroupInfo_Impl( SVX_CFGGROUP_FUNCTION, gids[i] );
504 0 : aArr.push_back( pInfo );
505 :
506 0 : pEntry->SetUserData( pInfo );
507 0 : }
508 0 : }
509 : }
510 :
511 : // Add Scripting Framework entries
512 0 : Reference< browse::XBrowseNode > rootNode;
513 :
514 : try
515 : {
516 0 : Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( xContext );
517 0 : rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
518 : }
519 0 : catch( const Exception& )
520 : {
521 : DBG_UNHANDLED_EXCEPTION();
522 : }
523 :
524 0 : if ( rootNode.is() )
525 : {
526 0 : if ( m_bShowSlots )
527 : {
528 : SvxGroupInfo_Impl *pInfo =
529 0 : new SvxGroupInfo_Impl( SVX_CFGGROUP_SCRIPTCONTAINER, 0, rootNode );
530 :
531 0 : OUString aTitle = CUI_RESSTR(RID_SVXSTR_PRODMACROS);
532 :
533 0 : SvTreeListEntry *pNewEntry = InsertEntry( aTitle, NULL );
534 0 : pNewEntry->SetUserData( pInfo );
535 0 : pNewEntry->EnableChildrenOnDemand( true );
536 0 : aArr.push_back( pInfo );
537 : }
538 : else
539 : {
540 0 : fillScriptList( rootNode, NULL, false );
541 : }
542 : }
543 0 : MakeVisible( GetEntry( 0,0 ) );
544 0 : SetUpdateMode( true );
545 0 : }
546 :
547 0 : Image SvxConfigGroupListBox::GetImage(
548 : Reference< browse::XBrowseNode > node,
549 : Reference< XComponentContext > xCtx,
550 : bool bIsRootNode
551 : )
552 : {
553 0 : Image aImage;
554 0 : if ( bIsRootNode )
555 : {
556 0 : if ( node->getName() == "user" || node->getName() == "share" )
557 : {
558 0 : aImage = m_hdImage;
559 : }
560 : else
561 : {
562 0 : OUString factoryURL;
563 0 : OUString nodeName = node->getName();
564 0 : Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
565 0 : if ( xDocumentModel.is() )
566 : {
567 0 : Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
568 : // get the long name of the document:
569 0 : OUString appModule( xModuleManager->identify(
570 0 : xDocumentModel ) );
571 0 : Sequence<beans::PropertyValue> moduleDescr;
572 0 : Any aAny = xModuleManager->getByName(appModule);
573 0 : if( !( aAny >>= moduleDescr ) )
574 : {
575 0 : throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
576 : }
577 : beans::PropertyValue const * pmoduleDescr =
578 0 : moduleDescr.getConstArray();
579 0 : for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
580 : {
581 0 : if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
582 : {
583 0 : pmoduleDescr[ pos ].Value >>= factoryURL;
584 0 : break;
585 : }
586 0 : }
587 : }
588 0 : if( !factoryURL.isEmpty() )
589 : {
590 0 : aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
591 : }
592 : else
593 : {
594 0 : aImage = m_docImage;
595 0 : }
596 : }
597 : }
598 : else
599 : {
600 0 : if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
601 0 : aImage = m_macImage;
602 : else
603 0 : aImage = m_libImage;
604 : }
605 0 : return aImage;
606 : }
607 :
608 : Reference< XInterface >
609 0 : SvxConfigGroupListBox::getDocumentModel(
610 : Reference< XComponentContext >& xCtx, OUString& docName )
611 : {
612 0 : Reference< XInterface > xModel;
613 0 : Reference< frame::XDesktop2 > desktop = Desktop::create(xCtx);
614 :
615 : Reference< container::XEnumerationAccess > componentsAccess =
616 0 : desktop->getComponents();
617 : Reference< container::XEnumeration > components =
618 0 : componentsAccess->createEnumeration();
619 0 : while (components->hasMoreElements())
620 : {
621 : Reference< frame::XModel > model(
622 0 : components->nextElement(), UNO_QUERY );
623 0 : if ( model.is() )
624 : {
625 0 : OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
626 0 : if( sTdocUrl.equals( docName ) )
627 : {
628 0 : xModel = model;
629 0 : break;
630 0 : }
631 : }
632 0 : }
633 0 : return xModel;
634 : }
635 :
636 0 : void SvxConfigGroupListBox::GroupSelected()
637 : {
638 0 : SvTreeListEntry *pEntry = FirstSelected();
639 0 : SvxGroupInfo_Impl *pInfo = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
640 0 : pFunctionListBox->SetUpdateMode(false);
641 0 : pFunctionListBox->ClearAll();
642 0 : if ( pInfo->nKind != SVX_CFGGROUP_FUNCTION &&
643 0 : pInfo->nKind != SVX_CFGGROUP_SCRIPTCONTAINER )
644 : {
645 0 : pFunctionListBox->SetUpdateMode(true);
646 0 : return;
647 : }
648 :
649 0 : switch ( pInfo->nKind )
650 : {
651 : case SVX_CFGGROUP_FUNCTION :
652 : {
653 0 : SvTreeListEntry *_pEntry = FirstSelected();
654 0 : if ( _pEntry != NULL )
655 : {
656 : SvxGroupInfo_Impl *_pInfo =
657 0 : static_cast<SvxGroupInfo_Impl*>(_pEntry->GetUserData());
658 :
659 : Reference< frame::XDispatchInformationProvider > xDIP(
660 0 : m_xFrame, UNO_QUERY );
661 :
662 0 : Sequence< frame::DispatchInformation > commands;
663 : try
664 : {
665 0 : commands = xDIP->getConfigurableDispatchInformation(
666 0 : _pInfo->nOrd );
667 : }
668 0 : catch ( container::NoSuchElementException& )
669 : {
670 : }
671 :
672 0 : for ( sal_Int32 i = 0; i < commands.getLength(); ++i )
673 : {
674 0 : if ( commands[i].Command.isEmpty() )
675 : {
676 0 : continue;
677 : }
678 :
679 0 : Image aImage;
680 :
681 0 : OUString aCmdURL( commands[i].Command );
682 :
683 0 : if ( m_pImageProvider )
684 : {
685 0 : aImage = m_pImageProvider->GetImage( aCmdURL );
686 : }
687 :
688 0 : OUString aLabel;
689 : try
690 : {
691 0 : Any a = m_xModuleCommands->getByName( aCmdURL );
692 0 : Sequence< beans::PropertyValue > aPropSeq;
693 :
694 0 : if ( a >>= aPropSeq )
695 : {
696 0 : for ( sal_Int32 k = 0; k < aPropSeq.getLength(); ++k )
697 : {
698 0 : if ( aPropSeq[k].Name == "Name" )
699 : {
700 0 : aPropSeq[k].Value >>= aLabel;
701 0 : break;
702 : }
703 : }
704 0 : }
705 : }
706 0 : catch ( container::NoSuchElementException& )
707 : {
708 : }
709 :
710 0 : if ( aLabel.isEmpty() )
711 : {
712 0 : aLabel = commands[i].Command;
713 : }
714 :
715 0 : SvTreeListEntry* pFuncEntry = NULL;
716 0 : if ( !!aImage )
717 : {
718 0 : pFuncEntry = pFunctionListBox->InsertEntry(
719 0 : aLabel, aImage, aImage );
720 : }
721 : else
722 : {
723 0 : pFuncEntry = pFunctionListBox->InsertEntry(
724 0 : aLabel, NULL );
725 : }
726 :
727 : SvxGroupInfo_Impl *_pGroupInfo = new SvxGroupInfo_Impl(
728 0 : SVX_CFGFUNCTION_SLOT, 123, aCmdURL, OUString() );
729 :
730 0 : pFunctionListBox->aArr.push_back( _pGroupInfo );
731 :
732 0 : pFuncEntry->SetUserData( _pGroupInfo );
733 0 : }
734 : }
735 0 : break;
736 : }
737 :
738 : case SVX_CFGGROUP_SCRIPTCONTAINER:
739 : {
740 0 : Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode );
741 :
742 : try {
743 0 : if ( rootNode->hasChildNodes() )
744 : {
745 : Sequence< Reference< browse::XBrowseNode > > children =
746 0 : rootNode->getChildNodes();
747 :
748 0 : for ( sal_Int32 n = 0; n < children.getLength(); ++n )
749 : {
750 0 : if (!children[n].is())
751 0 : continue;
752 0 : if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
753 : {
754 0 : OUString uri;
755 0 : OUString description;
756 :
757 0 : Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
758 0 : if (!xPropSet.is())
759 : {
760 0 : continue;
761 : }
762 :
763 0 : Any value = xPropSet->getPropertyValue(
764 0 : OUString("URI"));
765 0 : value >>= uri;
766 :
767 : try
768 : {
769 0 : value = xPropSet->getPropertyValue(
770 0 : OUString("Description"));
771 0 : value >>= description;
772 : }
773 0 : catch (Exception &) {
774 : // do nothing, the description will be empty
775 : }
776 :
777 : SvxGroupInfo_Impl* _pGroupInfo =
778 : new SvxGroupInfo_Impl(
779 0 : SVX_CFGFUNCTION_SCRIPT, 123, uri, description );
780 :
781 0 : Image aImage = GetImage( children[n], Reference< XComponentContext >(), false );
782 : SvTreeListEntry* pNewEntry =
783 0 : pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
784 0 : pFunctionListBox->SetExpandedEntryBmp( pNewEntry, aImage );
785 0 : pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage );
786 :
787 0 : pNewEntry->SetUserData( _pGroupInfo );
788 :
789 0 : pFunctionListBox->aArr.push_back( _pGroupInfo );
790 :
791 : }
792 0 : }
793 : }
794 : }
795 0 : catch (const Exception&)
796 : {
797 : DBG_UNHANDLED_EXCEPTION();
798 : }
799 0 : break;
800 : }
801 :
802 : default:
803 : {
804 0 : return;
805 : }
806 : }
807 :
808 0 : if ( pFunctionListBox->GetEntryCount() )
809 0 : pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
810 :
811 0 : pFunctionListBox->SetUpdateMode(true);
812 : }
813 :
814 0 : bool SvxConfigGroupListBox::Expand( SvTreeListEntry* pParent )
815 : {
816 0 : bool bRet = SvTreeListBox::Expand( pParent );
817 0 : if ( bRet )
818 : {
819 0 : sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
820 :
821 0 : sal_uLong nChildCount = GetVisibleChildCount( pParent );
822 :
823 0 : if ( nChildCount+1 > nEntries )
824 : {
825 0 : MakeVisible( pParent, true );
826 : }
827 : else
828 : {
829 0 : SvTreeListEntry *pEntry = GetFirstEntryInView();
830 0 : sal_uLong nParentPos = 0;
831 0 : while ( pEntry && pEntry != pParent )
832 : {
833 0 : ++nParentPos;
834 0 : pEntry = GetNextEntryInView( pEntry );
835 : }
836 :
837 0 : if ( nParentPos + nChildCount + 1 > nEntries )
838 0 : ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
839 : }
840 : }
841 :
842 0 : return bRet;
843 : }
844 :
845 0 : void SvxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
846 : {
847 0 : SvxGroupInfo_Impl *pInfo = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
848 0 : pInfo->bWasOpened = true;
849 0 : switch ( pInfo->nKind )
850 : {
851 : case SVX_CFGGROUP_SCRIPTCONTAINER:
852 : {
853 0 : if ( !GetChildCount( pEntry ) )
854 : {
855 0 : Reference< browse::XBrowseNode > rootNode( pInfo->xBrowseNode ) ;
856 0 : fillScriptList( rootNode, pEntry, true /* i30923 */ );
857 : }
858 0 : break;
859 : }
860 :
861 : default:
862 : OSL_FAIL( "Falscher Gruppentyp!" );
863 0 : break;
864 : }
865 0 : }
866 :
867 : /*
868 : * Implementation of SvxScriptSelectorDialog
869 : *
870 : * This dialog is used for selecting Slot API commands
871 : * and Scripting Framework Scripts.
872 : */
873 :
874 0 : SvxScriptSelectorDialog::SvxScriptSelectorDialog(
875 : vcl::Window* pParent, bool bShowSlots, const Reference< frame::XFrame >& xFrame)
876 : : ModelessDialog(pParent, "MacroSelectorDialog", "cui/ui/macroselectordialog.ui")
877 0 : , m_bShowSlots(bShowSlots)
878 : {
879 0 : get<FixedText>("libraryft")->Show(!m_bShowSlots);
880 0 : get<FixedText>("categoryft")->Show(m_bShowSlots);
881 0 : get<FixedText>("macronameft")->Show(!m_bShowSlots);
882 0 : get<FixedText>("commandsft")->Show(m_bShowSlots);
883 0 : get(m_pDescriptionText, "description");
884 0 : get(m_pCommands, "commands");
885 0 : if (m_bShowSlots)
886 : {
887 : // If we are showing Slot API commands update labels in the UI, and
888 : // enable drag'n'drop
889 0 : SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_ADD_COMMANDS));
890 0 : m_pCommands->SetDragDropMode( DragDropMode::APP_COPY );
891 :
892 0 : get(m_pCancelButton, "close");
893 0 : get(m_pDialogDescription, "helptoolbar");
894 0 : get(m_pOKButton, "add");
895 : }
896 : else
897 : {
898 0 : get(m_pCancelButton, "cancel");
899 0 : get(m_pDialogDescription, "helpmacro");
900 0 : get(m_pOKButton, "ok");
901 : }
902 0 : m_pCancelButton->Show();
903 0 : m_pDialogDescription->Show();
904 0 : m_pOKButton->Show();
905 :
906 0 : get(m_pCategories, "categories");
907 0 : m_pCategories->SetFunctionListBox(m_pCommands);
908 0 : m_pCategories->Init(bShowSlots, xFrame);
909 :
910 0 : m_pCategories->SetSelectHdl(
911 0 : LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
912 0 : m_pCommands->SetSelectHdl( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
913 0 : m_pCommands->SetDoubleClickHdl( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
914 :
915 0 : m_pOKButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
916 0 : m_pCancelButton->SetClickHdl( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
917 :
918 0 : m_sDefaultDesc = m_pDescriptionText->GetText();
919 :
920 0 : UpdateUI();
921 0 : }
922 :
923 0 : SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
924 : {
925 0 : disposeOnce();
926 0 : }
927 :
928 0 : void SvxScriptSelectorDialog::dispose()
929 : {
930 0 : m_pDialogDescription.clear();
931 0 : m_pCategories.clear();
932 0 : m_pCommands.clear();
933 0 : m_pOKButton.clear();
934 0 : m_pCancelButton.clear();
935 0 : m_pDescriptionText.clear();
936 0 : ModelessDialog::dispose();
937 0 : }
938 :
939 0 : IMPL_LINK( SvxScriptSelectorDialog, SelectHdl, Control*, pCtrl )
940 : {
941 0 : if (pCtrl == m_pCategories)
942 : {
943 0 : m_pCategories->GroupSelected();
944 : }
945 0 : else if (pCtrl == m_pCommands)
946 : {
947 0 : m_pCommands->FunctionSelected();
948 : }
949 0 : UpdateUI();
950 0 : return 0;
951 : }
952 :
953 0 : IMPL_LINK( SvxScriptSelectorDialog, FunctionDoubleClickHdl, Control*, pCtrl )
954 : {
955 : (void)pCtrl;
956 0 : if (m_pOKButton->IsEnabled())
957 0 : return ClickHdl(m_pOKButton);
958 0 : return 0;
959 : }
960 :
961 : // Check if command is selected and enable the OK button accordingly
962 : // Grab the help text for this id if available and update the description field
963 : void
964 0 : SvxScriptSelectorDialog::UpdateUI()
965 : {
966 0 : OUString url = GetScriptURL();
967 0 : if ( url != NULL && !url.isEmpty() )
968 : {
969 : OUString sMessage =
970 0 : m_pCommands->GetHelpText(m_pCommands->FirstSelected());
971 0 : m_pDescriptionText->SetText(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
972 :
973 0 : m_pOKButton->Enable( true );
974 : }
975 : else
976 : {
977 0 : m_pDescriptionText->SetText(m_sDefaultDesc);
978 0 : m_pOKButton->Enable( false );
979 0 : }
980 0 : }
981 :
982 0 : IMPL_LINK( SvxScriptSelectorDialog, ClickHdl, Button *, pButton )
983 : {
984 0 : if (pButton == m_pCancelButton)
985 : {
986 : // If we are displaying Slot API commands then the dialog is being
987 : // run from Tools/Configure and we should not close it, just hide it
988 0 : if ( !m_bShowSlots )
989 : {
990 0 : EndDialog( RET_CANCEL );
991 : }
992 : else
993 : {
994 0 : Hide();
995 : }
996 : }
997 0 : else if (pButton == m_pOKButton)
998 : {
999 0 : GetAddHdl().Call( this );
1000 :
1001 : // If we are displaying Slot API commands then this the dialog is being
1002 : // run from Tools/Configure and we should not close it
1003 0 : if ( !m_bShowSlots )
1004 : {
1005 0 : EndDialog( RET_OK );
1006 : }
1007 : else
1008 : {
1009 : // Select the next entry in the list if possible
1010 0 : SvTreeListEntry* current = m_pCommands->FirstSelected();
1011 0 : SvTreeListEntry* next = SvTreeListBox::NextSibling( current );
1012 :
1013 0 : if ( next != NULL )
1014 : {
1015 0 : m_pCommands->Select( next );
1016 : }
1017 : }
1018 : }
1019 :
1020 0 : return 0;
1021 : }
1022 :
1023 : void
1024 0 : SvxScriptSelectorDialog::SetRunLabel()
1025 : {
1026 0 : m_pOKButton->SetText(CUI_RESSTR(RID_SVXSTR_SELECTOR_RUN));
1027 0 : }
1028 :
1029 : void
1030 0 : SvxScriptSelectorDialog::SetDialogDescription( const OUString& rDescription )
1031 : {
1032 0 : m_pDialogDescription->SetText( rDescription );
1033 0 : }
1034 :
1035 : OUString
1036 0 : SvxScriptSelectorDialog::GetScriptURL() const
1037 : {
1038 0 : OUString result;
1039 :
1040 0 : SvTreeListEntry *pEntry = const_cast< SvxScriptSelectorDialog* >( this )->m_pCommands->GetLastSelectedEntry();
1041 0 : if ( pEntry )
1042 : {
1043 0 : SvxGroupInfo_Impl *pData = static_cast<SvxGroupInfo_Impl*>(pEntry->GetUserData());
1044 0 : if ( ( pData->nKind == SVX_CFGFUNCTION_SLOT )
1045 0 : || ( pData->nKind == SVX_CFGFUNCTION_SCRIPT )
1046 : )
1047 : {
1048 0 : result = pData->sURL;
1049 : }
1050 : }
1051 :
1052 0 : return result;
1053 : }
1054 :
1055 : OUString
1056 0 : SvxScriptSelectorDialog::GetSelectedDisplayName()
1057 : {
1058 0 : return m_pCommands->GetEntryText( m_pCommands->GetLastSelectedEntry() );
1059 0 : }
1060 :
1061 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|