LibreOffice Module framework (master) 1
uiconfigurationmanager.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
24#include <menuconfiguration.hxx>
27
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/container/ElementExistException.hpp>
30#include <com/sun/star/container/XIndexContainer.hpp>
31#include <com/sun/star/embed/ElementModes.hpp>
32#include <com/sun/star/embed/InvalidStorageException.hpp>
33#include <com/sun/star/embed/StorageWrappedTargetException.hpp>
34#include <com/sun/star/embed/XTransactedObject.hpp>
35#include <com/sun/star/lang/IllegalAccessException.hpp>
36#include <com/sun/star/lang/DisposedException.hpp>
37#include <com/sun/star/io/IOException.hpp>
38#include <com/sun/star/io/XStream.hpp>
39#include <com/sun/star/ui/UIElementType.hpp>
40#include <com/sun/star/ui/ConfigurationEvent.hpp>
41#include <com/sun/star/ui/DocumentAcceleratorConfiguration.hpp>
42#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
43#include <com/sun/star/ui/XUIConfigurationManager2.hpp>
44#include <com/sun/star/lang/XComponent.hpp>
45#include <com/sun/star/lang/XServiceInfo.hpp>
46
54#include <utility>
55#include <vcl/svapp.hxx>
56#include <sal/log.hxx>
57#include <o3tl/string_view.hxx>
58
59#include <mutex>
60#include <string_view>
61#include <unordered_map>
62
63using namespace com::sun::star::uno;
64using namespace com::sun::star::io;
65using namespace com::sun::star::embed;
66using namespace com::sun::star::lang;
67using namespace com::sun::star::container;
68using namespace com::sun::star::beans;
69using namespace com::sun::star::ui;
70using namespace framework;
71
72namespace {
73
74class UIConfigurationManager : public ::cppu::WeakImplHelper<
75 css::lang::XServiceInfo ,
76 css::ui::XUIConfigurationManager2 >
77{
78public:
79 virtual OUString SAL_CALL getImplementationName() override
80 {
81 return "com.sun.star.comp.framework.UIConfigurationManager";
82 }
83
84 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
85 {
86 return cppu::supportsService(this, ServiceName);
87 }
88
89 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
90 {
91 return {"com.sun.star.ui.UIConfigurationManager"};
92 }
93
94 explicit UIConfigurationManager( css::uno::Reference< css::uno::XComponentContext > xContext );
95
96 // XComponent
97 virtual void SAL_CALL dispose() override;
98 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
99 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
100
101 // XUIConfiguration
102 virtual void SAL_CALL addConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) override;
103 virtual void SAL_CALL removeConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) override;
104
105 // XUIConfigurationManager
106 virtual void SAL_CALL reset() override;
107 virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getUIElementsInfo( sal_Int16 ElementType ) override;
108 virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL createSettings( ) override;
109 virtual sal_Bool SAL_CALL hasSettings( const OUString& ResourceURL ) override;
110 virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getSettings( const OUString& ResourceURL, sal_Bool bWriteable ) override;
111 virtual void SAL_CALL replaceSettings( const OUString& ResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) override;
112 virtual void SAL_CALL removeSettings( const OUString& ResourceURL ) override;
113 virtual void SAL_CALL insertSettings( const OUString& NewResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) override;
114 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getImageManager() override;
115 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL getShortCutManager() override;
116 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL createShortCutManager() override;
117 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getEventsManager() override;
118
119 // XUIConfigurationPersistence
120 virtual void SAL_CALL reload() override;
121 virtual void SAL_CALL store() override;
122 virtual void SAL_CALL storeToStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) override;
123 virtual sal_Bool SAL_CALL isModified() override;
124 virtual sal_Bool SAL_CALL isReadOnly() override;
125
126 // XUIConfigurationStorage
127 virtual void SAL_CALL setStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) override;
128 virtual sal_Bool SAL_CALL hasStorage() override;
129
130private:
131 // private data types
132 enum NotifyOp
133 {
134 NotifyOp_Remove,
135 NotifyOp_Insert,
136 NotifyOp_Replace
137 };
138
139 struct UIElementInfo
140 {
141 UIElementInfo( OUString _aResourceURL, OUString _aUIName ) :
142 aResourceURL(std::move( _aResourceURL)), aUIName(std::move( _aUIName )) {}
143 OUString aResourceURL;
144 OUString aUIName;
145 };
146
147 struct UIElementData
148 {
149 UIElementData() : bModified( false ), bDefault( true ) {};
150
151 OUString aResourceURL;
152 OUString aName;
153 bool bModified; // has been changed since last storing
154 bool bDefault; // default settings
155 css::uno::Reference< css::container::XIndexAccess > xSettings;
156 };
157
158 struct UIElementType;
159 friend struct UIElementType;
160 typedef std::unordered_map< OUString, UIElementData > UIElementDataHashMap;
161
162 struct UIElementType
163 {
164 UIElementType() : bModified( false ),
165 bLoaded( false ),
166 nElementType( css::ui::UIElementType::UNKNOWN ) {}
167
168 bool bModified;
169 bool bLoaded;
170 sal_Int16 nElementType;
171 UIElementDataHashMap aElementsHashMap;
172 css::uno::Reference< css::embed::XStorage > xStorage;
173 };
174
175 typedef std::vector< UIElementType > UIElementTypesVector;
176 typedef std::vector< css::ui::ConfigurationEvent > ConfigEventNotifyContainer;
177 typedef std::unordered_map< OUString, UIElementInfo > UIElementInfoHashMap;
178
179 void impl_Initialize();
180 void implts_notifyContainerListener( const css::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
181 void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
182 void impl_preloadUIElementTypeList( sal_Int16 nElementType );
183 UIElementData* impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true );
184 void impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData );
185 void impl_storeElementTypeData( css::uno::Reference< css::embed::XStorage > const & xStorage, UIElementType& rElementType, bool bResetModifyState = true );
186 void impl_resetElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer );
187 void impl_reloadElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
188
189 UIElementTypesVector m_aUIElements;
190 css::uno::Reference< css::embed::XStorage > m_xDocConfigStorage;
191 bool m_bReadOnly;
192 bool m_bModified;
193 bool m_bDisposed;
194 OUString m_aPropUIName;
195 css::uno::Reference< css::uno::XComponentContext > m_xContext;
196 std::mutex m_mutex;
199 rtl::Reference< ImageManager > m_xImageManager;
200 css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xAccConfig;
201};
202
203// important: The order and position of the elements must match the constant
204// definition of "css::ui::UIElementType"
205std::u16string_view UIELEMENTTYPENAMES[] =
206{
207 u"", // Dummy value for unknown!
215};
216
217constexpr std::u16string_view RESOURCEURL_PREFIX = u"private:resource/";
218
219sal_Int16 RetrieveTypeFromResourceURL( std::u16string_view aResourceURL )
220{
221
222 if (( o3tl::starts_with(aResourceURL, RESOURCEURL_PREFIX ) ) &&
223 ( aResourceURL.size() > RESOURCEURL_PREFIX.size() ))
224 {
225 std::u16string_view aTmpStr = aResourceURL.substr( RESOURCEURL_PREFIX.size() );
226 size_t nIndex = aTmpStr.find( '/' );
227 if (( nIndex > 0 ) && ( aTmpStr.size() > nIndex ))
228 {
229 std::u16string_view aTypeStr( aTmpStr.substr( 0, nIndex ));
230 for ( int i = 0; i < UIElementType::COUNT; i++ )
231 {
232 if ( aTypeStr == UIELEMENTTYPENAMES[i] )
233 return sal_Int16( i );
234 }
235 }
236 }
237
238 return UIElementType::UNKNOWN;
239}
240
241OUString RetrieveNameFromResourceURL( std::u16string_view aResourceURL )
242{
243 if (( o3tl::starts_with(aResourceURL, RESOURCEURL_PREFIX ) ) &&
244 ( aResourceURL.size() > RESOURCEURL_PREFIX.size() ))
245 {
246 size_t nIndex = aResourceURL.rfind( '/' );
247 if ( (nIndex > 0) && (nIndex != std::u16string_view::npos) && (( nIndex+1 ) < aResourceURL.size()) )
248 return OUString(aResourceURL.substr( nIndex+1 ));
249 }
250
251 return OUString();
252}
253
254void UIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
255{
256 // preload list of element types on demand
257 impl_preloadUIElementTypeList( nElementType );
258
259 UIElementDataHashMap& rUserElements = m_aUIElements[nElementType].aElementsHashMap;
260
261 for (auto const& elem : rUserElements)
262 {
263 UIElementData* pDataSettings = impl_findUIElementData( elem.second.aResourceURL, nElementType );
264 if ( pDataSettings && !pDataSettings->bDefault )
265 {
266 // Retrieve user interface name from XPropertySet interface
267 OUString aUIName;
268 Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
269 if ( xPropSet.is() )
270 {
271 Any a = xPropSet->getPropertyValue( m_aPropUIName );
272 a >>= aUIName;
273 }
274
275 UIElementInfo aInfo( elem.second.aResourceURL, aUIName );
276 aUIElementInfoCollection.emplace( elem.second.aResourceURL, aInfo );
277 }
278 }
279}
280
281void UIConfigurationManager::impl_preloadUIElementTypeList( sal_Int16 nElementType )
282{
283 UIElementType& rElementTypeData = m_aUIElements[nElementType];
284
285 if ( !rElementTypeData.bLoaded )
286 {
287 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
288 if ( xElementTypeStorage.is() )
289 {
290 OUString aResURLPrefix =
291 OUString::Concat(RESOURCEURL_PREFIX) +
292 UIELEMENTTYPENAMES[ nElementType ] +
293 "/";
294
295 UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
296 const Sequence< OUString > aUIElementNames = xElementTypeStorage->getElementNames();
297 for ( OUString const & rElementName : aUIElementNames )
298 {
299 UIElementData aUIElementData;
300
301 // Resource name must be without ".xml"
302 sal_Int32 nIndex = rElementName.lastIndexOf( '.' );
303 if (( nIndex > 0 ) && ( nIndex < rElementName.getLength() ))
304 {
305 std::u16string_view aExtension( rElementName.subView( nIndex+1 ));
306 std::u16string_view aUIElementName( rElementName.subView( 0, nIndex ));
307
308 if (!aUIElementName.empty() &&
309 ( o3tl::equalsIgnoreAsciiCase(aExtension, u"xml")))
310 {
311 aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
312 aUIElementData.aName = rElementName;
313 aUIElementData.bModified = false;
314 aUIElementData.bDefault = false;
315
316 // Create unordered_map entries for all user interface elements inside the storage. We don't load the
317 // settings to speed up the process.
318 rHashMap.emplace( aUIElementData.aResourceURL, aUIElementData );
319 }
320 }
321 }
322 }
323 }
324
325 rElementTypeData.bLoaded = true;
326}
327
328void UIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData )
329{
330 UIElementType& rElementTypeData = m_aUIElements[nElementType];
331
332 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
333 if ( xElementTypeStorage.is() && !aUIElementData.aName.isEmpty() )
334 {
335 try
336 {
337 Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
338 Reference< XInputStream > xInputStream = xStream->getInputStream();
339
340 if ( xInputStream.is() )
341 {
342 switch ( nElementType )
343 {
344 case css::ui::UIElementType::UNKNOWN:
345 break;
346
347 case css::ui::UIElementType::MENUBAR:
348 case css::ui::UIElementType::POPUPMENU:
349 {
350 try
351 {
352 MenuConfiguration aMenuCfg( m_xContext );
353 Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
354 auto pRootItemContainer = dynamic_cast<RootItemContainer*>( xContainer.get() );
355 if ( pRootItemContainer )
356 aUIElementData.xSettings = new ConstItemContainer( pRootItemContainer, true );
357 else
358 aUIElementData.xSettings = new ConstItemContainer( xContainer, true );
359 return;
360 }
361 catch ( const css::lang::WrappedTargetException& )
362 {
363 }
364 }
365 break;
366
367 case css::ui::UIElementType::TOOLBAR:
368 {
369 try
370 {
371 Reference< XIndexContainer > xIndexContainer( new RootItemContainer() );
372 ToolBoxConfiguration::LoadToolBox( m_xContext, xInputStream, xIndexContainer );
373 auto pRootItemContainer = dynamic_cast<RootItemContainer*>( xIndexContainer.get() );
374 aUIElementData.xSettings = new ConstItemContainer( pRootItemContainer, true );
375 return;
376 }
377 catch ( const css::lang::WrappedTargetException& )
378 {
379 }
380
381 break;
382 }
383
384 case css::ui::UIElementType::STATUSBAR:
385 {
386 try
387 {
388 Reference< XIndexContainer > xIndexContainer( new RootItemContainer() );
389 StatusBarConfiguration::LoadStatusBar( m_xContext, xInputStream, xIndexContainer );
390 auto pRootItemContainer = dynamic_cast<RootItemContainer*>( xIndexContainer.get() );
391 aUIElementData.xSettings = new ConstItemContainer( pRootItemContainer, true );
392 return;
393 }
394 catch ( const css::lang::WrappedTargetException& )
395 {
396 }
397
398 break;
399 }
400
401 case css::ui::UIElementType::FLOATINGWINDOW:
402 {
403 break;
404 }
405 }
406 }
407 }
408 catch ( const css::embed::InvalidStorageException& )
409 {
410 }
411 catch ( const css::lang::IllegalArgumentException& )
412 {
413 }
414 catch ( const css::io::IOException& )
415 {
416 }
417 catch ( const css::embed::StorageWrappedTargetException& )
418 {
419 }
420 }
421
422 // At least we provide an empty settings container!
423 aUIElementData.xSettings = new ConstItemContainer();
424}
425
426UIConfigurationManager::UIElementData* UIConfigurationManager::impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
427{
428 // preload list of element types on demand
429 impl_preloadUIElementTypeList( nElementType );
430
431 // try to look into our document vector/unordered_map combination
432 UIElementDataHashMap& rUserHashMap = m_aUIElements[nElementType].aElementsHashMap;
433 UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
434 if ( pIter != rUserHashMap.end() )
435 {
436 // Default data settings data means removed!
437 if ( pIter->second.bDefault )
438 return &(pIter->second);
439 else
440 {
441 if ( !pIter->second.xSettings.is() && bLoad )
442 impl_requestUIElementData( nElementType, pIter->second );
443 return &(pIter->second);
444 }
445 }
446
447 // Nothing has been found!
448 return nullptr;
449}
450
451void UIConfigurationManager::impl_storeElementTypeData( Reference< XStorage > const & xStorage, UIElementType& rElementType, bool bResetModifyState )
452{
453 UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
454
455 for (auto & elem : rHashMap)
456 {
457 UIElementData& rElement = elem.second;
458 if ( rElement.bModified )
459 {
460 if ( rElement.bDefault )
461 {
462 xStorage->removeElement( rElement.aName );
463 rElement.bModified = false; // mark as not modified
464 }
465 else
466 {
467 Reference< XStream > xStream = xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE );
468 Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
469
470 if ( xOutputStream.is() )
471 {
472 switch( rElementType.nElementType )
473 {
474 case css::ui::UIElementType::MENUBAR:
475 case css::ui::UIElementType::POPUPMENU:
476 {
477 try
478 {
479 MenuConfiguration aMenuCfg( m_xContext );
480 aMenuCfg.StoreMenuBarConfigurationToXML(
481 rElement.xSettings, xOutputStream, rElementType.nElementType == css::ui::UIElementType::MENUBAR );
482 }
483 catch ( const css::lang::WrappedTargetException& )
484 {
485 }
486 }
487 break;
488
489 case css::ui::UIElementType::TOOLBAR:
490 {
491 try
492 {
493 ToolBoxConfiguration::StoreToolBox( m_xContext, xOutputStream, rElement.xSettings );
494 }
495 catch ( const css::lang::WrappedTargetException& )
496 {
497 }
498 }
499 break;
500
501 case css::ui::UIElementType::STATUSBAR:
502 {
503 try
504 {
505 StatusBarConfiguration::StoreStatusBar( m_xContext, xOutputStream, rElement.xSettings );
506 }
507 catch ( const css::lang::WrappedTargetException& )
508 {
509 }
510 }
511 break;
512
513 default:
514 break;
515 }
516 }
517
518 // mark as not modified if we store to our own storage
519 if ( bResetModifyState )
520 rElement.bModified = false;
521 }
522 }
523 }
524
525 // commit element type storage
526 Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
527 if ( xTransactedObject.is() )
528 xTransactedObject->commit();
529
530 // mark UIElementType as not modified if we store to our own storage
531 if ( bResetModifyState )
532 rElementType.bModified = false;
533}
534
535void UIConfigurationManager::impl_resetElementTypeData(
536 UIElementType& rDocElementType,
537 ConfigEventNotifyContainer& rRemoveNotifyContainer )
538{
539 UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
540
542 Reference< XInterface > xIfac( xThis, UNO_QUERY );
543
544 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
545 // our listeners!
546 for (auto & elem : rHashMap)
547 {
548 UIElementData& rElement = elem.second;
549 if ( !rElement.bDefault )
550 {
551 // Remove user-defined settings from document
552 ConfigurationEvent aEvent;
553 aEvent.ResourceURL = rElement.aResourceURL;
554 aEvent.Accessor <<= xThis;
555 aEvent.Source = xIfac;
556 aEvent.Element <<= rElement.xSettings;
557
558 rRemoveNotifyContainer.push_back( aEvent );
559
560 // Mark element as default.
561 rElement.bModified = false;
562 rElement.bDefault = true;
563 }
564 else
565 rElement.bModified = false;
566 }
567
568 // Remove all settings from our user interface elements
569 rHashMap.clear();
570}
571
572void UIConfigurationManager::impl_reloadElementTypeData(
573 UIElementType& rDocElementType,
574 ConfigEventNotifyContainer& rRemoveNotifyContainer,
575 ConfigEventNotifyContainer& rReplaceNotifyContainer )
576{
577 UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
578 Reference< XStorage > xElementStorage( rDocElementType.xStorage );
579
581 Reference< XInterface > xIfac( xThis, UNO_QUERY );
582 sal_Int16 nType = rDocElementType.nElementType;
583
584 for (auto & elem : rHashMap)
585 {
586 UIElementData& rElement = elem.second;
587 if ( rElement.bModified )
588 {
589 if ( xElementStorage->hasByName( rElement.aName ))
590 {
591 // Replace settings with data from user layer
592 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
593
594 impl_requestUIElementData( nType, rElement );
595
596 ConfigurationEvent aReplaceEvent;
597
598 aReplaceEvent.ResourceURL = rElement.aResourceURL;
599 aReplaceEvent.Accessor <<= xThis;
600 aReplaceEvent.Source = xIfac;
601 aReplaceEvent.ReplacedElement <<= xOldSettings;
602 aReplaceEvent.Element <<= rElement.xSettings;
603 rReplaceNotifyContainer.push_back( aReplaceEvent );
604
605 rElement.bModified = false;
606 }
607 else
608 {
609 // Element settings are not in any storage => remove
610 ConfigurationEvent aRemoveEvent;
611
612 aRemoveEvent.ResourceURL = rElement.aResourceURL;
613 aRemoveEvent.Accessor <<= xThis;
614 aRemoveEvent.Source = xIfac;
615 aRemoveEvent.Element <<= rElement.xSettings;
616
617 rRemoveNotifyContainer.push_back( aRemoveEvent );
618
619 // Mark element as default and not modified. That means "not active" in the document anymore
620 rElement.bModified = false;
621 rElement.bDefault = true;
622 }
623 }
624 }
625
626 rDocElementType.bModified = false;
627}
628
629void UIConfigurationManager::impl_Initialize()
630{
631 // Initialize the top-level structures with the storage data
632 if ( m_xDocConfigStorage.is() )
633 {
634 tools::Long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE;
635
636 // Try to access our module sub folder
637 for ( sal_Int16 i = 1; i < css::ui::UIElementType::COUNT;
638 i++ )
639 {
640 Reference< XStorage > xElementTypeStorage;
641 try
642 {
643 xElementTypeStorage = m_xDocConfigStorage->openStorageElement( OUString(UIELEMENTTYPENAMES[i]), nModes );
644 }
645 catch ( const css::container::NoSuchElementException& )
646 {
647 }
648 catch ( const css::embed::InvalidStorageException& )
649 {
650 }
651 catch ( const css::lang::IllegalArgumentException& )
652 {
653 }
654 catch ( const css::io::IOException& )
655 {
656 }
657 catch ( const css::embed::StorageWrappedTargetException& )
658 {
659 }
660
661 m_aUIElements[i].nElementType = i;
662 m_aUIElements[i].bModified = false;
663 m_aUIElements[i].xStorage = xElementTypeStorage;
664 }
665 }
666 else
667 {
668 // We have no storage, just initialize ui element types with empty storage!
669 for ( int i = 1; i < css::ui::UIElementType::COUNT; i++ )
670 m_aUIElements[i].xStorage = m_xDocConfigStorage;
671 }
672}
673
674UIConfigurationManager::UIConfigurationManager( css::uno::Reference< css::uno::XComponentContext > xContext ) :
675 m_bReadOnly( true )
676 , m_bModified( false )
677 , m_bDisposed( false )
678 , m_aPropUIName( "UIName" )
679 , m_xContext(std::move( xContext ))
680{
681 // Make sure we have a default initialized entry for every layer and user interface element type!
682 // The following code depends on this!
683 m_aUIElements.resize( css::ui::UIElementType::COUNT );
684}
685
686// XComponent
687void SAL_CALL UIConfigurationManager::dispose()
688{
689 Reference< XComponent > xThis(this);
690
691 css::lang::EventObject aEvent( xThis );
692 {
693 std::unique_lock aGuard(m_mutex);
694 m_aEventListeners.disposeAndClear( aGuard, aEvent );
695 }
696 {
697 std::unique_lock aGuard(m_mutex);
698 m_aConfigListeners.disposeAndClear( aGuard, aEvent );
699 }
700
701 {
703 try
704 {
705 if ( m_xImageManager.is() )
706 m_xImageManager->dispose();
707 }
708 catch ( const Exception& )
709 {
710 }
711
712 m_xImageManager.clear();
713 m_aUIElements.clear();
714 m_xDocConfigStorage.clear();
715 m_bModified = false;
716 m_bDisposed = true;
717 }
718}
719
720void SAL_CALL UIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener )
721{
722 {
724
725 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
726 if ( m_bDisposed )
727 throw DisposedException();
728 }
729
730 std::unique_lock aGuard(m_mutex);
731 m_aEventListeners.addInterface( aGuard, xListener );
732}
733
734void SAL_CALL UIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener )
735{
736 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
737 std::unique_lock aGuard(m_mutex);
738 m_aEventListeners.removeInterface( aGuard, xListener );
739}
740
741// XUIConfigurationManager
742void SAL_CALL UIConfigurationManager::addConfigurationListener( const Reference< css::ui::XUIConfigurationListener >& xListener )
743{
744 {
746
747 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
748 if ( m_bDisposed )
749 throw DisposedException();
750 }
751
752 std::unique_lock aGuard(m_mutex);
753 m_aConfigListeners.addInterface( aGuard, xListener );
754}
755
756void SAL_CALL UIConfigurationManager::removeConfigurationListener( const Reference< css::ui::XUIConfigurationListener >& xListener )
757{
758 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
759 std::unique_lock aGuard(m_mutex);
760 m_aConfigListeners.removeInterface( aGuard, xListener );
761}
762
763void SAL_CALL UIConfigurationManager::reset()
764{
766
767 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
768 if ( m_bDisposed )
769 throw DisposedException();
770
771 if ( isReadOnly() )
772 return;
773
774 if ( !m_xDocConfigStorage.is() )
775 return;
776
777 try
778 {
779 // Remove all elements from our user-defined storage!
780 bool bCommit( false );
781 for ( int i = 1; i < css::ui::UIElementType::COUNT; i++ )
782 {
783 UIElementType& rElementType = m_aUIElements[i];
784
785 if ( rElementType.xStorage.is() )
786 {
787 bool bCommitSubStorage( false );
788 const Sequence< OUString > aUIElementStreamNames = rElementType.xStorage->getElementNames();
789 for ( OUString const & rStreamName : aUIElementStreamNames )
790 {
791 rElementType.xStorage->removeElement( rStreamName );
792 bCommitSubStorage = true;
793 bCommit = true;
794 }
795
796 if ( bCommitSubStorage )
797 {
798 Reference< XTransactedObject > xTransactedObject( rElementType.xStorage, UNO_QUERY );
799 if ( xTransactedObject.is() )
800 xTransactedObject->commit();
801 }
802 }
803 }
804
805 // Commit changes
806 if ( bCommit )
807 {
808 Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
809 if ( xTransactedObject.is() )
810 xTransactedObject->commit();
811 }
812
813 // remove settings from user defined layer and notify listener about removed settings data!
814 // Try to access our module sub folder
815 ConfigEventNotifyContainer aRemoveEventNotifyContainer;
816 for ( sal_Int16 j = 1; j < css::ui::UIElementType::COUNT; j++ )
817 {
818 UIElementType& rDocElementType = m_aUIElements[j];
819
820 impl_resetElementTypeData( rDocElementType, aRemoveEventNotifyContainer );
821 rDocElementType.bModified = false;
822 }
823
824 m_bModified = false;
825
826 // Unlock mutex before notify our listeners
827 aGuard.clear();
828
829 // Notify our listeners
830 for (const ConfigurationEvent & k : aRemoveEventNotifyContainer)
831 implts_notifyContainerListener( k, NotifyOp_Remove );
832 }
833 catch ( const css::lang::IllegalArgumentException& )
834 {
835 }
836 catch ( const css::container::NoSuchElementException& )
837 {
838 }
839 catch ( const css::embed::InvalidStorageException& )
840 {
841 }
842 catch ( const css::embed::StorageWrappedTargetException& )
843 {
844 }
845}
846
847Sequence< Sequence< PropertyValue > > SAL_CALL UIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
848{
849 if (( ElementType < 0 ) || ( ElementType >= css::ui::UIElementType::COUNT ))
850 throw IllegalArgumentException();
851
853 if ( m_bDisposed )
854 throw DisposedException();
855
856 std::vector< Sequence< PropertyValue > > aElementInfoSeq;
857 UIElementInfoHashMap aUIElementInfoCollection;
858
859 if ( ElementType == css::ui::UIElementType::UNKNOWN )
860 {
861 for ( sal_Int16 i = 0; i < css::ui::UIElementType::COUNT; i++ )
862 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, i );
863 }
864 else
865 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
866
867 aElementInfoSeq.resize( aUIElementInfoCollection.size() );
868 sal_Int32 n = 0;
869 for (auto const& elem : aUIElementInfoCollection)
870 {
871 Sequence< PropertyValue > aUIElementInfo{
872 comphelper::makePropertyValue("ResourceURL", elem.second.aResourceURL),
873 comphelper::makePropertyValue(m_aPropUIName, elem.second.aUIName)
874 };
875 aElementInfoSeq[n++] = aUIElementInfo;
876 }
877
878 return comphelper::containerToSequence(aElementInfoSeq);
879}
880
881Reference< XIndexContainer > SAL_CALL UIConfigurationManager::createSettings()
882{
884
885 if ( m_bDisposed )
886 throw DisposedException();
887
888 // Creates an empty item container which can be filled from outside
890}
891
892sal_Bool SAL_CALL UIConfigurationManager::hasSettings( const OUString& ResourceURL )
893{
894 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
895
896 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
897 ( nElementType >= css::ui::UIElementType::COUNT ))
898 throw IllegalArgumentException();
899 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
900 if ( pDataSettings && !pDataSettings->bDefault )
901 return true;
902
903 return false;
904}
905
906Reference< XIndexAccess > SAL_CALL UIConfigurationManager::getSettings( const OUString& ResourceURL, sal_Bool bWriteable )
907{
908 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
909
910 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
911 ( nElementType >= css::ui::UIElementType::COUNT ))
912 throw IllegalArgumentException();
913
915
916 if ( m_bDisposed )
917 throw DisposedException();
918
919 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
920 if ( pDataSettings && !pDataSettings->bDefault )
921 {
922 // Create a copy of our data if someone wants to change the data.
923 if ( bWriteable )
924 return Reference< XIndexAccess >( new RootItemContainer( pDataSettings->xSettings ) );
925 else
926 return pDataSettings->xSettings;
927 }
928
929 throw NoSuchElementException();
930}
931
932void SAL_CALL UIConfigurationManager::replaceSettings( const OUString& ResourceURL, const Reference< css::container::XIndexAccess >& aNewData )
933{
934 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
935
936 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
937 ( nElementType >= css::ui::UIElementType::COUNT ))
938 throw IllegalArgumentException();
939 else if ( m_bReadOnly )
940 throw IllegalAccessException();
941 else
942 {
944
945 if ( m_bDisposed )
946 throw DisposedException();
947
948 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
949 if ( !pDataSettings || pDataSettings->bDefault )
950 throw NoSuchElementException();
951 // we have a settings entry in our user-defined layer - replace
952 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
953
954 // Create a copy of the data if the container is not const
955 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
956 if ( xReplace.is() )
957 pDataSettings->xSettings = new ConstItemContainer( aNewData );
958 else
959 pDataSettings->xSettings = aNewData;
960
961 pDataSettings->bDefault = false;
962 pDataSettings->bModified = true;
963 m_bModified = true;
964
965 // Modify type container
966 UIElementType& rElementType = m_aUIElements[nElementType];
967 rElementType.bModified = true;
968
970 Reference< XInterface > xIfac( xThis, UNO_QUERY );
971
972 // Create event to notify listener about replaced element settings
973 ConfigurationEvent aEvent;
974
975 aEvent.ResourceURL = ResourceURL;
976 aEvent.Accessor <<= xThis;
977 aEvent.Source = xIfac;
978 aEvent.ReplacedElement <<= xOldSettings;
979 aEvent.Element <<= pDataSettings->xSettings;
980
981 aGuard.clear();
982
983 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
984 }
985}
986
987void SAL_CALL UIConfigurationManager::removeSettings( const OUString& ResourceURL )
988{
989 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
990
991 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
992 ( nElementType >= css::ui::UIElementType::COUNT ))
993 throw IllegalArgumentException( "The ResourceURL is not valid or "
994 "describes an unknown type. "
995 "ResourceURL: " + ResourceURL, nullptr, 0 );
996 else if ( m_bReadOnly )
997 throw IllegalAccessException( "The configuration manager is read-only. "
998 "ResourceURL: " + ResourceURL, nullptr );
999 else
1000 {
1002
1003 if ( m_bDisposed )
1004 throw DisposedException( "The configuration manager has been disposed, "
1005 "and can't uphold its method specification anymore. "
1006 "ResourceURL: " + ResourceURL, nullptr );
1007
1008 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1009 if ( !pDataSettings )
1010 throw NoSuchElementException( "The settings data cannot be found. "
1011 "ResourceURL: " + ResourceURL, nullptr);
1012 // If element settings are default, we don't need to change anything!
1013 if ( pDataSettings->bDefault )
1014 return;
1015 else
1016 {
1017 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
1018 pDataSettings->bDefault = true;
1019
1020 // check if this is a default layer node
1021 pDataSettings->bModified = true; // we have to remove this node from the user layer!
1022 pDataSettings->xSettings.clear();
1023 m_bModified = true; // user layer must be written
1024
1025 // Modify type container
1026 UIElementType& rElementType = m_aUIElements[nElementType];
1027 rElementType.bModified = true;
1028
1030 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1031
1032 // Create event to notify listener about removed element settings
1033 ConfigurationEvent aEvent;
1034
1035 aEvent.ResourceURL = ResourceURL;
1036 aEvent.Accessor <<= xThis;
1037 aEvent.Source = xIfac;
1038 aEvent.Element <<= xRemovedSettings;
1039
1040 aGuard.clear();
1041
1042 implts_notifyContainerListener( aEvent, NotifyOp_Remove );
1043 }
1044 }
1045}
1046
1047void SAL_CALL UIConfigurationManager::insertSettings( const OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
1048{
1049 sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
1050
1051 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1052 ( nElementType >= css::ui::UIElementType::COUNT ))
1053 throw IllegalArgumentException();
1054 else if ( m_bReadOnly )
1055 throw IllegalAccessException();
1056 else
1057 {
1059
1060 if ( m_bDisposed )
1061 throw DisposedException();
1062
1063 bool bInsertData( false );
1064 UIElementData aUIElementData;
1065 UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
1066
1067 if ( pDataSettings && !pDataSettings->bDefault )
1068 throw ElementExistException();
1069
1070 if ( !pDataSettings )
1071 {
1072 pDataSettings = &aUIElementData;
1073 bInsertData = true;
1074 }
1075
1076 {
1077 pDataSettings->bDefault = false;
1078 pDataSettings->bModified = true;
1079
1080 // Create a copy of the data if the container is not const
1081 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1082 if ( xReplace.is() )
1083 pDataSettings->xSettings = new ConstItemContainer( aNewData );
1084 else
1085 pDataSettings->xSettings = aNewData;
1086
1087 m_bModified = true;
1088
1089 UIElementType& rElementType = m_aUIElements[nElementType];
1090 rElementType.bModified = true;
1091
1092 if ( bInsertData )
1093 {
1094 pDataSettings->aName = RetrieveNameFromResourceURL( NewResourceURL ) + ".xml";
1095 pDataSettings->aResourceURL = NewResourceURL;
1096
1097 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1098 rElements.emplace( NewResourceURL, *pDataSettings );
1099 }
1100
1101 Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
1103 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1104
1105 // Create event to notify listener about removed element settings
1106 ConfigurationEvent aEvent;
1107
1108 aEvent.ResourceURL = NewResourceURL;
1109 aEvent.Accessor <<= xThis;
1110 aEvent.Source = xIfac;
1111 aEvent.Element <<= xInsertSettings;
1112
1113 aGuard.clear();
1114
1115 implts_notifyContainerListener( aEvent, NotifyOp_Insert );
1116 }
1117 }
1118}
1119
1120Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager()
1121{
1122 if ( m_bDisposed )
1123 throw DisposedException();
1124
1125 if ( !m_xImageManager.is() )
1126 {
1127 m_xImageManager = new ImageManager( m_xContext, /*bForModule*/false );
1128
1130 {
1131 {"UserConfigStorage", Any(m_xDocConfigStorage)},
1132 {"ModuleIdentifier", Any(OUString())},
1133 }));
1134
1135 m_xImageManager->initialize( aPropSeq );
1136 }
1137
1138 return Reference< XInterface >( static_cast<cppu::OWeakObject*>(m_xImageManager.get()), UNO_QUERY );
1139}
1140
1141Reference< XAcceleratorConfiguration > SAL_CALL UIConfigurationManager::createShortCutManager()
1142{
1143 return DocumentAcceleratorConfiguration::createWithDocumentRoot(m_xContext, m_xDocConfigStorage);
1144}
1145
1146Reference< XAcceleratorConfiguration > SAL_CALL UIConfigurationManager::getShortCutManager()
1147{
1148 // SAFE ->
1150
1151 if (!m_xAccConfig.is()) try
1152 {
1153 m_xAccConfig = DocumentAcceleratorConfiguration::
1154 createWithDocumentRoot(m_xContext, m_xDocConfigStorage);
1155 }
1156 catch ( const css::uno::DeploymentException& )
1157 {
1158 SAL_WARN("fwk.uiconfiguration", "DocumentAcceleratorConfiguration"
1159 " not available. This should happen only on mobile platforms.");
1160 }
1161
1162 return m_xAccConfig;
1163}
1164
1165Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager()
1166{
1167 return Reference< XInterface >();
1168}
1169
1170// XUIConfigurationStorage
1171void SAL_CALL UIConfigurationManager::setStorage( const Reference< XStorage >& Storage )
1172{
1174
1175 if ( m_bDisposed )
1176 throw DisposedException();
1177
1178 if ( m_xDocConfigStorage.is() )
1179 {
1180 try
1181 {
1182 // Dispose old storage to be sure that it will be closed
1183 m_xDocConfigStorage->dispose();
1184 }
1185 catch ( const Exception& )
1186 {
1187 }
1188 }
1189
1190 // We store the new storage. Be careful it could be an empty reference!
1191 m_xDocConfigStorage = Storage;
1192 m_bReadOnly = true;
1193
1194 if ( m_xAccConfig.is() )
1195 m_xAccConfig->setStorage( m_xDocConfigStorage );
1196
1197 if ( m_xImageManager )
1198 m_xImageManager->setStorage( m_xDocConfigStorage );
1199
1200 if ( m_xDocConfigStorage.is() )
1201 {
1202 Reference< XPropertySet > xPropSet( m_xDocConfigStorage, UNO_QUERY );
1203 if ( xPropSet.is() )
1204 {
1205 try
1206 {
1207 tools::Long nOpenMode = 0;
1208 Any a = xPropSet->getPropertyValue("OpenMode");
1209 if ( a >>= nOpenMode )
1210 m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
1211 }
1212 catch ( const css::beans::UnknownPropertyException& )
1213 {
1214 }
1215 catch ( const css::lang::WrappedTargetException& )
1216 {
1217 }
1218 }
1219 }
1220
1221 impl_Initialize();
1222}
1223
1224sal_Bool SAL_CALL UIConfigurationManager::hasStorage()
1225{
1227
1228 if ( m_bDisposed )
1229 throw DisposedException();
1230
1231 return m_xDocConfigStorage.is();
1232}
1233
1234// XUIConfigurationPersistence
1235void SAL_CALL UIConfigurationManager::reload()
1236{
1238
1239 if ( m_bDisposed )
1240 throw DisposedException();
1241
1242 if ( !m_xDocConfigStorage.is() || !m_bModified || m_bReadOnly )
1243 return;
1244
1245 // Try to access our module sub folder
1246 ConfigEventNotifyContainer aRemoveNotifyContainer;
1247 ConfigEventNotifyContainer aReplaceNotifyContainer;
1248 for ( sal_Int16 i = 1; i < css::ui::UIElementType::COUNT; i++ )
1249 {
1250 try
1251 {
1252 UIElementType& rDocElementType = m_aUIElements[i];
1253 if ( rDocElementType.bModified )
1254 impl_reloadElementTypeData( rDocElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
1255 }
1256 catch ( const Exception& )
1257 {
1258 throw IOException();
1259 }
1260 }
1261
1262 m_bModified = false;
1263
1264 // Unlock mutex before notify our listeners
1265 aGuard.clear();
1266
1267 // Notify our listeners
1268 for (const ConfigurationEvent & j : aRemoveNotifyContainer)
1269 implts_notifyContainerListener( j, NotifyOp_Remove );
1270 for (const ConfigurationEvent & k : aReplaceNotifyContainer)
1271 implts_notifyContainerListener( k, NotifyOp_Replace );
1272}
1273
1274void SAL_CALL UIConfigurationManager::store()
1275{
1277
1278 if ( m_bDisposed )
1279 throw DisposedException();
1280
1281 if ( !m_xDocConfigStorage.is() || !m_bModified || m_bReadOnly )
1282 return;
1283
1284 // Try to access our module sub folder
1285 for ( int i = 1; i < css::ui::UIElementType::COUNT; i++ )
1286 {
1287 try
1288 {
1289 UIElementType& rElementType = m_aUIElements[i];
1290
1291 if ( rElementType.bModified && rElementType.xStorage.is() )
1292 impl_storeElementTypeData( rElementType.xStorage, rElementType );
1293 }
1294 catch ( const Exception& )
1295 {
1296 throw IOException();
1297 }
1298 }
1299
1300 m_bModified = false;
1301 Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
1302 if ( xTransactedObject.is() )
1303 xTransactedObject->commit();
1304}
1305
1306void SAL_CALL UIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage )
1307{
1309
1310 if ( m_bDisposed )
1311 throw DisposedException();
1312
1313 if ( !m_xDocConfigStorage.is() || !m_bModified || m_bReadOnly )
1314 return;
1315
1316 // Try to access our module sub folder
1317 for ( int i = 1; i < css::ui::UIElementType::COUNT; i++ )
1318 {
1319 try
1320 {
1321 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
1322 OUString(UIELEMENTTYPENAMES[i]), ElementModes::READWRITE ));
1323 UIElementType& rElementType = m_aUIElements[i];
1324
1325 if ( rElementType.bModified && xElementTypeStorage.is() )
1326 impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
1327 }
1328 catch ( const Exception& )
1329 {
1330 throw IOException();
1331 }
1332 }
1333
1334 Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
1335 if ( xTransactedObject.is() )
1336 xTransactedObject->commit();
1337}
1338
1339sal_Bool SAL_CALL UIConfigurationManager::isModified()
1340{
1342
1343 return m_bModified;
1344}
1345
1346sal_Bool SAL_CALL UIConfigurationManager::isReadOnly()
1347{
1349
1350 return m_bReadOnly;
1351}
1352
1353void UIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
1354{
1355 std::unique_lock aGuard(m_mutex);
1356 m_aConfigListeners.forEach(aGuard, [&eOp, &aEvent](const css::uno::Reference<XUIConfigurationListener>& l) {
1357 switch ( eOp )
1358 {
1359 case NotifyOp_Replace:
1360 l->elementReplaced( aEvent );
1361 break;
1362 case NotifyOp_Insert:
1363 l->elementInserted( aEvent );
1364 break;
1365 case NotifyOp_Remove:
1366 l->elementRemoved( aEvent );
1367 break;
1368 }
1369 });
1370}
1371
1372}
1373
1374extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1376 css::uno::XComponentContext *context,
1377 css::uno::Sequence<css::uno::Any> const &)
1378{
1379 return cppu::acquire(new UIConfigurationManager(context));
1380}
1381
1382/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
AnyEventRef aEvent
float u
UNKNOWN
css::uno::Reference< css::uno::XComponentContext > m_xContext
bool m_bDisposed
bool m_bReadOnly
sal_Int32 nIndex
OUString aName
sal_Int64 n
uno_Any a
std::mutex m_mutex
Definition: loadenv.cxx:108
#define SAL_WARN(area, stream)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
ElementType
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
void dispose()
long Long
QPRO_FUNC_TYPE nType
OUString aUIName
unsigned char sal_Bool
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_UIConfigurationManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define UIELEMENTTYPE_POPUPMENU_NAME
#define UIELEMENTTYPE_PROGRESSBAR_NAME
#define UIELEMENTTYPE_TOOLBAR_NAME
#define UIELEMENTTYPE_STATUSBAR_NAME
#define UIELEMENTTYPE_MENUBAR_NAME
#define UIELEMENTTYPE_TOOLPANEL_NAME
#define UIELEMENTTYPE_FLOATINGWINDOW_NAME