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