update credits
[LibreOffice.git] / framework / source / uiconfiguration / uicategorydescription.cxx
blob84dec3b1ff4b43c566f3f7bedbdd1dffc285bdc9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "uiconfiguration/uicategorydescription.hxx"
21 #include <threadhelp/resetableguard.hxx>
22 #include "services.h"
24 #include "properties.h"
26 #include "helper/mischelper.hxx"
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/configuration/theDefaultProvider.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/container/XNameContainer.hpp>
33 #include <com/sun/star/container/XContainer.hpp>
35 #include <rtl/ustrbuf.hxx>
36 #include <cppuhelper/implbase2.hxx>
37 #include <unotools/configmgr.hxx>
39 #include <vcl/mnemonic.hxx>
40 #include <comphelper/sequence.hxx>
41 #include <rtl/logfile.hxx>
43 //_________________________________________________________________________________________________________________
44 // Defines
45 //_________________________________________________________________________________________________________________
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::lang;
49 using namespace com::sun::star::beans;
50 using namespace com::sun::star::configuration;
51 using namespace com::sun::star::container;
52 using namespace ::com::sun::star::frame;
54 //_________________________________________________________________________________________________________________
55 // Namespace
56 //_________________________________________________________________________________________________________________
58 struct ModuleToCategory
60 const char* pModuleId;
61 const char* pCommands;
64 static const char GENERIC_MODULE_NAME[] = "generic";
65 static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
66 static const char CONFIGURATION_CATEGORY_ELEMENT_ACCESS[] = "/Commands/Categories";
67 static const char CONFIGURATION_PROPERTY_NAME[] = "Name";
69 namespace framework
72 //*****************************************************************************************************************
73 // Configuration access class for PopupMenuControllerFactory implementation
74 //*****************************************************************************************************************
76 class ConfigurationAccess_UICategory : // Order is necessary for right initialization!
77 private ThreadHelpBase ,
78 public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
80 public:
81 ConfigurationAccess_UICategory( const OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XComponentContext >& rxContext );
82 virtual ~ConfigurationAccess_UICategory();
84 // XNameAccess
85 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const OUString& aName )
86 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
88 virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getElementNames()
89 throw (::com::sun::star::uno::RuntimeException);
91 virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
92 throw (::com::sun::star::uno::RuntimeException);
94 // XElementAccess
95 virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
96 throw (::com::sun::star::uno::RuntimeException);
98 virtual sal_Bool SAL_CALL hasElements()
99 throw (::com::sun::star::uno::RuntimeException);
101 // container.XContainerListener
102 virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
103 virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
104 virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
106 // lang.XEventListener
107 virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
109 protected:
110 Any getUINameFromID( const OUString& rId );
111 Any getUINameFromCache( const OUString& rId );
112 Sequence< OUString > getAllIds();
113 sal_Bool fillCache();
115 private:
116 typedef ::boost::unordered_map< OUString,
117 OUString,
118 OUStringHash,
119 ::std::equal_to< OUString > > IdToInfoCache;
121 sal_Bool initializeConfigAccess();
123 OUString m_aConfigCategoryAccess;
124 OUString m_aPropUIName;
125 Reference< XNameAccess > m_xGenericUICategories;
126 Reference< XMultiServiceFactory > m_xConfigProvider;
127 Reference< XNameAccess > m_xConfigAccess;
128 Reference< XContainerListener > m_xConfigListener;
129 sal_Bool m_bConfigAccessInitialized;
130 sal_Bool m_bCacheFilled;
131 IdToInfoCache m_aIdCache;
134 //*****************************************************************************************************************
135 // XInterface, XTypeProvider
136 //*****************************************************************************************************************
138 ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( const OUString& aModuleName, const Reference< XNameAccess >& rGenericUICategories, const Reference< XComponentContext >& rxContext ) :
139 ThreadHelpBase(),
140 m_aConfigCategoryAccess( CONFIGURATION_ROOT_ACCESS ),
141 m_aPropUIName( CONFIGURATION_PROPERTY_NAME ),
142 m_xGenericUICategories( rGenericUICategories ),
143 m_bConfigAccessInitialized( sal_False ),
144 m_bCacheFilled( sal_False )
146 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::ConfigurationAccess_UICategory" );
147 // Create configuration hierachical access name
148 m_aConfigCategoryAccess += aModuleName;
149 m_aConfigCategoryAccess += OUString( CONFIGURATION_CATEGORY_ELEMENT_ACCESS );
151 m_xConfigProvider = theDefaultProvider::get( rxContext );
154 ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
156 // SAFE
157 ResetableGuard aLock( m_aLock );
158 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
159 if ( xContainer.is() )
160 xContainer->removeContainerListener(m_xConfigListener);
163 // XNameAccess
164 Any SAL_CALL ConfigurationAccess_UICategory::getByName( const OUString& rId )
165 throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
167 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getByName" );
168 ResetableGuard aLock( m_aLock );
169 if ( !m_bConfigAccessInitialized )
171 initializeConfigAccess();
172 m_bConfigAccessInitialized = sal_True;
173 fillCache();
176 // SAFE
177 Any a = getUINameFromID( rId );
179 if ( !a.hasValue() )
180 throw NoSuchElementException();
182 return a;
185 Sequence< OUString > SAL_CALL ConfigurationAccess_UICategory::getElementNames()
186 throw ( RuntimeException )
188 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementNames" );
189 return getAllIds();
192 sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasByName( const OUString& rId )
193 throw (::com::sun::star::uno::RuntimeException)
195 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasByName" );
196 return getByName( rId ).hasValue();
199 // XElementAccess
200 Type SAL_CALL ConfigurationAccess_UICategory::getElementType()
201 throw ( RuntimeException )
203 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementType" );
204 return( ::getCppuType( (const OUString*)NULL ) );
207 sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasElements()
208 throw ( RuntimeException )
210 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasElements" );
211 // There must be global categories!
212 return sal_True;
215 sal_Bool ConfigurationAccess_UICategory::fillCache()
217 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::fillCache" );
218 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
220 if ( m_bCacheFilled )
221 return sal_True;
223 sal_Int32 i( 0 );
224 OUString aUIName;
225 Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
227 for ( i = 0; i < aNameSeq.getLength(); i++ )
231 Reference< XNameAccess > xNameAccess(m_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
232 if ( xNameAccess.is() )
234 xNameAccess->getByName( m_aPropUIName ) >>= aUIName;
236 m_aIdCache.insert( IdToInfoCache::value_type( aNameSeq[i], aUIName ));
239 catch ( const com::sun::star::lang::WrappedTargetException& )
242 catch ( const com::sun::star::container::NoSuchElementException& )
247 m_bCacheFilled = sal_True;
249 return sal_True;
252 Any ConfigurationAccess_UICategory::getUINameFromID( const OUString& rId )
254 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromID" );
255 Any a;
259 a = getUINameFromCache( rId );
260 if ( !a.hasValue() )
262 // Try to ask our global commands configuration access
263 if ( m_xGenericUICategories.is() )
267 return m_xGenericUICategories->getByName( rId );
269 catch ( const com::sun::star::lang::WrappedTargetException& )
272 catch ( const com::sun::star::container::NoSuchElementException& )
278 catch( const com::sun::star::container::NoSuchElementException& )
281 catch ( const com::sun::star::lang::WrappedTargetException& )
285 return a;
288 Any ConfigurationAccess_UICategory::getUINameFromCache( const OUString& rId )
290 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromCache" );
291 Any a;
293 IdToInfoCache::const_iterator pIter = m_aIdCache.find( rId );
294 if ( pIter != m_aIdCache.end() )
295 a <<= pIter->second;
297 return a;
300 Sequence< OUString > ConfigurationAccess_UICategory::getAllIds()
302 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getAllIds" );
303 // SAFE
304 ResetableGuard aLock( m_aLock );
306 if ( !m_bConfigAccessInitialized )
308 initializeConfigAccess();
309 m_bConfigAccessInitialized = sal_True;
310 fillCache();
313 if ( m_xConfigAccess.is() )
315 Any a;
316 Reference< XNameAccess > xNameAccess;
320 Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
322 if ( m_xGenericUICategories.is() )
324 // Create concat list of supported user interface commands of the module
325 Sequence< OUString > aGenericNameSeq = m_xGenericUICategories->getElementNames();
326 sal_uInt32 nCount1 = aNameSeq.getLength();
327 sal_uInt32 nCount2 = aGenericNameSeq.getLength();
329 aNameSeq.realloc( nCount1 + nCount2 );
330 OUString* pNameSeq = aNameSeq.getArray();
331 const OUString* pGenericSeq = aGenericNameSeq.getConstArray();
332 for ( sal_uInt32 i = 0; i < nCount2; i++ )
333 pNameSeq[nCount1+i] = pGenericSeq[i];
336 return aNameSeq;
338 catch( const com::sun::star::container::NoSuchElementException& )
341 catch ( const com::sun::star::lang::WrappedTargetException& )
346 return Sequence< OUString >();
349 sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess()
351 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::initializeConfigAccess" );
352 Sequence< Any > aArgs( 1 );
353 PropertyValue aPropValue;
357 aPropValue.Name = OUString( "nodepath" );
358 aPropValue.Value <<= m_aConfigCategoryAccess;
359 aArgs[0] <<= aPropValue;
361 m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
362 if ( m_xConfigAccess.is() )
364 // Add as container listener
365 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
366 if ( xContainer.is() )
368 m_xConfigListener = new WeakContainerListener(this);
369 xContainer->addContainerListener(m_xConfigListener);
373 return sal_True;
375 catch ( const WrappedTargetException& )
378 catch ( const Exception& )
382 return sal_False;
385 // container.XContainerListener
386 void SAL_CALL ConfigurationAccess_UICategory::elementInserted( const ContainerEvent& ) throw(RuntimeException)
388 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementInserted" );
391 void SAL_CALL ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
393 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementRemoved " );
396 void SAL_CALL ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
398 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementReplaced" );
401 // lang.XEventListener
402 void SAL_CALL ConfigurationAccess_UICategory::disposing( const EventObject& aEvent ) throw(RuntimeException)
404 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::disposing" );
405 // SAFE
406 // remove our reference to the config access
407 ResetableGuard aLock( m_aLock );
409 Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
410 Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
411 if ( xIfac1 == xIfac2 )
412 m_xConfigAccess.clear();
415 //*****************************************************************************************************************
416 // XInterface, XTypeProvider, XServiceInfo
417 //*****************************************************************************************************************
419 #define SERVICENAME_UICATEGORYDESCRIPTION DECLARE_ASCII("com.sun.star.ui.UICategoryDescription" )
420 #define IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION DECLARE_ASCII("com.sun.star.comp.framework.UICategoryDescription" )
422 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2 ( UICategoryDescription ,
423 ::cppu::OWeakObject ,
424 SERVICENAME_UICATEGORYDESCRIPTION ,
425 IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION
428 DEFINE_INIT_SERVICE ( UICategoryDescription, {} )
430 UICategoryDescription::UICategoryDescription( const Reference< XComponentContext >& rxContext ) :
431 UICommandDescription(rxContext,true)
433 Reference< XNameAccess > xEmpty;
434 OUString aGenericCategories( "GenericCategories" );
435 m_xGenericUICommands = new ConfigurationAccess_UICategory( aGenericCategories, xEmpty, rxContext );
437 // insert generic categories mappings
438 m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type(
439 OUString(GENERIC_MODULE_NAME ), aGenericCategories ));
441 UICommandsHashMap::iterator pCatIter = m_aUICommandsHashMap.find( aGenericCategories );
442 if ( pCatIter != m_aUICommandsHashMap.end() )
443 pCatIter->second = m_xGenericUICommands;
445 impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
448 UICategoryDescription::~UICategoryDescription()
451 Reference< XNameAccess > UICategoryDescription::impl_createConfigAccess(const OUString& _sName)
453 return new ConfigurationAccess_UICategory( _sName, m_xGenericUICommands, m_xContext );
456 } // namespace framework
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */