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