1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UIConfigurationManagerImpl.cxx,v $
10 * $Revision: 1.19.208.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <uiconfigurationmanagerimpl.hxx>
34 #include <threadhelp/resetableguard.hxx>
36 #include <uielement/constitemcontainer.hxx>
37 #include <uielement/rootitemcontainer.hxx>
38 #include <uielement/uielementtypenames.hxx>
39 #include <xml/menuconfiguration.hxx>
40 #include <xml/toolboxconfiguration.hxx>
41 #include <uiconfiguration/imagemanager.hxx>
43 #ifndef __FRAMEWORK_XML_STATUSBARCONFIGURATION_HXX_
44 #include <xml/statusbarconfiguration.hxx>
47 //_________________________________________________________________________________________________________________
49 //_________________________________________________________________________________________________________________
50 #include <com/sun/star/ui/UIElementType.hpp>
51 #include <com/sun/star/ui/ConfigurationEvent.hpp>
52 #include <com/sun/star/lang/DisposedException.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include <com/sun/star/embed/ElementModes.hpp>
55 #include <com/sun/star/container/XNameAccess.hpp>
56 #include <com/sun/star/io/XStream.hpp>
58 //_________________________________________________________________________________________________________________
60 //_________________________________________________________________________________________________________________
62 #include <vcl/svapp.hxx>
63 #include <rtl/ustrbuf.hxx>
64 #include <comphelper/sequenceashashmap.hxx>
65 #include <boost/bind.hpp>
67 //_________________________________________________________________________________________________________________
69 //_________________________________________________________________________________________________________________
72 using namespace com::sun::star::uno
;
73 using namespace com::sun::star::io
;
74 using namespace com::sun::star::embed
;
75 using namespace com::sun::star::lang
;
76 using namespace com::sun::star::container
;
77 using namespace com::sun::star::beans
;
78 using namespace ::com::sun::star::ui
;
79 using namespace ::cppu
;
85 // important: The order and position of the elements must match the constant
86 // definition of "::com::sun::star::ui::UIElementType"
87 static const char* UIELEMENTTYPENAMES
[] =
89 "", // Dummy value for unknown!
90 UIELEMENTTYPE_MENUBAR_NAME
,
91 UIELEMENTTYPE_POPUPMENU_NAME
,
92 UIELEMENTTYPE_TOOLBAR_NAME
,
93 UIELEMENTTYPE_STATUSBAR_NAME
,
94 UIELEMENTTYPE_FLOATINGWINDOW_NAME
,
95 UIELEMENTTYPE_PROGRESSBAR_NAME
98 static const char RESOURCEURL_PREFIX
[] = "private:resource/";
99 static const sal_Int32 RESOURCEURL_PREFIX_SIZE
= 17;
100 static const char RESOURCEURL_CUSTOM_ELEMENT
[] = "custom_";
102 static sal_Int16
RetrieveTypeFromResourceURL( const rtl::OUString
& aResourceURL
)
105 if (( aResourceURL
.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
106 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
108 rtl::OUString aTmpStr
= aResourceURL
.copy( RESOURCEURL_PREFIX_SIZE
);
109 sal_Int32 nIndex
= aTmpStr
.indexOf( '/' );
110 if (( nIndex
> 0 ) && ( aTmpStr
.getLength() > nIndex
))
112 rtl::OUString
aTypeStr( aTmpStr
.copy( 0, nIndex
));
113 for ( int i
= 0; i
< UIElementType::COUNT
; i
++ )
115 if ( aTypeStr
.equalsAscii( UIELEMENTTYPENAMES
[i
] ))
116 return sal_Int16( i
);
121 return UIElementType::UNKNOWN
;
124 static rtl::OUString
RetrieveNameFromResourceURL( const rtl::OUString
& aResourceURL
)
126 if (( aResourceURL
.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX
))) == 0 ) &&
127 ( aResourceURL
.getLength() > RESOURCEURL_PREFIX_SIZE
))
129 sal_Int32 nIndex
= aResourceURL
.lastIndexOf( '/' );
130 if (( nIndex
> 0 ) && (( nIndex
+1 ) < aResourceURL
.getLength()))
131 return aResourceURL
.copy( nIndex
+1 );
134 return rtl::OUString();
137 void UIConfigurationManagerImpl::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap
& aUIElementInfoCollection
, sal_Int16 nElementType
)
139 // preload list of element types on demand
140 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
142 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
144 UIElementDataHashMap
& rUserElements
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
145 UIElementDataHashMap::const_iterator pUserIter
= rUserElements
.begin();
147 rtl::OUString
aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT
));
148 while ( pUserIter
!= rUserElements
.end() )
150 sal_Int32 nIndex
= pUserIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
151 if ( !m_bUseDefault
&& nIndex
> RESOURCEURL_PREFIX_SIZE
)
153 // Performance: Retrieve user interface name only for custom user interface elements.
154 // It's only used by them!
155 UIElementData
* pDataSettings
= impl_findUIElementData( pUserIter
->second
.aResourceURL
, nElementType
);
156 if ( pDataSettings
&& ( !m_bUseDefault
|| !pDataSettings
->bDefault
) )
158 // Retrieve user interface name from XPropertySet interface
159 rtl::OUString aUIName
;
160 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
163 xPropSet
->getPropertyValue( m_aPropUIName
) >>= aUIName
;
166 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, aUIName
);
167 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
172 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
173 UIElementInfo
aInfo( pUserIter
->second
.aResourceURL
, rtl::OUString() );
174 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pUserIter
->second
.aResourceURL
, aInfo
));
181 UIElementDataHashMap
& rDefaultElements
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
182 UIElementDataHashMap::const_iterator pDefIter
= rDefaultElements
.begin();
184 while ( pDefIter
!= rDefaultElements
.end() )
186 UIElementInfoHashMap::const_iterator pIterInfo
= aUIElementInfoCollection
.find( pDefIter
->second
.aResourceURL
);
187 if ( pIterInfo
== aUIElementInfoCollection
.end() )
189 sal_Int32 nIndex
= pDefIter
->second
.aResourceURL
.indexOf( aCustomUrlPrefix
, RESOURCEURL_PREFIX_SIZE
);
190 if ( nIndex
> RESOURCEURL_PREFIX_SIZE
)
192 // Performance: Retrieve user interface name only for custom user interface elements.
193 // It's only used by them!
194 UIElementData
* pDataSettings
= impl_findUIElementData( pDefIter
->second
.aResourceURL
, nElementType
);
197 // Retrieve user interface name from XPropertySet interface
198 rtl::OUString aUIName
;
199 Reference
< XPropertySet
> xPropSet( pDataSettings
->xSettings
, UNO_QUERY
);
202 xPropSet
->getPropertyValue( m_aPropUIName
) >>= aUIName
;
205 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, aUIName
);
206 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
211 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
212 UIElementInfo
aInfo( pDefIter
->second
.aResourceURL
, rtl::OUString() );
213 aUIElementInfoCollection
.insert( UIElementInfoHashMap::value_type( pDefIter
->second
.aResourceURL
, aInfo
));
218 } // while ( pDefIter != rDefaultElements.end() )
222 void UIConfigurationManagerImpl::impl_preloadUIElementTypeList( Layer eLayer
, sal_Int16 nElementType
)
224 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
226 if ( !rElementTypeData
.bLoaded
)
228 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
229 if ( xElementTypeStorage
.is() )
231 rtl::OUStringBuffer
aBuf( RESOURCEURL_PREFIX_SIZE
);
232 aBuf
.appendAscii( RESOURCEURL_PREFIX
);
233 aBuf
.appendAscii( UIELEMENTTYPENAMES
[ nElementType
] );
234 aBuf
.appendAscii( "/" );
235 rtl::OUString
aResURLPrefix( aBuf
.makeStringAndClear() );
237 UIElementDataHashMap
& rHashMap
= rElementTypeData
.aElementsHashMap
;
238 Reference
< XNameAccess
> xNameAccess( xElementTypeStorage
, UNO_QUERY
);
239 Sequence
< rtl::OUString
> aUIElementNames
= xNameAccess
->getElementNames();
240 for ( sal_Int32 n
= 0; n
< aUIElementNames
.getLength(); n
++ )
242 UIElementData aUIElementData
;
244 // Resource name must be without ".xml"
245 sal_Int32 nIndex
= aUIElementNames
[n
].lastIndexOf( '.' );
246 if (( nIndex
> 0 ) && ( nIndex
< aUIElementNames
[n
].getLength() ))
248 rtl::OUString
aExtension( aUIElementNames
[n
].copy( nIndex
+1 ));
249 rtl::OUString
aUIElementName( aUIElementNames
[n
].copy( 0, nIndex
));
251 if (( aUIElementName
.getLength() > 0 ) &&
252 ( aExtension
.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
254 aUIElementData
.aResourceURL
= aResURLPrefix
+ aUIElementName
;
255 aUIElementData
.aName
= aUIElementNames
[n
];
257 if ( eLayer
== LAYER_USERDEFINED
)
259 aUIElementData
.bModified
= false;
260 aUIElementData
.bDefault
= false;
261 aUIElementData
.bDefaultNode
= false;
264 // Create hash_map entries for all user interface elements inside the storage. We don't load the
265 // settings to speed up the process.
266 rHashMap
.insert( UIElementDataHashMap::value_type( aUIElementData
.aResourceURL
, aUIElementData
));
273 rElementTypeData
.bLoaded
= true;
276 void UIConfigurationManagerImpl::impl_requestUIElementData( sal_Int16 nElementType
, Layer eLayer
, UIElementData
& aUIElementData
)
278 UIElementType
& rElementTypeData
= m_aUIElements
[eLayer
][nElementType
];
280 Reference
< XStorage
> xElementTypeStorage
= rElementTypeData
.xStorage
;
281 if ( xElementTypeStorage
.is() && aUIElementData
.aName
.getLength() )
285 Reference
< XStream
> xStream
= xElementTypeStorage
->openStreamElement( aUIElementData
.aName
, ElementModes::READ
);
286 Reference
< XInputStream
> xInputStream
= xStream
->getInputStream();
288 if ( xInputStream
.is() )
290 switch ( nElementType
)
292 case ::com::sun::star::ui::UIElementType::UNKNOWN
:
295 case ::com::sun::star::ui::UIElementType::MENUBAR
:
299 MenuConfiguration
aMenuCfg( m_xServiceManager
);
300 Reference
< XIndexAccess
> xContainer( aMenuCfg
.CreateMenuBarConfigurationFromXML( xInputStream
));
301 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xContainer
);
302 if ( pRootItemContainer
)
303 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
305 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( xContainer
, sal_True
) ), UNO_QUERY
);
308 catch ( ::com::sun::star::lang::WrappedTargetException
& )
314 case ::com::sun::star::ui::UIElementType::POPUPMENU
:
319 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
323 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
324 ToolBoxConfiguration::LoadToolBox( m_xServiceManager
, xInputStream
, xIndexContainer
);
325 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
326 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
329 catch ( ::com::sun::star::lang::WrappedTargetException
& )
336 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
340 Reference
< XIndexContainer
> xIndexContainer( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
341 StatusBarConfiguration::LoadStatusBar( m_xServiceManager
, xInputStream
, xIndexContainer
);
342 RootItemContainer
* pRootItemContainer
= RootItemContainer::GetImplementation( xIndexContainer
);
343 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( pRootItemContainer
, sal_True
) ), UNO_QUERY
);
346 catch ( ::com::sun::star::lang::WrappedTargetException
& )
353 case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW
:
360 catch ( ::com::sun::star::embed::InvalidStorageException
& )
363 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
366 catch ( ::com::sun::star::io::IOException
& )
369 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
374 // At least we provide an empty settings container!
375 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer() ), UNO_QUERY
);
378 UIConfigurationManagerImpl::UIElementData
* UIConfigurationManagerImpl::impl_findUIElementData( const rtl::OUString
& aResourceURL
, sal_Int16 nElementType
, bool bLoad
)
380 // preload list of element types on demand
381 impl_preloadUIElementTypeList( LAYER_USERDEFINED
, nElementType
);
383 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
385 // first try to look into our user-defined vector/hash_map combination
386 UIElementDataHashMap
& rUserHashMap
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
].aElementsHashMap
;
387 UIElementDataHashMap::iterator pIter
= rUserHashMap
.find( aResourceURL
);
388 if ( pIter
!= rUserHashMap
.end() )
390 // Default data settings data must be retrieved from the default layer!
391 if ( !pIter
->second
.bDefault
)
393 if ( !pIter
->second
.xSettings
.is() && bLoad
)
394 impl_requestUIElementData( nElementType
, LAYER_USERDEFINED
, pIter
->second
);
395 return &(pIter
->second
);
401 // Not successfull, we have to look into our default vector/hash_map combination
402 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
403 pIter
= rDefaultHashMap
.find( aResourceURL
);
404 if ( pIter
!= rDefaultHashMap
.end() )
406 if ( !pIter
->second
.xSettings
.is() && bLoad
)
407 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
408 return &(pIter
->second
);
409 } // if ( pIter != rDefaultHashMap.end() )
412 // Nothing has been found!
416 void UIConfigurationManagerImpl::impl_storeElementTypeData( Reference
< XStorage
> xStorage
, UIElementType
& rElementType
, bool bResetModifyState
)
418 UIElementDataHashMap
& rHashMap
= rElementType
.aElementsHashMap
;
419 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
421 while ( pIter
!= rHashMap
.end() )
423 UIElementData
& rElement
= pIter
->second
;
424 if ( rElement
.bModified
)
426 if ( rElement
.bDefault
)
428 xStorage
->removeElement( rElement
.aName
);
429 rElement
.bModified
= sal_False
; // mark as not modified
433 Reference
< XStream
> xStream( xStorage
->openStreamElement( rElement
.aName
, ElementModes::WRITE
|ElementModes::TRUNCATE
), UNO_QUERY
);
434 Reference
< XOutputStream
> xOutputStream( xStream
->getOutputStream() );
436 if ( xOutputStream
.is() )
438 switch( rElementType
.nElementType
)
440 case ::com::sun::star::ui::UIElementType::MENUBAR
:
444 MenuConfiguration
aMenuCfg( m_xServiceManager
);
445 aMenuCfg
.StoreMenuBarConfigurationToXML( rElement
.xSettings
, xOutputStream
);
447 catch ( ::com::sun::star::lang::WrappedTargetException
& )
453 case ::com::sun::star::ui::UIElementType::TOOLBAR
:
457 ToolBoxConfiguration::StoreToolBox( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
459 catch ( ::com::sun::star::lang::WrappedTargetException
& )
465 case ::com::sun::star::ui::UIElementType::STATUSBAR
:
469 StatusBarConfiguration::StoreStatusBar( m_xServiceManager
, xOutputStream
, rElement
.xSettings
);
471 catch ( ::com::sun::star::lang::WrappedTargetException
& )
482 // mark as not modified if we store to our own storage
483 if ( bResetModifyState
)
484 rElement
.bModified
= sal_False
;
491 // commit element type storage
492 Reference
< XTransactedObject
> xTransactedObject( xStorage
, UNO_QUERY
);
493 if ( xTransactedObject
.is() )
494 xTransactedObject
->commit();
496 // mark UIElementType as not modified if we store to our own storage
497 if ( bResetModifyState
)
498 rElementType
.bModified
= sal_False
;
501 // This is only allowed to be called on the LAYER_USER_DEFINED!
502 void UIConfigurationManagerImpl::impl_resetElementTypeData(
503 UIElementType
& rUserElementType
,
504 UIElementType
& rDefaultElementType
,
505 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
506 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
508 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
509 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
511 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
512 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
513 sal_Int16 nType
= rUserElementType
.nElementType
;
515 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
517 while ( pIter
!= rHashMap
.end() )
519 UIElementData
& rElement
= pIter
->second
;
520 if ( !rElement
.bDefault
)
522 if ( m_bUseDefault
&& xDefaultNameAccess
->hasByName( rElement
.aName
))
524 // Replace settings with data from default layer
525 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
526 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
528 ConfigurationEvent aReplaceEvent
;
529 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
530 aReplaceEvent
.Accessor
<<= xThis
;
531 aReplaceEvent
.Source
= m_xOwner
;
532 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
533 aReplaceEvent
.Element
<<= rElement
.xSettings
;
535 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
537 // Mark element as default and not modified. That means "not active"
538 // in the user layer anymore.
539 rElement
.bModified
= false;
540 rElement
.bDefault
= true;
544 // Remove user-defined settings from user layer
545 ConfigurationEvent aEvent
;
546 aEvent
.ResourceURL
= rElement
.aResourceURL
;
547 aEvent
.Accessor
<<= xThis
;
548 aEvent
.Source
= m_xOwner
;
549 aEvent
.Element
<<= rElement
.xSettings
;
551 rRemoveNotifyContainer
.push_back( aEvent
);
553 // Mark element as default and not modified. That means "not active"
554 // in the user layer anymore.
555 rElement
.bModified
= false;
556 rElement
.bDefault
= true;
558 } // if ( !rElement.bDefault )
560 rElement
.bModified
= false;
565 // Remove all settings from our user interface elements
569 void UIConfigurationManagerImpl::impl_reloadElementTypeData(
570 UIElementType
& rUserElementType
,
571 UIElementType
& rDefaultElementType
,
572 ConfigEventNotifyContainer
& rRemoveNotifyContainer
,
573 ConfigEventNotifyContainer
& rReplaceNotifyContainer
)
575 UIElementDataHashMap
& rHashMap
= rUserElementType
.aElementsHashMap
;
576 UIElementDataHashMap::iterator pIter
= rHashMap
.begin();
577 Reference
< XStorage
> xUserStorage( rUserElementType
.xStorage
);
578 Reference
< XStorage
> xDefaultStorage( rDefaultElementType
.xStorage
);
579 Reference
< XNameAccess
> xUserNameAccess( rUserElementType
.xStorage
, UNO_QUERY
);
580 Reference
< XNameAccess
> xDefaultNameAccess( rDefaultElementType
.xStorage
, UNO_QUERY
);
582 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
583 sal_Int16 nType
= rUserElementType
.nElementType
;
585 while ( pIter
!= rHashMap
.end() )
587 UIElementData
& rElement
= pIter
->second
;
588 if ( rElement
.bModified
)
590 if ( xUserNameAccess
->hasByName( rElement
.aName
))
592 // Replace settings with data from user layer
593 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
595 impl_requestUIElementData( nType
, LAYER_USERDEFINED
, rElement
);
597 ConfigurationEvent aReplaceEvent
;
599 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
600 aReplaceEvent
.Accessor
<<= xThis
;
601 aReplaceEvent
.Source
= m_xOwner
;
602 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
603 aReplaceEvent
.Element
<<= rElement
.xSettings
;
604 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
606 rElement
.bModified
= false;
608 else if ( m_bUseDefault
&& xDefaultNameAccess
->hasByName( rElement
.aName
))
610 // Replace settings with data from default layer
611 Reference
< XIndexAccess
> xOldSettings( rElement
.xSettings
);
613 impl_requestUIElementData( nType
, LAYER_DEFAULT
, rElement
);
615 ConfigurationEvent aReplaceEvent
;
617 aReplaceEvent
.ResourceURL
= rElement
.aResourceURL
;
618 aReplaceEvent
.Accessor
<<= xThis
;
619 aReplaceEvent
.Source
= m_xOwner
;
620 aReplaceEvent
.ReplacedElement
<<= xOldSettings
;
621 aReplaceEvent
.Element
<<= rElement
.xSettings
;
622 rReplaceNotifyContainer
.push_back( aReplaceEvent
);
624 // Mark element as default and not modified. That means "not active"
625 // in the user layer anymore.
626 rElement
.bModified
= false;
627 rElement
.bDefault
= true;
631 // Element settings are not in any storage => remove
632 ConfigurationEvent aRemoveEvent
;
634 aRemoveEvent
.ResourceURL
= rElement
.aResourceURL
;
635 aRemoveEvent
.Accessor
<<= xThis
;
636 aRemoveEvent
.Source
= m_xOwner
;
637 aRemoveEvent
.Element
<<= rElement
.xSettings
;
639 rRemoveNotifyContainer
.push_back( aRemoveEvent
);
641 // Mark element as default and not modified. That means "not active"
642 // in the user layer anymore.
643 rElement
.bModified
= false;
644 rElement
.bDefault
= true;
650 rUserElementType
.bModified
= sal_False
;
653 void UIConfigurationManagerImpl::impl_Initialize()
655 // Initialize the top-level structures with the storage data
656 if ( m_xUserConfigStorage
.is() )
658 // Try to access our module sub folder
659 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
662 Reference
< XStorage
> xElementTypeStorage
;
665 if ( m_pStorageHandler
[i
] )
666 xElementTypeStorage
= m_pStorageHandler
[i
]->getWorkingStorageUser();
668 catch ( com::sun::star::container::NoSuchElementException
& )
671 catch ( ::com::sun::star::embed::InvalidStorageException
& )
674 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
677 catch ( ::com::sun::star::io::IOException
& )
680 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
684 m_aUIElements
[LAYER_USERDEFINED
][i
].nElementType
= i
;
685 m_aUIElements
[LAYER_USERDEFINED
][i
].bModified
= false;
686 m_aUIElements
[LAYER_USERDEFINED
][i
].xStorage
= xElementTypeStorage
;
687 m_aUIElements
[LAYER_USERDEFINED
][i
].bDefaultLayer
= false;
689 } // if ( m_xUserConfigStorage.is() )
690 else if ( !m_bUseDefault
)
692 // We have no storage, just initialize ui element types with empty storage!
693 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
694 m_aUIElements
[LAYER_USERDEFINED
][i
].xStorage
.clear();
697 if ( m_bUseDefault
&& m_xUserConfigStorage
.is() )
699 Reference
< XNameAccess
> xNameAccess( m_xDefaultConfigStorage
, UNO_QUERY_THROW
);
701 // Try to access our module sub folder
702 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
;
705 Reference
< XStorage
> xElementTypeStorage
;
708 xNameAccess
->getByName( rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] )) >>= xElementTypeStorage
;
710 catch ( com::sun::star::container::NoSuchElementException
& )
714 m_aUIElements
[LAYER_DEFAULT
][i
].nElementType
= i
;
715 m_aUIElements
[LAYER_DEFAULT
][i
].bModified
= false;
716 m_aUIElements
[LAYER_DEFAULT
][i
].xStorage
= xElementTypeStorage
;
717 m_aUIElements
[LAYER_DEFAULT
][i
].bDefaultLayer
= true;
722 UIConfigurationManagerImpl::UIConfigurationManagerImpl( const Reference
< com::sun::star::lang::XMultiServiceFactory
>& xServiceManager
723 ,const Reference
< XInterface
>& _xOwner
724 , bool _bUseDefault
) :
725 ThreadHelpBase( &Application::GetSolarMutex() )
726 , m_xOwner( _xOwner
)
727 , m_bUseDefault(_bUseDefault
)
728 , m_bReadOnly( true )
729 , m_bInitialized( false )
730 , m_bModified( false )
731 , m_bConfigRead( false )
732 , m_bDisposed( false )
733 , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
734 , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
735 , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
736 , m_xServiceManager( xServiceManager
)
737 , m_aListenerContainer( m_aLock
.getShareableOslMutex() )
739 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
740 m_pStorageHandler
[i
] = 0;
742 // Make sure we have a default initialized entry for every layer and user interface element type!
743 // The following code depends on this!
744 m_aUIElements
[LAYER_DEFAULT
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
745 m_aUIElements
[LAYER_USERDEFINED
].resize( ::com::sun::star::ui::UIElementType::COUNT
);
748 UIConfigurationManagerImpl::~UIConfigurationManagerImpl()
750 for ( int i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
751 delete m_pStorageHandler
[i
];
755 void UIConfigurationManagerImpl::dispose() throw (::com::sun::star::uno::RuntimeException
)
757 css::lang::EventObject
aEvent( m_xOwner
);
758 m_aListenerContainer
.disposeAndClear( aEvent
);
761 ResetableGuard
aGuard( m_aLock
);
764 if ( m_xModuleImageManager
.is() )
765 m_xModuleImageManager
->dispose();
771 m_xModuleImageManager
.clear();
772 m_aUIElements
[LAYER_USERDEFINED
].clear();
773 m_aUIElements
[LAYER_DEFAULT
].clear();
774 m_xDefaultConfigStorage
.clear();
775 m_xUserConfigStorage
.clear();
776 m_xUserRootCommit
.clear();
777 m_bConfigRead
= false;
783 void UIConfigurationManagerImpl::addEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
786 ResetableGuard
aGuard( m_aLock
);
788 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
790 throw DisposedException();
793 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
796 void UIConfigurationManagerImpl::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
798 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
799 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XEventListener
>* ) NULL
), xListener
);
803 void UIConfigurationManagerImpl::initialize( const Sequence
< Any
>& aArguments
) throw ( Exception
, RuntimeException
)
805 ResetableGuard
aLock( m_aLock
);
807 if ( !m_bInitialized
)
809 ::comphelper::SequenceAsHashMap
lArgs(aArguments
);
810 m_aModuleIdentifier
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleIdentifier"), ::rtl::OUString());
811 m_aModuleShortName
= lArgs
.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleShortName"), ::rtl::OUString());
813 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
815 rtl::OUString aResourceType
;
816 if ( i
== ::com::sun::star::ui::UIElementType::MENUBAR
)
817 aResourceType
= PresetHandler::RESOURCETYPE_MENUBAR();
818 else if ( i
== ::com::sun::star::ui::UIElementType::TOOLBAR
)
819 aResourceType
= PresetHandler::RESOURCETYPE_TOOLBAR();
820 else if ( i
== ::com::sun::star::ui::UIElementType::STATUSBAR
)
821 aResourceType
= PresetHandler::RESOURCETYPE_STATUSBAR();
823 if ( aResourceType
.getLength() > 0 )
825 m_pStorageHandler
[i
] = new PresetHandler( m_xServiceManager
);
826 m_pStorageHandler
[i
]->connectToResource( PresetHandler::E_MODULES
,
827 aResourceType
, // this path wont be used later ... seee next lines!
829 css::uno::Reference
< css::embed::XStorage
>()); // no document root used here!
833 // initialize root storages for all resource types
834 m_xUserRootCommit
= css::uno::Reference
< css::embed::XTransactedObject
>(
835 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY
); // can be empty
836 m_xDefaultConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageShare(
837 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageShare());
838 m_xUserConfigStorage
= m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getParentStorageUser(
839 m_pStorageHandler
[::com::sun::star::ui::UIElementType::MENUBAR
]->getWorkingStorageUser());
841 if ( m_xUserConfigStorage
.is() )
843 Reference
< XPropertySet
> xPropSet( m_xUserConfigStorage
, UNO_QUERY
);
847 if ( xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode
)
848 m_bReadOnly
= !( nOpenMode
& ElementModes::WRITE
);
854 m_bInitialized
= true;
859 void UIConfigurationManagerImpl::addConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
862 ResetableGuard
aGuard( m_aLock
);
864 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
866 throw DisposedException();
869 m_aListenerContainer
.addInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
872 void UIConfigurationManagerImpl::removeConfigurationListener( const Reference
< ::com::sun::star::ui::XUIConfigurationListener
>& xListener
) throw (::com::sun::star::uno::RuntimeException
)
874 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
875 m_aListenerContainer
.removeInterface( ::getCppuType( ( const Reference
< XUIConfigurationListener
>* ) NULL
), xListener
);
879 // XUIConfigurationManager
880 void UIConfigurationManagerImpl::reset() throw (::com::sun::star::uno::RuntimeException
)
882 ResetableGuard
aGuard( m_aLock
);
884 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
886 throw DisposedException();
888 bool bResetStorage( false );
892 // Remove all elements from our user-defined storage!
895 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
897 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
898 Reference
< XStorage
> xSubStorage( rElementType
.xStorage
, UNO_QUERY
);
900 if ( xSubStorage
.is() )
902 bool bCommitSubStorage( false );
903 Reference
< XNameAccess
> xSubStorageNameAccess( xSubStorage
, UNO_QUERY
);
904 Sequence
< rtl::OUString
> aUIElementStreamNames
= xSubStorageNameAccess
->getElementNames();
905 for ( sal_Int32 j
= 0; j
< aUIElementStreamNames
.getLength(); j
++ )
907 xSubStorage
->removeElement( aUIElementStreamNames
[j
] );
908 bCommitSubStorage
= true;
911 if ( bCommitSubStorage
)
913 Reference
< XTransactedObject
> xTransactedObject( xSubStorage
, UNO_QUERY
);
914 if ( xTransactedObject
.is() )
915 xTransactedObject
->commit();
916 m_pStorageHandler
[i
]->commitUserChanges();
921 bResetStorage
= true;
923 // remove settings from user defined layer and notify listener about removed settings data!
924 ConfigEventNotifyContainer aRemoveEventNotifyContainer
;
925 ConfigEventNotifyContainer aReplaceEventNotifyContainer
;
926 for ( sal_Int16 j
= 1; j
< ::com::sun::star::ui::UIElementType::COUNT
; j
++ )
930 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][j
];
931 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][j
];
933 impl_resetElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveEventNotifyContainer
, aReplaceEventNotifyContainer
);
934 rUserElementType
.bModified
= sal_False
;
942 m_bModified
= sal_False
;
944 // Unlock mutex before notify our listeners
947 // Notify our listeners
948 ::std::for_each(aRemoveEventNotifyContainer
.begin(),aRemoveEventNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Remove
));
949 ::std::for_each(aReplaceEventNotifyContainer
.begin(),aReplaceEventNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Replace
));
951 catch ( ::com::sun::star::lang::IllegalArgumentException
& )
954 catch ( ::com::sun::star::container::NoSuchElementException
& )
957 catch ( ::com::sun::star::embed::InvalidStorageException
& )
960 catch ( ::com::sun::star::embed::StorageWrappedTargetException
& )
966 Sequence
< Sequence
< PropertyValue
> > UIConfigurationManagerImpl::getUIElementsInfo( sal_Int16 ElementType
)
967 throw ( IllegalArgumentException
, RuntimeException
)
969 if (( ElementType
< 0 ) || ( ElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
970 throw IllegalArgumentException();
972 ResetableGuard
aGuard( m_aLock
);
974 throw DisposedException();
976 Sequence
< Sequence
< PropertyValue
> > aElementInfoSeq
;
977 UIElementInfoHashMap aUIElementInfoCollection
;
979 if ( ElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
)
981 for ( sal_Int16 i
= 0; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
982 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, sal_Int16( i
) );
985 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection
, ElementType
);
987 Sequence
< PropertyValue
> aUIElementInfo( 2 );
988 aUIElementInfo
[0].Name
= m_aPropResourceURL
;
989 aUIElementInfo
[1].Name
= m_aPropUIName
;
991 aElementInfoSeq
.realloc( aUIElementInfoCollection
.size() );
992 UIElementInfoHashMap::const_iterator pIter
= aUIElementInfoCollection
.begin();
995 while ( pIter
!= aUIElementInfoCollection
.end() )
997 aUIElementInfo
[0].Value
<<= pIter
->second
.aResourceURL
;
998 aUIElementInfo
[1].Value
<<= pIter
->second
.aUIName
;
999 aElementInfoSeq
[n
++] = aUIElementInfo
;
1003 return aElementInfoSeq
;
1006 Reference
< XIndexContainer
> UIConfigurationManagerImpl::createSettings() throw (::com::sun::star::uno::RuntimeException
)
1008 ResetableGuard
aGuard( m_aLock
);
1011 throw DisposedException();
1013 // Creates an empty item container which can be filled from outside
1014 return Reference
< XIndexContainer
>( static_cast< OWeakObject
* >( new RootItemContainer() ), UNO_QUERY
);
1017 sal_Bool
UIConfigurationManagerImpl::hasSettings( const ::rtl::OUString
& ResourceURL
)
1018 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1020 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1022 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1023 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1024 throw IllegalArgumentException();
1027 ResetableGuard
aGuard( m_aLock
);
1030 throw DisposedException();
1032 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1033 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1040 Reference
< XIndexAccess
> UIConfigurationManagerImpl::getSettings( const ::rtl::OUString
& ResourceURL
, sal_Bool bWriteable
)
1041 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1043 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1045 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1046 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1047 throw IllegalArgumentException();
1050 ResetableGuard
aGuard( m_aLock
);
1053 throw DisposedException();
1055 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1056 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1058 // Create a copy of our data if someone wants to change the data.
1060 return Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new RootItemContainer( pDataSettings
->xSettings
) ), UNO_QUERY
);
1062 return pDataSettings
->xSettings
;
1066 throw NoSuchElementException();
1069 void UIConfigurationManagerImpl::replaceSettings( const ::rtl::OUString
& ResourceURL
, const Reference
< ::com::sun::star::container::XIndexAccess
>& aNewData
)
1070 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::IllegalAccessException
, ::com::sun::star::uno::RuntimeException
)
1072 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1074 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1075 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1076 throw IllegalArgumentException();
1077 else if ( m_bReadOnly
)
1078 throw IllegalAccessException();
1081 ResetableGuard
aGuard( m_aLock
);
1084 throw DisposedException();
1086 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1087 if ( pDataSettings
&& ( m_bUseDefault
|| !pDataSettings
->bDefault
) )
1089 if ( !m_bUseDefault
|| !pDataSettings
->bDefaultNode
)
1091 // we have a settings entry in our user-defined layer - replace
1092 Reference
< XIndexAccess
> xOldSettings
= pDataSettings
->xSettings
;
1094 // Create a copy of the data if the container is not const
1095 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1096 if ( xReplace
.is() )
1097 pDataSettings
->xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1099 pDataSettings
->xSettings
= aNewData
;
1100 pDataSettings
->bDefault
= false;
1101 pDataSettings
->bModified
= true;
1104 // Modify type container
1105 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1106 rElementType
.bModified
= true;
1108 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1110 // Create event to notify listener about replaced element settings
1111 ConfigurationEvent aEvent
;
1113 aEvent
.ResourceURL
= ResourceURL
;
1114 aEvent
.Accessor
<<= xThis
;
1115 aEvent
.Source
= m_xOwner
;
1116 aEvent
.ReplacedElement
<<= xOldSettings
;
1117 aEvent
.Element
<<= pDataSettings
->xSettings
;
1121 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1125 // we have no settings in our user-defined layer - insert
1126 UIElementData aUIElementData
;
1128 aUIElementData
.bDefault
= false;
1129 aUIElementData
.bDefaultNode
= false;
1130 aUIElementData
.bModified
= true;
1132 // Create a copy of the data if the container is not const
1133 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1134 if ( xReplace
.is() )
1135 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1137 aUIElementData
.xSettings
= aNewData
;
1138 aUIElementData
.aName
= RetrieveNameFromResourceURL( ResourceURL
) + m_aXMLPostfix
;
1139 aUIElementData
.aResourceURL
= ResourceURL
;
1142 // Modify type container
1143 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1144 rElementType
.bModified
= true;
1146 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1148 // Check our user element settings hash map as it can already contain settings that have been set to default!
1149 // If no node can be found, we have to insert it.
1150 UIElementDataHashMap::iterator pIter
= rElements
.find( ResourceURL
);
1151 if ( pIter
!= rElements
.end() )
1152 pIter
->second
= aUIElementData
;
1154 rElements
.insert( UIElementDataHashMap::value_type( ResourceURL
, aUIElementData
));
1156 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1158 // Create event to notify listener about replaced element settings
1159 ConfigurationEvent aEvent
;
1161 aEvent
.ResourceURL
= ResourceURL
;
1162 aEvent
.Accessor
<<= xThis
;
1163 aEvent
.Source
= m_xOwner
;
1164 aEvent
.ReplacedElement
<<= pDataSettings
->xSettings
;
1165 aEvent
.Element
<<= aUIElementData
.xSettings
;
1169 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1173 throw NoSuchElementException();
1177 void UIConfigurationManagerImpl::removeSettings( const ::rtl::OUString
& ResourceURL
)
1178 throw ( NoSuchElementException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1180 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1182 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1183 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1184 throw IllegalArgumentException();
1185 else if ( m_bReadOnly
)
1186 throw IllegalAccessException();
1189 ResetableGuard
aGuard( m_aLock
);
1192 throw DisposedException();
1194 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
);
1195 if ( pDataSettings
)
1197 // If element settings are default, we don't need to change anything!
1198 if ( pDataSettings
->bDefault
)
1202 Reference
< XIndexAccess
> xRemovedSettings
= pDataSettings
->xSettings
;
1203 pDataSettings
->bDefault
= true;
1205 // check if this is a default layer node
1206 if ( !m_bUseDefault
|| !pDataSettings
->bDefaultNode
)
1207 pDataSettings
->bModified
= true; // we have to remove this node from the user layer!
1208 pDataSettings
->xSettings
.clear();
1209 m_bModified
= true; // user layer must be written
1211 // Modify type container
1212 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1213 rElementType
.bModified
= true;
1215 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1216 // Check if we have settings in the default layer which replaces the user-defined one!
1217 UIElementData
* pDefaultDataSettings
= m_bUseDefault
? impl_findUIElementData( ResourceURL
, nElementType
) : NULL
;
1218 if ( pDefaultDataSettings
)
1220 // Create event to notify listener about replaced element settings
1221 ConfigurationEvent aEvent
;
1223 aEvent
.ResourceURL
= ResourceURL
;
1224 aEvent
.Accessor
<<= xThis
;
1225 aEvent
.Source
= m_xOwner
;
1226 aEvent
.Element
<<= xRemovedSettings
;
1227 aEvent
.ReplacedElement
<<= pDefaultDataSettings
->xSettings
;
1231 implts_notifyContainerListener( aEvent
, NotifyOp_Replace
);
1235 // Create event to notify listener about removed element settings
1236 ConfigurationEvent aEvent
;
1238 aEvent
.ResourceURL
= ResourceURL
;
1239 aEvent
.Accessor
<<= xThis
;
1240 aEvent
.Source
= m_xOwner
;
1241 aEvent
.Element
<<= xRemovedSettings
;
1245 implts_notifyContainerListener( aEvent
, NotifyOp_Remove
);
1250 throw NoSuchElementException();
1254 void UIConfigurationManagerImpl::insertSettings( const ::rtl::OUString
& NewResourceURL
, const Reference
< XIndexAccess
>& aNewData
)
1255 throw ( ElementExistException
, IllegalArgumentException
, IllegalAccessException
, RuntimeException
)
1257 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( NewResourceURL
);
1259 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1260 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1261 throw IllegalArgumentException();
1262 else if ( m_bReadOnly
)
1263 throw IllegalAccessException();
1266 ResetableGuard
aGuard( m_aLock
);
1269 throw DisposedException();
1271 bool bInsertData( m_bUseDefault
);
1272 UIElementData aUIElementData
;
1273 UIElementData
* pDataSettings
= impl_findUIElementData( NewResourceURL
, nElementType
);
1274 if ( !m_bUseDefault
)
1276 if ( pDataSettings
&& !pDataSettings
->bDefault
)
1277 throw ElementExistException();
1278 if ( !pDataSettings
)
1280 pDataSettings
= &aUIElementData
;
1284 if ( !pDataSettings
|| bInsertData
)
1286 aUIElementData
.bDefault
= false;
1287 if ( !m_bUseDefault
)
1288 aUIElementData
.bDefaultNode
= false;
1289 aUIElementData
.bModified
= true;
1291 // Create a copy of the data if the container is not const
1292 Reference
< XIndexReplace
> xReplace( aNewData
, UNO_QUERY
);
1293 if ( xReplace
.is() )
1294 aUIElementData
.xSettings
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( new ConstItemContainer( aNewData
) ), UNO_QUERY
);
1296 aUIElementData
.xSettings
= aNewData
;
1300 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][nElementType
];
1301 rElementType
.bModified
= true;
1305 aUIElementData
.aName
= RetrieveNameFromResourceURL( NewResourceURL
) + m_aXMLPostfix
;
1306 aUIElementData
.aResourceURL
= NewResourceURL
;
1307 UIElementDataHashMap
& rElements
= rElementType
.aElementsHashMap
;
1308 rElements
.insert( UIElementDataHashMap::value_type( NewResourceURL
, aUIElementData
));
1311 Reference
< XIndexAccess
> xInsertSettings( aUIElementData
.xSettings
);
1312 Reference
< XUIConfigurationManager
> xThis( m_xOwner
, UNO_QUERY
);
1314 // Create event to notify listener about removed element settings
1315 ConfigurationEvent aEvent
;
1317 aEvent
.ResourceURL
= NewResourceURL
;
1318 aEvent
.Accessor
<<= xThis
;
1319 aEvent
.Source
= m_xOwner
;
1320 aEvent
.Element
<<= xInsertSettings
;
1324 implts_notifyContainerListener( aEvent
, NotifyOp_Insert
);
1327 throw ElementExistException();
1331 Reference
< XInterface
> UIConfigurationManagerImpl::getImageManager() throw (::com::sun::star::uno::RuntimeException
)
1333 ResetableGuard
aGuard( m_aLock
);
1336 throw DisposedException();
1338 if ( !m_xModuleImageManager
.is() )
1340 if ( m_bUseDefault
)
1341 m_xModuleImageManager
= Reference
< XComponent
>( static_cast< cppu::OWeakObject
*>( new ModuleImageManager( m_xServiceManager
)),
1344 m_xModuleImageManager
= Reference
< XComponent
>( static_cast< cppu::OWeakObject
*>( new ImageManager( m_xServiceManager
)),
1346 Reference
< XInitialization
> xInit( m_xModuleImageManager
, UNO_QUERY
);
1348 Sequence
< Any
> aPropSeq( m_bUseDefault
? 3 : 2 );
1349 PropertyValue aPropValue
;
1350 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
1351 aPropValue
.Value
<<= m_xUserConfigStorage
;
1352 aPropSeq
[0] <<= aPropValue
;
1353 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
1354 aPropValue
.Value
<<= m_aModuleIdentifier
;
1355 aPropSeq
[1] <<= aPropValue
;
1356 if ( m_bUseDefault
)
1358 aPropValue
.Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
1359 aPropValue
.Value
<<= m_xUserRootCommit
;
1360 aPropSeq
[2] <<= aPropValue
;
1363 xInit
->initialize( aPropSeq
);
1366 return Reference
< XInterface
>( m_xModuleImageManager
, UNO_QUERY
);
1368 // return Reference< XInterface >();
1371 Reference
< XInterface
> UIConfigurationManagerImpl::getShortCutManager() throw (::com::sun::star::uno::RuntimeException
)
1373 ResetableGuard
aGuard( m_aLock
);
1374 if ( !m_bUseDefault
&& m_xAccConfig
.is())
1375 return m_xAccConfig
;
1377 Reference
< XMultiServiceFactory
> xSMGR
= m_xServiceManager
;
1378 ::rtl::OUString aModule
= m_aModuleIdentifier
;
1379 Reference
< XStorage
> xDocumentRoot
= m_xUserConfigStorage
;
1381 Reference
< XInterface
> xManager
= xSMGR
->createInstance(m_bUseDefault
? SERVICENAME_MODULEACCELERATORCONFIGURATION
: SERVICENAME_DOCUMENTACCELERATORCONFIGURATION
);
1382 Reference
< XInitialization
> xInit (xManager
, UNO_QUERY_THROW
);
1384 PropertyValue aProp
;
1385 Sequence
< Any
> lArgs(1);
1386 if ( m_bUseDefault
)
1388 aProp
.Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier"));
1389 aProp
.Value
<<= aModule
;
1390 } // if ( m_bUseDefault )
1393 aProp
.Name
= ::rtl::OUString::createFromAscii("DocumentRoot");
1394 aProp
.Value
<<= xDocumentRoot
;
1397 xInit
->initialize(lArgs
);
1399 if ( !m_bUseDefault
)
1403 m_xAccConfig
= xManager
;
1411 Reference
< XInterface
> UIConfigurationManagerImpl::getEventsManager() throw (::com::sun::star::uno::RuntimeException
)
1413 return Reference
< XInterface
>();
1415 // XUIConfigurationStorage
1416 void UIConfigurationManagerImpl::setStorage( const Reference
< XStorage
>& Storage
) throw (::com::sun::star::uno::RuntimeException
)
1418 ResetableGuard
aGuard( m_aLock
);
1421 throw DisposedException();
1423 if ( m_xUserConfigStorage
.is() )
1427 // Dispose old storage to be sure that it will be closed
1428 Reference
< XComponent
> xComponent( m_xUserConfigStorage
, UNO_QUERY
);
1429 if ( xComponent
.is() )
1430 xComponent
->dispose();
1432 catch ( Exception
& )
1437 // We store the new storage. Be careful it could be an empty reference!
1438 m_xUserConfigStorage
= Storage
;
1439 m_bReadOnly
= sal_True
;
1441 Reference
< XUIConfigurationStorage
> xAccUpdate(m_xAccConfig
, UNO_QUERY
);
1442 if ( xAccUpdate
.is() )
1443 xAccUpdate
->setStorage( m_xUserConfigStorage
);
1445 if ( m_xModuleImageManager
.is() )
1447 ImageManager
* pImageManager
= (ImageManager
*)m_xModuleImageManager
.get();
1448 if ( pImageManager
)
1449 pImageManager
->setStorage( m_xUserConfigStorage
);
1452 if ( m_xUserConfigStorage
.is() )
1454 ::rtl::OUString sEmpty
;
1455 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1457 rtl::OUString aResourceType
;
1458 if ( i
== ::com::sun::star::ui::UIElementType::MENUBAR
)
1459 aResourceType
= PresetHandler::RESOURCETYPE_MENUBAR();
1460 else if ( i
== ::com::sun::star::ui::UIElementType::TOOLBAR
)
1461 aResourceType
= PresetHandler::RESOURCETYPE_TOOLBAR();
1462 else if ( i
== ::com::sun::star::ui::UIElementType::STATUSBAR
)
1463 aResourceType
= PresetHandler::RESOURCETYPE_STATUSBAR();
1465 //if ( aResourceType.getLength() > 0 )
1467 m_pStorageHandler
[i
] = new PresetHandler( m_xServiceManager
);
1468 m_pStorageHandler
[i
]->connectToResource( PresetHandler::E_DOCUMENT
,
1469 rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ), // this path wont be used later ... seee next lines!
1471 m_xUserConfigStorage
);
1474 Reference
< XPropertySet
> xPropSet( m_xUserConfigStorage
, UNO_QUERY
);
1475 if ( xPropSet
.is() )
1480 if ( xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode
)
1481 m_bReadOnly
= !( nOpenMode
& ElementModes::WRITE
);
1483 catch ( com::sun::star::beans::UnknownPropertyException
& )
1486 catch ( com::sun::star::lang::WrappedTargetException
& )
1494 // -----------------------------------------------------------------------------
1495 sal_Bool
UIConfigurationManagerImpl::hasStorage() throw (::com::sun::star::uno::RuntimeException
)
1497 ResetableGuard
aGuard( m_aLock
);
1500 throw DisposedException();
1502 return ( m_xUserConfigStorage
.is() );
1505 // XUIConfigurationManagerImpl
1506 sal_Bool
UIConfigurationManagerImpl::isDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1507 throw (::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1509 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1511 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1512 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1513 throw IllegalArgumentException();
1516 ResetableGuard
aGuard( m_aLock
);
1519 throw DisposedException();
1521 UIElementData
* pDataSettings
= impl_findUIElementData( ResourceURL
, nElementType
, false );
1522 if ( pDataSettings
&& pDataSettings
->bDefaultNode
)
1529 Reference
< XIndexAccess
> UIConfigurationManagerImpl::getDefaultSettings( const ::rtl::OUString
& ResourceURL
)
1530 throw (::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
1532 sal_Int16 nElementType
= RetrieveTypeFromResourceURL( ResourceURL
);
1534 if (( nElementType
== ::com::sun::star::ui::UIElementType::UNKNOWN
) ||
1535 ( nElementType
>= ::com::sun::star::ui::UIElementType::COUNT
))
1536 throw IllegalArgumentException();
1539 ResetableGuard
aGuard( m_aLock
);
1542 throw DisposedException();
1544 // preload list of element types on demand
1545 impl_preloadUIElementTypeList( LAYER_DEFAULT
, nElementType
);
1547 // Look into our default vector/hash_map combination
1548 UIElementDataHashMap
& rDefaultHashMap
= m_aUIElements
[LAYER_DEFAULT
][nElementType
].aElementsHashMap
;
1549 UIElementDataHashMap::iterator pIter
= rDefaultHashMap
.find( ResourceURL
);
1550 if ( pIter
!= rDefaultHashMap
.end() )
1552 if ( !pIter
->second
.xSettings
.is() )
1553 impl_requestUIElementData( nElementType
, LAYER_DEFAULT
, pIter
->second
);
1554 return pIter
->second
.xSettings
;
1558 // Nothing has been found!
1559 throw NoSuchElementException();
1562 // XUIConfigurationPersistence
1563 void UIConfigurationManagerImpl::reload() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1565 ResetableGuard
aGuard( m_aLock
);
1568 throw DisposedException();
1570 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1572 // Try to access our module sub folder
1573 ConfigEventNotifyContainer aRemoveNotifyContainer
;
1574 ConfigEventNotifyContainer aReplaceNotifyContainer
;
1575 for ( sal_Int16 i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1579 UIElementType
& rUserElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1580 UIElementType
& rDefaultElementType
= m_aUIElements
[LAYER_DEFAULT
][i
];
1582 if ( rUserElementType
.bModified
)
1583 impl_reloadElementTypeData( rUserElementType
, rDefaultElementType
, aRemoveNotifyContainer
, aReplaceNotifyContainer
);
1585 catch ( Exception
& )
1587 throw IOException();
1591 m_bModified
= sal_False
;
1593 // Unlock mutex before notify our listeners
1596 // Notify our listeners
1597 ::std::for_each(aRemoveNotifyContainer
.begin(),aRemoveNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Remove
));
1598 ::std::for_each(aReplaceNotifyContainer
.begin(),aReplaceNotifyContainer
.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener
,this,_1
,NotifyOp_Replace
));
1602 void UIConfigurationManagerImpl::store() throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1604 ResetableGuard
aGuard( m_aLock
);
1607 throw DisposedException();
1609 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1611 // Try to access our module sub folder
1612 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1616 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1617 Reference
< XStorage
> xStorage( rElementType
.xStorage
, UNO_QUERY
);
1619 if ( rElementType
.bModified
&& xStorage
.is() )
1621 impl_storeElementTypeData( xStorage
, rElementType
);
1622 m_pStorageHandler
[i
]->commitUserChanges();
1625 catch ( Exception
& )
1627 throw IOException();
1631 m_bModified
= false;
1635 void UIConfigurationManagerImpl::storeToStorage( const Reference
< XStorage
>& Storage
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
1637 ResetableGuard
aGuard( m_aLock
);
1640 throw DisposedException();
1642 if ( m_xUserConfigStorage
.is() && m_bModified
&& !m_bReadOnly
)
1644 // Try to access our module sub folder
1645 for ( int i
= 1; i
< ::com::sun::star::ui::UIElementType::COUNT
; i
++ )
1649 Reference
< XStorage
> xElementTypeStorage( Storage
->openStorageElement(
1650 rtl::OUString::createFromAscii( UIELEMENTTYPENAMES
[i
] ), ElementModes::READWRITE
));
1651 UIElementType
& rElementType
= m_aUIElements
[LAYER_USERDEFINED
][i
];
1653 if ( rElementType
.bModified
&& xElementTypeStorage
.is() )
1654 impl_storeElementTypeData( xElementTypeStorage
, rElementType
, false ); // store data to storage, but don't reset modify flag!
1656 catch ( Exception
& )
1658 throw IOException();
1662 Reference
< XTransactedObject
> xTransactedObject( Storage
, UNO_QUERY
);
1663 if ( xTransactedObject
.is() )
1664 xTransactedObject
->commit();
1668 sal_Bool
UIConfigurationManagerImpl::isModified() throw (::com::sun::star::uno::RuntimeException
)
1670 ResetableGuard
aGuard( m_aLock
);
1675 sal_Bool
UIConfigurationManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException
)
1677 ResetableGuard
aGuard( m_aLock
);
1682 void UIConfigurationManagerImpl::implts_notifyContainerListener( const ConfigurationEvent
& aEvent
, NotifyOp eOp
)
1684 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< ::com::sun::star::ui::XUIConfigurationListener
>*) NULL
) );
1685 if ( pContainer
!= NULL
)
1687 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
1688 while ( pIterator
.hasMoreElements() )
1694 case NotifyOp_Replace
:
1695 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementReplaced( aEvent
);
1697 case NotifyOp_Insert
:
1698 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementInserted( aEvent
);
1700 case NotifyOp_Remove
:
1701 ((::com::sun::star::ui::XUIConfigurationListener
*)pIterator
.next())->elementRemoved( aEvent
);
1705 catch( css::uno::RuntimeException
& )
1713 } // namespace framework