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