Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "uiconfiguration/uicategorydescription.hxx"
21 : #include <threadhelp/resetableguard.hxx>
22 : #include "services.h"
23 :
24 : #include "properties.h"
25 :
26 : #include "helper/mischelper.hxx"
27 :
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>
34 :
35 : #include <rtl/ustrbuf.hxx>
36 : #include <cppuhelper/implbase2.hxx>
37 : #include <unotools/configmgr.hxx>
38 :
39 : #include <vcl/mnemonic.hxx>
40 : #include <comphelper/sequence.hxx>
41 :
42 : //_________________________________________________________________________________________________________________
43 : // Defines
44 : //_________________________________________________________________________________________________________________
45 :
46 : using namespace com::sun::star::uno;
47 : using namespace com::sun::star::lang;
48 : using namespace com::sun::star::beans;
49 : using namespace com::sun::star::configuration;
50 : using namespace com::sun::star::container;
51 : using namespace ::com::sun::star::frame;
52 :
53 : //_________________________________________________________________________________________________________________
54 : // Namespace
55 : //_________________________________________________________________________________________________________________
56 :
57 : struct ModuleToCategory
58 : {
59 : const char* pModuleId;
60 : const char* pCommands;
61 : };
62 :
63 : static const char GENERIC_MODULE_NAME[] = "generic";
64 : static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
65 : static const char CONFIGURATION_CATEGORY_ELEMENT_ACCESS[] = "/Commands/Categories";
66 : static const char CONFIGURATION_PROPERTY_NAME[] = "Name";
67 :
68 : namespace framework
69 : {
70 :
71 : //*****************************************************************************************************************
72 : // Configuration access class for PopupMenuControllerFactory implementation
73 : //*****************************************************************************************************************
74 :
75 : class ConfigurationAccess_UICategory : // Order is necessary for right initialization!
76 : private ThreadHelpBase ,
77 : public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
78 : {
79 : public:
80 : ConfigurationAccess_UICategory( const OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XComponentContext >& rxContext );
81 : virtual ~ConfigurationAccess_UICategory();
82 :
83 : // XNameAccess
84 : virtual ::com::sun::star::uno::Any SAL_CALL getByName( const OUString& aName )
85 : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
86 :
87 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getElementNames()
88 : throw (::com::sun::star::uno::RuntimeException);
89 :
90 : virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
91 : throw (::com::sun::star::uno::RuntimeException);
92 :
93 : // XElementAccess
94 : virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
95 : throw (::com::sun::star::uno::RuntimeException);
96 :
97 : virtual sal_Bool SAL_CALL hasElements()
98 : throw (::com::sun::star::uno::RuntimeException);
99 :
100 : // container.XContainerListener
101 : virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
102 : virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
103 : virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
104 :
105 : // lang.XEventListener
106 : virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
107 :
108 : protected:
109 : Any getUINameFromID( const OUString& rId );
110 : Any getUINameFromCache( const OUString& rId );
111 : Sequence< OUString > getAllIds();
112 : sal_Bool fillCache();
113 :
114 : private:
115 : typedef ::boost::unordered_map< OUString,
116 : OUString,
117 : OUStringHash,
118 : ::std::equal_to< OUString > > IdToInfoCache;
119 :
120 : sal_Bool initializeConfigAccess();
121 :
122 : OUString m_aConfigCategoryAccess;
123 : OUString m_aPropUIName;
124 : Reference< XNameAccess > m_xGenericUICategories;
125 : Reference< XMultiServiceFactory > m_xConfigProvider;
126 : Reference< XNameAccess > m_xConfigAccess;
127 : Reference< XContainerListener > m_xConfigListener;
128 : sal_Bool m_bConfigAccessInitialized;
129 : sal_Bool m_bCacheFilled;
130 : IdToInfoCache m_aIdCache;
131 : };
132 :
133 : //*****************************************************************************************************************
134 : // XInterface, XTypeProvider
135 : //*****************************************************************************************************************
136 :
137 1 : ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( const OUString& aModuleName, const Reference< XNameAccess >& rGenericUICategories, const Reference< XComponentContext >& rxContext ) :
138 : ThreadHelpBase(),
139 : m_aConfigCategoryAccess( CONFIGURATION_ROOT_ACCESS ),
140 : m_aPropUIName( CONFIGURATION_PROPERTY_NAME ),
141 : m_xGenericUICategories( rGenericUICategories ),
142 : m_bConfigAccessInitialized( sal_False ),
143 1 : m_bCacheFilled( sal_False )
144 : {
145 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::ConfigurationAccess_UICategory" );
146 : // Create configuration hierachical access name
147 1 : m_aConfigCategoryAccess += aModuleName;
148 1 : m_aConfigCategoryAccess += OUString( CONFIGURATION_CATEGORY_ELEMENT_ACCESS );
149 :
150 1 : m_xConfigProvider = theDefaultProvider::get( rxContext );
151 1 : }
152 :
153 3 : ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
154 : {
155 : // SAFE
156 1 : ResetableGuard aLock( m_aLock );
157 2 : Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
158 1 : if ( xContainer.is() )
159 1 : xContainer->removeContainerListener(m_xConfigListener);
160 2 : }
161 :
162 : // XNameAccess
163 0 : Any SAL_CALL ConfigurationAccess_UICategory::getByName( const OUString& rId )
164 : throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
165 : {
166 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getByName" );
167 0 : ResetableGuard aLock( m_aLock );
168 0 : if ( !m_bConfigAccessInitialized )
169 : {
170 0 : initializeConfigAccess();
171 0 : m_bConfigAccessInitialized = sal_True;
172 0 : fillCache();
173 : }
174 :
175 : // SAFE
176 0 : Any a = getUINameFromID( rId );
177 :
178 0 : if ( !a.hasValue() )
179 0 : throw NoSuchElementException();
180 :
181 0 : return a;
182 : }
183 :
184 0 : Sequence< OUString > SAL_CALL ConfigurationAccess_UICategory::getElementNames()
185 : throw ( RuntimeException )
186 : {
187 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getElementNames" );
188 0 : return getAllIds();
189 : }
190 :
191 0 : sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasByName( const OUString& rId )
192 : throw (::com::sun::star::uno::RuntimeException)
193 : {
194 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::hasByName" );
195 0 : return getByName( rId ).hasValue();
196 : }
197 :
198 : // XElementAccess
199 0 : Type SAL_CALL ConfigurationAccess_UICategory::getElementType()
200 : throw ( RuntimeException )
201 : {
202 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getElementType" );
203 0 : return( ::getCppuType( (const OUString*)NULL ) );
204 : }
205 :
206 0 : sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasElements()
207 : throw ( RuntimeException )
208 : {
209 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::hasElements" );
210 : // There must be global categories!
211 0 : return sal_True;
212 : }
213 :
214 0 : sal_Bool ConfigurationAccess_UICategory::fillCache()
215 : {
216 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::fillCache" );
217 : SAL_INFO( "fwk", "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
218 :
219 0 : if ( m_bCacheFilled )
220 0 : return sal_True;
221 :
222 0 : sal_Int32 i( 0 );
223 0 : OUString aUIName;
224 0 : Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
225 :
226 0 : for ( i = 0; i < aNameSeq.getLength(); i++ )
227 : {
228 : try
229 : {
230 0 : Reference< XNameAccess > xNameAccess(m_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
231 0 : if ( xNameAccess.is() )
232 : {
233 0 : xNameAccess->getByName( m_aPropUIName ) >>= aUIName;
234 :
235 0 : m_aIdCache.insert( IdToInfoCache::value_type( aNameSeq[i], aUIName ));
236 0 : }
237 : }
238 0 : catch ( const com::sun::star::lang::WrappedTargetException& )
239 : {
240 : }
241 0 : catch ( const com::sun::star::container::NoSuchElementException& )
242 : {
243 : }
244 : }
245 :
246 0 : m_bCacheFilled = sal_True;
247 :
248 0 : return sal_True;
249 : }
250 :
251 0 : Any ConfigurationAccess_UICategory::getUINameFromID( const OUString& rId )
252 : {
253 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getUINameFromID" );
254 0 : Any a;
255 :
256 : try
257 : {
258 0 : a = getUINameFromCache( rId );
259 0 : if ( !a.hasValue() )
260 : {
261 : // Try to ask our global commands configuration access
262 0 : if ( m_xGenericUICategories.is() )
263 : {
264 : try
265 : {
266 0 : return m_xGenericUICategories->getByName( rId );
267 : }
268 0 : catch ( const com::sun::star::lang::WrappedTargetException& )
269 : {
270 : }
271 0 : catch ( const com::sun::star::container::NoSuchElementException& )
272 : {
273 : }
274 : }
275 : }
276 : }
277 0 : catch( const com::sun::star::container::NoSuchElementException& )
278 : {
279 : }
280 0 : catch ( const com::sun::star::lang::WrappedTargetException& )
281 : {
282 : }
283 :
284 0 : return a;
285 : }
286 :
287 0 : Any ConfigurationAccess_UICategory::getUINameFromCache( const OUString& rId )
288 : {
289 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getUINameFromCache" );
290 0 : Any a;
291 :
292 0 : IdToInfoCache::const_iterator pIter = m_aIdCache.find( rId );
293 0 : if ( pIter != m_aIdCache.end() )
294 0 : a <<= pIter->second;
295 :
296 0 : return a;
297 : }
298 :
299 0 : Sequence< OUString > ConfigurationAccess_UICategory::getAllIds()
300 : {
301 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::getAllIds" );
302 : // SAFE
303 0 : ResetableGuard aLock( m_aLock );
304 :
305 0 : if ( !m_bConfigAccessInitialized )
306 : {
307 0 : initializeConfigAccess();
308 0 : m_bConfigAccessInitialized = sal_True;
309 0 : fillCache();
310 : }
311 :
312 0 : if ( m_xConfigAccess.is() )
313 : {
314 0 : Any a;
315 0 : Reference< XNameAccess > xNameAccess;
316 :
317 : try
318 : {
319 0 : Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
320 :
321 0 : if ( m_xGenericUICategories.is() )
322 : {
323 : // Create concat list of supported user interface commands of the module
324 0 : Sequence< OUString > aGenericNameSeq = m_xGenericUICategories->getElementNames();
325 0 : sal_uInt32 nCount1 = aNameSeq.getLength();
326 0 : sal_uInt32 nCount2 = aGenericNameSeq.getLength();
327 :
328 0 : aNameSeq.realloc( nCount1 + nCount2 );
329 0 : OUString* pNameSeq = aNameSeq.getArray();
330 0 : const OUString* pGenericSeq = aGenericNameSeq.getConstArray();
331 0 : for ( sal_uInt32 i = 0; i < nCount2; i++ )
332 0 : pNameSeq[nCount1+i] = pGenericSeq[i];
333 : }
334 :
335 0 : return aNameSeq;
336 : }
337 0 : catch( const com::sun::star::container::NoSuchElementException& )
338 : {
339 : }
340 0 : catch ( const com::sun::star::lang::WrappedTargetException& )
341 : {
342 0 : }
343 : }
344 :
345 0 : return Sequence< OUString >();
346 : }
347 :
348 0 : sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess()
349 : {
350 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::initializeConfigAccess" );
351 0 : Sequence< Any > aArgs( 1 );
352 0 : PropertyValue aPropValue;
353 :
354 : try
355 : {
356 0 : aPropValue.Name = OUString( "nodepath" );
357 0 : aPropValue.Value <<= m_aConfigCategoryAccess;
358 0 : aArgs[0] <<= aPropValue;
359 :
360 0 : m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
361 0 : if ( m_xConfigAccess.is() )
362 : {
363 : // Add as container listener
364 0 : Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
365 0 : if ( xContainer.is() )
366 : {
367 0 : m_xConfigListener = new WeakContainerListener(this);
368 0 : xContainer->addContainerListener(m_xConfigListener);
369 0 : }
370 : }
371 :
372 0 : return sal_True;
373 : }
374 0 : catch ( const WrappedTargetException& )
375 : {
376 : }
377 0 : catch ( const Exception& )
378 : {
379 : }
380 :
381 0 : return sal_False;
382 : }
383 :
384 : // container.XContainerListener
385 0 : void SAL_CALL ConfigurationAccess_UICategory::elementInserted( const ContainerEvent& ) throw(RuntimeException)
386 : {
387 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::elementInserted" );
388 0 : }
389 :
390 0 : void SAL_CALL ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
391 : {
392 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::elementRemoved " );
393 0 : }
394 :
395 0 : void SAL_CALL ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
396 : {
397 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::elementReplaced" );
398 0 : }
399 :
400 : // lang.XEventListener
401 0 : void SAL_CALL ConfigurationAccess_UICategory::disposing( const EventObject& aEvent ) throw(RuntimeException)
402 : {
403 : SAL_INFO( "fwk", "framework Ocke.Janssen@sun.com ConfigurationAccess_UICategory::disposing" );
404 : // SAFE
405 : // remove our reference to the config access
406 0 : ResetableGuard aLock( m_aLock );
407 :
408 0 : Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
409 0 : Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
410 0 : if ( xIfac1 == xIfac2 )
411 0 : m_xConfigAccess.clear();
412 0 : }
413 :
414 : //*****************************************************************************************************************
415 : // XInterface, XTypeProvider, XServiceInfo
416 : //*****************************************************************************************************************
417 :
418 : #define SERVICENAME_UICATEGORYDESCRIPTION DECLARE_ASCII("com.sun.star.ui.UICategoryDescription" )
419 : #define IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION DECLARE_ASCII("com.sun.star.comp.framework.UICategoryDescription" )
420 :
421 506 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2 ( UICategoryDescription ,
422 : ::cppu::OWeakObject ,
423 : SERVICENAME_UICATEGORYDESCRIPTION ,
424 : IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION
425 : )
426 :
427 1 : DEFINE_INIT_SERVICE ( UICategoryDescription, {} )
428 :
429 1 : UICategoryDescription::UICategoryDescription( const Reference< XComponentContext >& rxContext ) :
430 1 : UICommandDescription(rxContext,true)
431 : {
432 1 : Reference< XNameAccess > xEmpty;
433 2 : OUString aGenericCategories( "GenericCategories" );
434 1 : m_xGenericUICommands = new ConfigurationAccess_UICategory( aGenericCategories, xEmpty, rxContext );
435 :
436 : // insert generic categories mappings
437 : m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type(
438 1 : OUString(GENERIC_MODULE_NAME ), aGenericCategories ));
439 :
440 1 : UICommandsHashMap::iterator pCatIter = m_aUICommandsHashMap.find( aGenericCategories );
441 1 : if ( pCatIter != m_aUICommandsHashMap.end() )
442 0 : pCatIter->second = m_xGenericUICommands;
443 :
444 2 : impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
445 1 : }
446 :
447 2 : UICategoryDescription::~UICategoryDescription()
448 : {
449 2 : }
450 0 : Reference< XNameAccess > UICategoryDescription::impl_createConfigAccess(const OUString& _sName)
451 : {
452 0 : return new ConfigurationAccess_UICategory( _sName, m_xGenericUICommands, m_xContext );
453 : }
454 :
455 : } // namespace framework
456 :
457 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|