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 neccessary 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 hierachical 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