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 "uielement/uicommanddescription.hxx"
21 : #include <threadhelp/resetableguard.hxx>
22 : #include "services.h"
23 :
24 : #include "properties.h"
25 :
26 : #include "helper/mischelper.hxx"
27 :
28 : #include <com/sun/star/beans/PropertyValue.hpp>
29 : #include <com/sun/star/beans/XPropertySet.hpp>
30 : #include <com/sun/star/frame/ModuleManager.hpp>
31 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
32 : #include <com/sun/star/container/XNameAccess.hpp>
33 : #include <com/sun/star/container/XNameContainer.hpp>
34 : #include <com/sun/star/container/XContainer.hpp>
35 :
36 : #include <rtl/ustrbuf.hxx>
37 : #include <cppuhelper/implbase2.hxx>
38 : #include <unotools/configmgr.hxx>
39 : #include <tools/string.hxx>
40 :
41 : #include <vcl/mnemonic.hxx>
42 : #include <comphelper/sequence.hxx>
43 : #include <comphelper/string.hxx>
44 : #include <rtl/logfile.hxx>
45 :
46 : //_________________________________________________________________________________________________________________
47 : // Defines
48 : //_________________________________________________________________________________________________________________
49 :
50 : using namespace com::sun::star::uno;
51 : using namespace com::sun::star::lang;
52 : using namespace com::sun::star::beans;
53 : using namespace com::sun::star::configuration;
54 : using namespace com::sun::star::container;
55 : using namespace ::com::sun::star::frame;
56 :
57 : //_________________________________________________________________________________________________________________
58 : // Namespace
59 : //_________________________________________________________________________________________________________________
60 :
61 : struct ModuleToCommands
62 : {
63 : const char* pModuleId;
64 : const char* pCommands;
65 : };
66 :
67 : static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
68 : static const char CONFIGURATION_CMD_ELEMENT_ACCESS[] = "/UserInterface/Commands";
69 : static const char CONFIGURATION_POP_ELEMENT_ACCESS[] = "/UserInterface/Popups";
70 : static const char CONFIGURATION_PROPERTY_LABEL[] = "Label";
71 : static const char CONFIGURATION_PROPERTY_CONTEXT_LABEL[] = "ContextLabel";
72 :
73 : // Property names of the resulting Property Set
74 : static const char PROPSET_LABEL[] = "Label";
75 : static const char PROPSET_NAME[] = "Name";
76 : static const char PROPSET_POPUP[] = "Popup";
77 : static const char PROPSET_PROPERTIES[] = "Properties";
78 :
79 : // Special resource URLs to retrieve additional information
80 : static const char PRIVATE_RESOURCE_URL[] = "private:";
81 :
82 : const sal_Int32 COMMAND_PROPERTY_IMAGE = 1;
83 : const sal_Int32 COMMAND_PROPERTY_ROTATE = 2;
84 : const sal_Int32 COMMAND_PROPERTY_MIRROR = 4;
85 :
86 : namespace framework
87 : {
88 :
89 : //*****************************************************************************************************************
90 : // Configuration access class for PopupMenuControllerFactory implementation
91 : //*****************************************************************************************************************
92 :
93 : class ConfigurationAccess_UICommand : // Order is necessary for right initialization!
94 : private ThreadHelpBase ,
95 : public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
96 : {
97 : public:
98 : ConfigurationAccess_UICommand( const ::rtl::OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XComponentContext >& rxContext );
99 : virtual ~ConfigurationAccess_UICommand();
100 :
101 : // XNameAccess
102 : virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
103 : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
104 :
105 : virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
106 : throw (::com::sun::star::uno::RuntimeException);
107 :
108 : virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
109 : throw (::com::sun::star::uno::RuntimeException);
110 :
111 : // XElementAccess
112 : virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
113 : throw (::com::sun::star::uno::RuntimeException);
114 :
115 : virtual sal_Bool SAL_CALL hasElements()
116 : throw (::com::sun::star::uno::RuntimeException);
117 :
118 : // container.XContainerListener
119 : virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
120 : virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
121 : virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
122 :
123 : // lang.XEventListener
124 : virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
125 :
126 : protected:
127 : virtual ::com::sun::star::uno::Any SAL_CALL getByNameImpl( const ::rtl::OUString& aName );
128 :
129 11480 : struct CmdToInfoMap
130 : {
131 2296 : CmdToInfoMap() : bPopup( false ),
132 : bCommandNameCreated( false ),
133 2296 : nProperties( 0 ) {}
134 :
135 : rtl::OUString aLabel;
136 : rtl::OUString aContextLabel;
137 : rtl::OUString aCommandName;
138 : bool bPopup : 1,
139 : bCommandNameCreated : 1;
140 : sal_Int32 nProperties;
141 : };
142 :
143 : Any getSequenceFromCache( const rtl::OUString& aCommandURL );
144 : Any getInfoFromCommand( const rtl::OUString& rCommandURL );
145 : void fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel );
146 : Any getUILabelFromCommand( const rtl::OUString& rCommandURL );
147 : Sequence< rtl::OUString > getAllCommands();
148 : sal_Bool fillCache();
149 : sal_Bool addGenericInfoToCache();
150 : void impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup,
151 : std::vector< ::rtl::OUString >& aImageCommandVector,
152 : std::vector< ::rtl::OUString >& aImageRotateVector,
153 : std::vector< ::rtl::OUString >& aImageMirrorVector);
154 :
155 : private:
156 : typedef ::boost::unordered_map< ::rtl::OUString,
157 : CmdToInfoMap,
158 : OUStringHashCode,
159 : ::std::equal_to< ::rtl::OUString > > CommandToInfoCache;
160 :
161 : sal_Bool initializeConfigAccess();
162 :
163 : rtl::OUString m_aConfigCmdAccess;
164 : rtl::OUString m_aConfigPopupAccess;
165 : rtl::OUString m_aPropUILabel;
166 : rtl::OUString m_aPropUIContextLabel;
167 : rtl::OUString m_aPropLabel;
168 : rtl::OUString m_aPropName;
169 : rtl::OUString m_aPropPopup;
170 : rtl::OUString m_aPropProperties;
171 : rtl::OUString m_aXMLFileFormatVersion;
172 : rtl::OUString m_aVersion;
173 : rtl::OUString m_aExtension;
174 : rtl::OUString m_aPrivateResourceURL;
175 : Reference< XNameAccess > m_xGenericUICommands;
176 : Reference< XMultiServiceFactory > m_xConfigProvider;
177 : Reference< XNameAccess > m_xConfigAccess;
178 : Reference< XContainerListener > m_xConfigListener;
179 : Reference< XNameAccess > m_xConfigAccessPopups;
180 : Reference< XContainerListener > m_xConfigAccessListener;
181 : Sequence< rtl::OUString > m_aCommandImageList;
182 : Sequence< rtl::OUString > m_aCommandRotateImageList;
183 : Sequence< rtl::OUString > m_aCommandMirrorImageList;
184 : CommandToInfoCache m_aCmdInfoCache;
185 : sal_Bool m_bConfigAccessInitialized;
186 : sal_Bool m_bCacheFilled;
187 : sal_Bool m_bGenericDataRetrieved;
188 : };
189 :
190 : //*****************************************************************************************************************
191 : // XInterface, XTypeProvider
192 : //*****************************************************************************************************************
193 4 : ConfigurationAccess_UICommand::ConfigurationAccess_UICommand( const rtl::OUString& aModuleName, const Reference< XNameAccess >& rGenericUICommands, const Reference< XComponentContext>& rxContext ) :
194 : ThreadHelpBase(),
195 : m_aConfigCmdAccess( CONFIGURATION_ROOT_ACCESS ),
196 : m_aConfigPopupAccess( CONFIGURATION_ROOT_ACCESS ),
197 : m_aPropUILabel( CONFIGURATION_PROPERTY_LABEL ),
198 : m_aPropUIContextLabel( CONFIGURATION_PROPERTY_CONTEXT_LABEL ),
199 : m_aPropLabel( PROPSET_LABEL ),
200 : m_aPropName( PROPSET_NAME ),
201 : m_aPropPopup( PROPSET_POPUP ),
202 : m_aPropProperties( PROPSET_PROPERTIES ),
203 : m_aPrivateResourceURL( PRIVATE_RESOURCE_URL ),
204 : m_xGenericUICommands( rGenericUICommands ),
205 : m_bConfigAccessInitialized( sal_False ),
206 : m_bCacheFilled( sal_False ),
207 4 : m_bGenericDataRetrieved( sal_False )
208 : {
209 : // Create configuration hierachical access name
210 4 : m_aConfigCmdAccess += aModuleName;
211 4 : m_aConfigCmdAccess += rtl::OUString( CONFIGURATION_CMD_ELEMENT_ACCESS );
212 :
213 4 : m_xConfigProvider = theDefaultProvider::get( rxContext );
214 :
215 4 : m_aConfigPopupAccess += aModuleName;
216 4 : m_aConfigPopupAccess += rtl::OUString( CONFIGURATION_POP_ELEMENT_ACCESS );
217 4 : }
218 :
219 12 : ConfigurationAccess_UICommand::~ConfigurationAccess_UICommand()
220 : {
221 : // SAFE
222 4 : ResetableGuard aLock( m_aLock );
223 4 : Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
224 4 : if ( xContainer.is() )
225 4 : xContainer->removeContainerListener(m_xConfigListener);
226 4 : xContainer = Reference< XContainer >( m_xConfigAccessPopups, UNO_QUERY );
227 4 : if ( xContainer.is() )
228 4 : xContainer->removeContainerListener(m_xConfigAccessListener);
229 8 : }
230 :
231 :
232 : // XNameAccess
233 815 : Any SAL_CALL ConfigurationAccess_UICommand::getByNameImpl( const ::rtl::OUString& rCommandURL )
234 : {
235 : static sal_Int32 nRequests = 0;
236 :
237 815 : ResetableGuard aLock( m_aLock );
238 815 : if ( !m_bConfigAccessInitialized )
239 : {
240 4 : initializeConfigAccess();
241 4 : m_bConfigAccessInitialized = sal_True;
242 4 : fillCache();
243 : }
244 :
245 815 : if ( rCommandURL.indexOf( m_aPrivateResourceURL ) == 0 )
246 : {
247 : // special keys to retrieve information about a set of commands
248 : // SAFE
249 34 : addGenericInfoToCache();
250 :
251 34 : if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST ))
252 6 : return makeAny( m_aCommandImageList );
253 28 : else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))
254 14 : return makeAny( m_aCommandRotateImageList );
255 14 : else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))
256 14 : return makeAny( m_aCommandMirrorImageList );
257 : else
258 0 : return Any();
259 : }
260 : else
261 : {
262 : // SAFE
263 781 : ++nRequests;
264 781 : return getInfoFromCommand( rCommandURL );
265 815 : }
266 : }
267 :
268 526 : Any SAL_CALL ConfigurationAccess_UICommand::getByName( const ::rtl::OUString& rCommandURL )
269 : throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
270 : {
271 526 : Any aRet( getByNameImpl( rCommandURL ) );
272 526 : if( !aRet.hasValue() )
273 0 : throw NoSuchElementException();
274 :
275 526 : return aRet;
276 : }
277 :
278 0 : Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_UICommand::getElementNames()
279 : throw ( RuntimeException )
280 : {
281 0 : return getAllCommands();
282 : }
283 :
284 289 : sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasByName( const ::rtl::OUString& rCommandURL )
285 : throw (::com::sun::star::uno::RuntimeException)
286 : {
287 289 : return getByNameImpl( rCommandURL ).hasValue();
288 : }
289 :
290 : // XElementAccess
291 0 : Type SAL_CALL ConfigurationAccess_UICommand::getElementType()
292 : throw ( RuntimeException )
293 : {
294 0 : return( ::getCppuType( (const Sequence< PropertyValue >*)NULL ) );
295 : }
296 :
297 0 : sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasElements()
298 : throw ( RuntimeException )
299 : {
300 : // There must are global commands!
301 0 : return sal_True;
302 : }
303 :
304 154 : void ConfigurationAccess_UICommand::fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel )
305 : {
306 154 : String rStr( aLabel );
307 : rStr.SearchAndReplaceAllAscii(
308 154 : "%PRODUCTNAME", utl::ConfigManager::getProductName() );
309 154 : rCmdInfo.aLabel = ::rtl::OUString( rStr );
310 154 : rStr = comphelper::string::stripEnd(rStr, '.'); // Remove "..." from string
311 154 : rCmdInfo.aCommandName = ::rtl::OUString( MnemonicGenerator::EraseAllMnemonicChars( rStr ));
312 154 : rCmdInfo.bCommandNameCreated = sal_True;
313 154 : }
314 :
315 781 : Any ConfigurationAccess_UICommand::getSequenceFromCache( const ::rtl::OUString& aCommandURL )
316 : {
317 781 : CommandToInfoCache::iterator pIter = m_aCmdInfoCache.find( aCommandURL );
318 781 : if ( pIter != m_aCmdInfoCache.end() )
319 : {
320 528 : if ( !pIter->second.bCommandNameCreated )
321 154 : fillInfoFromResult( pIter->second, pIter->second.aLabel );
322 :
323 528 : Sequence< PropertyValue > aPropSeq( 4 );
324 528 : aPropSeq[0].Name = m_aPropLabel;
325 1056 : aPropSeq[0].Value = !pIter->second.aContextLabel.isEmpty() ?
326 1056 : makeAny( pIter->second.aContextLabel ): makeAny( pIter->second.aLabel );
327 528 : aPropSeq[1].Name = m_aPropName;
328 528 : aPropSeq[1].Value <<= pIter->second.aCommandName;
329 528 : aPropSeq[2].Name = m_aPropPopup;
330 528 : aPropSeq[2].Value <<= pIter->second.bPopup;
331 528 : aPropSeq[3].Name = m_aPropProperties;
332 528 : aPropSeq[3].Value <<= pIter->second.nProperties;
333 528 : return makeAny( aPropSeq );
334 : }
335 :
336 253 : return Any();
337 : }
338 8 : void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup,
339 : std::vector< ::rtl::OUString >& aImageCommandVector,
340 : std::vector< ::rtl::OUString >& aImageRotateVector,
341 : std::vector< ::rtl::OUString >& aImageMirrorVector)
342 : {
343 8 : if ( _xConfigAccess.is() )
344 : {
345 8 : Sequence< ::rtl::OUString> aNameSeq = _xConfigAccess->getElementNames();
346 8 : const sal_Int32 nCount = aNameSeq.getLength();
347 2304 : for ( sal_Int32 i = 0; i < nCount; i++ )
348 : {
349 : try
350 : {
351 2296 : Reference< XNameAccess > xNameAccess(_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
352 2296 : if ( xNameAccess.is() )
353 : {
354 2296 : CmdToInfoMap aCmdToInfo;
355 :
356 2296 : aCmdToInfo.bPopup = _bPopup;
357 2296 : xNameAccess->getByName( m_aPropUILabel ) >>= aCmdToInfo.aLabel;
358 2296 : xNameAccess->getByName( m_aPropUIContextLabel ) >>= aCmdToInfo.aContextLabel;
359 2296 : xNameAccess->getByName( m_aPropProperties ) >>= aCmdToInfo.nProperties;
360 :
361 2296 : m_aCmdInfoCache.insert( CommandToInfoCache::value_type( aNameSeq[i], aCmdToInfo ));
362 :
363 2296 : if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_IMAGE )
364 1286 : aImageCommandVector.push_back( aNameSeq[i] );
365 2296 : if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_ROTATE )
366 62 : aImageRotateVector.push_back( aNameSeq[i] );
367 2296 : if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_MIRROR )
368 52 : aImageMirrorVector.push_back( aNameSeq[i] );
369 2296 : }
370 : }
371 0 : catch (const com::sun::star::lang::WrappedTargetException&)
372 : {
373 : }
374 0 : catch (const com::sun::star::container::NoSuchElementException&)
375 : {
376 : }
377 8 : }
378 : }
379 8 : }
380 4 : sal_Bool ConfigurationAccess_UICommand::fillCache()
381 : {
382 : RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICommand::fillCache" );
383 :
384 4 : if ( m_bCacheFilled )
385 0 : return sal_True;
386 :
387 4 : std::vector< ::rtl::OUString > aImageCommandVector;
388 4 : std::vector< ::rtl::OUString > aImageRotateVector;
389 4 : std::vector< ::rtl::OUString > aImageMirrorVector;
390 :
391 4 : impl_fill(m_xConfigAccess,sal_False,aImageCommandVector,aImageRotateVector,aImageMirrorVector);
392 4 : impl_fill(m_xConfigAccessPopups,sal_True,aImageCommandVector,aImageRotateVector,aImageMirrorVector);
393 : // Create cached sequences for fast retrieving
394 4 : m_aCommandImageList = comphelper::containerToSequence( aImageCommandVector );
395 4 : m_aCommandRotateImageList = comphelper::containerToSequence( aImageRotateVector );
396 4 : m_aCommandMirrorImageList = comphelper::containerToSequence( aImageMirrorVector );
397 :
398 4 : m_bCacheFilled = sal_True;
399 :
400 4 : return sal_True;
401 : }
402 :
403 34 : sal_Bool ConfigurationAccess_UICommand::addGenericInfoToCache()
404 : {
405 34 : if ( m_xGenericUICommands.is() && !m_bGenericDataRetrieved )
406 : {
407 2 : Sequence< rtl::OUString > aCommandNameSeq;
408 : try
409 : {
410 6 : if ( m_xGenericUICommands->getByName(
411 4 : rtl::OUString( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST )) >>= aCommandNameSeq )
412 2 : m_aCommandRotateImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandRotateImageList, aCommandNameSeq );
413 : }
414 0 : catch (const RuntimeException&)
415 : {
416 0 : throw;
417 : }
418 0 : catch (const Exception&)
419 : {
420 : }
421 :
422 : try
423 : {
424 6 : if ( m_xGenericUICommands->getByName(
425 4 : rtl::OUString( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST )) >>= aCommandNameSeq )
426 2 : m_aCommandMirrorImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandMirrorImageList, aCommandNameSeq );
427 : }
428 0 : catch (const RuntimeException&)
429 : {
430 0 : throw;
431 : }
432 0 : catch (const Exception&)
433 : {
434 : }
435 :
436 2 : m_bGenericDataRetrieved = sal_True;
437 : }
438 :
439 34 : return sal_True;
440 : }
441 :
442 781 : Any ConfigurationAccess_UICommand::getInfoFromCommand( const rtl::OUString& rCommandURL )
443 : {
444 781 : Any a;
445 :
446 : try
447 : {
448 781 : a = getSequenceFromCache( rCommandURL );
449 781 : if ( !a.hasValue() )
450 : {
451 : // First try to ask our global commands configuration access. It also caches maybe
452 : // we find the entry in its cache first.
453 253 : if ( m_xGenericUICommands.is() && m_xGenericUICommands->hasByName( rCommandURL ) )
454 : {
455 : try
456 : {
457 241 : return m_xGenericUICommands->getByName( rCommandURL );
458 : }
459 0 : catch (const com::sun::star::lang::WrappedTargetException&)
460 : {
461 : }
462 0 : catch (const com::sun::star::container::NoSuchElementException&)
463 : {
464 : }
465 : }
466 : }
467 : }
468 0 : catch (const com::sun::star::container::NoSuchElementException&)
469 : {
470 : }
471 0 : catch (const com::sun::star::lang::WrappedTargetException&)
472 : {
473 : }
474 :
475 540 : return a;
476 : }
477 :
478 0 : Sequence< rtl::OUString > ConfigurationAccess_UICommand::getAllCommands()
479 : {
480 : // SAFE
481 0 : ResetableGuard aLock( m_aLock );
482 :
483 0 : if ( !m_bConfigAccessInitialized )
484 : {
485 0 : initializeConfigAccess();
486 0 : m_bConfigAccessInitialized = sal_True;
487 0 : fillCache();
488 : }
489 :
490 0 : if ( m_xConfigAccess.is() )
491 : {
492 0 : Reference< XNameAccess > xNameAccess;
493 :
494 : try
495 : {
496 0 : Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
497 :
498 0 : if ( m_xGenericUICommands.is() )
499 : {
500 : // Create concat list of supported user interface commands of the module
501 0 : Sequence< ::rtl::OUString > aGenericNameSeq = m_xGenericUICommands->getElementNames();
502 0 : sal_uInt32 nCount1 = aNameSeq.getLength();
503 0 : sal_uInt32 nCount2 = aGenericNameSeq.getLength();
504 :
505 0 : aNameSeq.realloc( nCount1 + nCount2 );
506 0 : ::rtl::OUString* pNameSeq = aNameSeq.getArray();
507 0 : const ::rtl::OUString* pGenericSeq = aGenericNameSeq.getConstArray();
508 0 : for ( sal_uInt32 i = 0; i < nCount2; i++ )
509 0 : pNameSeq[nCount1+i] = pGenericSeq[i];
510 : }
511 :
512 0 : return aNameSeq;
513 : }
514 0 : catch (const com::sun::star::container::NoSuchElementException&)
515 : {
516 : }
517 0 : catch (const com::sun::star::lang::WrappedTargetException&)
518 : {
519 0 : }
520 : }
521 :
522 0 : return Sequence< rtl::OUString >();
523 : }
524 :
525 4 : sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess()
526 : {
527 4 : Sequence< Any > aArgs( 1 );
528 4 : PropertyValue aPropValue;
529 :
530 : try
531 : {
532 4 : aPropValue.Name = rtl::OUString( "nodepath" );
533 4 : aPropValue.Value <<= m_aConfigCmdAccess;
534 4 : aArgs[0] <<= aPropValue;
535 :
536 4 : m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
537 4 : if ( m_xConfigAccess.is() )
538 : {
539 : // Add as container listener
540 4 : Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
541 4 : if ( xContainer.is() )
542 : {
543 4 : m_xConfigListener = new WeakContainerListener(this);
544 4 : xContainer->addContainerListener(m_xConfigListener);
545 4 : }
546 : }
547 :
548 4 : aPropValue.Value <<= m_aConfigPopupAccess;
549 4 : aArgs[0] <<= aPropValue;
550 4 : m_xConfigAccessPopups = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
551 4 : if ( m_xConfigAccessPopups.is() )
552 : {
553 : // Add as container listener
554 4 : Reference< XContainer > xContainer( m_xConfigAccessPopups, UNO_QUERY );
555 4 : if ( xContainer.is() )
556 : {
557 4 : m_xConfigAccessListener = new WeakContainerListener(this);
558 4 : xContainer->addContainerListener(m_xConfigAccessListener);
559 4 : }
560 : }
561 :
562 4 : return sal_True;
563 : }
564 0 : catch (const WrappedTargetException&)
565 : {
566 : }
567 0 : catch (const Exception&)
568 : {
569 : }
570 :
571 0 : return sal_False;
572 : }
573 :
574 : // container.XContainerListener
575 0 : void SAL_CALL ConfigurationAccess_UICommand::elementInserted( const ContainerEvent& ) throw(RuntimeException)
576 : {
577 0 : ResetableGuard aLock( m_aLock );
578 0 : m_bCacheFilled = sal_False;
579 0 : fillCache();
580 0 : }
581 :
582 0 : void SAL_CALL ConfigurationAccess_UICommand::elementRemoved( const ContainerEvent& ) throw(RuntimeException)
583 : {
584 0 : ResetableGuard aLock( m_aLock );
585 0 : m_bCacheFilled = sal_False;
586 0 : fillCache();
587 0 : }
588 :
589 0 : void SAL_CALL ConfigurationAccess_UICommand::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
590 : {
591 0 : ResetableGuard aLock( m_aLock );
592 0 : m_bCacheFilled = sal_False;
593 0 : fillCache();
594 0 : }
595 :
596 : // lang.XEventListener
597 0 : void SAL_CALL ConfigurationAccess_UICommand::disposing( const EventObject& aEvent ) throw(RuntimeException)
598 : {
599 : // SAFE
600 : // remove our reference to the config access
601 0 : ResetableGuard aLock( m_aLock );
602 :
603 0 : Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
604 0 : Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
605 0 : if ( xIfac1 == xIfac2 )
606 0 : m_xConfigAccess.clear();
607 : else
608 : {
609 0 : xIfac2 = Reference< XInterface >( m_xConfigAccessPopups, UNO_QUERY );
610 0 : if ( xIfac1 == xIfac2 )
611 0 : m_xConfigAccessPopups.clear();
612 0 : }
613 0 : }
614 :
615 : //*****************************************************************************************************************
616 : // XInterface, XTypeProvider, XServiceInfo
617 : //*****************************************************************************************************************
618 778 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2 ( UICommandDescription ,
619 : ::cppu::OWeakObject ,
620 : SERVICENAME_UICOMMANDDESCRIPTION ,
621 : IMPLEMENTATIONNAME_UICOMMANDDESCRIPTION
622 : )
623 :
624 2 : DEFINE_INIT_SERVICE ( UICommandDescription, {} )
625 :
626 2 : UICommandDescription::UICommandDescription( const Reference< XComponentContext >& rxContext ) :
627 : ThreadHelpBase(),
628 : m_aPrivateResourceURL( PRIVATE_RESOURCE_URL ),
629 2 : m_xContext( rxContext )
630 : {
631 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::UICommandDescription" );
632 2 : Reference< XNameAccess > xEmpty;
633 2 : rtl::OUString aGenericUICommand( "GenericCommands" );
634 2 : m_xGenericUICommands = new ConfigurationAccess_UICommand( aGenericUICommand, xEmpty, m_xContext );
635 :
636 2 : impl_fillElements("ooSetupFactoryCommandConfigRef");
637 :
638 : // insert generic commands
639 2 : UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aGenericUICommand );
640 2 : if ( pIter != m_aUICommandsHashMap.end() )
641 0 : pIter->second = m_xGenericUICommands;
642 2 : }
643 0 : UICommandDescription::UICommandDescription( const Reference< XComponentContext >& rxContext, bool ) :
644 : ThreadHelpBase(),
645 0 : m_xContext( rxContext )
646 : {
647 0 : }
648 6 : UICommandDescription::~UICommandDescription()
649 : {
650 2 : ResetableGuard aLock( m_aLock );
651 2 : m_aModuleToCommandFileMap.clear();
652 2 : m_aUICommandsHashMap.clear();
653 2 : m_xGenericUICommands.clear();
654 4 : }
655 2 : void UICommandDescription::impl_fillElements(const sal_Char* _pName)
656 : {
657 2 : m_xModuleManager.set( ModuleManager::create( m_xContext ) );
658 2 : Sequence< rtl::OUString > aElementNames = m_xModuleManager->getElementNames();
659 2 : Sequence< PropertyValue > aSeq;
660 2 : ::rtl::OUString aModuleIdentifier;
661 :
662 46 : for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
663 : {
664 44 : aModuleIdentifier = aElementNames[i];
665 44 : if ( m_xModuleManager->getByName( aModuleIdentifier ) >>= aSeq )
666 : {
667 44 : ::rtl::OUString aCommandStr;
668 572 : for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ )
669 : {
670 572 : if ( aSeq[y].Name.equalsAscii(_pName) )
671 : {
672 44 : aSeq[y].Value >>= aCommandStr;
673 44 : break;
674 : }
675 : }
676 :
677 : // Create first mapping ModuleIdentifier ==> Command File
678 44 : m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type( aModuleIdentifier, aCommandStr ));
679 :
680 : // Create second mapping Command File ==> commands instance
681 44 : UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandStr );
682 44 : if ( pIter == m_aUICommandsHashMap.end() )
683 20 : m_aUICommandsHashMap.insert( UICommandsHashMap::value_type( aCommandStr, Reference< XNameAccess >() ));
684 : }
685 2 : } // for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
686 2 : }
687 0 : Reference< XNameAccess > UICommandDescription::impl_createConfigAccess(const ::rtl::OUString& _sName)
688 : {
689 0 : return new ConfigurationAccess_UICommand( _sName, m_xGenericUICommands, m_xContext );
690 : }
691 :
692 19 : Any SAL_CALL UICommandDescription::getByName( const ::rtl::OUString& aName )
693 : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
694 : {
695 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getByName" );
696 19 : Any a;
697 :
698 19 : ResetableGuard aLock( m_aLock );
699 :
700 19 : ModuleToCommandFileMap::const_iterator pM2CIter = m_aModuleToCommandFileMap.find( aName );
701 19 : if ( pM2CIter != m_aModuleToCommandFileMap.end() )
702 : {
703 17 : ::rtl::OUString aCommandFile( pM2CIter->second );
704 17 : UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandFile );
705 17 : if ( pIter != m_aUICommandsHashMap.end() )
706 : {
707 17 : if ( pIter->second.is() )
708 15 : a <<= pIter->second;
709 : else
710 : {
711 2 : Reference< XNameAccess > xUICommands;
712 : ConfigurationAccess_UICommand* pUICommands = new ConfigurationAccess_UICommand( aCommandFile,
713 : m_xGenericUICommands,
714 2 : m_xContext );
715 2 : xUICommands = Reference< XNameAccess >( static_cast< cppu::OWeakObject* >( pUICommands ),UNO_QUERY );
716 2 : pIter->second = xUICommands;
717 2 : a <<= xUICommands;
718 : }
719 17 : }
720 : }
721 2 : else if ( !m_aPrivateResourceURL.isEmpty() && aName.indexOf( m_aPrivateResourceURL ) == 0 )
722 : {
723 : // special keys to retrieve information about a set of commands
724 2 : return m_xGenericUICommands->getByName( aName );
725 : }
726 : else
727 : {
728 0 : throw NoSuchElementException();
729 : }
730 :
731 36 : return a;
732 : }
733 :
734 0 : Sequence< ::rtl::OUString > SAL_CALL UICommandDescription::getElementNames()
735 : throw (::com::sun::star::uno::RuntimeException)
736 : {
737 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementNames" );
738 0 : ResetableGuard aLock( m_aLock );
739 :
740 0 : Sequence< rtl::OUString > aSeq( m_aModuleToCommandFileMap.size() );
741 :
742 0 : sal_Int32 n = 0;
743 0 : ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.begin();
744 0 : while ( pIter != m_aModuleToCommandFileMap.end() )
745 : {
746 0 : aSeq[n] = pIter->first;
747 0 : ++pIter;
748 : }
749 :
750 0 : return aSeq;
751 : }
752 :
753 0 : sal_Bool SAL_CALL UICommandDescription::hasByName( const ::rtl::OUString& aName )
754 : throw (::com::sun::star::uno::RuntimeException)
755 : {
756 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasByName" );
757 0 : ResetableGuard aLock( m_aLock );
758 :
759 0 : ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.find( aName );
760 0 : return ( pIter != m_aModuleToCommandFileMap.end() );
761 : }
762 :
763 : // XElementAccess
764 0 : Type SAL_CALL UICommandDescription::getElementType()
765 : throw (::com::sun::star::uno::RuntimeException)
766 : {
767 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementType" );
768 0 : return( ::getCppuType( (const Reference< XNameAccess >*)NULL ) );
769 : }
770 :
771 0 : sal_Bool SAL_CALL UICommandDescription::hasElements()
772 : throw (::com::sun::star::uno::RuntimeException)
773 : {
774 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasElements" );
775 : // generic UI commands are always available!
776 0 : return sal_True;
777 : }
778 :
779 : } // namespace framework
780 :
781 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|