1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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 //_________________________________________________________________________________________________________________
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 //_________________________________________________________________________________________________________________
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";
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
>
81 ConfigurationAccess_UICategory( const OUString
& aModuleName
, const Reference
< XNameAccess
>& xGenericUICommands
, const Reference
< XComponentContext
>& rxContext
);
82 virtual ~ConfigurationAccess_UICategory();
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
);
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
);
110 Any
getUINameFromID( const OUString
& rId
);
111 Any
getUINameFromCache( const OUString
& rId
);
112 Sequence
< OUString
> getAllIds();
113 sal_Bool
fillCache();
116 typedef ::boost::unordered_map
< OUString
,
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
) :
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()
157 ResetableGuard
aLock( m_aLock
);
158 Reference
< XContainer
> xContainer( m_xConfigAccess
, UNO_QUERY
);
159 if ( xContainer
.is() )
160 xContainer
->removeContainerListener(m_xConfigListener
);
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
;
177 Any a
= getUINameFromID( rId
);
180 throw NoSuchElementException();
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" );
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();
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!
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
)
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
;
252 Any
ConfigurationAccess_UICategory::getUINameFromID( const OUString
& rId
)
254 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromID" );
259 a
= getUINameFromCache( rId
);
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
& )
288 Any
ConfigurationAccess_UICategory::getUINameFromCache( const OUString
& rId
)
290 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromCache" );
293 IdToInfoCache::const_iterator pIter
= m_aIdCache
.find( rId
);
294 if ( pIter
!= m_aIdCache
.end() )
300 Sequence
< OUString
> ConfigurationAccess_UICategory::getAllIds()
302 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getAllIds" );
304 ResetableGuard
aLock( m_aLock
);
306 if ( !m_bConfigAccessInitialized
)
308 initializeConfigAccess();
309 m_bConfigAccessInitialized
= sal_True
;
313 if ( m_xConfigAccess
.is() )
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
];
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
);
375 catch ( const WrappedTargetException
& )
378 catch ( const Exception
& )
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" );
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: */