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 <uiconfigurationmanagerimpl.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>
38 #include <uiconfiguration/imagemanager.hxx>
40 #ifndef __FRAMEWORK_XML_STATUSBARCONFIGURATION_HXX_
41 #include <xml/statusbarconfiguration.hxx>
44 //_________________________________________________________________________________________________________________
46 //_________________________________________________________________________________________________________________
47 #include <com/sun/star/ui/UIElementType.hpp>
48 #include <com/sun/star/ui/ConfigurationEvent.hpp>
49 #include <com/sun/star/lang/DisposedException.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/embed/ElementModes.hpp>
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #include <com/sun/star/io/XStream.hpp>
55 //_________________________________________________________________________________________________________________
57 //_________________________________________________________________________________________________________________
59 #include <vcl/svapp.hxx>
60 #include <rtl/ustrbuf.hxx>
61 #include <comphelper/sequenceashashmap.hxx>
62 #include <boost/bind.hpp>
64 //_________________________________________________________________________________________________________________
66 //_________________________________________________________________________________________________________________
69 using namespace com::sun::star::uno
;
70 using namespace com::sun::star::io
;
71 using namespace com::sun::star::embed
;
72 using namespace com::sun::star::lang
;
73 using namespace com::sun::star::container
;
74 using namespace com::sun::star::beans
;
75 using namespace ::com::sun::star::ui
;
76 using namespace ::cppu
;
82 // important: The order and position of the elements must match the constant
83 // definition of "::com::sun::star::ui::UIElementType"
84 static const char* UIELEMENTTYPENAMES
[] =
86 "", // Dummy value for unknown!
87 UIELEMENTTYPE_MENUBAR_NAME
,
88 UIELEMENTTYPE_POPUPMENU_NAME
,
89 UIELEMENTTYPE_TOOLBAR_NAME
,
90 UIELEMENTTYPE_STATUSBAR_NAME
,
91 UIELEMENTTYPE_FLOATINGWINDOW_NAME
,
92 UIELEMENTTYPE_PROGRESSBAR_NAME
95 static const char RESOURCEURL_PREFIX
[] = "private:resource/";
96 static const sal_Int32 RESOURCEURL_PREFIX_SIZE
= 17;
97 static const char RESOURCEURL_CUSTOM_ELEMENT
[] = "custom_";
99 static sal_Int16
RetrieveTypeFromResourceURL( const rtl::OUString
& aResourceURL
)
102 if (( aResourceURL
.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
103 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
105 rtl::OUString aTmpStr
= aResourceURL
.copy( RESOURCEURL_PREFIX_SIZE
);
106 sal_Int32 nIndex
= aTmpStr
.indexOf( '/' );
107 if (( nIndex
> 0 ) && ( aTmpStr
.getLength() > nIndex
))
109 rtl::OUString
aTypeStr( aTmpStr
.copy( 0, nIndex
));
110 for ( int i
= 0; i
< UIElementType::COUNT
; i
++ )
112 if ( aTypeStr
.equalsAscii( UIELEMENTTYPENAMES
[i
] ))
113 return sal_Int16( i
);
118 return UIElementType::UNKNOWN
;
121 static rtl::OUString
RetrieveNameFromResourceURL( const rtl::OUString
& aResourceURL
)
123 if (( aResourceURL
.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
124 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
126 sal_Int32 nIndex
= aResourceURL
.lastIndexOf( '/' );
127 if (( nIndex
> 0 ) && (( nIndex
+1 ) < aResourceURL
.getLength()))
128 return aResourceURL
.copy( nIndex
+1 );
131 return rtl::OUString();
134 void UIConfigurationManagerImpl::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap
& aUIElementInfoCollection
, sal_Int16 nElementType
)
136 // preload list of element types on demand
137 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
139 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
141 UIElementDataHashMap
& rUserElements
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
142 UIElementDataHashMap::const_iterator pUserIter
= rUserElements
.begin();
144 rtl::OUString
aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT
));
145 while ( pUserIter
!= rUserElements
.end() )
147 sal_Int32 nIndex
= pUserIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
148 if ( nIndex
> RESOURCEURL_PREFIX_SIZE
)
150 // Performance: Retrieve user interface name only for custom user interface elements.
151 // It's only used by them!
152 UIElementData
* pDataSettings
= impl_findUIElementData( pUserIter
->second
.aResourceURL
, nElementType
);
153 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
))
155 // Retrieve user interface name from XPropertySet interface
156 rtl::OUString aUIName
;
157 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
160 xPropSet
->getPropertyValue( m_aPropUIName
) >>= aUIName
;
163 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, aUIName
);
164 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
169 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
170 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, rtl::OUString() );
171 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
178 UIElementDataHashMap
& rDefaultElements
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
179 UIElementDataHashMap::const_iterator pDefIter
= rDefaultElements
.begin();
181 while ( pDefIter
!= rDefaultElements
.end() )
183 UIElementInfoHashMap::const_iterator pIterInfo
= aUIElementInfoCollection
.find( pDefIter
->second
.aResourceURL
);
184 if ( pIterInfo
== aUIElementInfoCollection
.end() )
186 sal_Int32 nIndex
= pDefIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
187 if ( nIndex
> RESOURCEURL_PREFIX_SIZE
)
189 // Performance: Retrieve user interface name only for custom user interface elements.
190 // It's only used by them!
191 UIElementData
* pDataSettings
= impl_findUIElementData( pDefIter
->second
.aResourceURL
, nElementType
);
194 // Retrieve user interface name from XPropertySet interface
195 rtl::OUString aUIName
;
196 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
199 xPropSet
->getPropertyValue( m_aPropUIName
) >>= aUIName
;
202 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, aUIName
);
203 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
208 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
209 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, rtl::OUString() );
210 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
215 } // while ( pDefIter != rDefaultElements.end() )
219 void UIConfigurationManagerImpl::impl_preloadUIElementTypeList( Layer eLayer
, sal_Int16 nElementType
)
221 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
223 if ( !rElementTypeData
.bLoaded
)
225 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
226 if ( xElementTypeStorage
.is() )
228 rtl::OUStringBuffer
aBuf( RESOURCEURL_PREFIX_SIZE
);
229 aBuf
.appendAscii( RESOURCEURL_PREFIX
);
230 aBuf
.appendAscii( UIELEMENTTYPENAMES
[ nElementType
] );
231 aBuf
.appendAscii( "/" );
232 rtl::OUString
aResURLPrefix( aBuf
.makeStringAndClear() );
234 UIElementDataHashMap
& rHashMap
= rElementTypeData
.aElementsHashMap
;
235 Reference
< XNameAccess
> xNameAccess( xElementTypeStorage
, UNO_QUERY
);
236 Sequence
< rtl::OUString
> aUIElementNames
= xNameAccess
->getElementNames();
237 for ( sal_Int32 n
= 0; n
< aUIElementNames
.getLength(); n
++ )
239 UIElementData aUIElementData
;
241 // Resource name must be without ".xml"
242 sal_Int32 nIndex
= aUIElementNames
[n
].lastIndexOf( '.' );
243 if (( nIndex
> 0 ) && ( nIndex
< aUIElementNames
[n
].getLength() ))
245 rtl::OUString
aExtension( aUIElementNames
[n
].copy( nIndex
+1 ));
246 rtl::OUString
aUIElementName( aUIElementNames
[n
].copy( 0, nIndex
));
248 if (( aUIElementName
.getLength() > 0 ) &&
249 ( aExtension
.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
251 aUIElementData
.aResourceURL
= aResURLPrefix
+ aUIElementName
;
252 aUIElementData
.aName
= aUIElementNames
[n
];
254 if ( eLayer
== LAYER_USERDEFINED
)
256 aUIElementData
.bModified
= false;
257 aUIElementData
.bDefault
= false;
258 aUIElementData
.bDefaultNode
= false;
261 // Create hash_map entries for all user interface elements inside the storage. We don't load the
262 // settings to speed up the process.
263 rHashMap
.insert( UIElementDataHashMap::value_type( aUIElementData
.aResourceURL
, aUIElementData
));
270 rElementTypeData
.bLoaded
= true;
273 void UIConfigurationManagerImpl::impl_requestUIElementData( sal_Int16 nElementType
, Layer eLayer
, UIElementData
& aUIElementData
)
275 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
277 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
278 if ( xElementTypeStorage
.is() && aUIElementData
.aName
.getLength() )
282 Reference
< XStream
> xStream
= xElementTypeStorage
->openStreamElement( aUIElementData
.aName
, ElementModes::READ
);
283 Reference
< XInputStream
> xInputStream
= xStream
->getInputStream();
285 if ( xInputStream
.is() )
287 switch ( nElementType
)
289 case ::com::sun::star::ui::UIElementType::UNKNOWN
:
292 case ::com::sun::star::ui::UIElementType::MENUBAR
:
296 MenuConfiguration
aMenuCfg( m_xServiceManager
);
297 Reference
< XIndexAccess
> xContainer( aMenuCfg
.CreateMenuBarConfigurationFromXML( xInputStream
));
298 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xContainer
);
299 if ( pRootItemContainer
)
300 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
302 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( xContainer
, sal_True
) ), UNO_QUERY
);
305 catch ( ::com::sun::star::lang::WrappedTargetException
& )
311 case ::com::sun::star::ui::UIElementType::POPUPMENU
:
316 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
320 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
321 ToolBoxConfiguration::LoadToolBox( m_xServiceManager
, xInputStream
, xIndexContainer
);
322 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
323 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
326 catch ( ::com::sun::star::lang::WrappedTargetException
& )
333 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
337 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
338 StatusBarConfiguration::LoadStatusBar( m_xServiceManager
, xInputStream
, xIndexContainer
);
339 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
340 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
343 catch ( ::com::sun::star::lang::WrappedTargetException
& )
350 case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW
:
357 catch ( ::com::sun::star::embed::InvalidStorageException
& )
360 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
363 catch ( ::com::sun::star::io::IOException
& )
366 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
371 // At least we provide an empty settings container!
372 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer() ), UNO_QUERY
);
375 UIConfigurationManagerImpl::UIElementData
* UIConfigurationManagerImpl::impl_findUIElementData( const rtl::OUString
& aResourceURL
, sal_Int16 nElementType
, bool bLoad
)
377 // preload list of element types on demand
378 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
380 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
382 // first try to look into our user-defined vector/hash_map combination
383 UIElementDataHashMap
& rUserHashMap
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
384 UIElementDataHashMap::iterator pIter
= rUserHashMap
.find( aResourceURL
);
385 if ( pIter
!= rUserHashMap
.end() )
387 // Default data settings data must be retrieved from the default layer!
388 if ( !pIter
->second
.bDefault
)
390 if ( !pIter
->second
.xSettings
.is() && bLoad
)
391 impl_requestUIElementData( nElementType
, LAYER_USERDEFINED
, pIter
->second
);
392 return &(pIter
->second
);
398 // Not successfull, we have to look into our default vector/hash_map combination
399 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
400 pIter
= rDefaultHashMap
.find( aResourceURL
);
401 if ( pIter
!= rDefaultHashMap
.end() )
403 if ( !pIter
->second
.xSettings
.is() && bLoad
)
404 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
405 return &(pIter
->second
);
406 } // if ( pIter != rDefaultHashMap.end() )
409 // Nothing has been found!
413 void UIConfigurationManagerImpl::impl_storeElementTypeData( Reference
< XStorage
> xStorage
, UIElementType
& rElementType
, bool bResetModifyState
)
415 UIElementDataHashMap
& rHashMap
= rElementType
.aElementsHashMap
;
416 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
418 while ( pIter
!= rHashMap
.end() )
420 UIElementData
& rElement
= pIter
->second
;
421 if ( rElement
.bModified
)
423 if ( rElement
.bDefault
)
425 xStorage
->removeElement( rElement
.aName
);
426 rElement
.bModified
= sal_False
; // mark as not modified
430 Reference
< XStream
> xStream( xStorage
->openStreamElement( rElement
.aName
, ElementModes::WRITE
|ElementModes::TRUNCATE
), UNO_QUERY
);
431 Reference
< XOutputStream
> xOutputStream( xStream
->getOutputStream() );
433 if ( xOutputStream
.is() )
435 switch( rElementType
.nElementType
)
437 case ::com::sun::star::ui::UIElementType::MENUBAR
:
441 MenuConfiguration
aMenuCfg( m_xServiceManager
);
442 aMenuCfg
.StoreMenuBarConfigurationToXML( rElement
.xSettings
, xOutputStream
);
444 catch ( ::com::sun::star::lang::WrappedTargetException
& )
450 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
454 ToolBoxConfiguration::StoreToolBox( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
456 catch ( ::com::sun::star::lang::WrappedTargetException
& )
462 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
466 StatusBarConfiguration::StoreStatusBar( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
468 catch ( ::com::sun::star::lang::WrappedTargetException
& )
479 // mark as not modified if we store to our own storage
480 if ( bResetModifyState
)
481 rElement
.bModified
= sal_False
;
488 // commit element type storage
489 Reference
< XTransactedObject
> xTransactedObject( xStorage
, UNO_QUERY
);
490 if ( xTransactedObject
.is() )
491 xTransactedObject
->commit();
493 // mark UIElementType as not modified if we store to our own storage
494 if ( bResetModifyState
)
495 rElementType
.bModified
= sal_False
;
498 // This is only allowed to be called on the LAYER_USER_DEFINED!
499 void UIConfigurationManagerImpl::impl_resetElementTypeData(
500 UIElementType
& rUserElementType
,
501 UIElementType
& rDefaultElementType
,
502 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
503 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
505 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
506 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
508 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
509 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
510 sal_Int16 nType
= rUserElementType
.nElementType
;
512 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
514 while ( pIter
!= rHashMap
.end() )
516 UIElementData
& rElement
= pIter
->second
;
517 if ( !rElement
.bDefault
)
519 if ( m_bUseDefault
&& xDefaultNameAccess
->hasByName( rElement
.aName
))
521 // Replace settings with data from default layer
522 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
523 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
525 ConfigurationEvent aReplaceEvent
;
526 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
527 aReplaceEvent
.Accessor
<<= xThis
;
528 aReplaceEvent
.Source
= m_xOwner
;
529 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
530 aReplaceEvent
.Element
<<= rElement
.xSettings
;
532 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
534 // Mark element as default and not modified. That means "not active"
535 // in the user layer anymore.
536 rElement
.bModified
= false;
537 rElement
.bDefault
= true;
541 // Remove user-defined settings from user layer
542 ConfigurationEvent aEvent
;
543 aEvent
.ResourceURL
= rElement
.aResourceURL
;
544 aEvent
.Accessor
<<= xThis
;
545 aEvent
.Source
= m_xOwner
;
546 aEvent
.Element
<<= rElement
.xSettings
;
548 rRemoveNotifyContainer
.push_back( aEvent
);
550 // Mark element as default and not modified. That means "not active"
551 // in the user layer anymore.
552 rElement
.bModified
= false;
553 rElement
.bDefault
= true;
555 } // if ( !rElement.bDefault )
557 rElement
.bModified
= false;
562 // Remove all settings from our user interface elements
566 void UIConfigurationManagerImpl::impl_reloadElementTypeData(
567 UIElementType
& rUserElementType
,
568 UIElementType
& rDefaultElementType
,
569 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
570 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
572 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
573 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
574 Reference
< XStorage
> xUserStorage( rUserElementType
.xStorage
);
575 Reference
< XStorage
> xDefaultStorage( rDefaultElementType
.xStorage
);
576 Reference
< XNameAccess
> xUserNameAccess( rUserElementType
.xStorage
, UNO_QUERY
);
577 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
579 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
580 sal_Int16 nType
= rUserElementType
.nElementType
;
582 while ( pIter
!= rHashMap
.end() )
584 UIElementData
& rElement
= pIter
->second
;
585 if ( rElement
.bModified
)
587 if ( xUserNameAccess
->hasByName( rElement
.aName
))
589 // Replace settings with data from user layer
590 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
592 impl_requestUIElementData( nType
, LAYER_USERDEFINED
, rElement
);
594 ConfigurationEvent aReplaceEvent
;
596 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
597 aReplaceEvent
.Accessor
<<= xThis
;
598 aReplaceEvent
.Source
= m_xOwner
;
599 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
600 aReplaceEvent
.Element
<<= rElement
.xSettings
;
601 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
603 rElement
.bModified
= false;
605 else if ( m_bUseDefault
&& xDefaultNameAccess
->hasByName( rElement
.aName
))
607 // Replace settings with data from default layer
608 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
610 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
612 ConfigurationEvent aReplaceEvent
;
614 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
615 aReplaceEvent
.Accessor
<<= xThis
;
616 aReplaceEvent
.Source
= m_xOwner
;
617 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
618 aReplaceEvent
.Element
<<= rElement
.xSettings
;
619 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
621 // Mark element as default and not modified. That means "not active"
622 // in the user layer anymore.
623 rElement
.bModified
= false;
624 rElement
.bDefault
= true;
628 // Element settings are not in any storage => remove
629 ConfigurationEvent aRemoveEvent
;
631 aRemoveEvent
.ResourceURL
= rElement
.aResourceURL
;
632 aRemoveEvent
.Accessor
<<= xThis
;
633 aRemoveEvent
.Source
= m_xOwner
;
634 aRemoveEvent
.Element
<<= rElement
.xSettings
;
636 rRemoveNotifyContainer
.push_back( aRemoveEvent
);
638 // Mark element as default and not modified. That means "not active"
639 // in the user layer anymore.
640 rElement
.bModified
= false;
641 rElement
.bDefault
= true;
647 rUserElementType
.bModified
= sal_False
;
650 void UIConfigurationManagerImpl::impl_Initialize()
652 // Initialize the top-level structures with the storage data
653 if ( m_xUserConfigStorage
.is() )
655 // Try to access our module sub folder
656 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
659 Reference
< XStorage
> xElementTypeStorage
;
662 if ( m_pStorageHandler
[i
] )
663 xElementTypeStorage
= m_pStorageHandler
[i
]->getWorkingStorageUser();
665 catch ( com::sun::star::container::NoSuchElementException
& )
668 catch ( ::com::sun::star::embed::InvalidStorageException
& )
671 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
674 catch ( ::com::sun::star::io::IOException
& )
677 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
681 m_aUIElements
[LAYER_USERDEFINED
][i
].nElementType
= i
;
682 m_aUIElements
[LAYER_USERDEFINED
][i
].bModified
= false;
683 m_aUIElements
[LAYER_USERDEFINED
][i
].xStorage
= xElementTypeStorage
;
684 m_aUIElements
[LAYER_USERDEFINED
][i
].bDefaultLayer
= false;
686 } // if ( m_xUserConfigStorage.is() )
687 else if ( !m_bUseDefault
)
689 // We have no storage, just initialize ui element types with empty storage!
690 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
691 m_aUIElements
[LAYER_USERDEFINED
][i
].xStorage
.clear();
694 if ( m_bUseDefault
&& m_xUserConfigStorage
.is() )
696 Reference
< XNameAccess
> xNameAccess( m_xDefaultConfigStorage
, UNO_QUERY_THROW
);
698 // Try to access our module sub folder
699 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
702 Reference
< XStorage
> xElementTypeStorage
;
705 xNameAccess
->getByName( rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] )) >>= xElementTypeStorage
;
707 catch ( com::sun::star::container::NoSuchElementException
& )
711 m_aUIElements
[LAYER_DEFAULT
][i
].nElementType
= i
;
712 m_aUIElements
[LAYER_DEFAULT
][i
].bModified
= false;
713 m_aUIElements
[LAYER_DEFAULT
][i
].xStorage
= xElementTypeStorage
;
714 m_aUIElements
[LAYER_DEFAULT
][i
].bDefaultLayer
= true;
719 UIConfigurationManagerImpl::UIConfigurationManagerImpl( const Reference
< com::sun::star::lang::XMultiServiceFactory
>& xServiceManager
720 ,const Reference
< XInterface
>& _xOwner
721 , bool _bUseDefault
) :
722 ThreadHelpBase( &Application::GetSolarMutex() )
723 , m_xOwner( _xOwner
)
724 , m_bUseDefault(_bUseDefault
)
725 , m_bReadOnly( true )
726 , m_bInitialized( false )
727 , m_bModified( false )
728 , m_bConfigRead( false )
729 , m_bDisposed( false )
730 , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
731 , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
732 , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
733 , m_xServiceManager( xServiceManager
)
734 , m_aListenerContainer( m_aLock
.getShareableOslMutex() )
736 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
737 m_pStorageHandler
[i
] = 0;
739 // Make sure we have a default initialized entry for every layer and user interface element type!
740 // The following code depends on this!
741 m_aUIElements
[LAYER_DEFAULT
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
742 m_aUIElements
[LAYER_USERDEFINED
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
745 UIConfigurationManagerImpl::~UIConfigurationManagerImpl()
747 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
748 delete m_pStorageHandler
[i
];
752 void UIConfigurationManagerImpl::dispose() throw (::com::sun::star::uno::RuntimeException
)
754 css::lang::EventObject
aEvent( m_xOwner
);
755 m_aListenerContainer
.disposeAndClear( aEvent
);
758 ResetableGuard
aGuard( m_aLock
);
761 if ( m_xModuleImageManager
.is() )
762 m_xModuleImageManager
->dispose();
768 m_xModuleImageManager
.clear();
769 m_aUIElements
[LAYER_USERDEFINED
].clear();
770 m_aUIElements
[LAYER_DEFAULT
].clear();
771 m_xDefaultConfigStorage
.clear();
772 m_xUserConfigStorage
.clear();
773 m_xUserRootCommit
.clear();
774 m_bConfigRead
= false;
780 void UIConfigurationManagerImpl::addEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
783 ResetableGuard
aGuard( m_aLock
);
785 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
787 throw DisposedException();
790 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
793 void UIConfigurationManagerImpl::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
795 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
796 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
800 void UIConfigurationManagerImpl::initialize( const Sequence
< Any
>& aArguments
) throw ( Exception
, RuntimeException
)
802 ResetableGuard
aLock( m_aLock
);
804 if ( !m_bInitialized
)
806 ::comphelper::SequenceAsHashMap
lArgs(aArguments
);
807 m_aModuleIdentifier
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleIdentifier"), ::rtl::OUString());
808 m_aModuleShortName
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleShortName"), ::rtl::OUString());
810 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
812 rtl::OUString aResourceType
;
813 if ( i
== ::com::sun::star::ui::UIElementType::MENUBAR
)
814 aResourceType
= PresetHandler::RESOURCETYPE_MENUBAR();
815 else if ( i
== ::com::sun::star::ui::UIElementType::TOOLBAR
)
816 aResourceType
= PresetHandler::RESOURCETYPE_TOOLBAR();
817 else if ( i
== ::com::sun::star::ui::UIElementType::STATUSBAR
)
818 aResourceType
= PresetHandler::RESOURCETYPE_STATUSBAR();
820 if ( aResourceType
.getLength() > 0 )
822 m_pStorageHandler
[i
] = new PresetHandler( m_xServiceManager
);
823 m_pStorageHandler
[i
]->connectToResource( PresetHandler::E_MODULES
,
824 aResourceType
, // this path wont be used later ... seee next lines!
826 css::uno::Reference
< css::embed::XStorage
>()); // no document root used here!
830 // initialize root storages for all resource types
831 m_xUserRootCommit
= css::uno::Reference
< css::embed::XTransactedObject
>(
832 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY
); // can be empty
833 m_xDefaultConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageShare(
834 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageShare());
835 m_xUserConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageUser(
836 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageUser());
838 if ( m_xUserConfigStorage
.is() )
840 Reference
< XPropertySet
> xPropSet( m_xUserConfigStorage
, UNO_QUERY
);
844 if ( xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode
)
845 m_bReadOnly
= !( nOpenMode
& ElementModes::WRITE
);
851 m_bInitialized
= true;
856 void UIConfigurationManagerImpl::addConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
859 ResetableGuard
aGuard( m_aLock
);
861 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
863 throw DisposedException();
866 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
869 void UIConfigurationManagerImpl::removeConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
871 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
872 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
876 // XUIConfigurationManager
877 void UIConfigurationManagerImpl::reset() throw (::com::sun::star::uno::RuntimeException
)
879 ResetableGuard
aGuard( m_aLock
);
881 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
883 throw DisposedException();
885 bool bResetStorage( false );
889 // Remove all elements from our user-defined storage!
892 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
894 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
895 Reference
< XStorage
> xSubStorage( rElementType
.xStorage
, UNO_QUERY
);
897 if ( xSubStorage
.is() )
899 bool bCommitSubStorage( false );
900 Reference
< XNameAccess
> xSubStorageNameAccess( xSubStorage
, UNO_QUERY
);
901 Sequence
< rtl::OUString
> aUIElementStreamNames
= xSubStorageNameAccess
->getElementNames();
902 for ( sal_Int32 j
= 0; j
< aUIElementStreamNames
.getLength(); j
++ )
904 xSubStorage
->removeElement( aUIElementStreamNames
[j
] );
905 bCommitSubStorage
= true;
908 if ( bCommitSubStorage
)
910 Reference
< XTransactedObject
> xTransactedObject( xSubStorage
, UNO_QUERY
);
911 if ( xTransactedObject
.is() )
912 xTransactedObject
->commit();
913 m_pStorageHandler
[i
]->commitUserChanges();
918 bResetStorage
= true;
920 // remove settings from user defined layer and notify listener about removed settings data!
921 ConfigEventNotifyContainer aRemoveEventNotifyContainer
;
922 ConfigEventNotifyContainer aReplaceEventNotifyContainer
;
923 for ( sal_Int16 j
= 1; j
< ::com::sun::star::ui::UIElementType::COUNT
; j
++ )
927 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][j
];
928 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][j
];
930 impl_resetElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveEventNotifyContainer
, aReplaceEventNotifyContainer
);
931 rUserElementType
.bModified
= sal_False
;
939 m_bModified
= sal_False
;
941 // Unlock mutex before notify our listeners
944 // Notify our listeners
945 ::std::for_each(aRemoveEventNotifyContainer
.begin(),aRemoveEventNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Remove
));
946 ::std::for_each(aReplaceEventNotifyContainer
.begin(),aReplaceEventNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Replace
));
948 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
951 catch ( ::com::sun::star::container::NoSuchElementException
& )
954 catch ( ::com::sun::star::embed::InvalidStorageException
& )
957 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
963 Sequence
< Sequence
< PropertyValue
> > UIConfigurationManagerImpl::getUIElementsInfo( sal_Int16 ElementType
)
964 throw ( IllegalArgumentException
, RuntimeException
)
966 if (( ElementType
< 0 ) || ( ElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
967 throw IllegalArgumentException();
969 ResetableGuard
aGuard( m_aLock
);
971 throw DisposedException();
973 Sequence
< Sequence
< PropertyValue
> > aElementInfoSeq
;
974 UIElementInfoHashMap aUIElementInfoCollection
;
976 if ( ElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
)
978 for ( sal_Int16 i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
979 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, sal_Int16( i
) );
982 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, ElementType
);
984 Sequence
< PropertyValue
> aUIElementInfo( 2 );
985 aUIElementInfo
[0].Name
= m_aPropResourceURL
;
986 aUIElementInfo
[1].Name
= m_aPropUIName
;
988 aElementInfoSeq
.realloc( aUIElementInfoCollection
.size() );
989 UIElementInfoHashMap::const_iterator pIter
= aUIElementInfoCollection
.begin();
992 while ( pIter
!= aUIElementInfoCollection
.end() )
994 aUIElementInfo
[0].Value
<<= pIter
->second
.aResourceURL
;
995 aUIElementInfo
[1].Value
<<= pIter
->second
.aUIName
;
996 aElementInfoSeq
[n
++] = aUIElementInfo
;
1000 return aElementInfoSeq
;
1003 Reference
< XIndexContainer
> UIConfigurationManagerImpl::createSettings() throw (::com::sun::star::uno::RuntimeException
)
1005 ResetableGuard
aGuard( m_aLock
);
1008 throw DisposedException();
1010 // Creates an empty item container which can be filled from outside
1011 return Reference
< XIndexContainer
>( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
1014 sal_Bool
UIConfigurationManagerImpl::hasSettings( const ::rtl::OUString
& ResourceURL
)
1015 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1017 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1019 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1020 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1021 throw IllegalArgumentException();
1024 ResetableGuard
aGuard( m_aLock
);
1027 throw DisposedException();
1029 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1030 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1037 Reference
< XIndexAccess
> UIConfigurationManagerImpl::getSettings( const ::rtl::OUString
& ResourceURL
, sal_Bool bWriteable
)
1038 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1040 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1042 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1043 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1044 throw IllegalArgumentException();
1047 ResetableGuard
aGuard( m_aLock
);
1050 throw DisposedException();
1052 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1053 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1055 // Create a copy of our data if someone wants to change the data.
1057 return Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new RootItemContainer( pDataSettings
->xSettings
) ), UNO_QUERY
);
1059 return pDataSettings
->xSettings
;
1063 throw NoSuchElementException();
1066 void UIConfigurationManagerImpl::replaceSettings( const ::rtl::OUString
& ResourceURL
, const Reference
< ::com::sun::star::container::XIndexAccess
>& aNewData
)
1067 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::IllegalAccessException
, ::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();
1074 else if ( m_bReadOnly
)
1075 throw IllegalAccessException();
1078 ResetableGuard
aGuard( m_aLock
);
1081 throw DisposedException();
1083 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1084 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1086 if ( !m_bUseDefault
|| !pDataSettings
->bDefaultNode
)
1088 // we have a settings entry in our user-defined layer - replace
1089 Reference
< XIndexAccess
> xOldSettings
= pDataSettings
->xSettings
;
1091 // Create a copy of the data if the container is not const
1092 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1093 if ( xReplace
.is() )
1094 pDataSettings
->xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1096 pDataSettings
->xSettings
= aNewData
;
1097 pDataSettings
->bDefault
= false;
1098 pDataSettings
->bModified
= true;
1101 // Modify type container
1102 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1103 rElementType
.bModified
= true;
1105 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1107 // Create event to notify listener about replaced element settings
1108 ConfigurationEvent aEvent
;
1110 aEvent
.ResourceURL
= ResourceURL
;
1111 aEvent
.Accessor
<<= xThis
;
1112 aEvent
.Source
= m_xOwner
;
1113 aEvent
.ReplacedElement
<<= xOldSettings
;
1114 aEvent
.Element
<<= pDataSettings
->xSettings
;
1118 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1122 // we have no settings in our user-defined layer - insert
1123 UIElementData aUIElementData
;
1125 aUIElementData
.bDefault
= false;
1126 aUIElementData
.bDefaultNode
= false;
1127 aUIElementData
.bModified
= true;
1129 // Create a copy of the data if the container is not const
1130 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1131 if ( xReplace
.is() )
1132 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1134 aUIElementData
.xSettings
= aNewData
;
1135 aUIElementData
.aName
= RetrieveNameFromResourceURL( ResourceURL
) + m_aXMLPostfix
;
1136 aUIElementData
.aResourceURL
= ResourceURL
;
1139 // Modify type container
1140 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1141 rElementType
.bModified
= true;
1143 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1145 // Check our user element settings hash map as it can already contain settings that have been set to default!
1146 // If no node can be found, we have to insert it.
1147 UIElementDataHashMap::iterator pIter
= rElements
.find( ResourceURL
);
1148 if ( pIter
!= rElements
.end() )
1149 pIter
->second
= aUIElementData
;
1151 rElements
.insert( UIElementDataHashMap::value_type( ResourceURL
, aUIElementData
));
1153 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1155 // Create event to notify listener about replaced element settings
1156 ConfigurationEvent aEvent
;
1158 aEvent
.ResourceURL
= ResourceURL
;
1159 aEvent
.Accessor
<<= xThis
;
1160 aEvent
.Source
= m_xOwner
;
1161 aEvent
.ReplacedElement
<<= pDataSettings
->xSettings
;
1162 aEvent
.Element
<<= aUIElementData
.xSettings
;
1166 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1170 throw NoSuchElementException();
1174 void UIConfigurationManagerImpl::removeSettings( const ::rtl::OUString
& ResourceURL
)
1175 throw ( NoSuchElementException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1177 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1179 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1180 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1181 throw IllegalArgumentException();
1182 else if ( m_bReadOnly
)
1183 throw IllegalAccessException();
1186 ResetableGuard
aGuard( m_aLock
);
1189 throw DisposedException();
1191 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1192 if ( pDataSettings
)
1194 // If element settings are default, we don't need to change anything!
1195 if ( pDataSettings
->bDefault
)
1199 Reference
< XIndexAccess
> xRemovedSettings
= pDataSettings
->xSettings
;
1200 pDataSettings
->bDefault
= true;
1202 // check if this is a default layer node
1203 if ( !m_bUseDefault
|| !pDataSettings
->bDefaultNode
)
1204 pDataSettings
->bModified
= true; // we have to remove this node from the user layer!
1205 pDataSettings
->xSettings
.clear();
1206 m_bModified
= true; // user layer must be written
1208 // Modify type container
1209 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1210 rElementType
.bModified
= true;
1212 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1213 // Check if we have settings in the default layer which replaces the user-defined one!
1214 UIElementData
* pDefaultDataSettings
= m_bUseDefault
? impl_findUIElementData( ResourceURL
, nElementType
) : NULL
;
1215 if ( pDefaultDataSettings
)
1217 // Create event to notify listener about replaced element settings
1218 ConfigurationEvent aEvent
;
1220 aEvent
.ResourceURL
= ResourceURL
;
1221 aEvent
.Accessor
<<= xThis
;
1222 aEvent
.Source
= m_xOwner
;
1223 aEvent
.Element
<<= xRemovedSettings
;
1224 aEvent
.ReplacedElement
<<= pDefaultDataSettings
->xSettings
;
1228 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1232 // Create event to notify listener about removed element settings
1233 ConfigurationEvent aEvent
;
1235 aEvent
.ResourceURL
= ResourceURL
;
1236 aEvent
.Accessor
<<= xThis
;
1237 aEvent
.Source
= m_xOwner
;
1238 aEvent
.Element
<<= xRemovedSettings
;
1242 implts_notifyContainerListener( aEvent
, NotifyOp_Remove
);
1247 throw NoSuchElementException();
1251 void UIConfigurationManagerImpl::insertSettings( const ::rtl::OUString
& NewResourceURL
, const Reference
< XIndexAccess
>& aNewData
)
1252 throw ( ElementExistException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1254 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( NewResourceURL
);
1256 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1257 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1258 throw IllegalArgumentException();
1259 else if ( m_bReadOnly
)
1260 throw IllegalAccessException();
1263 ResetableGuard
aGuard( m_aLock
);
1266 throw DisposedException();
1268 bool bInsertData( false );
1269 UIElementData aUIElementData
;
1270 UIElementData
* pDataSettings
= impl_findUIElementData( NewResourceURL
, nElementType
);
1271 if ( !m_bUseDefault
)
1273 if ( pDataSettings
&& !pDataSettings
->bDefault
)
1274 throw ElementExistException();
1275 if ( !pDataSettings
)
1277 pDataSettings
= &aUIElementData
;
1281 if ( !pDataSettings
|| !m_bUseDefault
)
1283 aUIElementData
.bDefault
= false;
1284 if ( !m_bUseDefault
)
1285 aUIElementData
.bDefaultNode
= false;
1286 aUIElementData
.bModified
= true;
1288 // Create a copy of the data if the container is not const
1289 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1290 if ( xReplace
.is() )
1291 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1293 aUIElementData
.xSettings
= aNewData
;
1297 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1298 rElementType
.bModified
= true;
1302 aUIElementData
.aName
= RetrieveNameFromResourceURL( NewResourceURL
) + m_aXMLPostfix
;
1303 aUIElementData
.aResourceURL
= NewResourceURL
;
1304 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1305 rElements
.insert( UIElementDataHashMap::value_type( NewResourceURL
, aUIElementData
));
1308 Reference
< XIndexAccess
> xInsertSettings( aUIElementData
.xSettings
);
1309 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1311 // Create event to notify listener about removed element settings
1312 ConfigurationEvent aEvent
;
1314 aEvent
.ResourceURL
= NewResourceURL
;
1315 aEvent
.Accessor
<<= xThis
;
1316 aEvent
.Source
= m_xOwner
;
1317 aEvent
.Element
<<= xInsertSettings
;
1321 implts_notifyContainerListener( aEvent
, NotifyOp_Insert
);
1324 throw ElementExistException();
1328 Reference
< XInterface
> UIConfigurationManagerImpl::getImageManager() throw (::com::sun::star::uno::RuntimeException
)
1330 ResetableGuard
aGuard( m_aLock
);
1333 throw DisposedException();
1335 if ( !m_xModuleImageManager
.is() )
1337 if ( m_bUseDefault
)
1338 m_xModuleImageManager
= Reference
< XComponent
>( static_cast< cppu::OWeakObject
*>( new ModuleImageManager( m_xServiceManager
)),
1341 m_xModuleImageManager
= Reference
< XComponent
>( static_cast< cppu::OWeakObject
*>( new ImageManager( m_xServiceManager
)),
1343 Reference
< XInitialization
> xInit( m_xModuleImageManager
, UNO_QUERY
);
1345 Sequence
< Any
> aPropSeq( m_bUseDefault
? 3 : 2 );
1346 PropertyValue aPropValue
;
1347 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
1348 aPropValue
.Value
<<= m_xUserConfigStorage
;
1349 aPropSeq
[0] <<= aPropValue
;
1350 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
1351 aPropValue
.Value
<<= m_aModuleIdentifier
;
1352 aPropSeq
[1] <<= aPropValue
;
1353 if ( m_bUseDefault
)
1355 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
1356 aPropValue
.Value
<<= m_xUserRootCommit
;
1357 aPropSeq
[2] <<= aPropValue
;
1360 xInit
->initialize( aPropSeq
);
1363 return Reference
< XInterface
>( m_xModuleImageManager
, UNO_QUERY
);
1365 // return Reference< XInterface >();
1368 Reference
< XInterface
> UIConfigurationManagerImpl::getShortCutManager() throw (::com::sun::star::uno::RuntimeException
)
1370 ResetableGuard
aGuard( m_aLock
);
1371 if ( !m_bUseDefault
&& m_xAccConfig
.is())
1372 return m_xAccConfig
;
1374 Reference
< XMultiServiceFactory
> xSMGR
= m_xServiceManager
;
1375 ::rtl::OUString aModule
= m_aModuleIdentifier
;
1376 Reference
< XStorage
> xDocumentRoot
= m_xUserConfigStorage
;
1378 Reference
< XInterface
> xManager
= xSMGR
->createInstance(m_bUseDefault
? SERVICENAME_MODULEACCELERATORCONFIGURATION
: SERVICENAME_DOCUMENTACCELERATORCONFIGURATION
);
1379 Reference
< XInitialization
> xInit (xManager
, UNO_QUERY_THROW
);
1381 PropertyValue aProp
;
1382 Sequence
< Any
> lArgs(1);
1383 if ( m_bUseDefault
)
1385 aProp
.Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier"));
1386 aProp
.Value
<<= aModule
;
1387 } // if ( m_bUseDefault )
1390 aProp
.Name
= ::rtl::OUString::createFromAscii("DocumentRoot");
1391 aProp
.Value
<<= xDocumentRoot
;
1394 xInit
->initialize(lArgs
);
1396 if ( !m_bUseDefault
)
1400 m_xAccConfig
= xManager
;
1408 Reference
< XInterface
> UIConfigurationManagerImpl::getEventsManager() throw (::com::sun::star::uno::RuntimeException
)
1410 return Reference
< XInterface
>();
1412 // XUIConfigurationStorage
1413 void UIConfigurationManagerImpl::setStorage( const Reference
< XStorage
>& Storage
) throw (::com::sun::star::uno::RuntimeException
)
1415 ResetableGuard
aGuard( m_aLock
);
1418 throw DisposedException();
1420 if ( m_xUserConfigStorage
.is() )
1424 // Dispose old storage to be sure that it will be closed
1425 Reference
< XComponent
> xComponent( m_xUserConfigStorage
, UNO_QUERY
);
1426 if ( xComponent
.is() )
1427 xComponent
->dispose();
1429 catch ( Exception
& )
1434 // We store the new storage. Be careful it could be an empty reference!
1435 m_xUserConfigStorage
= Storage
;
1436 m_bReadOnly
= sal_True
;
1438 Reference
< XUIConfigurationStorage
> xAccUpdate(m_xAccConfig
, UNO_QUERY
);
1439 if ( xAccUpdate
.is() )
1440 xAccUpdate
->setStorage( m_xUserConfigStorage
);
1442 if ( m_xModuleImageManager
.is() )
1444 ImageManager
* pImageManager
= (ImageManager
*)m_xModuleImageManager
.get();
1445 if ( pImageManager
)
1446 pImageManager
->setStorage( m_xUserConfigStorage
);
1449 if ( m_xUserConfigStorage
.is() )
1451 ::rtl::OUString sEmpty
;
1452 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1454 rtl::OUString aResourceType
;
1455 if ( i
== ::com::sun::star::ui::UIElementType::MENUBAR
)
1456 aResourceType
= PresetHandler::RESOURCETYPE_MENUBAR();
1457 else if ( i
== ::com::sun::star::ui::UIElementType::TOOLBAR
)
1458 aResourceType
= PresetHandler::RESOURCETYPE_TOOLBAR();
1459 else if ( i
== ::com::sun::star::ui::UIElementType::STATUSBAR
)
1460 aResourceType
= PresetHandler::RESOURCETYPE_STATUSBAR();
1462 //if ( aResourceType.getLength() > 0 )
1464 m_pStorageHandler
[i
] = new PresetHandler( m_xServiceManager
);
1465 m_pStorageHandler
[i
]->connectToResource( PresetHandler::E_DOCUMENT
,
1466 rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ), // this path wont be used later ... seee next lines!
1468 m_xUserConfigStorage
);
1471 Reference
< XPropertySet
> xPropSet( m_xUserConfigStorage
, UNO_QUERY
);
1472 if ( xPropSet
.is() )
1477 if ( xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode
)
1478 m_bReadOnly
= !( nOpenMode
& ElementModes::WRITE
);
1480 catch ( com::sun::star::beans::UnknownPropertyException
& )
1483 catch ( com::sun::star::lang::WrappedTargetException
& )
1491 // -----------------------------------------------------------------------------
1492 sal_Bool
UIConfigurationManagerImpl::hasStorage() throw (::com::sun::star::uno::RuntimeException
)
1494 ResetableGuard
aGuard( m_aLock
);
1497 throw DisposedException();
1499 return ( m_xUserConfigStorage
.is() );
1502 // XUIConfigurationManagerImpl
1503 sal_Bool
UIConfigurationManagerImpl::isDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1504 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1506 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1508 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1509 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1510 throw IllegalArgumentException();
1513 ResetableGuard
aGuard( m_aLock
);
1516 throw DisposedException();
1518 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1519 if ( pDataSettings
&& pDataSettings
->bDefaultNode
)
1526 Reference
< XIndexAccess
> UIConfigurationManagerImpl::getDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1527 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1529 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1531 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1532 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1533 throw IllegalArgumentException();
1536 ResetableGuard
aGuard( m_aLock
);
1539 throw DisposedException();
1541 // preload list of element types on demand
1542 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
1544 // Look into our default vector/hash_map combination
1545 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
1546 UIElementDataHashMap::iterator pIter
= rDefaultHashMap
.find( ResourceURL
);
1547 if ( pIter
!= rDefaultHashMap
.end() )
1549 if ( !pIter
->second
.xSettings
.is() )
1550 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
1551 return pIter
->second
.xSettings
;
1555 // Nothing has been found!
1556 throw NoSuchElementException();
1559 // XUIConfigurationPersistence
1560 void UIConfigurationManagerImpl::reload() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1562 ResetableGuard
aGuard( m_aLock
);
1565 throw DisposedException();
1567 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1569 // Try to access our module sub folder
1570 ConfigEventNotifyContainer aRemoveNotifyContainer
;
1571 ConfigEventNotifyContainer aReplaceNotifyContainer
;
1572 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1576 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1577 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][i
];
1579 if ( rUserElementType
.bModified
)
1580 impl_reloadElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveNotifyContainer
, aReplaceNotifyContainer
);
1582 catch ( Exception
& )
1584 throw IOException();
1588 m_bModified
= sal_False
;
1590 // Unlock mutex before notify our listeners
1593 // Notify our listeners
1594 ::std::for_each(aRemoveNotifyContainer
.begin(),aRemoveNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Remove
));
1595 ::std::for_each(aReplaceNotifyContainer
.begin(),aReplaceNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Replace
));
1599 void UIConfigurationManagerImpl::store() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1601 ResetableGuard
aGuard( m_aLock
);
1604 throw DisposedException();
1606 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1608 // Try to access our module sub folder
1609 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1613 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1614 Reference
< XStorage
> xStorage( rElementType
.xStorage
, UNO_QUERY
);
1616 if ( rElementType
.bModified
&& xStorage
.is() )
1618 impl_storeElementTypeData( xStorage
, rElementType
);
1619 m_pStorageHandler
[i
]->commitUserChanges();
1622 catch ( Exception
& )
1624 throw IOException();
1628 m_bModified
= false;
1632 void UIConfigurationManagerImpl::storeToStorage( const Reference
< XStorage
>& Storage
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1634 ResetableGuard
aGuard( m_aLock
);
1637 throw DisposedException();
1639 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1641 // Try to access our module sub folder
1642 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1646 Reference
< XStorage
> xElementTypeStorage( Storage
->openStorageElement(
1647 rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ), ElementModes::READWRITE
));
1648 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1650 if ( rElementType
.bModified
&& xElementTypeStorage
.is() )
1651 impl_storeElementTypeData( xElementTypeStorage
, rElementType
, false ); // store data to storage, but don't reset modify flag!
1653 catch ( Exception
& )
1655 throw IOException();
1659 Reference
< XTransactedObject
> xTransactedObject( Storage
, UNO_QUERY
);
1660 if ( xTransactedObject
.is() )
1661 xTransactedObject
->commit();
1665 sal_Bool
UIConfigurationManagerImpl::isModified() throw (::com::sun::star::uno::RuntimeException
)
1667 ResetableGuard
aGuard( m_aLock
);
1672 sal_Bool
UIConfigurationManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException
)
1674 ResetableGuard
aGuard( m_aLock
);
1679 void UIConfigurationManagerImpl::implts_notifyContainerListener( const ConfigurationEvent
& aEvent
, NotifyOp eOp
)
1681 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< ::com::sun::star::ui::XUIConfigurationListener
>*) NULL
) );
1682 if ( pContainer
!= NULL
)
1684 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
1685 while ( pIterator
.hasMoreElements() )
1691 case NotifyOp_Replace
:
1692 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementReplaced( aEvent
);
1694 case NotifyOp_Insert
:
1695 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementInserted( aEvent
);
1697 case NotifyOp_Remove
:
1698 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementRemoved( aEvent
);
1702 catch( css::uno::RuntimeException
& )
1710 } // namespace framework