xref: /trunk/main/framework/source/uielement/uicommanddescription.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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