30#include <com/sun/star/ui/UIElementType.hpp>
31#include <com/sun/star/ui/ConfigurationEvent.hpp>
32#include <com/sun/star/ui/ModuleAcceleratorConfiguration.hpp>
33#include <com/sun/star/ui/XModuleUIConfigurationManager2.hpp>
34#include <com/sun/star/lang/DisposedException.hpp>
35#include <com/sun/star/lang/IllegalAccessException.hpp>
36#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
37#include <com/sun/star/beans/XPropertySet.hpp>
38#include <com/sun/star/embed/ElementModes.hpp>
39#include <com/sun/star/embed/InvalidStorageException.hpp>
40#include <com/sun/star/embed/StorageWrappedTargetException.hpp>
41#include <com/sun/star/embed/XTransactedObject.hpp>
42#include <com/sun/star/container/ElementExistException.hpp>
43#include <com/sun/star/container/XNameAccess.hpp>
44#include <com/sun/star/container/XIndexContainer.hpp>
45#include <com/sun/star/io/IOException.hpp>
46#include <com/sun/star/io/XStream.hpp>
47#include <com/sun/star/lang/XServiceInfo.hpp>
48#include <com/sun/star/lang/XComponent.hpp>
83class ModuleUIConfigurationManager :
public cppu::WeakImplHelper<
84 css::lang::XServiceInfo,
85 css::lang::XComponent,
86 css::ui::XModuleUIConfigurationManager2 >
89 ModuleUIConfigurationManager(
90 const css::uno::Reference< css::uno::XComponentContext >& xServiceManager,
91 const css::uno::Sequence< css::uno::Any >&
aArguments);
95 return "com.sun.star.comp.framework.ModuleUIConfigurationManager";
105 return {
"com.sun.star.ui.ModuleUIConfigurationManager"};
109 virtual void SAL_CALL
dispose()
override;
110 virtual void SAL_CALL addEventListener(
const css::uno::Reference< css::lang::XEventListener >& xListener )
override;
111 virtual void SAL_CALL removeEventListener(
const css::uno::Reference< css::lang::XEventListener >& aListener )
override;
114 virtual void SAL_CALL addConfigurationListener(
const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener )
override;
115 virtual void SAL_CALL removeConfigurationListener(
const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener )
override;
118 virtual void SAL_CALL reset()
override;
119 virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getUIElementsInfo( sal_Int16
ElementType )
override;
120 virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL createSettings( )
override;
121 virtual sal_Bool SAL_CALL hasSettings(
const OUString& ResourceURL )
override;
122 virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getSettings(
const OUString& ResourceURL,
sal_Bool bWriteable )
override;
123 virtual void SAL_CALL replaceSettings(
const OUString& ResourceURL,
const css::uno::Reference< css::container::XIndexAccess >& aNewData )
override;
124 virtual void SAL_CALL removeSettings(
const OUString& ResourceURL )
override;
125 virtual void SAL_CALL insertSettings(
const OUString& NewResourceURL,
const css::uno::Reference< css::container::XIndexAccess >& aNewData )
override;
126 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getImageManager()
override;
127 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL getShortCutManager()
override;
128 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL createShortCutManager()
override;
129 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getEventsManager()
override;
132 virtual sal_Bool SAL_CALL isDefaultSettings(
const OUString& ResourceURL )
override;
133 virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getDefaultSettings(
const OUString& ResourceURL )
override;
136 virtual void SAL_CALL reload()
override;
137 virtual void SAL_CALL
store()
override;
138 virtual void SAL_CALL storeToStorage(
const css::uno::Reference< css::embed::XStorage >&
Storage )
override;
139 virtual sal_Bool SAL_CALL isModified()
override;
140 virtual sal_Bool SAL_CALL isReadOnly()
override;
160 UIElementInfo( OUString _aResourceURL, OUString _aUIName ) :
161 aResourceURL(std::move( _aResourceURL)),
aUIName(std::move( _aUIName )) {}
162 OUString aResourceURL;
168 UIElementData() : bModified(
false ), bDefault(
true ), bDefaultNode(
true ) {};
170 OUString aResourceURL;
175 css::uno::Reference< css::container::XIndexAccess > xSettings;
178 typedef std::unordered_map< OUString, UIElementData > UIElementDataHashMap;
182 UIElementType() : bModified(
false ),
184 nElementType( css::ui::UIElementType::UNKNOWN ) {}
188 sal_Int16 nElementType;
189 UIElementDataHashMap aElementsHashMap;
190 css::uno::Reference< css::embed::XStorage > xStorage;
193 typedef std::vector< UIElementType > UIElementTypesVector;
194 typedef std::vector< css::ui::ConfigurationEvent > ConfigEventNotifyContainer;
195 typedef std::unordered_map< OUString, UIElementInfo > UIElementInfoHashMap;
197 void impl_Initialize();
198 void implts_notifyContainerListener(
const css::ui::ConfigurationEvent&
aEvent, NotifyOp eOp );
199 void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
200 void impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType );
201 UIElementData* impl_findUIElementData(
const OUString& aResourceURL, sal_Int16 nElementType,
bool bLoad =
true );
202 void impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData );
203 void impl_storeElementTypeData(
const css::uno::Reference< css::embed::XStorage >& xStorage, UIElementType& rElementType,
bool bResetModifyState =
true );
204 void impl_resetElementTypeData( UIElementType& rUserElementType, UIElementType
const & rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
205 void impl_reloadElementTypeData( UIElementType& rUserElementType, UIElementType
const & rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
207 UIElementTypesVector m_aUIElements[LAYER_COUNT];
208 std::unique_ptr<PresetHandler> m_pStorageHandler[css::ui::UIElementType::COUNT];
209 css::uno::Reference< css::embed::XStorage > m_xDefaultConfigStorage;
210 css::uno::Reference< css::embed::XStorage > m_xUserConfigStorage;
214 OUString m_aXMLPostfix;
215 OUString m_aPropUIName;
216 OUString m_aModuleIdentifier;
217 css::uno::Reference< css::embed::XTransactedObject > m_xUserRootCommit;
218 css::uno::Reference< css::uno::XComponentContext >
m_xContext;
223 css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xModuleAcceleratorManager;
228std::u16string_view UIELEMENTTYPENAMES[] =
240constexpr std::u16string_view RESOURCEURL_PREFIX =
u"private:resource/";
242sal_Int16 RetrieveTypeFromResourceURL( std::u16string_view aResourceURL )
246 ( aResourceURL.size() > RESOURCEURL_PREFIX.size() ))
248 std::u16string_view aTmpStr = aResourceURL.substr( RESOURCEURL_PREFIX.size() );
249 size_t nIndex = aTmpStr.find(
'/' );
252 std::u16string_view aTypeStr( aTmpStr.substr( 0,
nIndex ));
253 for (
int i = 0;
i < ui::UIElementType::COUNT;
i++ )
255 if ( aTypeStr == UIELEMENTTYPENAMES[
i] )
256 return sal_Int16(
i );
261 return ui::UIElementType::UNKNOWN;
264OUString RetrieveNameFromResourceURL( std::u16string_view aResourceURL )
267 ( aResourceURL.size() > RESOURCEURL_PREFIX.size() ))
269 size_t nIndex = aResourceURL.rfind(
'/' );
271 if (
nIndex > 0 &&
nIndex != std::u16string_view::npos && ((
nIndex+1 ) < aResourceURL.size()) )
272 return OUString(aResourceURL.substr(
nIndex+1 ));
278void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
281 impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
282 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
284 UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
286 OUString aCustomUrlPrefix(
"custom_" );
287 for (
auto const& userElement : rUserElements)
289 sal_Int32
nIndex = userElement.second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX.size() );
290 if (
nIndex >
static_cast<sal_Int32
>(RESOURCEURL_PREFIX.size()) )
294 UIElementData* pDataSettings = impl_findUIElementData( userElement.second.aResourceURL, nElementType );
302 Any a = xPropSet->getPropertyValue( m_aPropUIName );
306 UIElementInfo aInfo( userElement.second.aResourceURL,
aUIName );
307 aUIElementInfoCollection.emplace( userElement.second.aResourceURL, aInfo );
313 UIElementInfo aInfo( userElement.second.aResourceURL, OUString() );
314 aUIElementInfoCollection.emplace( userElement.second.aResourceURL, aInfo );
318 UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
320 for (
auto const& defaultElement : rDefaultElements)
322 UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( defaultElement.second.aResourceURL );
323 if ( pIterInfo == aUIElementInfoCollection.end() )
325 sal_Int32
nIndex = defaultElement.second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX.size() );
326 if (
nIndex >
static_cast<sal_Int32
>(RESOURCEURL_PREFIX.size()) )
330 UIElementData* pDataSettings = impl_findUIElementData( defaultElement.second.aResourceURL, nElementType );
338 Any a = xPropSet->getPropertyValue( m_aPropUIName );
341 UIElementInfo aInfo( defaultElement.second.aResourceURL,
aUIName );
342 aUIElementInfoCollection.emplace( defaultElement.second.aResourceURL, aInfo );
348 UIElementInfo aInfo( defaultElement.second.aResourceURL, OUString() );
349 aUIElementInfoCollection.emplace( defaultElement.second.aResourceURL, aInfo );
355void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType )
357 UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
359 if ( rElementTypeData.bLoaded )
363 if ( !xElementTypeStorage.is() )
366 OUString aResURLPrefix =
367 OUString::Concat(RESOURCEURL_PREFIX) +
368 UIELEMENTTYPENAMES[ nElementType ] +
371 UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
373 for ( OUString
const & rElementName : aUIElementNames )
375 UIElementData aUIElementData;
378 sal_Int32
nIndex = rElementName.lastIndexOf(
'.' );
379 if ((
nIndex > 0 ) && (
nIndex < rElementName.getLength() ))
381 std::u16string_view aExtension( rElementName.subView(
nIndex+1 ));
382 std::u16string_view aUIElementName( rElementName.subView( 0,
nIndex ));
384 if (!aUIElementName.empty() &&
387 aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
388 aUIElementData.aName = rElementName;
390 if ( eLayer == LAYER_USERDEFINED )
392 aUIElementData.bModified =
false;
393 aUIElementData.bDefault =
false;
394 aUIElementData.bDefaultNode =
false;
399 rHashMap.emplace( aUIElementData.aResourceURL, aUIElementData );
402 rElementTypeData.bLoaded =
true;
407void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData )
409 UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
412 if ( xElementTypeStorage.is() && !aUIElementData.aName.isEmpty() )
419 if ( xInputStream.is() )
421 switch ( nElementType )
423 case css::ui::UIElementType::UNKNOWN:
426 case css::ui::UIElementType::MENUBAR:
427 case css::ui::UIElementType::POPUPMENU:
434 if ( pRootItemContainer )
440 catch (
const css::lang::WrappedTargetException& )
446 case css::ui::UIElementType::TOOLBAR:
451 ToolBoxConfiguration::LoadToolBox(
m_xContext, xInputStream, xIndexContainer );
452 auto pRootItemContainer =
dynamic_cast<RootItemContainer*
>( xIndexContainer.get() );
456 catch (
const css::lang::WrappedTargetException& )
463 case css::ui::UIElementType::STATUSBAR:
468 StatusBarConfiguration::LoadStatusBar(
m_xContext, xInputStream, xIndexContainer );
469 auto pRootItemContainer =
dynamic_cast<RootItemContainer*
>( xIndexContainer.get() );
473 catch (
const css::lang::WrappedTargetException& )
480 case css::ui::UIElementType::FLOATINGWINDOW:
487 catch (
const css::embed::InvalidStorageException& )
490 catch (
const css::lang::IllegalArgumentException& )
493 catch (
const css::io::IOException& )
496 catch (
const css::embed::StorageWrappedTargetException& )
505ModuleUIConfigurationManager::UIElementData* ModuleUIConfigurationManager::impl_findUIElementData(
const OUString& aResourceURL, sal_Int16 nElementType,
bool bLoad )
508 impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
509 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
512 UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
513 UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
514 if ( pIter != rUserHashMap.end() )
517 if ( !pIter->second.bDefault )
519 if ( !pIter->second.xSettings.is() && bLoad )
520 impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second );
521 return &(pIter->second);
526 UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
527 pIter = rDefaultHashMap.find( aResourceURL );
528 if ( pIter != rDefaultHashMap.end() )
530 if ( !pIter->second.xSettings.is() && bLoad )
531 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
532 return &(pIter->second);
539void ModuleUIConfigurationManager::impl_storeElementTypeData(
const Reference< XStorage >& xStorage, UIElementType& rElementType,
bool bResetModifyState )
541 UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
543 for (
auto & elem : rHashMap)
545 UIElementData& rElement = elem.second;
546 if ( rElement.bModified )
548 if ( rElement.bDefault )
550 xStorage->removeElement( rElement.aName );
551 rElement.bModified =
false;
558 if ( xOutputStream.is() )
560 switch( rElementType.nElementType )
562 case css::ui::UIElementType::MENUBAR:
563 case css::ui::UIElementType::POPUPMENU:
569 rElement.xSettings, xOutputStream, rElementType.nElementType == css::ui::UIElementType::MENUBAR );
571 catch (
const css::lang::WrappedTargetException& )
577 case css::ui::UIElementType::TOOLBAR:
581 ToolBoxConfiguration::StoreToolBox(
m_xContext, xOutputStream, rElement.xSettings );
583 catch (
const css::lang::WrappedTargetException& )
589 case css::ui::UIElementType::STATUSBAR:
593 StatusBarConfiguration::StoreStatusBar(
m_xContext, xOutputStream, rElement.xSettings );
595 catch (
const css::lang::WrappedTargetException& )
607 if ( bResetModifyState )
608 rElement.bModified =
false;
615 if ( xTransactedObject.is() )
616 xTransactedObject->commit();
619 if ( bResetModifyState )
620 rElementType.bModified =
false;
624void ModuleUIConfigurationManager::impl_resetElementTypeData(
625 UIElementType& rUserElementType,
626 UIElementType
const & rDefaultElementType,
627 ConfigEventNotifyContainer& rRemoveNotifyContainer,
628 ConfigEventNotifyContainer& rReplaceNotifyContainer )
630 UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
634 sal_Int16
nType = rUserElementType.nElementType;
638 for (
auto & elem : rHashMap)
640 UIElementData& rElement = elem.second;
641 if ( !rElement.bDefault )
643 if ( rDefaultElementType.xStorage->hasByName( rElement.aName ))
647 impl_requestUIElementData(
nType, LAYER_DEFAULT, rElement );
649 ui::ConfigurationEvent aReplaceEvent;
650 aReplaceEvent.ResourceURL = rElement.aResourceURL;
651 aReplaceEvent.Accessor <<= xThis;
652 aReplaceEvent.Source = xIfac;
653 aReplaceEvent.ReplacedElement <<= xOldSettings;
654 aReplaceEvent.Element <<= rElement.xSettings;
656 rReplaceNotifyContainer.push_back( aReplaceEvent );
660 rElement.bModified =
false;
661 rElement.bDefault =
true;
666 ui::ConfigurationEvent
aEvent;
667 aEvent.ResourceURL = rElement.aResourceURL;
668 aEvent.Accessor <<= xThis;
670 aEvent.Element <<= rElement.xSettings;
672 rRemoveNotifyContainer.push_back(
aEvent );
676 rElement.bModified =
false;
677 rElement.bDefault =
true;
686void ModuleUIConfigurationManager::impl_reloadElementTypeData(
687 UIElementType& rUserElementType,
688 UIElementType
const & rDefaultElementType,
689 ConfigEventNotifyContainer& rRemoveNotifyContainer,
690 ConfigEventNotifyContainer& rReplaceNotifyContainer )
692 UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
696 sal_Int16
nType = rUserElementType.nElementType;
698 for (
auto & elem : rHashMap)
700 UIElementData& rElement = elem.second;
701 if ( rElement.bModified )
703 if ( rUserElementType.xStorage->hasByName( rElement.aName ))
708 impl_requestUIElementData(
nType, LAYER_USERDEFINED, rElement );
710 ui::ConfigurationEvent aReplaceEvent;
712 aReplaceEvent.ResourceURL = rElement.aResourceURL;
713 aReplaceEvent.Accessor <<= xThis;
714 aReplaceEvent.Source = xIfac;
715 aReplaceEvent.ReplacedElement <<= xOldSettings;
716 aReplaceEvent.Element <<= rElement.xSettings;
717 rReplaceNotifyContainer.push_back( aReplaceEvent );
719 rElement.bModified =
false;
721 else if ( rDefaultElementType.xStorage->hasByName( rElement.aName ))
726 impl_requestUIElementData(
nType, LAYER_DEFAULT, rElement );
728 ui::ConfigurationEvent aReplaceEvent;
730 aReplaceEvent.ResourceURL = rElement.aResourceURL;
731 aReplaceEvent.Accessor <<= xThis;
732 aReplaceEvent.Source = xIfac;
733 aReplaceEvent.ReplacedElement <<= xOldSettings;
734 aReplaceEvent.Element <<= rElement.xSettings;
735 rReplaceNotifyContainer.push_back( aReplaceEvent );
739 rElement.bModified =
false;
740 rElement.bDefault =
true;
745 ui::ConfigurationEvent aRemoveEvent;
747 aRemoveEvent.ResourceURL = rElement.aResourceURL;
748 aRemoveEvent.Accessor <<= xThis;
749 aRemoveEvent.Source = xIfac;
750 aRemoveEvent.Element <<= rElement.xSettings;
752 rRemoveNotifyContainer.push_back( aRemoveEvent );
756 rElement.bModified =
false;
757 rElement.bDefault =
true;
762 rUserElementType.bModified =
false;
765void ModuleUIConfigurationManager::impl_Initialize()
768 if ( m_xUserConfigStorage.is() )
771 for ( sal_Int16
i = 1;
i < css::ui::UIElementType::COUNT;
777 if ( m_pStorageHandler[
i] )
778 xElementTypeStorage = m_pStorageHandler[
i]->getWorkingStorageUser();
780 catch (
const css::container::NoSuchElementException& )
783 catch (
const css::embed::InvalidStorageException& )
786 catch (
const css::lang::IllegalArgumentException& )
789 catch (
const css::io::IOException& )
792 catch (
const css::embed::StorageWrappedTargetException& )
796 m_aUIElements[LAYER_USERDEFINED][
i].nElementType =
i;
797 m_aUIElements[LAYER_USERDEFINED][
i].bModified =
false;
798 m_aUIElements[LAYER_USERDEFINED][
i].xStorage = xElementTypeStorage;
802 if ( !m_xDefaultConfigStorage.is() )
808 for ( sal_Int16
i = 1;
i < css::ui::UIElementType::COUNT;
814 const OUString
sName( UIELEMENTTYPENAMES[
i] );
815 if( xNameAccess->hasByName(
sName ) )
816 xNameAccess->getByName(
sName ) >>= xElementTypeStorage;
818 catch (
const css::container::NoSuchElementException& )
822 m_aUIElements[LAYER_DEFAULT][
i].nElementType =
i;
823 m_aUIElements[LAYER_DEFAULT][
i].bModified =
false;
824 m_aUIElements[LAYER_DEFAULT][
i].xStorage = xElementTypeStorage;
828ModuleUIConfigurationManager::ModuleUIConfigurationManager(
830 const css::uno::Sequence< css::uno::Any >&
aArguments)
832 , m_bModified(
false )
834 , m_aXMLPostfix(
".xml" )
835 , m_aPropUIName(
"UIName" )
840 m_aUIElements[LAYER_DEFAULT].resize( css::ui::UIElementType::COUNT );
841 m_aUIElements[LAYER_USERDEFINED].resize( css::ui::UIElementType::COUNT );
845 OUString aModuleShortName;
856 for (
int i = 1;
i < css::ui::UIElementType::COUNT;
i++ )
858 OUString aResourceType;
859 if (
i == css::ui::UIElementType::MENUBAR )
861 else if (
i == css::ui::UIElementType::TOOLBAR )
863 else if (
i == css::ui::UIElementType::STATUSBAR )
865 else if (
i == css::ui::UIElementType::POPUPMENU )
868 if ( !aResourceType.isEmpty() )
871 m_pStorageHandler[
i]->connectToResource( PresetHandler::E_MODULES,
874 css::uno::Reference< css::embed::XStorage >());
879 m_xUserRootCommit.set( m_pStorageHandler[css::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY);
880 m_xDefaultConfigStorage = m_pStorageHandler[css::ui::UIElementType::MENUBAR]->getParentStorageShare();
881 m_xUserConfigStorage = m_pStorageHandler[css::ui::UIElementType::MENUBAR]->getParentStorageUser();
883 if ( m_xUserConfigStorage.is() )
889 Any a = xPropSet->getPropertyValue(
"OpenMode");
890 if (
a >>= nOpenMode )
891 m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
899void SAL_CALL ModuleUIConfigurationManager::dispose()
903 css::lang::EventObject
aEvent( xThis );
905 std::unique_lock aGuard(
m_mutex);
906 m_aEventListeners.disposeAndClear( aGuard,
aEvent );
909 std::unique_lock aGuard(
m_mutex);
910 m_aConfigListeners.disposeAndClear( aGuard,
aEvent );
916 m_xModuleImageManager.clear();
917 m_xModuleAcceleratorManager.clear();
918 m_aUIElements[LAYER_USERDEFINED].clear();
919 m_aUIElements[LAYER_DEFAULT].clear();
920 m_xDefaultConfigStorage.clear();
921 m_xUserConfigStorage.clear();
922 m_xUserRootCommit.clear();
930 if ( xModuleImageManager.is() )
931 xModuleImageManager->dispose();
945 throw DisposedException();
948 std::unique_lock aGuard(
m_mutex);
949 m_aEventListeners.addInterface( aGuard, xListener );
955 std::unique_lock aGuard(
m_mutex);
956 m_aEventListeners.removeInterface( aGuard, xListener );
967 throw DisposedException();
970 std::unique_lock aGuard(
m_mutex);
971 m_aConfigListeners.addInterface( aGuard, xListener );
977 std::unique_lock aGuard(
m_mutex);
978 m_aConfigListeners.removeInterface( aGuard, xListener );
982void SAL_CALL ModuleUIConfigurationManager::reset()
988 throw DisposedException();
996 for (
int i = 1;
i < css::ui::UIElementType::COUNT;
i++ )
998 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][
i];
1000 if ( rElementType.xStorage.is() )
1002 bool bCommitSubStorage(
false );
1004 for ( OUString
const & rName : aUIElementStreamNames )
1006 rElementType.xStorage->removeElement( rName );
1007 bCommitSubStorage =
true;
1010 if ( bCommitSubStorage )
1013 if ( xTransactedObject.is() )
1014 xTransactedObject->commit();
1015 m_pStorageHandler[
i]->commitUserChanges();
1021 ConfigEventNotifyContainer aRemoveEventNotifyContainer;
1022 ConfigEventNotifyContainer aReplaceEventNotifyContainer;
1023 for ( sal_Int16 j = 1; j < css::ui::UIElementType::COUNT; j++ )
1027 UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][j];
1028 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][j];
1030 impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer );
1031 rUserElementType.bModified =
false;
1036 throw css::lang::WrappedTargetRuntimeException(
1037 "ModuleUIConfigurationManager::reset exception",
1038 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
1042 m_bModified =
false;
1048 for (
auto const & k: aRemoveEventNotifyContainer )
1049 implts_notifyContainerListener( k, NotifyOp_Remove );
1050 for (
auto const & k: aReplaceEventNotifyContainer )
1051 implts_notifyContainerListener( k, NotifyOp_Replace );
1053 catch (
const css::lang::IllegalArgumentException& )
1056 catch (
const css::container::NoSuchElementException& )
1059 catch (
const css::embed::InvalidStorageException& )
1062 catch (
const css::embed::StorageWrappedTargetException& )
1070 throw IllegalArgumentException();
1074 throw DisposedException();
1076 std::vector< Sequence< PropertyValue > > aElementInfoSeq;
1077 UIElementInfoHashMap aUIElementInfoCollection;
1079 if (
ElementType == css::ui::UIElementType::UNKNOWN )
1081 for ( sal_Int16
i = 0;
i < css::ui::UIElementType::COUNT;
i++ )
1082 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection,
i );
1085 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection,
ElementType );
1087 aElementInfoSeq.resize( aUIElementInfoCollection.size() );
1090 for (
auto const& elem : aUIElementInfoCollection)
1096 aElementInfoSeq[
n++] = aUIElementInfo;
1107 throw DisposedException();
1113sal_Bool SAL_CALL ModuleUIConfigurationManager::hasSettings(
const OUString& ResourceURL )
1115 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1117 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1118 ( nElementType >= css::ui::UIElementType::COUNT ))
1119 throw IllegalArgumentException();
1124 throw DisposedException();
1126 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType,
false );
1127 if ( pDataSettings )
1135 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1137 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1138 ( nElementType >= css::ui::UIElementType::COUNT ))
1139 throw IllegalArgumentException();
1144 throw DisposedException();
1146 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1147 if ( pDataSettings )
1153 return pDataSettings->xSettings;
1156 throw NoSuchElementException();
1161 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1163 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1164 ( nElementType >= css::ui::UIElementType::COUNT ))
1165 throw IllegalArgumentException();
1167 throw IllegalAccessException();
1173 throw DisposedException();
1175 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1176 if ( !pDataSettings )
1177 throw NoSuchElementException();
1178 if ( !pDataSettings->bDefaultNode )
1185 if ( xReplace.is() )
1188 pDataSettings->xSettings = aNewData;
1189 pDataSettings->bDefault =
false;
1190 pDataSettings->bModified =
true;
1194 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1195 rElementType.bModified =
true;
1201 ui::ConfigurationEvent
aEvent;
1202 aEvent.ResourceURL = ResourceURL;
1203 aEvent.Accessor <<= xThis;
1205 aEvent.ReplacedElement <<= xOldSettings;
1206 aEvent.Element <<= pDataSettings->xSettings;
1210 implts_notifyContainerListener(
aEvent, NotifyOp_Replace );
1215 UIElementData aUIElementData;
1217 aUIElementData.bDefault =
false;
1218 aUIElementData.bDefaultNode =
false;
1219 aUIElementData.bModified =
true;
1223 if ( xReplace.is() )
1226 aUIElementData.xSettings = aNewData;
1227 aUIElementData.aName = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
1228 aUIElementData.aResourceURL = ResourceURL;
1232 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1233 rElementType.bModified =
true;
1235 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1239 UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
1240 if ( pIter != rElements.end() )
1241 pIter->second = aUIElementData;
1243 rElements.emplace( ResourceURL, aUIElementData );
1249 ui::ConfigurationEvent
aEvent;
1251 aEvent.ResourceURL = ResourceURL;
1252 aEvent.Accessor <<= xThis;
1254 aEvent.ReplacedElement <<= pDataSettings->xSettings;
1255 aEvent.Element <<= aUIElementData.xSettings;
1259 implts_notifyContainerListener(
aEvent, NotifyOp_Replace );
1264void SAL_CALL ModuleUIConfigurationManager::removeSettings(
const OUString& ResourceURL )
1266 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1268 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1269 ( nElementType >= css::ui::UIElementType::COUNT ))
1270 throw IllegalArgumentException(
"The ResourceURL is not valid or "
1271 "describes an unknown type. "
1272 "ResourceURL: " + ResourceURL,
nullptr, 0 );
1274 throw IllegalAccessException(
"The configuration manager is read-only. "
1275 "ResourceURL: " + ResourceURL,
nullptr );
1281 throw DisposedException(
"The configuration manager has been disposed, "
1282 "and can't uphold its method specification anymore. "
1283 "ResourceURL: " + ResourceURL,
nullptr );
1285 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1286 if ( !pDataSettings )
1287 throw NoSuchElementException(
"The settings data cannot be found. "
1288 "ResourceURL: " + ResourceURL,
nullptr );
1290 if ( pDataSettings->bDefault )
1295 pDataSettings->bDefault =
true;
1298 if ( !pDataSettings->bDefaultNode )
1299 pDataSettings->bModified =
true;
1300 pDataSettings->xSettings.clear();
1304 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1305 rElementType.bModified =
true;
1311 UIElementData* pDefaultDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1312 if ( pDefaultDataSettings )
1315 ui::ConfigurationEvent
aEvent;
1317 aEvent.ResourceURL = ResourceURL;
1318 aEvent.Accessor <<= xThis;
1320 aEvent.Element <<= xRemovedSettings;
1321 aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
1325 implts_notifyContainerListener(
aEvent, NotifyOp_Replace );
1330 ui::ConfigurationEvent
aEvent;
1332 aEvent.ResourceURL = ResourceURL;
1333 aEvent.Accessor <<= xThis;
1335 aEvent.Element <<= xRemovedSettings;
1339 implts_notifyContainerListener(
aEvent, NotifyOp_Remove );
1345void SAL_CALL ModuleUIConfigurationManager::insertSettings(
const OUString& NewResourceURL,
const Reference< XIndexAccess >& aNewData )
1347 sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
1349 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1350 ( nElementType >= css::ui::UIElementType::COUNT ))
1351 throw IllegalArgumentException();
1353 throw IllegalAccessException();
1359 throw DisposedException();
1361 UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
1362 if ( !(!pDataSettings) )
1363 throw ElementExistException();
1364 UIElementData aUIElementData;
1366 aUIElementData.bDefault =
false;
1367 aUIElementData.bDefaultNode =
false;
1368 aUIElementData.bModified =
true;
1372 if ( xReplace.is() )
1375 aUIElementData.xSettings = aNewData;
1376 aUIElementData.aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
1377 aUIElementData.aResourceURL = NewResourceURL;
1380 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1381 rElementType.bModified =
true;
1383 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1384 rElements.emplace( NewResourceURL, aUIElementData );
1390 ui::ConfigurationEvent
aEvent;
1392 aEvent.ResourceURL = NewResourceURL;
1393 aEvent.Accessor <<= xThis;
1395 aEvent.Element <<= xInsertSettings;
1399 implts_notifyContainerListener(
aEvent, NotifyOp_Insert );
1408 throw DisposedException();
1410 if ( !m_xModuleImageManager.is() )
1416 {
"UserConfigStorage",
uno::Any(m_xUserConfigStorage)},
1417 {
"ModuleIdentifier",
uno::Any(m_aModuleIdentifier)},
1418 {
"UserRootCommit",
uno::Any(m_xUserRootCommit)},
1420 m_xModuleImageManager->initialize( aPropSeq );
1428 return ui::ModuleAcceleratorConfiguration::createWithModuleIdentifier(
m_xContext, m_aModuleIdentifier);
1436 throw DisposedException();
1438 if ( !m_xModuleAcceleratorManager.is() )
try
1440 m_xModuleAcceleratorManager = ui::ModuleAcceleratorConfiguration::
1441 createWithModuleIdentifier(
m_xContext, m_aModuleIdentifier);
1443 catch (
const css::uno::DeploymentException& )
1445 SAL_WARN(
"fwk.uiconfiguration",
"ModuleAcceleratorConfiguration"
1446 " not available. This should happen only on mobile platforms.");
1449 return m_xModuleAcceleratorManager;
1458sal_Bool SAL_CALL ModuleUIConfigurationManager::isDefaultSettings(
const OUString& ResourceURL )
1460 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1462 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1463 ( nElementType >= css::ui::UIElementType::COUNT ))
1464 throw IllegalArgumentException();
1469 throw DisposedException();
1471 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType,
false );
1472 if ( pDataSettings && pDataSettings->bDefaultNode )
1480 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1482 if (( nElementType == css::ui::UIElementType::UNKNOWN ) ||
1483 ( nElementType >= css::ui::UIElementType::COUNT ))
1484 throw IllegalArgumentException();
1489 throw DisposedException();
1492 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
1495 UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
1496 UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
1497 if ( pIter != rDefaultHashMap.end() )
1499 if ( !pIter->second.xSettings.is() )
1500 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
1501 return pIter->second.xSettings;
1505 throw NoSuchElementException();
1509void SAL_CALL ModuleUIConfigurationManager::reload()
1514 throw DisposedException();
1516 if ( !m_xUserConfigStorage.is() || !m_bModified ||
m_bReadOnly )
1520 ConfigEventNotifyContainer aRemoveNotifyContainer;
1521 ConfigEventNotifyContainer aReplaceNotifyContainer;
1522 for ( sal_Int16
i = 1;
i < css::ui::UIElementType::COUNT;
i++ )
1526 UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][
i];
1528 if ( rUserElementType.bModified )
1530 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][
i];
1531 impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
1540 m_bModified =
false;
1546 for (
const ui::ConfigurationEvent & j : aRemoveNotifyContainer)
1547 implts_notifyContainerListener( j, NotifyOp_Remove );
1548 for (
const ui::ConfigurationEvent & k : aReplaceNotifyContainer)
1549 implts_notifyContainerListener( k, NotifyOp_Replace );
1552void SAL_CALL ModuleUIConfigurationManager::store()
1557 throw DisposedException();
1559 if ( !m_xUserConfigStorage.is() || !m_bModified ||
m_bReadOnly )
1563 for (
int i = 1;
i < css::ui::UIElementType::COUNT;
i++ )
1567 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][
i];
1569 if ( rElementType.bModified && rElementType.xStorage.is() )
1571 impl_storeElementTypeData( rElementType.xStorage, rElementType );
1572 m_pStorageHandler[
i]->commitUserChanges();
1581 m_bModified =
false;
1589 throw DisposedException();
1591 if ( !m_xUserConfigStorage.is() || !m_bModified ||
m_bReadOnly )
1595 for (
int i = 1;
i < css::ui::UIElementType::COUNT;
i++ )
1600 OUString(UIELEMENTTYPENAMES[
i]), ElementModes::READWRITE ));
1601 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][
i];
1603 if ( rElementType.bModified && xElementTypeStorage.is() )
1604 impl_storeElementTypeData( xElementTypeStorage, rElementType,
false );
1613 if ( xTransactedObject.is() )
1614 xTransactedObject->commit();
1617sal_Bool SAL_CALL ModuleUIConfigurationManager::isModified()
1624sal_Bool SAL_CALL ModuleUIConfigurationManager::isReadOnly()
1631void ModuleUIConfigurationManager::implts_notifyContainerListener(
const ui::ConfigurationEvent&
aEvent, NotifyOp eOp )
1633 std::unique_lock aGuard(
m_mutex);
1634 using ListenerMethodType = void (SAL_CALL css::ui::XUIConfigurationListener::*)(
const ui::ConfigurationEvent&);
1635 ListenerMethodType aListenerMethod {};
1638 case NotifyOp_Replace:
1639 aListenerMethod = &css::ui::XUIConfigurationListener::elementReplaced;
1641 case NotifyOp_Insert:
1642 aListenerMethod = &css::ui::XUIConfigurationListener::elementInserted;
1644 case NotifyOp_Remove:
1645 aListenerMethod = &css::ui::XUIConfigurationListener::elementRemoved;
1648 m_aConfigListeners.notifyEach(aGuard, aListenerMethod,
aEvent);
1653extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1655 css::uno::XComponentContext *context,
1656 css::uno::Sequence<css::uno::Any>
const &arguments)
1658 return cppu::acquire(
new ModuleUIConfigurationManager(context, arguments));
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
css::uno::Reference< css::uno::XComponentContext > m_xContext
Sequence< PropertyValue > aArguments
#define SAL_WARN(area, stream)
constexpr OUStringLiteral RESOURCETYPE_POPUPMENU
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_ModuleUIConfigurationManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &arguments)
constexpr OUStringLiteral RESOURCETYPE_TOOLBAR
constexpr OUStringLiteral RESOURCETYPE_MENUBAR
constexpr OUStringLiteral RESOURCETYPE_STATUSBAR
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)
Any SAL_CALL getCaughtException()
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
#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