1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 #include <uiconfiguration/moduleuiconfigurationmanager.hxx>
31 #include <threadhelp/resetableguard.hxx>
33 #include <uielement/constitemcontainer.hxx>
34 #include <uielement/rootitemcontainer.hxx>
35 #include <uielement/uielementtypenames.hxx>
36 #include <xml/menuconfiguration.hxx>
37 #include <xml/toolboxconfiguration.hxx>
39 #ifndef __FRAMEWORK_XML_STATUSBARCONFIGURATION_HXX_
40 #include <xml/statusbarconfiguration.hxx>
43 //_________________________________________________________________________________________________________________
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/ui/UIElementType.hpp>
47 #include <com/sun/star/ui/ConfigurationEvent.hpp>
48 #include <com/sun/star/lang/DisposedException.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/embed/ElementModes.hpp>
51 #include <com/sun/star/container/XNameAccess.hpp>
52 #include <com/sun/star/io/XStream.hpp>
54 //_________________________________________________________________________________________________________________
56 //_________________________________________________________________________________________________________________
58 #include <vcl/svapp.hxx>
59 #include <rtl/ustrbuf.hxx>
60 #include <comphelper/sequenceashashmap.hxx>
62 //_________________________________________________________________________________________________________________
64 //_________________________________________________________________________________________________________________
67 using namespace com::sun::star::uno
;
68 using namespace com::sun::star::io
;
69 using namespace com::sun::star::embed
;
70 using namespace com::sun::star::lang
;
71 using namespace com::sun::star::container
;
72 using namespace com::sun::star::beans
;
73 using namespace ::com::sun::star::ui
;
78 //*****************************************************************************************************************
79 // XInterface, XTypeProvider, XServiceInfo
80 //*****************************************************************************************************************
81 DEFINE_XINTERFACE_8 ( ModuleUIConfigurationManager
,
83 DIRECT_INTERFACE( css::lang::XTypeProvider
),
84 DIRECT_INTERFACE( css::lang::XServiceInfo
),
85 DIRECT_INTERFACE( css::lang::XComponent
),
86 DIRECT_INTERFACE( css::lang::XInitialization
),
87 DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfiguration
),
88 DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationManager
),
89 DIRECT_INTERFACE( ::com::sun::star::ui::XModuleUIConfigurationManager
),
90 DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationPersistence
)
93 DEFINE_XTYPEPROVIDER_8 ( ModuleUIConfigurationManager
,
94 css::lang::XTypeProvider
,
95 css::lang::XServiceInfo
,
96 css::lang::XComponent
,
97 css::lang::XInitialization
,
98 ::com::sun::star::ui::XUIConfiguration
,
99 ::com::sun::star::ui::XUIConfigurationManager
,
100 ::com::sun::star::ui::XModuleUIConfigurationManager
,
101 ::com::sun::star::ui::XUIConfigurationPersistence
104 DEFINE_XSERVICEINFO_MULTISERVICE ( ModuleUIConfigurationManager
,
105 ::cppu::OWeakObject
,
106 SERVICENAME_MODULEUICONFIGURATIONMANAGER
,
107 IMPLEMENTATIONNAME_MODULEUICONFIGURATIONMANAGER
110 DEFINE_INIT_SERVICE ( ModuleUIConfigurationManager
, {} )
113 // important: The order and position of the elements must match the constant
114 // definition of "::com::sun::star::ui::UIElementType"
115 static const char* UIELEMENTTYPENAMES
[] =
117 "", // Dummy value for unknown!
118 UIELEMENTTYPE_MENUBAR_NAME
,
119 UIELEMENTTYPE_POPUPMENU_NAME
,
120 UIELEMENTTYPE_TOOLBAR_NAME
,
121 UIELEMENTTYPE_STATUSBAR_NAME
,
122 UIELEMENTTYPE_FLOATINGWINDOW_NAME
,
123 UIELEMENTTYPE_PROGRESSBAR_NAME
,
124 UIELEMENTTYPE_TOOLPANEL_NAME
127 static const char RESOURCEURL_PREFIX
[] = "private:resource/";
128 static const sal_Int32 RESOURCEURL_PREFIX_SIZE
= 17;
129 static const char RESOURCEURL_CUSTOM_ELEMENT
[] = "custom_";
131 static sal_Int16
RetrieveTypeFromResourceURL( const rtl::OUString
& aResourceURL
)
134 if (( aResourceURL
.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
135 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
137 OUString aTmpStr
= aResourceURL
.copy( RESOURCEURL_PREFIX_SIZE
);
138 sal_Int32 nIndex
= aTmpStr
.indexOf( '/' );
139 if (( nIndex
> 0 ) && ( aTmpStr
.getLength() > nIndex
))
141 OUString
aTypeStr( aTmpStr
.copy( 0, nIndex
));
142 for ( int i
= 0; i
< UIElementType::COUNT
; i
++ )
144 if ( aTypeStr
.equalsAscii( UIELEMENTTYPENAMES
[i
] ))
145 return sal_Int16( i
);
150 return UIElementType::UNKNOWN
;
153 static OUString
RetrieveNameFromResourceURL( const rtl::OUString
& aResourceURL
)
155 if (( aResourceURL
.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
156 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
158 sal_Int32 nIndex
= aResourceURL
.lastIndexOf( '/' );
159 if (( nIndex
> 0 ) && (( nIndex
+1 ) < aResourceURL
.getLength()))
160 return aResourceURL
.copy( nIndex
+1 );
166 void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap
& aUIElementInfoCollection
, sal_Int16 nElementType
)
168 // preload list of element types on demand
169 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
170 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
172 UIElementDataHashMap
& rUserElements
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
173 UIElementDataHashMap::const_iterator pUserIter
= rUserElements
.begin();
175 OUString
aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT
));
176 while ( pUserIter
!= rUserElements
.end() )
178 sal_Int32 nIndex
= pUserIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
179 if ( nIndex
> RESOURCEURL_PREFIX_SIZE
)
181 // Performance: Retrieve user interface name only for custom user interface elements.
182 // It's only used by them!
183 UIElementData
* pDataSettings
= impl_findUIElementData( pUserIter
->second
.aResourceURL
, nElementType
);
186 // Retrieve user interface name from XPropertySet interface
187 rtl::OUString aUIName
;
188 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
191 Any a
= xPropSet
->getPropertyValue( m_aPropUIName
);
195 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, aUIName
);
196 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
201 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
202 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, OUString() );
203 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
208 UIElementDataHashMap
& rDefaultElements
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
209 UIElementDataHashMap::const_iterator pDefIter
= rDefaultElements
.begin();
211 while ( pDefIter
!= rDefaultElements
.end() )
213 UIElementInfoHashMap::const_iterator pIterInfo
= aUIElementInfoCollection
.find( pDefIter
->second
.aResourceURL
);
214 if ( pIterInfo
== aUIElementInfoCollection
.end() )
216 sal_Int32 nIndex
= pDefIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
217 if ( nIndex
> RESOURCEURL_PREFIX_SIZE
)
219 // Performance: Retrieve user interface name only for custom user interface elements.
220 // It's only used by them!
221 UIElementData
* pDataSettings
= impl_findUIElementData( pDefIter
->second
.aResourceURL
, nElementType
);
224 // Retrieve user interface name from XPropertySet interface
225 rtl::OUString aUIName
;
226 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
229 Any a
= xPropSet
->getPropertyValue( m_aPropUIName
);
233 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, aUIName
);
234 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
239 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
240 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, OUString() );
241 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
249 void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer
, sal_Int16 nElementType
)
251 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
253 if ( !rElementTypeData
.bLoaded
)
255 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
256 if ( xElementTypeStorage
.is() )
258 rtl::OUStringBuffer
aBuf( RESOURCEURL_PREFIX_SIZE
);
259 aBuf
.appendAscii( RESOURCEURL_PREFIX
);
260 aBuf
.appendAscii( UIELEMENTTYPENAMES
[ nElementType
] );
261 aBuf
.appendAscii( "/" );
262 OUString
aResURLPrefix( aBuf
.makeStringAndClear() );
264 UIElementDataHashMap
& rHashMap
= rElementTypeData
.aElementsHashMap
;
265 Reference
< XNameAccess
> xNameAccess( xElementTypeStorage
, UNO_QUERY
);
266 Sequence
< OUString
> aUIElementNames
= xNameAccess
->getElementNames();
267 for ( sal_Int32 n
= 0; n
< aUIElementNames
.getLength(); n
++ )
269 UIElementData aUIElementData
;
271 // Resource name must be without ".xml"
272 sal_Int32 nIndex
= aUIElementNames
[n
].lastIndexOf( '.' );
273 if (( nIndex
> 0 ) && ( nIndex
< aUIElementNames
[n
].getLength() ))
275 OUString
aExtension( aUIElementNames
[n
].copy( nIndex
+1 ));
276 OUString
aUIElementName( aUIElementNames
[n
].copy( 0, nIndex
));
278 if (( aUIElementName
.getLength() > 0 ) &&
279 ( aExtension
.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
281 aUIElementData
.aResourceURL
= aResURLPrefix
+ aUIElementName
;
282 aUIElementData
.aName
= aUIElementNames
[n
];
284 if ( eLayer
== LAYER_USERDEFINED
)
286 aUIElementData
.bModified
= false;
287 aUIElementData
.bDefault
= false;
288 aUIElementData
.bDefaultNode
= false;
291 // Create hash_map entries for all user interface elements inside the storage. We don't load the
292 // settings to speed up the process.
293 rHashMap
.insert( UIElementDataHashMap::value_type( aUIElementData
.aResourceURL
, aUIElementData
));
296 rElementTypeData
.bLoaded
= true;
301 //rElementTypeData.bLoaded = true;
304 void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType
, Layer eLayer
, UIElementData
& aUIElementData
)
306 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
308 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
309 if ( xElementTypeStorage
.is() && aUIElementData
.aName
.getLength() )
313 Reference
< XStream
> xStream
= xElementTypeStorage
->openStreamElement( aUIElementData
.aName
, ElementModes::READ
);
314 Reference
< XInputStream
> xInputStream
= xStream
->getInputStream();
316 if ( xInputStream
.is() )
318 switch ( nElementType
)
320 case ::com::sun::star::ui::UIElementType::UNKNOWN
:
323 case ::com::sun::star::ui::UIElementType::MENUBAR
:
327 MenuConfiguration
aMenuCfg( m_xServiceManager
);
328 Reference
< XIndexAccess
> xContainer( aMenuCfg
.CreateMenuBarConfigurationFromXML( xInputStream
));
329 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xContainer
);
330 if ( pRootItemContainer
)
331 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
333 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( xContainer
, sal_True
) ), UNO_QUERY
);
336 catch ( ::com::sun::star::lang::WrappedTargetException
& )
342 case ::com::sun::star::ui::UIElementType::POPUPMENU
:
347 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
351 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
352 ToolBoxConfiguration::LoadToolBox( m_xServiceManager
, xInputStream
, xIndexContainer
);
353 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
354 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
357 catch ( ::com::sun::star::lang::WrappedTargetException
& )
364 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
368 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
369 StatusBarConfiguration::LoadStatusBar( m_xServiceManager
, xInputStream
, xIndexContainer
);
370 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
371 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
374 catch ( ::com::sun::star::lang::WrappedTargetException
& )
381 case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW
:
388 catch ( ::com::sun::star::embed::InvalidStorageException
& )
391 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
394 catch ( ::com::sun::star::io::IOException
& )
397 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
402 // At least we provide an empty settings container!
403 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer() ), UNO_QUERY
);
406 ModuleUIConfigurationManager::UIElementData
* ModuleUIConfigurationManager::impl_findUIElementData( const rtl::OUString
& aResourceURL
, sal_Int16 nElementType
, bool bLoad
)
408 // preload list of element types on demand
409 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
410 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
412 // first try to look into our user-defined vector/hash_map combination
413 UIElementDataHashMap
& rUserHashMap
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
414 UIElementDataHashMap::iterator pIter
= rUserHashMap
.find( aResourceURL
);
415 if ( pIter
!= rUserHashMap
.end() )
417 // Default data settings data must be retrieved from the default layer!
418 if ( !pIter
->second
.bDefault
)
420 if ( !pIter
->second
.xSettings
.is() && bLoad
)
421 impl_requestUIElementData( nElementType
, LAYER_USERDEFINED
, pIter
->second
);
422 return &(pIter
->second
);
426 // Not successfull, we have to look into our default vector/hash_map combination
427 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
428 pIter
= rDefaultHashMap
.find( aResourceURL
);
429 if ( pIter
!= rDefaultHashMap
.end() )
431 if ( !pIter
->second
.xSettings
.is() && bLoad
)
432 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
433 return &(pIter
->second
);
436 // Nothing has been found!
440 void ModuleUIConfigurationManager::impl_storeElementTypeData( Reference
< XStorage
> xStorage
, UIElementType
& rElementType
, bool bResetModifyState
)
442 UIElementDataHashMap
& rHashMap
= rElementType
.aElementsHashMap
;
443 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
445 while ( pIter
!= rHashMap
.end() )
447 UIElementData
& rElement
= pIter
->second
;
448 if ( rElement
.bModified
)
450 if ( rElement
.bDefault
)
452 xStorage
->removeElement( rElement
.aName
);
453 rElement
.bModified
= sal_False
; // mark as not modified
457 Reference
< XStream
> xStream( xStorage
->openStreamElement( rElement
.aName
, ElementModes::WRITE
|ElementModes::TRUNCATE
), UNO_QUERY
);
458 Reference
< XOutputStream
> xOutputStream( xStream
->getOutputStream() );
460 if ( xOutputStream
.is() )
462 switch( rElementType
.nElementType
)
464 case ::com::sun::star::ui::UIElementType::MENUBAR
:
468 MenuConfiguration
aMenuCfg( m_xServiceManager
);
469 aMenuCfg
.StoreMenuBarConfigurationToXML( rElement
.xSettings
, xOutputStream
);
471 catch ( ::com::sun::star::lang::WrappedTargetException
& )
477 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
481 ToolBoxConfiguration::StoreToolBox( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
483 catch ( ::com::sun::star::lang::WrappedTargetException
& )
489 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
493 StatusBarConfiguration::StoreStatusBar( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
495 catch ( ::com::sun::star::lang::WrappedTargetException
& )
506 // mark as not modified if we store to our own storage
507 if ( bResetModifyState
)
508 rElement
.bModified
= sal_False
;
515 // commit element type storage
516 Reference
< XTransactedObject
> xTransactedObject( xStorage
, UNO_QUERY
);
517 if ( xTransactedObject
.is() )
518 xTransactedObject
->commit();
520 // mark UIElementType as not modified if we store to our own storage
521 if ( bResetModifyState
)
522 rElementType
.bModified
= sal_False
;
525 // This is only allowed to be called on the LAYER_USER_DEFINED!
526 void ModuleUIConfigurationManager::impl_resetElementTypeData(
527 UIElementType
& rUserElementType
,
528 UIElementType
& rDefaultElementType
,
529 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
530 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
532 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
533 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
535 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
536 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
537 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
538 sal_Int16 nType
= rUserElementType
.nElementType
;
540 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
542 while ( pIter
!= rHashMap
.end() )
544 UIElementData
& rElement
= pIter
->second
;
545 if ( !rElement
.bDefault
)
547 if ( xDefaultNameAccess
->hasByName( rElement
.aName
))
549 // Replace settings with data from default layer
550 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
551 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
553 ConfigurationEvent aReplaceEvent
;
554 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
555 aReplaceEvent
.Accessor
<<= xThis
;
556 aReplaceEvent
.Source
= xIfac
;
557 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
558 aReplaceEvent
.Element
<<= rElement
.xSettings
;
560 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
562 // Mark element as default and not modified. That means "not active"
563 // in the user layer anymore.
564 rElement
.bModified
= false;
565 rElement
.bDefault
= true;
569 // Remove user-defined settings from user layer
570 ConfigurationEvent aEvent
;
571 aEvent
.ResourceURL
= rElement
.aResourceURL
;
572 aEvent
.Accessor
<<= xThis
;
573 aEvent
.Source
= xIfac
;
574 aEvent
.Element
<<= rElement
.xSettings
;
576 rRemoveNotifyContainer
.push_back( aEvent
);
578 // Mark element as default and not modified. That means "not active"
579 // in the user layer anymore.
580 rElement
.bModified
= false;
581 rElement
.bDefault
= true;
588 // Remove all settings from our user interface elements
592 void ModuleUIConfigurationManager::impl_reloadElementTypeData(
593 UIElementType
& rUserElementType
,
594 UIElementType
& rDefaultElementType
,
595 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
596 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
598 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
599 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
600 Reference
< XStorage
> xUserStorage( rUserElementType
.xStorage
);
601 Reference
< XStorage
> xDefaultStorage( rDefaultElementType
.xStorage
);
602 Reference
< XNameAccess
> xUserNameAccess( rUserElementType
.xStorage
, UNO_QUERY
);
603 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
605 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
606 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
607 sal_Int16 nType
= rUserElementType
.nElementType
;
609 while ( pIter
!= rHashMap
.end() )
611 UIElementData
& rElement
= pIter
->second
;
612 if ( rElement
.bModified
)
614 if ( xUserNameAccess
->hasByName( rElement
.aName
))
616 // Replace settings with data from user layer
617 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
619 impl_requestUIElementData( nType
, LAYER_USERDEFINED
, rElement
);
621 ConfigurationEvent aReplaceEvent
;
623 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
624 aReplaceEvent
.Accessor
<<= xThis
;
625 aReplaceEvent
.Source
= xIfac
;
626 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
627 aReplaceEvent
.Element
<<= rElement
.xSettings
;
628 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
630 rElement
.bModified
= false;
632 else if ( xDefaultNameAccess
->hasByName( rElement
.aName
))
634 // Replace settings with data from default layer
635 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
637 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
639 ConfigurationEvent aReplaceEvent
;
641 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
642 aReplaceEvent
.Accessor
<<= xThis
;
643 aReplaceEvent
.Source
= xIfac
;
644 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
645 aReplaceEvent
.Element
<<= rElement
.xSettings
;
646 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
648 // Mark element as default and not modified. That means "not active"
649 // in the user layer anymore.
650 rElement
.bModified
= false;
651 rElement
.bDefault
= true;
655 // Element settings are not in any storage => remove
656 ConfigurationEvent aRemoveEvent
;
658 aRemoveEvent
.ResourceURL
= rElement
.aResourceURL
;
659 aRemoveEvent
.Accessor
<<= xThis
;
660 aRemoveEvent
.Source
= xIfac
;
661 aRemoveEvent
.Element
<<= rElement
.xSettings
;
663 rRemoveNotifyContainer
.push_back( aRemoveEvent
);
665 // Mark element as default and not modified. That means "not active"
666 // in the user layer anymore.
667 rElement
.bModified
= false;
668 rElement
.bDefault
= true;
674 rUserElementType
.bModified
= sal_False
;
677 void ModuleUIConfigurationManager::impl_Initialize()
679 // Initialize the top-level structures with the storage data
680 if ( m_xUserConfigStorage
.is() )
682 // Try to access our module sub folder
683 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
686 Reference
< XStorage
> xElementTypeStorage
;
689 if ( m_pStorageHandler
[i
] )
690 xElementTypeStorage
= m_pStorageHandler
[i
]->getWorkingStorageUser();
692 catch ( com::sun::star::container::NoSuchElementException
& )
695 catch ( ::com::sun::star::embed::InvalidStorageException
& )
698 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
701 catch ( ::com::sun::star::io::IOException
& )
704 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
708 m_aUIElements
[LAYER_USERDEFINED
][i
].nElementType
= i
;
709 m_aUIElements
[LAYER_USERDEFINED
][i
].bModified
= false;
710 m_aUIElements
[LAYER_USERDEFINED
][i
].xStorage
= xElementTypeStorage
;
711 m_aUIElements
[LAYER_USERDEFINED
][i
].bDefaultLayer
= false;
715 if ( m_xDefaultConfigStorage
.is() )
717 Reference
< XNameAccess
> xNameAccess( m_xDefaultConfigStorage
, UNO_QUERY_THROW
);
719 // Try to access our module sub folder
720 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
723 Reference
< XStorage
> xElementTypeStorage
;
726 Any a
= xNameAccess
->getByName( OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ));
727 a
>>= xElementTypeStorage
;
729 catch ( com::sun::star::container::NoSuchElementException
& )
733 m_aUIElements
[LAYER_DEFAULT
][i
].nElementType
= i
;
734 m_aUIElements
[LAYER_DEFAULT
][i
].bModified
= false;
735 m_aUIElements
[LAYER_DEFAULT
][i
].xStorage
= xElementTypeStorage
;
736 m_aUIElements
[LAYER_DEFAULT
][i
].bDefaultLayer
= true;
741 ModuleUIConfigurationManager::ModuleUIConfigurationManager( com::sun::star::uno::Reference
< com::sun::star::lang::XMultiServiceFactory
> xServiceManager
) :
742 ThreadHelpBase( &Application::GetSolarMutex() )
743 , m_xDefaultConfigStorage( 0 )
744 , m_xUserConfigStorage( 0 )
745 , m_bReadOnly( true )
746 , m_bInitialized( false )
747 , m_bModified( false )
748 , m_bConfigRead( false )
749 , m_bDisposed( false )
750 , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
751 , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
752 , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
753 , m_xServiceManager( xServiceManager
)
754 , m_aListenerContainer( m_aLock
.getShareableOslMutex() )
756 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
757 m_pStorageHandler
[i
] = 0;
759 // Make sure we have a default initialized entry for every layer and user interface element type!
760 // The following code depends on this!
761 m_aUIElements
[LAYER_DEFAULT
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
762 m_aUIElements
[LAYER_USERDEFINED
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
765 ModuleUIConfigurationManager::~ModuleUIConfigurationManager()
767 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
768 delete m_pStorageHandler
[i
];
772 void SAL_CALL
ModuleUIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException
)
774 Reference
< XComponent
> xThis( static_cast< OWeakObject
* >(this), UNO_QUERY
);
776 css::lang::EventObject
aEvent( xThis
);
777 m_aListenerContainer
.disposeAndClear( aEvent
);
779 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
780 ResetableGuard
aGuard( m_aLock
);
781 Reference
< XComponent
> xModuleImageManager( m_xModuleImageManager
);
782 m_xModuleImageManager
.clear();
783 m_xModuleAcceleratorManager
.clear();
784 m_aUIElements
[LAYER_USERDEFINED
].clear();
785 m_aUIElements
[LAYER_DEFAULT
].clear();
786 m_xDefaultConfigStorage
.clear();
787 m_xUserConfigStorage
.clear();
788 m_xUserRootCommit
.clear();
789 m_bConfigRead
= false;
793 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
797 if ( xModuleImageManager
.is() )
798 xModuleImageManager
->dispose();
805 void SAL_CALL
ModuleUIConfigurationManager::addEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
808 ResetableGuard
aGuard( m_aLock
);
810 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
812 throw DisposedException();
815 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
818 void SAL_CALL
ModuleUIConfigurationManager::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
820 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
821 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
825 void SAL_CALL
ModuleUIConfigurationManager::initialize( const Sequence
< Any
>& aArguments
) throw ( Exception
, RuntimeException
)
827 ResetableGuard
aLock( m_aLock
);
829 if ( !m_bInitialized
)
831 ::comphelper::SequenceAsHashMap
lArgs(aArguments
);
832 m_aModuleIdentifier
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleIdentifier"), ::rtl::OUString());
833 m_aModuleShortName
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleShortName"), ::rtl::OUString());
835 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
837 rtl::OUString aResourceType
;
838 if ( i
== ::com::sun::star::ui::UIElementType::MENUBAR
)
839 aResourceType
= PresetHandler::RESOURCETYPE_MENUBAR();
840 else if ( i
== ::com::sun::star::ui::UIElementType::TOOLBAR
)
841 aResourceType
= PresetHandler::RESOURCETYPE_TOOLBAR();
842 else if ( i
== ::com::sun::star::ui::UIElementType::STATUSBAR
)
843 aResourceType
= PresetHandler::RESOURCETYPE_STATUSBAR();
845 if ( aResourceType
.getLength() > 0 )
847 m_pStorageHandler
[i
] = new PresetHandler( m_xServiceManager
);
848 m_pStorageHandler
[i
]->connectToResource( PresetHandler::E_MODULES
,
849 aResourceType
, // this path wont be used later ... seee next lines!
851 css::uno::Reference
< css::embed::XStorage
>()); // no document root used here!
855 // initialize root storages for all resource types
856 m_xUserRootCommit
= css::uno::Reference
< css::embed::XTransactedObject
>(
857 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY
); // can be empty
858 m_xDefaultConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageShare(
859 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageShare());
860 m_xUserConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageUser(
861 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageUser());
863 if ( m_xUserConfigStorage
.is() )
865 Reference
< XPropertySet
> xPropSet( m_xUserConfigStorage
, UNO_QUERY
);
869 Any a
= xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" )));
870 if ( a
>>= nOpenMode
)
871 m_bReadOnly
= !( nOpenMode
& ElementModes::WRITE
);
877 m_bInitialized
= true;
882 void SAL_CALL
ModuleUIConfigurationManager::addConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
885 ResetableGuard
aGuard( m_aLock
);
887 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
889 throw DisposedException();
892 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
895 void SAL_CALL
ModuleUIConfigurationManager::removeConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
897 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
898 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
902 // XUIConfigurationManager
903 void SAL_CALL
ModuleUIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException
)
905 ResetableGuard
aGuard( m_aLock
);
907 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
909 throw DisposedException();
911 bool bResetStorage( false );
915 // Remove all elements from our user-defined storage!
918 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
920 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
921 Reference
< XStorage
> xSubStorage( rElementType
.xStorage
, UNO_QUERY
);
923 if ( xSubStorage
.is() )
925 bool bCommitSubStorage( false );
926 Reference
< XNameAccess
> xSubStorageNameAccess( xSubStorage
, UNO_QUERY
);
927 Sequence
< OUString
> aUIElementStreamNames
= xSubStorageNameAccess
->getElementNames();
928 for ( sal_Int32 j
= 0; j
< aUIElementStreamNames
.getLength(); j
++ )
930 xSubStorage
->removeElement( aUIElementStreamNames
[j
] );
931 bCommitSubStorage
= true;
934 if ( bCommitSubStorage
)
936 Reference
< XTransactedObject
> xTransactedObject( xSubStorage
, UNO_QUERY
);
937 if ( xTransactedObject
.is() )
938 xTransactedObject
->commit();
939 m_pStorageHandler
[i
]->commitUserChanges();
944 bResetStorage
= true;
946 // remove settings from user defined layer and notify listener about removed settings data!
947 ConfigEventNotifyContainer aRemoveEventNotifyContainer
;
948 ConfigEventNotifyContainer aReplaceEventNotifyContainer
;
949 for ( sal_Int16 j
= 1; j
< ::com::sun::star::ui::UIElementType::COUNT
; j
++ )
953 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][j
];
954 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][j
];
956 impl_resetElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveEventNotifyContainer
, aReplaceEventNotifyContainer
);
957 rUserElementType
.bModified
= sal_False
;
965 m_bModified
= sal_False
;
967 // Unlock mutex before notify our listeners
970 // Notify our listeners
972 for ( k
= 0; k
< aRemoveEventNotifyContainer
.size(); k
++ )
973 implts_notifyContainerListener( aRemoveEventNotifyContainer
[k
], NotifyOp_Remove
);
974 for ( k
= 0; k
< aReplaceEventNotifyContainer
.size(); k
++ )
975 implts_notifyContainerListener( aReplaceEventNotifyContainer
[k
], NotifyOp_Replace
);
977 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
980 catch ( ::com::sun::star::container::NoSuchElementException
& )
983 catch ( ::com::sun::star::embed::InvalidStorageException
& )
986 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
992 Sequence
< Sequence
< PropertyValue
> > SAL_CALL
ModuleUIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType
)
993 throw ( IllegalArgumentException
, RuntimeException
)
995 if (( ElementType
< 0 ) || ( ElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
996 throw IllegalArgumentException();
998 ResetableGuard
aGuard( m_aLock
);
1000 throw DisposedException();
1002 Sequence
< Sequence
< PropertyValue
> > aElementInfoSeq
;
1003 UIElementInfoHashMap aUIElementInfoCollection
;
1005 if ( ElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
)
1007 for ( sal_Int16 i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1008 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, sal_Int16( i
) );
1011 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, ElementType
);
1013 Sequence
< PropertyValue
> aUIElementInfo( 2 );
1014 aUIElementInfo
[0].Name
= m_aPropResourceURL
;
1015 aUIElementInfo
[1].Name
= m_aPropUIName
;
1017 aElementInfoSeq
.realloc( aUIElementInfoCollection
.size() );
1018 UIElementInfoHashMap::const_iterator pIter
= aUIElementInfoCollection
.begin();
1021 while ( pIter
!= aUIElementInfoCollection
.end() )
1023 aUIElementInfo
[0].Value
<<= pIter
->second
.aResourceURL
;
1024 aUIElementInfo
[1].Value
<<= pIter
->second
.aUIName
;
1025 aElementInfoSeq
[n
++] = aUIElementInfo
;
1029 return aElementInfoSeq
;
1032 Reference
< XIndexContainer
> SAL_CALL
ModuleUIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException
)
1034 ResetableGuard
aGuard( m_aLock
);
1037 throw DisposedException();
1039 // Creates an empty item container which can be filled from outside
1040 return Reference
< XIndexContainer
>( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
1043 sal_Bool SAL_CALL
ModuleUIConfigurationManager::hasSettings( const ::rtl::OUString
& ResourceURL
)
1044 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1046 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1048 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1049 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1050 throw IllegalArgumentException();
1053 ResetableGuard
aGuard( m_aLock
);
1056 throw DisposedException();
1058 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1059 if ( pDataSettings
)
1066 Reference
< XIndexAccess
> SAL_CALL
ModuleUIConfigurationManager::getSettings( const ::rtl::OUString
& ResourceURL
, sal_Bool bWriteable
)
1067 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1069 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1071 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1072 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1073 throw IllegalArgumentException();
1076 ResetableGuard
aGuard( m_aLock
);
1079 throw DisposedException();
1081 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1082 if ( pDataSettings
)
1084 // Create a copy of our data if someone wants to change the data.
1086 return Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new RootItemContainer( pDataSettings
->xSettings
) ), UNO_QUERY
);
1088 return pDataSettings
->xSettings
;
1092 throw NoSuchElementException();
1095 void SAL_CALL
ModuleUIConfigurationManager::replaceSettings( const ::rtl::OUString
& ResourceURL
, const Reference
< ::com::sun::star::container::XIndexAccess
>& aNewData
)
1096 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::IllegalAccessException
, ::com::sun::star::uno::RuntimeException
)
1098 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1100 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1101 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1102 throw IllegalArgumentException();
1103 else if ( m_bReadOnly
)
1104 throw IllegalAccessException();
1107 ResetableGuard
aGuard( m_aLock
);
1110 throw DisposedException();
1112 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1113 if ( pDataSettings
)
1115 if ( !pDataSettings
->bDefaultNode
)
1117 // we have a settings entry in our user-defined layer - replace
1118 Reference
< XIndexAccess
> xOldSettings
= pDataSettings
->xSettings
;
1120 // Create a copy of the data if the container is not const
1121 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1122 if ( xReplace
.is() )
1123 pDataSettings
->xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1125 pDataSettings
->xSettings
= aNewData
;
1126 pDataSettings
->bDefault
= false;
1127 pDataSettings
->bModified
= true;
1130 // Modify type container
1131 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1132 rElementType
.bModified
= true;
1134 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
1136 // Create event to notify listener about replaced element settings
1137 ConfigurationEvent aEvent
;
1138 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
1140 aEvent
.ResourceURL
= ResourceURL
;
1141 aEvent
.Accessor
<<= xThis
;
1142 aEvent
.Source
= xIfac
;
1143 aEvent
.ReplacedElement
<<= xOldSettings
;
1144 aEvent
.Element
<<= pDataSettings
->xSettings
;
1148 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1152 // we have no settings in our user-defined layer - insert
1153 UIElementData aUIElementData
;
1155 aUIElementData
.bDefault
= false;
1156 aUIElementData
.bDefaultNode
= false;
1157 aUIElementData
.bModified
= true;
1159 // Create a copy of the data if the container is not const
1160 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1161 if ( xReplace
.is() )
1162 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1164 aUIElementData
.xSettings
= aNewData
;
1165 aUIElementData
.aName
= RetrieveNameFromResourceURL( ResourceURL
) + m_aXMLPostfix
;
1166 aUIElementData
.aResourceURL
= ResourceURL
;
1169 // Modify type container
1170 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1171 rElementType
.bModified
= true;
1173 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1175 // Check our user element settings hash map as it can already contain settings that have been set to default!
1176 // If no node can be found, we have to insert it.
1177 UIElementDataHashMap::iterator pIter
= rElements
.find( ResourceURL
);
1178 if ( pIter
!= rElements
.end() )
1179 pIter
->second
= aUIElementData
;
1181 rElements
.insert( UIElementDataHashMap::value_type( ResourceURL
, aUIElementData
));
1183 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
1184 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
1186 // Create event to notify listener about replaced element settings
1187 ConfigurationEvent aEvent
;
1189 aEvent
.ResourceURL
= ResourceURL
;
1190 aEvent
.Accessor
<<= xThis
;
1191 aEvent
.Source
= xIfac
;
1192 aEvent
.ReplacedElement
<<= pDataSettings
->xSettings
;
1193 aEvent
.Element
<<= aUIElementData
.xSettings
;
1197 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1201 throw NoSuchElementException();
1205 void SAL_CALL
ModuleUIConfigurationManager::removeSettings( const ::rtl::OUString
& ResourceURL
)
1206 throw ( NoSuchElementException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1208 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1210 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1211 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1212 throw IllegalArgumentException();
1213 else if ( m_bReadOnly
)
1214 throw IllegalAccessException();
1217 ResetableGuard
aGuard( m_aLock
);
1220 throw DisposedException();
1222 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1223 if ( pDataSettings
)
1225 // If element settings are default, we don't need to change anything!
1226 if ( pDataSettings
->bDefault
)
1230 Reference
< XIndexAccess
> xRemovedSettings
= pDataSettings
->xSettings
;
1231 pDataSettings
->bDefault
= true;
1233 // check if this is a default layer node
1234 if ( !pDataSettings
->bDefaultNode
)
1235 pDataSettings
->bModified
= true; // we have to remove this node from the user layer!
1236 pDataSettings
->xSettings
.clear();
1237 m_bModified
= true; // user layer must be written
1239 // Modify type container
1240 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1241 rElementType
.bModified
= true;
1243 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
1244 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
1246 // Check if we have settings in the default layer which replaces the user-defined one!
1247 UIElementData
* pDefaultDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1248 if ( pDefaultDataSettings
)
1250 // Create event to notify listener about replaced element settings
1251 ConfigurationEvent aEvent
;
1253 aEvent
.ResourceURL
= ResourceURL
;
1254 aEvent
.Accessor
<<= xThis
;
1255 aEvent
.Source
= xIfac
;
1256 aEvent
.Element
<<= xRemovedSettings
;
1257 aEvent
.ReplacedElement
<<= pDefaultDataSettings
->xSettings
;
1261 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1265 // Create event to notify listener about removed element settings
1266 ConfigurationEvent aEvent
;
1268 aEvent
.ResourceURL
= ResourceURL
;
1269 aEvent
.Accessor
<<= xThis
;
1270 aEvent
.Source
= xIfac
;
1271 aEvent
.Element
<<= xRemovedSettings
;
1275 implts_notifyContainerListener( aEvent
, NotifyOp_Remove
);
1280 throw NoSuchElementException();
1284 void SAL_CALL
ModuleUIConfigurationManager::insertSettings( const ::rtl::OUString
& NewResourceURL
, const Reference
< XIndexAccess
>& aNewData
)
1285 throw ( ElementExistException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1287 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( NewResourceURL
);
1289 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1290 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1291 throw IllegalArgumentException();
1292 else if ( m_bReadOnly
)
1293 throw IllegalAccessException();
1296 ResetableGuard
aGuard( m_aLock
);
1299 throw DisposedException();
1301 UIElementData
* pDataSettings
= impl_findUIElementData( NewResourceURL
, nElementType
);
1302 if ( !pDataSettings
)
1304 UIElementData aUIElementData
;
1306 aUIElementData
.bDefault
= false;
1307 aUIElementData
.bDefaultNode
= false;
1308 aUIElementData
.bModified
= true;
1310 // Create a copy of the data if the container is not const
1311 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1312 if ( xReplace
.is() )
1313 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1315 aUIElementData
.xSettings
= aNewData
;
1316 aUIElementData
.aName
= RetrieveNameFromResourceURL( NewResourceURL
) + m_aXMLPostfix
;
1317 aUIElementData
.aResourceURL
= NewResourceURL
;
1320 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1321 rElementType
.bModified
= true;
1323 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1324 rElements
.insert( UIElementDataHashMap::value_type( NewResourceURL
, aUIElementData
));
1326 Reference
< XIndexAccess
> xInsertSettings( aUIElementData
.xSettings
);
1327 Reference
< XUIConfigurationManager
> xThis( static_cast< OWeakObject
* >( this ), UNO_QUERY
);
1328 Reference
< XInterface
> xIfac( xThis
, UNO_QUERY
);
1330 // Create event to notify listener about removed element settings
1331 ConfigurationEvent aEvent
;
1333 aEvent
.ResourceURL
= NewResourceURL
;
1334 aEvent
.Accessor
<<= xThis
;
1335 aEvent
.Source
= xIfac
;
1336 aEvent
.Element
<<= xInsertSettings
;
1340 implts_notifyContainerListener( aEvent
, NotifyOp_Insert
);
1343 throw ElementExistException();
1347 Reference
< XInterface
> SAL_CALL
ModuleUIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException
)
1349 ResetableGuard
aGuard( m_aLock
);
1352 throw DisposedException();
1354 if ( !m_xModuleImageManager
.is() )
1356 m_xModuleImageManager
= Reference
< XComponent
>( static_cast< cppu::OWeakObject
*>( new ModuleImageManager( m_xServiceManager
)),
1358 Reference
< XInitialization
> xInit( m_xModuleImageManager
, UNO_QUERY
);
1360 Sequence
< Any
> aPropSeq( 3 );
1361 PropertyValue aPropValue
;
1362 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
1363 aPropValue
.Value
= makeAny( m_xUserConfigStorage
);
1364 aPropSeq
[0] = makeAny( aPropValue
);
1365 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
1366 aPropValue
.Value
= makeAny( m_aModuleIdentifier
);
1367 aPropSeq
[1] = makeAny( aPropValue
);
1368 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
1369 aPropValue
.Value
= makeAny( m_xUserRootCommit
);
1370 aPropSeq
[2] = makeAny( aPropValue
);
1372 xInit
->initialize( aPropSeq
);
1375 return Reference
< XInterface
>( m_xModuleImageManager
, UNO_QUERY
);
1378 Reference
< XInterface
> SAL_CALL
ModuleUIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException
)
1380 ResetableGuard
aGuard( m_aLock
);
1383 throw DisposedException();
1385 Reference
< XMultiServiceFactory
> xSMGR
= m_xServiceManager
;
1386 ::rtl::OUString aModule
= m_aModuleIdentifier
;
1388 if ( !m_xModuleAcceleratorManager
.is() )
1390 Reference
< XInterface
> xManager
= xSMGR
->createInstance(SERVICENAME_MODULEACCELERATORCONFIGURATION
);
1391 Reference
< XInitialization
> xInit (xManager
, UNO_QUERY_THROW
);
1393 PropertyValue aProp
;
1394 aProp
.Name
= ::rtl::OUString::createFromAscii("ModuleIdentifier");
1395 aProp
.Value
<<= aModule
;
1397 Sequence
< Any
> lArgs(1);
1400 xInit
->initialize(lArgs
);
1401 m_xModuleAcceleratorManager
= Reference
< XInterface
>( xManager
, UNO_QUERY
);
1404 return m_xModuleAcceleratorManager
;
1407 Reference
< XInterface
> SAL_CALL
ModuleUIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException
)
1409 return Reference
< XInterface
>();
1412 // XModuleUIConfigurationManager
1413 sal_Bool SAL_CALL
ModuleUIConfigurationManager::isDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1414 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1416 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1418 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1419 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1420 throw IllegalArgumentException();
1423 ResetableGuard
aGuard( m_aLock
);
1426 throw DisposedException();
1428 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1429 if ( pDataSettings
&& pDataSettings
->bDefaultNode
)
1436 Reference
< XIndexAccess
> SAL_CALL
ModuleUIConfigurationManager::getDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1437 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1439 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1441 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1442 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1443 throw IllegalArgumentException();
1446 ResetableGuard
aGuard( m_aLock
);
1449 throw DisposedException();
1451 // preload list of element types on demand
1452 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
1454 // Look into our default vector/hash_map combination
1455 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
1456 UIElementDataHashMap::iterator pIter
= rDefaultHashMap
.find( ResourceURL
);
1457 if ( pIter
!= rDefaultHashMap
.end() )
1459 if ( !pIter
->second
.xSettings
.is() )
1460 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
1461 return pIter
->second
.xSettings
;
1465 // Nothing has been found!
1466 throw NoSuchElementException();
1469 // XUIConfigurationPersistence
1470 void SAL_CALL
ModuleUIConfigurationManager::reload() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1472 ResetableGuard
aGuard( m_aLock
);
1475 throw DisposedException();
1477 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1479 // Try to access our module sub folder
1480 ConfigEventNotifyContainer aRemoveNotifyContainer
;
1481 ConfigEventNotifyContainer aReplaceNotifyContainer
;
1482 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1486 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1487 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][i
];
1489 if ( rUserElementType
.bModified
)
1490 impl_reloadElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveNotifyContainer
, aReplaceNotifyContainer
);
1492 catch ( Exception
& )
1494 throw IOException();
1498 m_bModified
= sal_False
;
1500 // Unlock mutex before notify our listeners
1503 // Notify our listeners
1504 for ( sal_uInt32 j
= 0; j
< aRemoveNotifyContainer
.size(); j
++ )
1505 implts_notifyContainerListener( aRemoveNotifyContainer
[j
], NotifyOp_Remove
);
1506 for ( sal_uInt32 k
= 0; k
< aReplaceNotifyContainer
.size(); k
++ )
1507 implts_notifyContainerListener( aReplaceNotifyContainer
[k
], NotifyOp_Replace
);
1511 void SAL_CALL
ModuleUIConfigurationManager::store() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1513 ResetableGuard
aGuard( m_aLock
);
1516 throw DisposedException();
1518 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1520 // Try to access our module sub folder
1521 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1525 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1526 Reference
< XStorage
> xStorage( rElementType
.xStorage
, UNO_QUERY
);
1528 if ( rElementType
.bModified
&& xStorage
.is() )
1530 impl_storeElementTypeData( xStorage
, rElementType
);
1531 m_pStorageHandler
[i
]->commitUserChanges();
1534 catch ( Exception
& )
1536 throw IOException();
1540 m_bModified
= false;
1544 void SAL_CALL
ModuleUIConfigurationManager::storeToStorage( const Reference
< XStorage
>& Storage
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1546 ResetableGuard
aGuard( m_aLock
);
1549 throw DisposedException();
1551 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1553 // Try to access our module sub folder
1554 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1558 Reference
< XStorage
> xElementTypeStorage( Storage
->openStorageElement(
1559 OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ), ElementModes::READWRITE
));
1560 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1562 if ( rElementType
.bModified
&& xElementTypeStorage
.is() )
1563 impl_storeElementTypeData( xElementTypeStorage
, rElementType
, false ); // store data to storage, but don't reset modify flag!
1565 catch ( Exception
& )
1567 throw IOException();
1571 Reference
< XTransactedObject
> xTransactedObject( Storage
, UNO_QUERY
);
1572 if ( xTransactedObject
.is() )
1573 xTransactedObject
->commit();
1577 sal_Bool SAL_CALL
ModuleUIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException
)
1579 ResetableGuard
aGuard( m_aLock
);
1584 sal_Bool SAL_CALL
ModuleUIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException
)
1586 ResetableGuard
aGuard( m_aLock
);
1591 void ModuleUIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent
& aEvent
, NotifyOp eOp
)
1593 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< ::com::sun::star::ui::XUIConfigurationListener
>*) NULL
) );
1594 if ( pContainer
!= NULL
)
1596 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
1597 while ( pIterator
.hasMoreElements() )
1603 case NotifyOp_Replace
:
1604 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementReplaced( aEvent
);
1606 case NotifyOp_Insert
:
1607 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementInserted( aEvent
);
1609 case NotifyOp_Remove
:
1610 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementRemoved( aEvent
);
1614 catch( css::uno::RuntimeException
& )
1622 } // namespace framework