merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uiconfiguration / uicategorydescription.cxx
blob739130ae4c8ad207f24d084831719ba7ad8ebd53
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: uicategorydescription.cxx,v $
10 * $Revision: 1.8.34.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
38 #ifndef __FRAMEWORK_UICONFIGURATION_UICATEGORYDESCRPTION_HXX_
39 #include "uiconfiguration/uicategorydescription.hxx"
40 #endif
41 #include <threadhelp/resetableguard.hxx>
42 #include "services.h"
44 #include "properties.h"
46 //_________________________________________________________________________________________________________________
47 // interface includes
48 //_________________________________________________________________________________________________________________
49 #include <com/sun/star/beans/PropertyValue.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/container/XNameAccess.hpp>
52 #include <com/sun/star/container/XNameContainer.hpp>
53 #include <com/sun/star/container/XContainer.hpp>
55 //_________________________________________________________________________________________________________________
56 // includes of other projects
57 //_________________________________________________________________________________________________________________
58 #include <rtl/ustrbuf.hxx>
59 #include <cppuhelper/implbase2.hxx>
60 #include <unotools/configmgr.hxx>
61 #include <tools/string.hxx>
63 #ifndef _VCL_MNEMONIC_HXX_
64 #include <vcl/mnemonic.hxx>
65 #endif
66 #include <comphelper/sequence.hxx>
67 #include <rtl/logfile.hxx>
69 //_________________________________________________________________________________________________________________
70 // Defines
71 //_________________________________________________________________________________________________________________
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star::lang;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::container;
78 using namespace ::com::sun::star::frame;
80 //_________________________________________________________________________________________________________________
81 // Namespace
82 //_________________________________________________________________________________________________________________
85 struct ModuleToCategory
87 const char* pModuleId;
88 const char* pCommands;
91 static const char CATEGORY[] = "Category";
92 static const char GENERIC_MODULE_NAME[] = "generic";
93 static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
94 static const char CONFIGURATION_CATEGORY_ELEMENT_ACCESS[] = "/Commands/Categories";
95 static const char CONFIGURATION_PROPERTY_NAME[] = "Name";
97 namespace framework
100 //*****************************************************************************************************************
101 // Configuration access class for PopupMenuControllerFactory implementation
102 //*****************************************************************************************************************
104 class ConfigurationAccess_UICategory : // Order is neccessary for right initialization!
105 private ThreadHelpBase ,
106 public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
108 public:
109 ConfigurationAccess_UICategory( const ::rtl::OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager );
110 virtual ~ConfigurationAccess_UICategory();
112 // XNameAccess
113 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
114 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
116 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
117 throw (::com::sun::star::uno::RuntimeException);
119 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
120 throw (::com::sun::star::uno::RuntimeException);
122 // XElementAccess
123 virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
124 throw (::com::sun::star::uno::RuntimeException);
126 virtual sal_Bool SAL_CALL hasElements()
127 throw (::com::sun::star::uno::RuntimeException);
129 // container.XContainerListener
130 virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
131 virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
132 virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
134 // lang.XEventListener
135 virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
137 protected:
138 Any getUINameFromID( const rtl::OUString& rId );
139 Any getUINameFromCache( const rtl::OUString& rId );
140 Sequence< rtl::OUString > getAllIds();
141 sal_Bool fillCache();
143 private:
144 typedef ::std::hash_map< ::rtl::OUString,
145 ::rtl::OUString,
146 OUStringHashCode,
147 ::std::equal_to< ::rtl::OUString > > IdToInfoCache;
149 sal_Bool initializeConfigAccess();
151 rtl::OUString m_aConfigCategoryAccess;
152 rtl::OUString m_aPropUIName;
153 Reference< XNameAccess > m_xGenericUICategories;
154 Reference< XMultiServiceFactory > m_xServiceManager;
155 Reference< XMultiServiceFactory > m_xConfigProvider;
156 Reference< XNameAccess > m_xConfigAccess;
157 sal_Bool m_bConfigAccessInitialized;
158 sal_Bool m_bCacheFilled;
159 IdToInfoCache m_aIdCache;
162 //*****************************************************************************************************************
163 // XInterface, XTypeProvider
164 //*****************************************************************************************************************
166 ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( const rtl::OUString& aModuleName, const Reference< XNameAccess >& rGenericUICategories, const Reference< XMultiServiceFactory >& rServiceManager ) :
167 ThreadHelpBase(),
168 m_aConfigCategoryAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
169 m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_NAME )),
170 m_xGenericUICategories( rGenericUICategories ),
171 m_xServiceManager( rServiceManager ),
172 m_bConfigAccessInitialized( sal_False ),
173 m_bCacheFilled( sal_False )
175 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::ConfigurationAccess_UICategory" );
176 // Create configuration hierachical access name
177 m_aConfigCategoryAccess += aModuleName;
178 m_aConfigCategoryAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_CATEGORY_ELEMENT_ACCESS ));
180 m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY );
183 ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
185 // SAFE
186 ResetableGuard aLock( m_aLock );
187 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
188 if ( xContainer.is() )
189 xContainer->removeContainerListener( this );
192 // XNameAccess
193 Any SAL_CALL ConfigurationAccess_UICategory::getByName( const ::rtl::OUString& rId )
194 throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
196 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getByName" );
197 ResetableGuard aLock( m_aLock );
198 if ( !m_bConfigAccessInitialized )
200 initializeConfigAccess();
201 m_bConfigAccessInitialized = sal_True;
202 fillCache();
205 // SAFE
206 Any a = getUINameFromID( rId );
208 if ( !a.hasValue() )
209 throw NoSuchElementException();
211 return a;
214 Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_UICategory::getElementNames()
215 throw ( RuntimeException )
217 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementNames" );
218 return getAllIds();
221 sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasByName( const ::rtl::OUString& rId )
222 throw (::com::sun::star::uno::RuntimeException)
224 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasByName" );
225 return getByName( rId ).hasValue();
228 // XElementAccess
229 Type SAL_CALL ConfigurationAccess_UICategory::getElementType()
230 throw ( RuntimeException )
232 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementType" );
233 return( ::getCppuType( (const rtl::OUString*)NULL ) );
236 sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasElements()
237 throw ( RuntimeException )
239 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasElements" );
240 // There must be global categories!
241 return sal_True;
244 sal_Bool ConfigurationAccess_UICategory::fillCache()
246 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::fillCache" );
247 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
249 if ( m_bCacheFilled )
250 return sal_True;
252 sal_Int32 i( 0 );
253 rtl::OUString aUIName;
254 Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
256 for ( i = 0; i < aNameSeq.getLength(); i++ )
260 Reference< XNameAccess > xNameAccess(m_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
261 if ( xNameAccess.is() )
263 xNameAccess->getByName( m_aPropUIName ) >>= aUIName;
265 m_aIdCache.insert( IdToInfoCache::value_type( aNameSeq[i], aUIName ));
268 catch ( com::sun::star::lang::WrappedTargetException& )
271 catch ( com::sun::star::container::NoSuchElementException& )
276 m_bCacheFilled = sal_True;
278 return sal_True;
281 Any ConfigurationAccess_UICategory::getUINameFromID( const rtl::OUString& rId )
283 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromID" );
284 Any a;
288 a = getUINameFromCache( rId );
289 if ( !a.hasValue() )
291 // Try to ask our global commands configuration access
292 if ( m_xGenericUICategories.is() )
296 return m_xGenericUICategories->getByName( rId );
298 catch ( com::sun::star::lang::WrappedTargetException& )
301 catch ( com::sun::star::container::NoSuchElementException& )
307 catch( com::sun::star::container::NoSuchElementException& )
310 catch ( com::sun::star::lang::WrappedTargetException& )
314 return a;
317 Any ConfigurationAccess_UICategory::getUINameFromCache( const rtl::OUString& rId )
319 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromCache" );
320 Any a;
322 IdToInfoCache::const_iterator pIter = m_aIdCache.find( rId );
323 if ( pIter != m_aIdCache.end() )
324 a <<= pIter->second;
326 return a;
329 Sequence< rtl::OUString > ConfigurationAccess_UICategory::getAllIds()
331 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getAllIds" );
332 // SAFE
333 ResetableGuard aLock( m_aLock );
335 if ( !m_bConfigAccessInitialized )
337 initializeConfigAccess();
338 m_bConfigAccessInitialized = sal_True;
339 fillCache();
342 if ( m_xConfigAccess.is() )
344 Any a;
345 Reference< XNameAccess > xNameAccess;
349 Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
351 if ( m_xGenericUICategories.is() )
353 // Create concat list of supported user interface commands of the module
354 Sequence< ::rtl::OUString > aGenericNameSeq = m_xGenericUICategories->getElementNames();
355 sal_uInt32 nCount1 = aNameSeq.getLength();
356 sal_uInt32 nCount2 = aGenericNameSeq.getLength();
358 aNameSeq.realloc( nCount1 + nCount2 );
359 ::rtl::OUString* pNameSeq = aNameSeq.getArray();
360 const ::rtl::OUString* pGenericSeq = aGenericNameSeq.getConstArray();
361 for ( sal_uInt32 i = 0; i < nCount2; i++ )
362 pNameSeq[nCount1+i] = pGenericSeq[i];
365 return aNameSeq;
367 catch( com::sun::star::container::NoSuchElementException& )
370 catch ( com::sun::star::lang::WrappedTargetException& )
375 return Sequence< rtl::OUString >();
378 sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess()
380 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::initializeConfigAccess" );
381 Sequence< Any > aArgs( 1 );
382 PropertyValue aPropValue;
386 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
387 aPropValue.Value <<= m_aConfigCategoryAccess;
388 aArgs[0] <<= aPropValue;
390 m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
391 if ( m_xConfigAccess.is() )
393 // Add as container listener
394 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
395 if ( xContainer.is() )
396 xContainer->addContainerListener( this );
399 return sal_True;
401 catch ( WrappedTargetException& )
404 catch ( Exception& )
408 return sal_False;
411 // container.XContainerListener
412 void SAL_CALL ConfigurationAccess_UICategory::elementInserted( const ContainerEvent& ) throw(RuntimeException)
414 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementInserted" );
417 void SAL_CALL ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
419 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementRemoved " );
422 void SAL_CALL ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
424 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementReplaced" );
427 // lang.XEventListener
428 void SAL_CALL ConfigurationAccess_UICategory::disposing( const EventObject& aEvent ) throw(RuntimeException)
430 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::disposing" );
431 // SAFE
432 // remove our reference to the config access
433 ResetableGuard aLock( m_aLock );
435 Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
436 Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
437 if ( xIfac1 == xIfac2 )
438 m_xConfigAccess.clear();
441 //*****************************************************************************************************************
442 // XInterface, XTypeProvider, XServiceInfo
443 //*****************************************************************************************************************
444 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UICategoryDescription ,
445 ::cppu::OWeakObject ,
446 SERVICENAME_UICATEGORYDESCRIPTION ,
447 IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION
450 DEFINE_INIT_SERVICE ( UICategoryDescription, {} )
452 UICategoryDescription::UICategoryDescription( const Reference< XMultiServiceFactory >& xServiceManager ) :
453 UICommandDescription(xServiceManager,true)
455 Reference< XNameAccess > xEmpty;
456 rtl::OUString aGenericCategories( RTL_CONSTASCII_USTRINGPARAM( "GenericCategories" ));
457 m_xGenericUICommands = new ConfigurationAccess_UICategory( aGenericCategories, xEmpty, xServiceManager );
459 // insert generic categories mappings
460 m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type(
461 rtl::OUString::createFromAscii( GENERIC_MODULE_NAME ), aGenericCategories ));
463 UICommandsHashMap::iterator pCatIter = m_aUICommandsHashMap.find( aGenericCategories );
464 if ( pCatIter != m_aUICommandsHashMap.end() )
465 pCatIter->second = m_xGenericUICommands;
467 impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
470 UICategoryDescription::~UICategoryDescription()
473 Reference< XNameAccess > UICategoryDescription::impl_createConfigAccess(const ::rtl::OUString& _sName)
475 return new ConfigurationAccess_UICategory( _sName,m_xGenericUICommands,m_xServiceManager );
478 } // namespace framework