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