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