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