LibreOffice Module framework (master) 1
uicategorydescription.cxx
Go to the documentation of this file.
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
21
22#include <helper/mischelper.hxx>
23
24#include <com/sun/star/configuration/theDefaultProvider.hpp>
25#include <com/sun/star/container/XNameAccess.hpp>
26#include <com/sun/star/container/XContainer.hpp>
27#include <com/sun/star/lang/XServiceInfo.hpp>
28
29#include <sal/log.hxx>
33
35
36#include <string_view>
37#include <unordered_map>
38
39using namespace com::sun::star::uno;
40using namespace com::sun::star::lang;
41using namespace com::sun::star::beans;
42using namespace com::sun::star::configuration;
43using namespace com::sun::star::container;
44using namespace framework;
45
46namespace {
47
48class ConfigurationAccess_UICategory : public ::cppu::WeakImplHelper<XNameAccess,XContainerListener>
49{
50 std::mutex aMutex;
51 public:
52 ConfigurationAccess_UICategory( std::u16string_view aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XComponentContext >& rxContext );
53 virtual ~ConfigurationAccess_UICategory() override;
54
55 // XNameAccess
56 virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override;
57
58 virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
59
60 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
61
62 // XElementAccess
63 virtual css::uno::Type SAL_CALL getElementType() override;
64
65 virtual sal_Bool SAL_CALL hasElements() override;
66
67 // container.XContainerListener
68 virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) override;
69 virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) override;
70 virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) override;
71
72 // lang.XEventListener
73 virtual void SAL_CALL disposing( const EventObject& aEvent ) override;
74
75 protected:
76 Any getUINameFromID( const OUString& rId );
77 Any getUINameFromCache( const OUString& rId );
78 Sequence< OUString > getAllIds();
79 void fillCache();
80
81 private:
82 typedef std::unordered_map< OUString,
83 OUString > IdToInfoCache;
84
85 void initializeConfigAccess();
86
87 OUString m_aConfigCategoryAccess;
88 OUString m_aPropUIName;
89 Reference< XNameAccess > m_xGenericUICategories;
94 bool m_bCacheFilled;
95 IdToInfoCache m_aIdCache;
96};
97
98// XInterface, XTypeProvider
99
100ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( std::u16string_view aModuleName, const Reference< XNameAccess >& rGenericUICategories, const Reference< XComponentContext >& rxContext ) :
101 // Create configuration hierarchical access name
102 m_aConfigCategoryAccess(
103 OUString::Concat("/org.openoffice.Office.UI.") + aModuleName + "/Commands/Categories"),
104 m_aPropUIName( "Name" ),
105 m_xGenericUICategories( rGenericUICategories ),
106 m_xConfigProvider(theDefaultProvider::get( rxContext )),
108 m_bCacheFilled( false )
109{
110}
111
112ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
113{
114 // SAFE
115 std::unique_lock g(aMutex);
116 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
117 if ( xContainer.is() )
118 xContainer->removeContainerListener(m_xConfigListener);
119}
120
121// XNameAccess
122Any SAL_CALL ConfigurationAccess_UICategory::getByName( const OUString& rId )
123{
124 std::unique_lock g(aMutex);
126 {
127 initializeConfigAccess();
129 fillCache();
130 }
131
132 // SAFE
133 Any a = getUINameFromID( rId );
134
135 if ( !a.hasValue() )
136 throw NoSuchElementException();
137
138 return a;
139}
140
141Sequence< OUString > SAL_CALL ConfigurationAccess_UICategory::getElementNames()
142{
143 return getAllIds();
144}
145
146sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasByName( const OUString& rId )
147{
148 return getByName( rId ).hasValue();
149}
150
151// XElementAccess
152Type SAL_CALL ConfigurationAccess_UICategory::getElementType()
153{
155}
156
157sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasElements()
158{
159 // There must be global categories!
160 return true;
161}
162
163void ConfigurationAccess_UICategory::fillCache()
164{
165 SAL_INFO( "fwk", "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
166
167 if ( m_bCacheFilled )
168 return;
169
170 OUString aUIName;
171 const Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
172
173 for ( OUString const & rName : aNameSeq )
174 {
175 try
176 {
177 Reference< XNameAccess > xNameAccess(m_xConfigAccess->getByName( rName ),UNO_QUERY);
178 if ( xNameAccess.is() )
179 {
180 xNameAccess->getByName( m_aPropUIName ) >>= aUIName;
181
182 m_aIdCache.emplace( rName, aUIName );
183 }
184 }
185 catch ( const css::lang::WrappedTargetException& )
186 {
187 }
188 catch ( const css::container::NoSuchElementException& )
189 {
190 }
191 }
192
193 m_bCacheFilled = true;
194}
195
196Any ConfigurationAccess_UICategory::getUINameFromID( const OUString& rId )
197{
198 Any a;
199
200 try
201 {
202 a = getUINameFromCache( rId );
203 if ( !a.hasValue() )
204 {
205 // Try to ask our global commands configuration access
206 if ( m_xGenericUICategories.is() )
207 {
208 try
209 {
210 return m_xGenericUICategories->getByName( rId );
211 }
212 catch ( const css::lang::WrappedTargetException& )
213 {
214 }
215 catch ( const css::container::NoSuchElementException& )
216 {
217 }
218 }
219 }
220 }
221 catch( const css::container::NoSuchElementException& )
222 {
223 }
224 catch ( const css::lang::WrappedTargetException& )
225 {
226 }
227
228 return a;
229}
230
231Any ConfigurationAccess_UICategory::getUINameFromCache( const OUString& rId )
232{
233 Any a;
234
235 IdToInfoCache::const_iterator pIter = m_aIdCache.find( rId );
236 if ( pIter != m_aIdCache.end() )
237 a <<= pIter->second;
238
239 return a;
240}
241
242Sequence< OUString > ConfigurationAccess_UICategory::getAllIds()
243{
244 // SAFE
245 std::unique_lock g(aMutex);
246
248 {
249 initializeConfigAccess();
251 fillCache();
252 }
253
254 if ( m_xConfigAccess.is() )
255 {
256 try
257 {
258 Sequence< OUString > aNameSeq = m_xConfigAccess->getElementNames();
259
260 if ( m_xGenericUICategories.is() )
261 {
262 // Create concat list of supported user interface commands of the module
263 Sequence< OUString > aGenericNameSeq = m_xGenericUICategories->getElementNames();
264 sal_uInt32 nCount1 = aNameSeq.getLength();
265 sal_uInt32 nCount2 = aGenericNameSeq.getLength();
266
267 aNameSeq.realloc( nCount1 + nCount2 );
268 OUString* pNameSeq = aNameSeq.getArray();
269 const OUString* pGenericSeq = aGenericNameSeq.getConstArray();
270 for ( sal_uInt32 i = 0; i < nCount2; i++ )
271 pNameSeq[nCount1+i] = pGenericSeq[i];
272 }
273
274 return aNameSeq;
275 }
276 catch( const css::container::NoSuchElementException& )
277 {
278 }
279 catch ( const css::lang::WrappedTargetException& )
280 {
281 }
282 }
283
284 return Sequence< OUString >();
285}
286
287void ConfigurationAccess_UICategory::initializeConfigAccess()
288{
289 try
290 {
292 {
293 {"nodepath", Any(m_aConfigCategoryAccess)}
294 }));
295
296 m_xConfigAccess.set( m_xConfigProvider->createInstanceWithArguments(
297 "com.sun.star.configuration.ConfigurationAccess", aArgs ),UNO_QUERY );
298 if ( m_xConfigAccess.is() )
299 {
300 // Add as container listener
301 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
302 if ( xContainer.is() )
303 {
305 xContainer->addContainerListener(m_xConfigListener);
306 }
307 }
308 }
309 catch ( const WrappedTargetException& )
310 {
311 }
312 catch ( const Exception& )
313 {
314 }
315}
316
317// container.XContainerListener
318void SAL_CALL ConfigurationAccess_UICategory::elementInserted( const ContainerEvent& )
319{
320}
321
322void SAL_CALL ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent& )
323{
324}
325
326void SAL_CALL ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent& )
327{
328}
329
330// lang.XEventListener
331void SAL_CALL ConfigurationAccess_UICategory::disposing( const EventObject& aEvent )
332{
333 // SAFE
334 // remove our reference to the config access
335 std::unique_lock g(aMutex);
336
337 Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
338 Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
339 if ( xIfac1 == xIfac2 )
340 m_xConfigAccess.clear();
341}
342
343class UICategoryDescription : public UICommandDescription
344{
345public:
346 explicit UICategoryDescription( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
347
348 virtual OUString SAL_CALL getImplementationName() override
349 {
350 return "com.sun.star.comp.framework.UICategoryDescription";
351 }
352
353 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
354 {
355 return cppu::supportsService(this, ServiceName);
356 }
357
358 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
359 {
360 return {"com.sun.star.ui.UICategoryDescription"};
361 }
362
363};
364
365UICategoryDescription::UICategoryDescription( const Reference< XComponentContext >& rxContext ) :
366 UICommandDescription(rxContext,true)
367{
368 SvtSysLocale aSysLocale;
369 const LanguageTag& rCurrentLanguage = aSysLocale.GetUILanguageTag();
371 OUString aGenericCategories( "GenericCategories" );
372 m_xGenericUICommands[rCurrentLanguage] = new ConfigurationAccess_UICategory( aGenericCategories, xEmpty, rxContext );
373
374 // insert generic categories mappings
375 m_aModuleToCommandFileMap.emplace( OUString("generic"), aGenericCategories );
376
377 auto& rMap = m_aUICommandsHashMap[rCurrentLanguage];
378 UICommandsHashMap::iterator pCatIter = rMap.find( aGenericCategories );
379 if ( pCatIter != rMap.end() )
380 pCatIter->second = m_xGenericUICommands[rCurrentLanguage];
381
382 impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
383}
384
385}
386
387extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
389 css::uno::XComponentContext *context,
390 css::uno::Sequence<css::uno::Any> const &)
391{
392 return cppu::acquire(new UICategoryDescription(context));
393}
394
395/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
const LanguageTag & GetUILanguageTag() const
css::uno::Type const & get()
virtual sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::container::XNameAccess > m_xConfigAccess
uno_Any a
void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
#define SAL_INFO(area, stream)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
std::mutex aMutex
OUString aUIName
unsigned char sal_Bool
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_UICategoryDescription_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Reference< XMultiServiceFactory > m_xConfigProvider
Reference< XNameAccess > m_xGenericUICommands
Reference< XContainerListener > m_xConfigListener
bool m_bConfigAccessInitialized
bool m_bCacheFilled