1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
31 //_________________________________________________________________________________________________________________
33 //_________________________________________________________________________________________________________________
35 #ifndef __FRAMEWORK_UICONFIGURATION_UICATEGORYDESCRPTION_HXX_
36 #include "uiconfiguration/uicategorydescription.hxx"
38 #include <threadhelp/resetableguard.hxx>
41 #include "properties.h"
43 //_________________________________________________________________________________________________________________
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/beans/PropertyValue.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/container/XNameAccess.hpp>
49 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <com/sun/star/container/XContainer.hpp>
52 //_________________________________________________________________________________________________________________
53 // includes of other projects
54 //_________________________________________________________________________________________________________________
55 #include <rtl/ustrbuf.hxx>
56 #include <cppuhelper/implbase2.hxx>
57 #include <unotools/configmgr.hxx>
58 #include <tools/string.hxx>
60 #ifndef _VCL_MNEMONIC_HXX_
61 #include <vcl/mnemonic.hxx>
63 #include <comphelper/sequence.hxx>
64 #include <rtl/logfile.hxx>
66 //_________________________________________________________________________________________________________________
68 //_________________________________________________________________________________________________________________
71 using namespace com::sun::star::uno
;
72 using namespace com::sun::star::lang
;
73 using namespace com::sun::star::beans
;
74 using namespace com::sun::star::container
;
75 using namespace ::com::sun::star::frame
;
77 //_________________________________________________________________________________________________________________
79 //_________________________________________________________________________________________________________________
82 struct ModuleToCategory
84 const char* pModuleId
;
85 const char* pCommands
;
88 static const char CATEGORY
[] = "Category";
89 static const char GENERIC_MODULE_NAME
[] = "generic";
90 static const char CONFIGURATION_ROOT_ACCESS
[] = "/org.openoffice.Office.UI.";
91 static const char CONFIGURATION_CATEGORY_ELEMENT_ACCESS
[] = "/Commands/Categories";
92 static const char CONFIGURATION_PROPERTY_NAME
[] = "Name";
97 //*****************************************************************************************************************
98 // Configuration access class for PopupMenuControllerFactory implementation
99 //*****************************************************************************************************************
101 class ConfigurationAccess_UICategory
: // Order is neccessary for right initialization!
102 private ThreadHelpBase
,
103 public ::cppu::WeakImplHelper2
<XNameAccess
,XContainerListener
>
106 ConfigurationAccess_UICategory( const ::rtl::OUString
& aModuleName
, const Reference
< XNameAccess
>& xGenericUICommands
, const Reference
< XMultiServiceFactory
>& rServiceManager
);
107 virtual ~ConfigurationAccess_UICategory();
110 virtual ::com::sun::star::uno::Any SAL_CALL
getByName( const ::rtl::OUString
& aName
)
111 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
);
113 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames()
114 throw (::com::sun::star::uno::RuntimeException
);
116 virtual sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& aName
)
117 throw (::com::sun::star::uno::RuntimeException
);
120 virtual ::com::sun::star::uno::Type SAL_CALL
getElementType()
121 throw (::com::sun::star::uno::RuntimeException
);
123 virtual sal_Bool SAL_CALL
hasElements()
124 throw (::com::sun::star::uno::RuntimeException
);
126 // container.XContainerListener
127 virtual void SAL_CALL
elementInserted( const ContainerEvent
& aEvent
) throw(RuntimeException
);
128 virtual void SAL_CALL
elementRemoved ( const ContainerEvent
& aEvent
) throw(RuntimeException
);
129 virtual void SAL_CALL
elementReplaced( const ContainerEvent
& aEvent
) throw(RuntimeException
);
131 // lang.XEventListener
132 virtual void SAL_CALL
disposing( const EventObject
& aEvent
) throw(RuntimeException
);
135 Any
getUINameFromID( const rtl::OUString
& rId
);
136 Any
getUINameFromCache( const rtl::OUString
& rId
);
137 Sequence
< rtl::OUString
> getAllIds();
138 sal_Bool
fillCache();
141 typedef ::std::hash_map
< ::rtl::OUString
,
144 ::std::equal_to
< ::rtl::OUString
> > IdToInfoCache
;
146 sal_Bool
initializeConfigAccess();
148 rtl::OUString m_aConfigCategoryAccess
;
149 rtl::OUString m_aPropUIName
;
150 Reference
< XNameAccess
> m_xGenericUICategories
;
151 Reference
< XMultiServiceFactory
> m_xServiceManager
;
152 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
153 Reference
< XNameAccess
> m_xConfigAccess
;
154 sal_Bool m_bConfigAccessInitialized
;
155 sal_Bool m_bCacheFilled
;
156 IdToInfoCache m_aIdCache
;
159 //*****************************************************************************************************************
160 // XInterface, XTypeProvider
161 //*****************************************************************************************************************
163 ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( const rtl::OUString
& aModuleName
, const Reference
< XNameAccess
>& rGenericUICategories
, const Reference
< XMultiServiceFactory
>& rServiceManager
) :
165 m_aConfigCategoryAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS
)),
166 m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_NAME
)),
167 m_xGenericUICategories( rGenericUICategories
),
168 m_xServiceManager( rServiceManager
),
169 m_bConfigAccessInitialized( sal_False
),
170 m_bCacheFilled( sal_False
)
172 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::ConfigurationAccess_UICategory" );
173 // Create configuration hierachical access name
174 m_aConfigCategoryAccess
+= aModuleName
;
175 m_aConfigCategoryAccess
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_CATEGORY_ELEMENT_ACCESS
));
177 m_xConfigProvider
= Reference
< XMultiServiceFactory
>( rServiceManager
->createInstance(SERVICENAME_CFGPROVIDER
),UNO_QUERY
);
180 ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
183 ResetableGuard
aLock( m_aLock
);
184 Reference
< XContainer
> xContainer( m_xConfigAccess
, UNO_QUERY
);
185 if ( xContainer
.is() )
186 xContainer
->removeContainerListener( this );
190 Any SAL_CALL
ConfigurationAccess_UICategory::getByName( const ::rtl::OUString
& rId
)
191 throw ( NoSuchElementException
, WrappedTargetException
, RuntimeException
)
193 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getByName" );
194 ResetableGuard
aLock( m_aLock
);
195 if ( !m_bConfigAccessInitialized
)
197 initializeConfigAccess();
198 m_bConfigAccessInitialized
= sal_True
;
203 Any a
= getUINameFromID( rId
);
206 throw NoSuchElementException();
211 Sequence
< ::rtl::OUString
> SAL_CALL
ConfigurationAccess_UICategory::getElementNames()
212 throw ( RuntimeException
)
214 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementNames" );
218 sal_Bool SAL_CALL
ConfigurationAccess_UICategory::hasByName( const ::rtl::OUString
& rId
)
219 throw (::com::sun::star::uno::RuntimeException
)
221 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasByName" );
222 return getByName( rId
).hasValue();
226 Type SAL_CALL
ConfigurationAccess_UICategory::getElementType()
227 throw ( RuntimeException
)
229 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementType" );
230 return( ::getCppuType( (const rtl::OUString
*)NULL
) );
233 sal_Bool SAL_CALL
ConfigurationAccess_UICategory::hasElements()
234 throw ( RuntimeException
)
236 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasElements" );
237 // There must be global categories!
241 sal_Bool
ConfigurationAccess_UICategory::fillCache()
243 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::fillCache" );
244 RTL_LOGFILE_CONTEXT( aLog
, "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
246 if ( m_bCacheFilled
)
250 rtl::OUString aUIName
;
251 Sequence
< ::rtl::OUString
> aNameSeq
= m_xConfigAccess
->getElementNames();
253 for ( i
= 0; i
< aNameSeq
.getLength(); i
++ )
257 Reference
< XNameAccess
> xNameAccess(m_xConfigAccess
->getByName( aNameSeq
[i
] ),UNO_QUERY
);
258 if ( xNameAccess
.is() )
260 xNameAccess
->getByName( m_aPropUIName
) >>= aUIName
;
262 m_aIdCache
.insert( IdToInfoCache::value_type( aNameSeq
[i
], aUIName
));
265 catch ( com::sun::star::lang::WrappedTargetException
& )
268 catch ( com::sun::star::container::NoSuchElementException
& )
273 m_bCacheFilled
= sal_True
;
278 Any
ConfigurationAccess_UICategory::getUINameFromID( const rtl::OUString
& rId
)
280 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromID" );
285 a
= getUINameFromCache( rId
);
288 // Try to ask our global commands configuration access
289 if ( m_xGenericUICategories
.is() )
293 return m_xGenericUICategories
->getByName( rId
);
295 catch ( com::sun::star::lang::WrappedTargetException
& )
298 catch ( com::sun::star::container::NoSuchElementException
& )
304 catch( com::sun::star::container::NoSuchElementException
& )
307 catch ( com::sun::star::lang::WrappedTargetException
& )
314 Any
ConfigurationAccess_UICategory::getUINameFromCache( const rtl::OUString
& rId
)
316 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromCache" );
319 IdToInfoCache::const_iterator pIter
= m_aIdCache
.find( rId
);
320 if ( pIter
!= m_aIdCache
.end() )
326 Sequence
< rtl::OUString
> ConfigurationAccess_UICategory::getAllIds()
328 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getAllIds" );
330 ResetableGuard
aLock( m_aLock
);
332 if ( !m_bConfigAccessInitialized
)
334 initializeConfigAccess();
335 m_bConfigAccessInitialized
= sal_True
;
339 if ( m_xConfigAccess
.is() )
342 Reference
< XNameAccess
> xNameAccess
;
346 Sequence
< ::rtl::OUString
> aNameSeq
= m_xConfigAccess
->getElementNames();
348 if ( m_xGenericUICategories
.is() )
350 // Create concat list of supported user interface commands of the module
351 Sequence
< ::rtl::OUString
> aGenericNameSeq
= m_xGenericUICategories
->getElementNames();
352 sal_uInt32 nCount1
= aNameSeq
.getLength();
353 sal_uInt32 nCount2
= aGenericNameSeq
.getLength();
355 aNameSeq
.realloc( nCount1
+ nCount2
);
356 ::rtl::OUString
* pNameSeq
= aNameSeq
.getArray();
357 const ::rtl::OUString
* pGenericSeq
= aGenericNameSeq
.getConstArray();
358 for ( sal_uInt32 i
= 0; i
< nCount2
; i
++ )
359 pNameSeq
[nCount1
+i
] = pGenericSeq
[i
];
364 catch( com::sun::star::container::NoSuchElementException
& )
367 catch ( com::sun::star::lang::WrappedTargetException
& )
372 return Sequence
< rtl::OUString
>();
375 sal_Bool
ConfigurationAccess_UICategory::initializeConfigAccess()
377 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::initializeConfigAccess" );
378 Sequence
< Any
> aArgs( 1 );
379 PropertyValue aPropValue
;
383 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
384 aPropValue
.Value
<<= m_aConfigCategoryAccess
;
385 aArgs
[0] <<= aPropValue
;
387 m_xConfigAccess
= Reference
< XNameAccess
>( m_xConfigProvider
->createInstanceWithArguments(SERVICENAME_CFGREADACCESS
,aArgs
),UNO_QUERY
);
388 if ( m_xConfigAccess
.is() )
390 // Add as container listener
391 Reference
< XContainer
> xContainer( m_xConfigAccess
, UNO_QUERY
);
392 if ( xContainer
.is() )
393 xContainer
->addContainerListener( this );
398 catch ( WrappedTargetException
& )
408 // container.XContainerListener
409 void SAL_CALL
ConfigurationAccess_UICategory::elementInserted( const ContainerEvent
& ) throw(RuntimeException
)
411 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementInserted" );
414 void SAL_CALL
ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent
& ) throw(RuntimeException
)
416 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementRemoved " );
419 void SAL_CALL
ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent
& ) throw(RuntimeException
)
421 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementReplaced" );
424 // lang.XEventListener
425 void SAL_CALL
ConfigurationAccess_UICategory::disposing( const EventObject
& aEvent
) throw(RuntimeException
)
427 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::disposing" );
429 // remove our reference to the config access
430 ResetableGuard
aLock( m_aLock
);
432 Reference
< XInterface
> xIfac1( aEvent
.Source
, UNO_QUERY
);
433 Reference
< XInterface
> xIfac2( m_xConfigAccess
, UNO_QUERY
);
434 if ( xIfac1
== xIfac2
)
435 m_xConfigAccess
.clear();
438 //*****************************************************************************************************************
439 // XInterface, XTypeProvider, XServiceInfo
440 //*****************************************************************************************************************
441 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UICategoryDescription
,
442 ::cppu::OWeakObject
,
443 SERVICENAME_UICATEGORYDESCRIPTION
,
444 IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION
447 DEFINE_INIT_SERVICE ( UICategoryDescription
, {} )
449 UICategoryDescription::UICategoryDescription( const Reference
< XMultiServiceFactory
>& xServiceManager
) :
450 UICommandDescription(xServiceManager
,true)
452 Reference
< XNameAccess
> xEmpty
;
453 rtl::OUString
aGenericCategories( RTL_CONSTASCII_USTRINGPARAM( "GenericCategories" ));
454 m_xGenericUICommands
= new ConfigurationAccess_UICategory( aGenericCategories
, xEmpty
, xServiceManager
);
456 // insert generic categories mappings
457 m_aModuleToCommandFileMap
.insert( ModuleToCommandFileMap::value_type(
458 rtl::OUString::createFromAscii( GENERIC_MODULE_NAME
), aGenericCategories
));
460 UICommandsHashMap::iterator pCatIter
= m_aUICommandsHashMap
.find( aGenericCategories
);
461 if ( pCatIter
!= m_aUICommandsHashMap
.end() )
462 pCatIter
->second
= m_xGenericUICommands
;
464 impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
467 UICategoryDescription::~UICategoryDescription()
470 Reference
< XNameAccess
> UICategoryDescription::impl_createConfigAccess(const ::rtl::OUString
& _sName
)
472 return new ConfigurationAccess_UICategory( _sName
,m_xGenericUICommands
,m_xServiceManager
);
475 } // namespace framework