1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 #include "uiconfiguration/windowstateconfiguration.hxx"
35 #include <threadhelp/resetableguard.hxx>
36 #include "services.h"
37 
38 //_________________________________________________________________________________________________________________
39 //	interface includes
40 //_________________________________________________________________________________________________________________
41 #include <com/sun/star/beans/PropertyValue.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/container/XNameAccess.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/container/XContainer.hpp>
46 #include <com/sun/star/awt/Point.hpp>
47 #include <com/sun/star/awt/Size.hpp>
48 #include <com/sun/star/ui/DockingArea.hpp>
49 #include <com/sun/star/util/XChangesBatch.hpp>
50 
51 //_________________________________________________________________________________________________________________
52 //	includes of other projects
53 //_________________________________________________________________________________________________________________
54 #include <rtl/ustrbuf.hxx>
55 #include <cppuhelper/weak.hxx>
56 #include <tools/debug.hxx>
57 
58 //_________________________________________________________________________________________________________________
59 //	Defines
60 //_________________________________________________________________________________________________________________
61 //
62 
63 using namespace com::sun::star::uno;
64 using namespace com::sun::star::lang;
65 using namespace com::sun::star::beans;
66 using namespace com::sun::star::util;
67 using namespace com::sun::star::container;
68 using namespace ::com::sun::star::frame;
69 using namespace ::com::sun::star::ui;
70 
71 //_________________________________________________________________________________________________________________
72 //	Namespace
73 //_________________________________________________________________________________________________________________
74 //
75 
76 static const char CONFIGURATION_ROOT_ACCESS[]               = "/org.openoffice.Office.UI.";
77 static const char CONFIGURATION_WINDOWSTATE_ACCESS[]        = "/UIElements/States";
78 
79 static const char CONFIGURATION_PROPERTY_LOCKED[]           = WINDOWSTATE_PROPERTY_LOCKED;
80 static const char CONFIGURATION_PROPERTY_DOCKED[]           = WINDOWSTATE_PROPERTY_DOCKED;
81 static const char CONFIGURATION_PROPERTY_VISIBLE[]          = WINDOWSTATE_PROPERTY_VISIBLE;
82 static const char CONFIGURATION_PROPERTY_DOCKINGAREA[]      = WINDOWSTATE_PROPERTY_DOCKINGAREA;
83 static const char CONFIGURATION_PROPERTY_DOCKPOS[]          = WINDOWSTATE_PROPERTY_DOCKPOS;
84 static const char CONFIGURATION_PROPERTY_DOCKSIZE[]         = WINDOWSTATE_PROPERTY_DOCKSIZE;
85 static const char CONFIGURATION_PROPERTY_POS[]              = WINDOWSTATE_PROPERTY_POS;
86 static const char CONFIGURATION_PROPERTY_SIZE[]             = WINDOWSTATE_PROPERTY_SIZE;
87 static const char CONFIGURATION_PROPERTY_UINAME[]           = WINDOWSTATE_PROPERTY_UINAME;
88 static const char CONFIGURATION_PROPERTY_INTERNALSTATE[]    = WINDOWSTATE_PROPERTY_INTERNALSTATE;
89 static const char CONFIGURATION_PROPERTY_STYLE[]            = WINDOWSTATE_PROPERTY_STYLE;
90 static const char CONFIGURATION_PROPERTY_CONTEXT[]          = WINDOWSTATE_PROPERTY_CONTEXT;
91 static const char CONFIGURATION_PROPERTY_HIDEFROMMENU[]     = WINDOWSTATE_PROPERTY_HIDEFROMENU;
92 static const char CONFIGURATION_PROPERTY_NOCLOSE[]          = WINDOWSTATE_PROPERTY_NOCLOSE;
93 static const char CONFIGURATION_PROPERTY_SOFTCLOSE[]        = WINDOWSTATE_PROPERTY_SOFTCLOSE;
94 static const char CONFIGURATION_PROPERTY_CONTEXTACTIVE[]    = WINDOWSTATE_PROPERTY_CONTEXTACTIVE;
95 
96 // Zero based indexes, order must be the same as WindowStateMask && CONFIGURATION_PROPERTIES!
97 static const sal_Int16 PROPERTY_LOCKED                  = 0;
98 static const sal_Int16 PROPERTY_DOCKED                  = 1;
99 static const sal_Int16 PROPERTY_VISIBLE                 = 2;
100 static const sal_Int16 PROPERTY_CONTEXT                 = 3;
101 static const sal_Int16 PROPERTY_HIDEFROMMENU            = 4;
102 static const sal_Int16 PROPERTY_NOCLOSE                 = 5;
103 static const sal_Int16 PROPERTY_SOFTCLOSE               = 6;
104 static const sal_Int16 PROPERTY_CONTEXTACTIVE           = 7;
105 static const sal_Int16 PROPERTY_DOCKINGAREA             = 8;
106 static const sal_Int16 PROPERTY_POS                     = 9;
107 static const sal_Int16 PROPERTY_SIZE                    = 10;
108 static const sal_Int16 PROPERTY_UINAME                  = 11;
109 static const sal_Int16 PROPERTY_INTERNALSTATE           = 12;
110 static const sal_Int16 PROPERTY_STYLE                   = 13;
111 static const sal_Int16 PROPERTY_DOCKPOS                 = 14;
112 static const sal_Int16 PROPERTY_DOCKSIZE                = 15;
113 
114 // Order must be the same as WindowStateMask!!
115 static const char* CONFIGURATION_PROPERTIES[]           =
116 {
117     CONFIGURATION_PROPERTY_LOCKED,
118     CONFIGURATION_PROPERTY_DOCKED,
119     CONFIGURATION_PROPERTY_VISIBLE,
120     CONFIGURATION_PROPERTY_CONTEXT,
121     CONFIGURATION_PROPERTY_HIDEFROMMENU,
122     CONFIGURATION_PROPERTY_NOCLOSE,
123     CONFIGURATION_PROPERTY_SOFTCLOSE,
124     CONFIGURATION_PROPERTY_CONTEXTACTIVE,
125     CONFIGURATION_PROPERTY_DOCKINGAREA,
126     CONFIGURATION_PROPERTY_POS,
127     CONFIGURATION_PROPERTY_SIZE,
128     CONFIGURATION_PROPERTY_UINAME,
129     CONFIGURATION_PROPERTY_INTERNALSTATE,
130     CONFIGURATION_PROPERTY_STYLE,
131     CONFIGURATION_PROPERTY_DOCKPOS,
132     CONFIGURATION_PROPERTY_DOCKSIZE,
133     0
134 };
135 
136 namespace framework
137 {
138 
139 //*****************************************************************************************************************
140 //	Configuration access class for WindowState supplier implementation
141 //*****************************************************************************************************************
142 
143 class ConfigurationAccess_WindowState : // interfaces
144                                         public  XTypeProvider                            ,
145                                         public  XNameContainer                           ,
146                                         public  XContainerListener                       ,
147                                         // baseclasses
148 							            // Order is neccessary for right initialization!
149                                         private ThreadHelpBase                           ,
150                                         public  ::cppu::OWeakObject
151 {
152     public:
153                                   ConfigurationAccess_WindowState( const ::rtl::OUString& aWindowStateConfigFile, const Reference< XMultiServiceFactory >& rServiceManager );
154         virtual                   ~ConfigurationAccess_WindowState();
155 
156         //  XInterface, XTypeProvider
157         FWK_DECLARE_XINTERFACE
158         FWK_DECLARE_XTYPEPROVIDER
159 
160         // XNameAccess
161         virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
162             throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
163 
164         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
165             throw (::com::sun::star::uno::RuntimeException);
166 
167         virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
168             throw (::com::sun::star::uno::RuntimeException);
169 
170         // XNameContainer
171         virtual void SAL_CALL removeByName( const ::rtl::OUString& sName )
172             throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException );
173 
174         virtual void SAL_CALL insertByName( const ::rtl::OUString& sName, const css::uno::Any&   aPropertySet )
175             throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, css::uno::RuntimeException );
176 
177         // XNameReplace
178         virtual void SAL_CALL replaceByName( const ::rtl::OUString& sName, const css::uno::Any& aPropertySet )
179             throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException );
180 
181         // XElementAccess
182         virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
183             throw (::com::sun::star::uno::RuntimeException);
184 
185         virtual sal_Bool SAL_CALL hasElements()
186             throw (::com::sun::star::uno::RuntimeException);
187 
188         // container.XContainerListener
189         virtual void SAL_CALL     elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
190         virtual void SAL_CALL     elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
191         virtual void SAL_CALL     elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
192 
193         // lang.XEventListener
194         virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
195 
196     protected:
197         enum WindowStateMask
198         {
199             WINDOWSTATE_MASK_LOCKED         = 1,
200             WINDOWSTATE_MASK_DOCKED         = 2,
201             WINDOWSTATE_MASK_VISIBLE        = 4,
202             WINDOWSTATE_MASK_CONTEXT        = 8,
203             WINDOWSTATE_MASK_HIDEFROMMENU   = 16,
204             WINDOWSTATE_MASK_NOCLOSE        = 32,
205             WINDOWSTATE_MASK_SOFTCLOSE      = 64,
206             WINDOWSTATE_MASK_CONTEXTACTIVE  = 128,
207             WINDOWSTATE_MASK_DOCKINGAREA    = 256,
208             WINDOWSTATE_MASK_POS            = 512,
209             WINDOWSTATE_MASK_SIZE           = 1024,
210             WINDOWSTATE_MASK_UINAME         = 2048,
211             WINDOWSTATE_MASK_INTERNALSTATE  = 4096,
212             WINDOWSTATE_MASK_STYLE          = 8192,
213             WINDOWSTATE_MASK_DOCKPOS        = 16384,
214             WINDOWSTATE_MASK_DOCKSIZE       = 32768
215         };
216 
217         // Cache structure. Valid values are described by tje eMask member. All other values should not be
218         // provided to outside code!
219         struct WindowStateInfo
220         {
221             WindowStateInfo() : aDockingArea( ::com::sun::star::ui::DockingArea_DOCKINGAREA_TOP ),
222                                 aDockPos( 0, 0 ),
223                                 aPos( 0, 0 ),
224                                 aSize( 0, 0 ),
225                                 nInternalState( 0 ),
226                                 nStyle( 0 ),
227                                 nMask( 0 ) {}
228 
229             bool                                    bLocked : 1,
230                                                     bDocked : 1,
231                                                     bVisible : 1,
232                                                     bContext : 1,
233                                                     bHideFromMenu : 1,
234                                                     bNoClose : 1,
235                                                     bSoftClose : 1,
236                                                     bContextActive : 1;
237             ::com::sun::star::ui::DockingArea       aDockingArea;
238             com::sun::star::awt::Point              aDockPos;
239             com::sun::star::awt::Size               aDockSize;
240             com::sun::star::awt::Point              aPos;
241             com::sun::star::awt::Size               aSize;
242             rtl::OUString                           aUIName;
243             sal_uInt32                              nInternalState;
244             sal_uInt16                              nStyle;
245             sal_uInt32                              nMask; // see WindowStateMask
246         };
247 
248         void                      impl_putPropertiesFromStruct( const WindowStateInfo& rWinStateInfo, Reference< XPropertySet >& xPropSet );
249         Any                       impl_insertCacheAndReturnSequence( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess );
250         WindowStateInfo&          impl_insertCacheAndReturnWinState( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess );
251         Any                       impl_getSequenceFromStruct( const WindowStateInfo& rWinStateInfo );
252         void                      impl_fillStructFromSequence( WindowStateInfo& rWinStateInfo, const Sequence< PropertyValue >& rSeq );
253         Any                       impl_getWindowStateFromResourceURL( const rtl::OUString& rResourceURL );
254         sal_Bool                  impl_initializeConfigAccess();
255 
256     private:
257         typedef ::std::hash_map< ::rtl::OUString,
258                                  WindowStateInfo,
259                                  OUStringHashCode,
260                                  ::std::equal_to< ::rtl::OUString > > ResourceURLToInfoCache;
261 
262         rtl::OUString                     m_aConfigWindowAccess;
263         Reference< XMultiServiceFactory > m_xServiceManager;
264         Reference< XMultiServiceFactory > m_xConfigProvider;
265         Reference< XNameAccess >          m_xConfigAccess;
266         ResourceURLToInfoCache            m_aResourceURLToInfoCache;
267         sal_Bool                          m_bConfigAccessInitialized : 1,
268                                           m_bModified : 1;
269         std::vector< ::rtl::OUString >           m_aPropArray;
270 };
271 
272 //*****************************************************************************************************************
273 //	XInterface, XTypeProvider
274 //*****************************************************************************************************************
275 DEFINE_XINTERFACE_7     (   ConfigurationAccess_WindowState                                                   ,
276                             OWeakObject                                                                     ,
277                             DIRECT_INTERFACE ( css::container::XNameContainer                               ),
278                             DIRECT_INTERFACE ( css::container::XContainerListener                           ),
279                             DIRECT_INTERFACE ( css::lang::XTypeProvider                                     ),
280                             DERIVED_INTERFACE( css::container::XElementAccess, css::container::XNameAccess  ),
281                             DERIVED_INTERFACE( css::container::XNameAccess, css::container::XNameReplace    ),
282                             DERIVED_INTERFACE( css::container::XNameReplace, css::container::XNameContainer ),
283                             DERIVED_INTERFACE( css::lang::XEventListener, XContainerListener                )
284 						)
285 
286 DEFINE_XTYPEPROVIDER_7  (   ConfigurationAccess_WindowState         ,
287                             css::container::XNameContainer          ,
288                             css::container::XNameReplace            ,
289                             css::container::XNameAccess             ,
290                             css::container::XElementAccess          ,
291                             css::container::XContainerListener      ,
292                             css::lang::XEventListener               ,
293                             css::lang::XTypeProvider
294 						)
295 
296 ConfigurationAccess_WindowState::ConfigurationAccess_WindowState( const rtl::OUString& aModuleName, const Reference< XMultiServiceFactory >& rServiceManager ) :
297     ThreadHelpBase(),
298     m_aConfigWindowAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
299     m_xServiceManager( rServiceManager ),
300     m_bConfigAccessInitialized( sal_False ),
301     m_bModified( sal_False )
302 {
303     // Create configuration hierachical access name
304     m_aConfigWindowAccess += aModuleName;
305     m_aConfigWindowAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_WINDOWSTATE_ACCESS ));
306     m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER ), UNO_QUERY );
307 
308     // Initialize access array with property names.
309     sal_Int32 n = 0;
310     while ( CONFIGURATION_PROPERTIES[n] )
311     {
312         m_aPropArray.push_back( ::rtl::OUString::createFromAscii( CONFIGURATION_PROPERTIES[n] ));
313         ++n;
314     }
315 }
316 
317 ConfigurationAccess_WindowState::~ConfigurationAccess_WindowState()
318 {
319     // SAFE
320     ResetableGuard aLock( m_aLock );
321     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
322     if ( xContainer.is() )
323         xContainer->removeContainerListener( this );
324 }
325 
326 // XNameAccess
327 Any SAL_CALL ConfigurationAccess_WindowState::getByName( const ::rtl::OUString& rResourceURL )
328 throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
329 {
330     // SAFE
331     ResetableGuard aLock( m_aLock );
332 
333     ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
334     if ( pIter != m_aResourceURLToInfoCache.end() )
335         return impl_getSequenceFromStruct( pIter->second );
336     else
337     {
338         Any a( impl_getWindowStateFromResourceURL( rResourceURL ) );
339         if ( a == Any() )
340             throw NoSuchElementException();
341         else
342             return a;
343     }
344 }
345 
346 Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_WindowState::getElementNames()
347 throw ( RuntimeException )
348 {
349     // SAFE
350     ResetableGuard aLock( m_aLock );
351 
352     if ( !m_bConfigAccessInitialized )
353     {
354         impl_initializeConfigAccess();
355         m_bConfigAccessInitialized = sal_True;
356     }
357 
358     if ( m_xConfigAccess.is() )
359         return m_xConfigAccess->getElementNames();
360     else
361         return Sequence< ::rtl::OUString > ();
362 }
363 
364 sal_Bool SAL_CALL ConfigurationAccess_WindowState::hasByName( const ::rtl::OUString& rResourceURL )
365 throw (::com::sun::star::uno::RuntimeException)
366 {
367     // SAFE
368     ResetableGuard aLock( m_aLock );
369 
370     ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
371     if ( pIter != m_aResourceURLToInfoCache.end() )
372         return sal_True;
373     else
374     {
375         Any a( impl_getWindowStateFromResourceURL( rResourceURL ) );
376         if ( a == Any() )
377             return sal_False;
378         else
379             return sal_True;
380     }
381 }
382 
383 // XElementAccess
384 Type SAL_CALL ConfigurationAccess_WindowState::getElementType()
385 throw ( RuntimeException )
386 {
387     return( ::getCppuType( (const Sequence< PropertyValue >*)NULL ) );
388 }
389 
390 sal_Bool SAL_CALL ConfigurationAccess_WindowState::hasElements()
391 throw ( RuntimeException )
392 {
393     // SAFE
394     ResetableGuard aLock( m_aLock );
395 
396     if ( !m_bConfigAccessInitialized )
397     {
398         impl_initializeConfigAccess();
399         m_bConfigAccessInitialized = sal_True;
400     }
401 
402     if ( m_xConfigAccess.is() )
403         return m_xConfigAccess->hasElements();
404     else
405         return sal_False;
406 }
407 
408 // XNameContainer
409 void SAL_CALL ConfigurationAccess_WindowState::removeByName( const ::rtl::OUString& rResourceURL )
410 throw( NoSuchElementException, WrappedTargetException, RuntimeException )
411 {
412     // SAFE
413     ResetableGuard aLock( m_aLock );
414 
415     ResourceURLToInfoCache::iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
416     if ( pIter != m_aResourceURLToInfoCache.end() )
417         m_aResourceURLToInfoCache.erase( pIter );
418 
419     if ( !m_bConfigAccessInitialized )
420     {
421         impl_initializeConfigAccess();
422         m_bConfigAccessInitialized = sal_True;
423     }
424 
425     try
426     {
427         // Remove must be write-through => remove element from configuration
428         Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
429         if ( xNameContainer.is() )
430         {
431             aLock.unlock();
432 
433             xNameContainer->removeByName( rResourceURL );
434             Reference< XChangesBatch > xFlush( m_xConfigAccess, UNO_QUERY );
435             if ( xFlush.is() )
436                 xFlush->commitChanges();
437         }
438     }
439     catch ( com::sun::star::lang::WrappedTargetException& )
440     {
441     }
442 }
443 
444 void SAL_CALL ConfigurationAccess_WindowState::insertByName( const ::rtl::OUString& rResourceURL, const css::uno::Any& aPropertySet )
445 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
446 {
447     // SAFE
448     ResetableGuard aLock( m_aLock );
449 
450     Sequence< PropertyValue > aPropSet;
451     if ( aPropertySet >>= aPropSet )
452     {
453         ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
454         if ( pIter != m_aResourceURLToInfoCache.end() )
455             throw ElementExistException();
456         else
457         {
458             if ( !m_bConfigAccessInitialized )
459             {
460                 impl_initializeConfigAccess();
461                 m_bConfigAccessInitialized = sal_True;
462             }
463 
464             // Try to ask our configuration access
465             if ( m_xConfigAccess.is() )
466             {
467                 if ( m_xConfigAccess->hasByName( rResourceURL ) )
468                     throw ElementExistException();
469                 else
470                 {
471                     WindowStateInfo aWinStateInfo;
472                     impl_fillStructFromSequence( aWinStateInfo, aPropSet );
473                     m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWinStateInfo ));
474 
475                     // insert must be write-through => insert element into configuration
476                     Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
477                     if ( xNameContainer.is() )
478                     {
479                         Reference< XSingleServiceFactory > xFactory( m_xConfigAccess, UNO_QUERY );
480                         aLock.unlock();
481 
482                         try
483                         {
484                             Reference< XPropertySet > xPropSet( xFactory->createInstance(), UNO_QUERY );
485                             if ( xPropSet.is() )
486                             {
487                                 Any a;
488                                 impl_putPropertiesFromStruct( aWinStateInfo, xPropSet );
489                                 a <<= xPropSet;
490                                 xNameContainer->insertByName( rResourceURL, a );
491                                 Reference< XChangesBatch > xFlush( xFactory, UNO_QUERY );
492                                 if ( xFlush.is() )
493                                     xFlush->commitChanges();
494                             }
495                         }
496                         catch ( Exception& )
497                         {
498                         }
499                     }
500                 }
501             }
502         }
503     }
504     else
505         throw IllegalArgumentException();
506 }
507 
508 // XNameReplace
509 void SAL_CALL ConfigurationAccess_WindowState::replaceByName( const ::rtl::OUString& rResourceURL, const css::uno::Any& aPropertySet )
510 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
511 {
512     // SAFE
513     ResetableGuard aLock( m_aLock );
514 
515     Sequence< PropertyValue > aPropSet;
516     if ( aPropertySet >>= aPropSet )
517     {
518         ResourceURLToInfoCache::iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
519         if ( pIter != m_aResourceURLToInfoCache.end() )
520         {
521             WindowStateInfo& rWinStateInfo = pIter->second;
522             impl_fillStructFromSequence( rWinStateInfo, aPropSet );
523             m_bModified = sal_True;
524         }
525         else
526         {
527             if ( !m_bConfigAccessInitialized )
528             {
529                 impl_initializeConfigAccess();
530                 m_bConfigAccessInitialized = sal_True;
531             }
532 
533             // Try to ask our configuration access
534             Reference< XNameAccess > xNameAccess;
535             Any a( m_xConfigAccess->getByName( rResourceURL ));
536 
537             if ( a >>= xNameAccess )
538             {
539                 WindowStateInfo& rWinStateInfo( impl_insertCacheAndReturnWinState( rResourceURL, xNameAccess ));
540                 impl_fillStructFromSequence( rWinStateInfo, aPropSet );
541                 m_bModified = sal_True;
542                 pIter = m_aResourceURLToInfoCache.find( rResourceURL );
543             }
544             else
545                 throw NoSuchElementException();
546         }
547 
548         if ( m_bModified && pIter != m_aResourceURLToInfoCache.end() )
549         {
550             Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
551             if ( xNameContainer.is() )
552             {
553                 WindowStateInfo aWinStateInfo( pIter->second );
554                 ::rtl::OUString        aResourceURL( pIter->first );
555                 m_bModified = sal_False;
556                 aLock.unlock();
557 
558                 try
559                 {
560                     Reference< XPropertySet > xPropSet;
561                     if ( xNameContainer->getByName( aResourceURL ) >>= xPropSet )
562                     {
563                         impl_putPropertiesFromStruct( aWinStateInfo, xPropSet );
564 
565                         Reference< XChangesBatch > xFlush( m_xConfigAccess, UNO_QUERY );
566                         if ( xFlush.is() )
567                             xFlush->commitChanges();
568                     }
569                 }
570                 catch ( Exception& )
571                 {
572                 }
573             }
574         }
575     }
576     else
577         throw IllegalArgumentException();
578 }
579 
580 // container.XContainerListener
581 void SAL_CALL ConfigurationAccess_WindowState::elementInserted( const ContainerEvent& ) throw(RuntimeException)
582 {
583     // do nothing - next time someone wants to retrieve this node we will find it in the configuration
584 }
585 
586 void SAL_CALL ConfigurationAccess_WindowState::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
587 {
588     //
589 }
590 
591 void SAL_CALL ConfigurationAccess_WindowState::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
592 {
593     //
594 }
595 
596 // lang.XEventListener
597 void SAL_CALL ConfigurationAccess_WindowState::disposing( const EventObject& aEvent ) throw(RuntimeException)
598 {
599     // SAFE
600     // remove our reference to the config access
601     ResetableGuard aLock( m_aLock );
602 
603     Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
604     Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
605     if ( xIfac1 == xIfac2 )
606         m_xConfigAccess.clear();
607 }
608 
609 // private helper methods
610 Any ConfigurationAccess_WindowState::impl_getSequenceFromStruct( const WindowStateInfo& rWinStateInfo )
611 {
612     sal_Int32                 i( 0 );
613     sal_Int32                 nCount( m_aPropArray.size() );
614     Sequence< PropertyValue > aPropSeq;
615 
616     for ( i = 0; i < nCount; i++ )
617     {
618         if ( rWinStateInfo.nMask & ( 1 << i ))
619         {
620             // put value into the return sequence
621             sal_Int32 nIndex( aPropSeq.getLength());
622             aPropSeq.realloc( nIndex+1 );
623             aPropSeq[nIndex].Name = m_aPropArray[i];
624 
625             switch ( i )
626             {
627                 case PROPERTY_LOCKED:
628                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bLocked ); break;
629                 case PROPERTY_DOCKED:
630                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bDocked ); break;
631                 case PROPERTY_VISIBLE:
632                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bVisible ); break;
633                 case PROPERTY_CONTEXT:
634                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bContext ); break;
635                 case PROPERTY_HIDEFROMMENU:
636                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bHideFromMenu ); break;
637                 case PROPERTY_NOCLOSE:
638                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bNoClose ); break;
639                 case PROPERTY_SOFTCLOSE:
640                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bSoftClose ); break;
641                 case PROPERTY_CONTEXTACTIVE:
642                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bContextActive ); break;
643                 case PROPERTY_DOCKINGAREA:
644                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockingArea ); break;
645                 case PROPERTY_POS:
646                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aPos ); break;
647                 case PROPERTY_SIZE:
648                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aSize ); break;
649                 case PROPERTY_UINAME:
650                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aUIName ); break;
651                 case PROPERTY_INTERNALSTATE:
652                     aPropSeq[nIndex].Value = makeAny( sal_Int32( rWinStateInfo.nInternalState )); break;
653                 case PROPERTY_STYLE:
654                     aPropSeq[nIndex].Value = makeAny( sal_Int16( rWinStateInfo.nStyle )); break;
655                 case PROPERTY_DOCKPOS:
656                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockPos ); break;
657                 case PROPERTY_DOCKSIZE:
658                     aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockSize ); break;
659                 default:
660                     DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
661             }
662         }
663     }
664 
665     return makeAny( aPropSeq );
666 }
667 
668 Any ConfigurationAccess_WindowState::impl_insertCacheAndReturnSequence( const rtl::OUString& rResourceURL, Reference< XNameAccess >& xNameAccess )
669 {
670     sal_Int32                 nMask( 0 );
671     sal_Int32                 nCount( m_aPropArray.size() );
672     sal_Int32                 i( 0 );
673     sal_Int32                 nIndex( 0 );
674     Sequence< PropertyValue > aPropSeq;
675     WindowStateInfo           aWindowStateInfo;
676 
677     for ( i = 0; i < nCount; i++ )
678     {
679         try
680         {
681             bool    bAddToSeq( false );
682             Any     a( xNameAccess->getByName( m_aPropArray[i] ) );
683             switch ( i )
684             {
685                 case PROPERTY_LOCKED:
686                 case PROPERTY_DOCKED:
687                 case PROPERTY_VISIBLE:
688                 case PROPERTY_CONTEXT:
689                 case PROPERTY_HIDEFROMMENU:
690                 case PROPERTY_NOCLOSE:
691                 case PROPERTY_SOFTCLOSE:
692                 case PROPERTY_CONTEXTACTIVE:
693                 {
694                     sal_Bool bValue = sal_Bool();
695                     if ( a >>= bValue )
696                     {
697                         sal_Int32 nValue( 1 << i );
698                         nMask |= nValue;
699                         bAddToSeq = true;
700                         switch ( i )
701                         {
702                             case PROPERTY_LOCKED:
703                                 aWindowStateInfo.bLocked = bValue; break;
704                             case PROPERTY_DOCKED:
705                                 aWindowStateInfo.bDocked = bValue; break;
706                             case PROPERTY_VISIBLE:
707                                 aWindowStateInfo.bVisible = bValue; break;
708                             case PROPERTY_CONTEXT:
709                                 aWindowStateInfo.bContext = bValue; break;
710                             case PROPERTY_HIDEFROMMENU:
711                                 aWindowStateInfo.bHideFromMenu = bValue; break;
712                             case PROPERTY_NOCLOSE:
713                                 aWindowStateInfo.bNoClose = bValue; break;
714                             case PROPERTY_SOFTCLOSE:
715                                 aWindowStateInfo.bSoftClose = bValue; break;
716                             case PROPERTY_CONTEXTACTIVE:
717                                 aWindowStateInfo.bContextActive = bValue; break;
718                         }
719                     }
720                 }
721                 break;
722 
723                 case PROPERTY_DOCKINGAREA:
724                 {
725                     sal_Int32 nDockingArea = 0;
726                     if ( a >>= nDockingArea )
727                     {
728                         if (( nDockingArea >= 0 ) &&
729                             ( nDockingArea <= sal_Int32( DockingArea_DOCKINGAREA_RIGHT )))
730                         {
731                             aWindowStateInfo.aDockingArea = (DockingArea)nDockingArea;
732                             nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
733                             a = makeAny( aWindowStateInfo.aDockingArea );
734                             bAddToSeq = true;
735                         }
736                     }
737                 }
738                 break;
739 
740                 case PROPERTY_POS:
741                 case PROPERTY_DOCKPOS:
742                 {
743                     ::rtl::OUString aString;
744                     if ( a >>= aString )
745                     {
746                         sal_Int32 nToken( 0 );
747                         ::rtl::OUString aXStr = aString.getToken( 0, ',', nToken );
748                         if ( nToken > 0 )
749                         {
750                             com::sun::star::awt::Point aPos;
751                             aPos.X = aXStr.toInt32();
752                             aPos.Y = aString.getToken( 0, ',', nToken ).toInt32();
753 
754                             if ( i == PROPERTY_POS )
755                             {
756                                 aWindowStateInfo.aPos = aPos;
757                                 nMask |= WINDOWSTATE_MASK_POS;
758                             }
759                             else
760                             {
761                                 aWindowStateInfo.aDockPos = aPos;
762                                 nMask |= WINDOWSTATE_MASK_DOCKPOS;
763                             }
764 
765                             a <<= aPos;
766                             bAddToSeq = true;
767                         }
768                     }
769                 }
770                 break;
771 
772                 case PROPERTY_SIZE:
773                 case PROPERTY_DOCKSIZE:
774                 {
775                     ::rtl::OUString aString;
776                     if ( a >>= aString )
777                     {
778                         sal_Int32 nToken( 0 );
779                         ::rtl::OUString aStr = aString.getToken( 0, ',', nToken );
780                         if ( nToken > 0 )
781                         {
782                             com::sun::star::awt::Size aSize;
783                             aSize.Width = aStr.toInt32();
784                             aSize.Height = aString.getToken( 0, ',', nToken ).toInt32();
785                             if ( i == PROPERTY_SIZE )
786                             {
787                                 aWindowStateInfo.aSize = aSize;
788                                 nMask |= WINDOWSTATE_MASK_SIZE;
789                             }
790                             else
791                             {
792                                 aWindowStateInfo.aDockSize = aSize;
793                                 nMask |= WINDOWSTATE_MASK_DOCKSIZE;
794                             }
795 
796                             a <<= aSize;
797                             bAddToSeq = true;
798                         }
799                     }
800                 }
801                 break;
802 
803                 case PROPERTY_UINAME:
804                 {
805                     ::rtl::OUString aValue;
806                     if ( a >>= aValue )
807                     {
808                         nMask |= WINDOWSTATE_MASK_UINAME;
809                         aWindowStateInfo.aUIName = aValue;
810                         bAddToSeq = true;
811                     }
812                 }
813                 break;
814 
815                 case PROPERTY_INTERNALSTATE:
816                 {
817                     sal_uInt32 nValue = 0;
818                     if ( a >>= nValue )
819                     {
820                         nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
821                         aWindowStateInfo.nInternalState = nValue;
822                         bAddToSeq = true;
823                     }
824                 }
825                 break;
826 
827                 case PROPERTY_STYLE:
828                 {
829                     sal_Int32 nValue = 0;
830                     if ( a >>= nValue )
831                     {
832                         nMask |= WINDOWSTATE_MASK_STYLE;
833                         aWindowStateInfo.nStyle = sal_uInt16( nValue );
834                         bAddToSeq = true;
835                     }
836                 }
837                 break;
838 
839                 default:
840                     DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
841             }
842 
843             if ( bAddToSeq )
844             {
845                 // put value into the return sequence
846                 nIndex = aPropSeq.getLength();
847                 aPropSeq.realloc( nIndex+1 );
848                 aPropSeq[nIndex].Name  = m_aPropArray[i];
849                 aPropSeq[nIndex].Value = a;
850             }
851         }
852         catch( com::sun::star::container::NoSuchElementException& )
853         {
854         }
855         catch ( com::sun::star::lang::WrappedTargetException& )
856         {
857         }
858     }
859 
860     aWindowStateInfo.nMask = nMask;
861     m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWindowStateInfo ));
862     return makeAny( aPropSeq );
863 }
864 
865 ConfigurationAccess_WindowState::WindowStateInfo& ConfigurationAccess_WindowState::impl_insertCacheAndReturnWinState( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess )
866 {
867     sal_Int32                 nMask( 0 );
868     sal_Int32                 nCount( m_aPropArray.size() );
869     sal_Int32                 i( 0 );
870     Sequence< PropertyValue > aPropSeq;
871     WindowStateInfo           aWindowStateInfo;
872 
873     for ( i = 0; i < nCount; i++ )
874     {
875         try
876         {
877             Any     a( rNameAccess->getByName( m_aPropArray[i] ) );
878             switch ( i )
879             {
880                 case PROPERTY_LOCKED:
881                 case PROPERTY_DOCKED:
882                 case PROPERTY_VISIBLE:
883                 case PROPERTY_CONTEXT:
884                 case PROPERTY_HIDEFROMMENU:
885                 case PROPERTY_NOCLOSE:
886                 case PROPERTY_SOFTCLOSE:
887                 case PROPERTY_CONTEXTACTIVE:
888                 {
889                     sal_Bool bValue = sal_Bool();
890                     if ( a >>= bValue )
891                     {
892                         sal_Int32 nValue( 1 << i );
893                         nMask |= nValue;
894                         switch ( i )
895                         {
896                             case PROPERTY_LOCKED:
897                                 aWindowStateInfo.bLocked = bValue; break;
898                             case PROPERTY_DOCKED:
899                                 aWindowStateInfo.bDocked = bValue; break;
900                             case PROPERTY_VISIBLE:
901                                 aWindowStateInfo.bVisible = bValue; break;
902                             case PROPERTY_CONTEXT:
903                                 aWindowStateInfo.bContext = bValue; break;
904                             case PROPERTY_HIDEFROMMENU:
905                                 aWindowStateInfo.bHideFromMenu = bValue; break;
906                             case PROPERTY_NOCLOSE:
907                                 aWindowStateInfo.bNoClose = bValue; break;
908                             case PROPERTY_SOFTCLOSE:
909                                 aWindowStateInfo.bNoClose = bValue; break;
910                             case PROPERTY_CONTEXTACTIVE:
911                                 aWindowStateInfo.bContextActive = bValue; break;
912                             default:
913                                 DBG_ASSERT( sal_False, "Unknown boolean property in WindowState found!" );
914                         }
915                     }
916                 }
917                 break;
918 
919                 case PROPERTY_DOCKINGAREA:
920                 {
921                     sal_Int32 nDockingArea = 0;
922                     if ( a >>= nDockingArea )
923                     {
924                         if (( nDockingArea >= 0 ) &&
925                             ( nDockingArea <= sal_Int32( DockingArea_DOCKINGAREA_RIGHT )))
926                         {
927                             aWindowStateInfo.aDockingArea = (DockingArea)nDockingArea;
928                             nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
929                         }
930                     }
931                 }
932                 break;
933 
934                 case PROPERTY_POS:
935                 case PROPERTY_DOCKPOS:
936                 {
937                     ::rtl::OUString aString;
938                     if ( a >>= aString )
939                     {
940                         sal_Int32 nToken( 0 );
941                         ::rtl::OUString aXStr = aString.getToken( 0, ',', nToken );
942                         if ( nToken > 0 )
943                         {
944                             com::sun::star::awt::Point aPos;
945                             aPos.X = aXStr.toInt32();
946                             aPos.Y = aString.getToken( 0, ',', nToken ).toInt32();
947 
948                             if ( i == PROPERTY_POS )
949                             {
950                                 aWindowStateInfo.aPos = aPos;
951                                 nMask |= WINDOWSTATE_MASK_POS;
952                             }
953                             else
954                             {
955                                 aWindowStateInfo.aDockPos = aPos;
956                                 nMask |= WINDOWSTATE_MASK_DOCKPOS;
957                             }
958                         }
959                     }
960                 }
961                 break;
962 
963                 case PROPERTY_SIZE:
964                 case PROPERTY_DOCKSIZE:
965                 {
966                     ::rtl::OUString aString;
967                     if ( a >>= aString )
968                     {
969                         sal_Int32 nToken( 0 );
970                         ::rtl::OUString aStr = aString.getToken( 0, ',', nToken );
971                         if ( nToken > 0 )
972                         {
973                             com::sun::star::awt::Size aSize;
974                             aSize.Width  = aStr.toInt32();
975                             aSize.Height = aString.getToken( 0, ',', nToken ).toInt32();
976                             if ( i == PROPERTY_SIZE )
977                             {
978                                 aWindowStateInfo.aSize = aSize;
979                                 nMask |= WINDOWSTATE_MASK_SIZE;
980                             }
981                             else
982                             {
983                                 aWindowStateInfo.aDockSize = aSize;
984                                 nMask |= WINDOWSTATE_MASK_DOCKSIZE;
985                             }
986                         }
987                     }
988                 }
989                 break;
990 
991                 case PROPERTY_UINAME:
992                 {
993                     ::rtl::OUString aValue;
994                     if ( a >>= aValue )
995                     {
996                         nMask |= WINDOWSTATE_MASK_UINAME;
997                         aWindowStateInfo.aUIName = aValue;
998                     }
999                 }
1000                 break;
1001 
1002                 case PROPERTY_INTERNALSTATE:
1003                 {
1004                     sal_Int32 nValue = 0;
1005                     if ( a >>= nValue )
1006                     {
1007                         nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
1008                         aWindowStateInfo.nInternalState = sal_uInt32( nValue );
1009                     }
1010                 }
1011                 break;
1012 
1013                 case PROPERTY_STYLE:
1014                 {
1015                     sal_Int32 nValue = 0;
1016                     if ( a >>= nValue )
1017                     {
1018                         nMask |= WINDOWSTATE_MASK_STYLE;
1019                         aWindowStateInfo.nStyle = sal_uInt16( nValue );
1020                     }
1021                 }
1022 
1023                 default:
1024                     DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
1025             }
1026         }
1027         catch( com::sun::star::container::NoSuchElementException& )
1028         {
1029         }
1030         catch ( com::sun::star::lang::WrappedTargetException& )
1031         {
1032         }
1033     }
1034 
1035     aWindowStateInfo.nMask = nMask;
1036     ResourceURLToInfoCache::iterator pIter = (m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWindowStateInfo ))).first;
1037     return pIter->second;
1038 }
1039 
1040 Any ConfigurationAccess_WindowState::impl_getWindowStateFromResourceURL( const rtl::OUString& rResourceURL )
1041 {
1042     if ( !m_bConfigAccessInitialized )
1043     {
1044         impl_initializeConfigAccess();
1045         m_bConfigAccessInitialized = sal_True;
1046     }
1047 
1048     try
1049     {
1050         // Try to ask our configuration access
1051         if ( m_xConfigAccess.is() && m_xConfigAccess->hasByName( rResourceURL ) )
1052         {
1053 
1054             Reference< XNameAccess > xNameAccess( m_xConfigAccess->getByName( rResourceURL ), UNO_QUERY );
1055             if ( xNameAccess.is() )
1056                 return impl_insertCacheAndReturnSequence( rResourceURL, xNameAccess );
1057         }
1058     }
1059     catch( com::sun::star::container::NoSuchElementException& )
1060     {
1061     }
1062     catch ( com::sun::star::lang::WrappedTargetException& )
1063     {
1064     }
1065 
1066     return Any();
1067 }
1068 
1069 void ConfigurationAccess_WindowState::impl_fillStructFromSequence( WindowStateInfo& rWinStateInfo, const Sequence< PropertyValue >& rSeq )
1070 {
1071     sal_Int32 nCompareCount( m_aPropArray.size() );
1072     sal_Int32 nCount( rSeq.getLength() );
1073     sal_Int32 i( 0 );
1074 
1075     for ( i = 0; i < nCount; i++ )
1076     {
1077         for ( sal_Int32 j = 0; j < nCompareCount; j++ )
1078         {
1079             if ( rSeq[i].Name.equals( m_aPropArray[j] ))
1080             {
1081                 switch ( j )
1082                 {
1083                     case PROPERTY_LOCKED:
1084                     case PROPERTY_DOCKED:
1085                     case PROPERTY_VISIBLE:
1086                     case PROPERTY_CONTEXT:
1087                     case PROPERTY_HIDEFROMMENU:
1088                     case PROPERTY_NOCLOSE:
1089                     case PROPERTY_SOFTCLOSE:
1090                     case PROPERTY_CONTEXTACTIVE:
1091                     {
1092                         sal_Bool bValue = sal_Bool();
1093                         if ( rSeq[i].Value >>= bValue )
1094                         {
1095                             sal_Int32 nValue( 1 << j );
1096                             rWinStateInfo.nMask |= nValue;
1097                             switch ( j )
1098                             {
1099                                 case PROPERTY_LOCKED:
1100                                     rWinStateInfo.bLocked = bValue;
1101                                     break;
1102                                 case PROPERTY_DOCKED:
1103                                     rWinStateInfo.bDocked = bValue;
1104                                     break;
1105                                 case PROPERTY_VISIBLE:
1106                                     rWinStateInfo.bVisible = bValue;
1107                                     break;
1108                                 case PROPERTY_CONTEXT:
1109                                     rWinStateInfo.bContext = bValue;
1110                                     break;
1111                                 case PROPERTY_HIDEFROMMENU:
1112                                     rWinStateInfo.bHideFromMenu = bValue;
1113                                     break;
1114                                 case PROPERTY_NOCLOSE:
1115                                     rWinStateInfo.bNoClose = bValue;
1116                                     break;
1117                                 case PROPERTY_SOFTCLOSE:
1118                                     rWinStateInfo.bSoftClose = bValue;
1119                                     break;
1120                                 case PROPERTY_CONTEXTACTIVE:
1121                                     rWinStateInfo.bContextActive = bValue;
1122                                     break;
1123                                 default:
1124                                     DBG_ASSERT( sal_False, "Unknown boolean property in WindowState found!" );
1125                             }
1126                         }
1127                     }
1128                     break;
1129 
1130                     case PROPERTY_DOCKINGAREA:
1131                     {
1132                         ::com::sun::star::ui::DockingArea eDockingArea;
1133                         if ( rSeq[i].Value >>= eDockingArea )
1134                         {
1135                             rWinStateInfo.aDockingArea = eDockingArea;
1136                             rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
1137                         }
1138                     }
1139                     break;
1140 
1141                     case PROPERTY_POS:
1142                     case PROPERTY_DOCKPOS:
1143                     {
1144                         com::sun::star::awt::Point aPoint;
1145                         if ( rSeq[i].Value >>= aPoint )
1146                         {
1147                             if ( j == PROPERTY_POS )
1148                             {
1149                                 rWinStateInfo.aPos = aPoint;
1150                                 rWinStateInfo.nMask |= WINDOWSTATE_MASK_POS;
1151                             }
1152                             else
1153                             {
1154                                 rWinStateInfo.aDockPos = aPoint;
1155                                 rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKPOS;
1156                             }
1157                         }
1158                     }
1159                     break;
1160 
1161                     case PROPERTY_SIZE:
1162                     case PROPERTY_DOCKSIZE:
1163                     {
1164                         com::sun::star::awt::Size aSize;
1165                         if ( rSeq[i].Value >>= aSize )
1166                         {
1167                             if ( j == PROPERTY_SIZE )
1168                             {
1169                                 rWinStateInfo.aSize = aSize;
1170                                 rWinStateInfo.nMask |= WINDOWSTATE_MASK_SIZE;
1171                             }
1172                             else
1173                             {
1174                                 rWinStateInfo.aDockSize = aSize;
1175                                 rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKSIZE;
1176                             }
1177                         }
1178                     }
1179                     break;
1180 
1181                     case PROPERTY_UINAME:
1182                     {
1183                         ::rtl::OUString aValue;
1184                         if ( rSeq[i].Value >>= aValue )
1185                         {
1186                             rWinStateInfo.aUIName = aValue;
1187                             rWinStateInfo.nMask |= WINDOWSTATE_MASK_UINAME;
1188                         }
1189                     }
1190                     break;
1191 
1192                     case PROPERTY_INTERNALSTATE:
1193                     {
1194                         sal_Int32 nValue = 0;
1195                         if ( rSeq[i].Value >>= nValue )
1196                         {
1197                             rWinStateInfo.nInternalState = sal_uInt32( nValue );
1198                             rWinStateInfo.nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
1199                         }
1200                     }
1201                     break;
1202 
1203                     case PROPERTY_STYLE:
1204                     {
1205                         sal_Int32 nValue = 0;
1206                         if ( rSeq[i].Value >>= nValue )
1207                         {
1208                             rWinStateInfo.nStyle = sal_uInt16( nValue );
1209                             rWinStateInfo.nMask |= WINDOWSTATE_MASK_STYLE;
1210                         }
1211                     }
1212                     break;
1213 
1214                     default:
1215                         DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
1216                 }
1217 
1218                 break;
1219             }
1220         }
1221     }
1222 }
1223 
1224 void ConfigurationAccess_WindowState::impl_putPropertiesFromStruct( const WindowStateInfo& rWinStateInfo, Reference< XPropertySet >& xPropSet )
1225 {
1226     sal_Int32                 i( 0 );
1227     sal_Int32                 nCount( m_aPropArray.size() );
1228     Sequence< PropertyValue > aPropSeq;
1229     ::rtl::OUString                  aDelim( ::rtl::OUString::createFromAscii( "," ));
1230 
1231     for ( i = 0; i < nCount; i++ )
1232     {
1233         if ( rWinStateInfo.nMask & ( 1 << i ))
1234         {
1235             try
1236             {
1237                 // put values into the property set
1238                 switch ( i )
1239                 {
1240                     case PROPERTY_LOCKED:
1241                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bLocked )) ); break;
1242                     case PROPERTY_DOCKED:
1243                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bDocked )) ); break;
1244                     case PROPERTY_VISIBLE:
1245                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bVisible )) ); break;
1246                     case PROPERTY_CONTEXT:
1247                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bContext )) ); break;
1248                     case PROPERTY_HIDEFROMMENU:
1249                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bHideFromMenu )) ); break;
1250                     case PROPERTY_NOCLOSE:
1251                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bNoClose )) ); break;
1252                     case PROPERTY_SOFTCLOSE:
1253                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bSoftClose )) ); break;
1254                     case PROPERTY_CONTEXTACTIVE:
1255                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bContextActive )) ); break;
1256                     case PROPERTY_DOCKINGAREA:
1257                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int16( rWinStateInfo.aDockingArea ) ) ); break;
1258                     case PROPERTY_POS:
1259                     case PROPERTY_DOCKPOS:
1260                     {
1261                         ::rtl::OUString aPosStr;
1262                         if ( i == PROPERTY_POS )
1263                             aPosStr = ::rtl::OUString::valueOf( rWinStateInfo.aPos.X );
1264                         else
1265                             aPosStr = ::rtl::OUString::valueOf( rWinStateInfo.aDockPos.X );
1266                         aPosStr += aDelim;
1267                         if ( i == PROPERTY_POS )
1268                             aPosStr += ::rtl::OUString::valueOf( rWinStateInfo.aPos.Y );
1269                         else
1270                             aPosStr += ::rtl::OUString::valueOf( rWinStateInfo.aDockPos.Y );
1271                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( aPosStr ) );
1272                         break;
1273                     }
1274                     case PROPERTY_SIZE:
1275                     case PROPERTY_DOCKSIZE:
1276                     {
1277                         ::rtl::OUString aSizeStr;
1278                         if ( i == PROPERTY_SIZE )
1279                             aSizeStr = ( ::rtl::OUString::valueOf( rWinStateInfo.aSize.Width ));
1280                         else
1281                             aSizeStr = ( ::rtl::OUString::valueOf( rWinStateInfo.aDockSize.Width ));
1282                         aSizeStr += aDelim;
1283                         if ( i == PROPERTY_SIZE )
1284                             aSizeStr += ::rtl::OUString::valueOf( rWinStateInfo.aSize.Height );
1285                         else
1286                             aSizeStr += ::rtl::OUString::valueOf( rWinStateInfo.aDockSize.Height );
1287                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( aSizeStr ) );
1288                         break;
1289                     }
1290                     case PROPERTY_UINAME:
1291                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( rWinStateInfo.aUIName ) ); break;
1292                     case PROPERTY_INTERNALSTATE:
1293                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int32( rWinStateInfo.nInternalState )) ); break;
1294                     case PROPERTY_STYLE:
1295                         xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int32( rWinStateInfo.nStyle )) ); break;
1296                     default:
1297                         DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
1298                 }
1299             }
1300             catch( Exception& )
1301             {
1302             }
1303         }
1304     }
1305 }
1306 
1307 sal_Bool ConfigurationAccess_WindowState::impl_initializeConfigAccess()
1308 {
1309     Sequence< Any > aArgs( 2 );
1310     PropertyValue   aPropValue;
1311 
1312     try
1313     {
1314         aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
1315         aPropValue.Value <<= m_aConfigWindowAccess;
1316         aArgs[0] <<= aPropValue;
1317         aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lazywrite" ));
1318         aPropValue.Value <<= sal_True;
1319         aArgs[1] <<= aPropValue;
1320 
1321         m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(
1322                                                         SERVICENAME_CFGUPDATEACCESS, aArgs ),
1323                                                     UNO_QUERY );
1324         if ( m_xConfigAccess.is() )
1325         {
1326             // Add as container listener
1327             Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
1328             if ( xContainer.is() )
1329                 xContainer->addContainerListener( this );
1330         }
1331 
1332         return sal_True;
1333     }
1334     catch ( WrappedTargetException& )
1335     {
1336     }
1337     catch ( Exception& )
1338     {
1339     }
1340 
1341     return sal_False;
1342 }
1343 
1344 
1345 //*****************************************************************************************************************
1346 //	XInterface, XTypeProvider, XServiceInfo
1347 //*****************************************************************************************************************
1348 DEFINE_XINTERFACE_4                    (    WindowStateConfiguration                                                            ,
1349                                             OWeakObject                                                                     ,
1350                                             DIRECT_INTERFACE( css::lang::XTypeProvider                                      ),
1351                                             DIRECT_INTERFACE( css::lang::XServiceInfo                                       ),
1352 											DIRECT_INTERFACE( css::container::XNameAccess		                            ),
1353                                             DERIVED_INTERFACE( css::container::XElementAccess, css::container::XNameAccess  )
1354 										)
1355 
1356 DEFINE_XTYPEPROVIDER_4                  (   WindowStateConfiguration		    ,
1357                                             css::lang::XTypeProvider		,
1358                                             css::lang::XServiceInfo			,
1359                                             css::container::XNameAccess     ,
1360 											css::container::XElementAccess
1361 										)
1362 
1363 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   WindowStateConfiguration				    ,
1364                                             ::cppu::OWeakObject						    ,
1365                                             SERVICENAME_WINDOWSTATECONFIGURATION	    ,
1366 											IMPLEMENTATIONNAME_WINDOWSTATECONFIGURATION
1367 										)
1368 
1369 DEFINE_INIT_SERVICE                     (   WindowStateConfiguration, {} )
1370 
1371 WindowStateConfiguration::WindowStateConfiguration( const Reference< XMultiServiceFactory >& xServiceManager ) :
1372     ThreadHelpBase(),
1373     m_xServiceManager( xServiceManager )
1374 {
1375     m_xModuleManager = Reference< XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ),
1376                                                     UNO_QUERY );
1377     Reference< XNameAccess > xEmptyNameAccess;
1378     Reference< XNameAccess > xNameAccess( m_xModuleManager, UNO_QUERY_THROW );
1379     Sequence< rtl::OUString > aElementNames = xNameAccess->getElementNames();
1380     Sequence< PropertyValue > aSeq;
1381     ::rtl::OUString                  aModuleIdentifier;
1382 
1383     for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
1384     {
1385         aModuleIdentifier = aElementNames[i];
1386         if ( xNameAccess->getByName( aModuleIdentifier ) >>= aSeq )
1387         {
1388             ::rtl::OUString aWindowStateFileStr;
1389             for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ )
1390             {
1391                 if ( aSeq[y].Name.equalsAscii("ooSetupFactoryWindowStateConfigRef") )
1392                 {
1393                     aSeq[y].Value >>= aWindowStateFileStr;
1394                     break;
1395                 }
1396             }
1397 
1398             if ( aWindowStateFileStr.getLength() > 0 )
1399             {
1400                 // Create first mapping ModuleIdentifier ==> Window state configuration file
1401                 m_aModuleToFileHashMap.insert( ModuleToWindowStateFileMap::value_type( aModuleIdentifier, aWindowStateFileStr ));
1402 
1403                 // Create second mapping Command File ==> Window state configuration instance
1404                 ModuleToWindowStateConfigHashMap::iterator pIter = m_aModuleToWindowStateHashMap.find( aWindowStateFileStr );
1405                 if ( pIter == m_aModuleToWindowStateHashMap.end() )
1406                     m_aModuleToWindowStateHashMap.insert( ModuleToWindowStateConfigHashMap::value_type( aWindowStateFileStr, xEmptyNameAccess ));
1407             }
1408         }
1409     }
1410 }
1411 
1412 WindowStateConfiguration::~WindowStateConfiguration()
1413 {
1414     ResetableGuard aLock( m_aLock );
1415     m_aModuleToFileHashMap.clear();
1416     m_aModuleToWindowStateHashMap.clear();
1417 }
1418 
1419 Any SAL_CALL WindowStateConfiguration::getByName( const ::rtl::OUString& aModuleIdentifier )
1420 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1421 {
1422     ResetableGuard aLock( m_aLock );
1423 
1424     ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.find( aModuleIdentifier );
1425     if ( pIter != m_aModuleToFileHashMap.end() )
1426     {
1427         Any a;
1428         ::rtl::OUString aWindowStateConfigFile( pIter->second );
1429 
1430         ModuleToWindowStateConfigHashMap::iterator pModuleIter = m_aModuleToWindowStateHashMap.find( aWindowStateConfigFile );
1431         if ( pModuleIter != m_aModuleToWindowStateHashMap.end() )
1432         {
1433             if ( pModuleIter->second.is() )
1434                 a = makeAny( pModuleIter->second );
1435             else
1436             {
1437                 Reference< XNameAccess > xResourceURLWindowState;
1438                 ConfigurationAccess_WindowState* pModuleWindowState = new ConfigurationAccess_WindowState( aWindowStateConfigFile, m_xServiceManager );
1439                 xResourceURLWindowState = Reference< XNameAccess >( static_cast< cppu::OWeakObject* >( pModuleWindowState ),UNO_QUERY );
1440                 pModuleIter->second = xResourceURLWindowState;
1441                 a <<= xResourceURLWindowState;
1442             }
1443 
1444             return a;
1445         }
1446     }
1447 
1448     throw NoSuchElementException();
1449 }
1450 
1451 Sequence< ::rtl::OUString > SAL_CALL WindowStateConfiguration::getElementNames()
1452 throw (::com::sun::star::uno::RuntimeException)
1453 {
1454     ResetableGuard aLock( m_aLock );
1455 
1456     Sequence< rtl::OUString > aSeq( m_aModuleToFileHashMap.size() );
1457 
1458     sal_Int32 n = 0;
1459     ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.begin();
1460     while ( pIter != m_aModuleToFileHashMap.end() )
1461     {
1462         aSeq[n] = pIter->first;
1463         ++pIter;
1464     }
1465 
1466     return aSeq;
1467 }
1468 
1469 sal_Bool SAL_CALL WindowStateConfiguration::hasByName( const ::rtl::OUString& aName )
1470 throw (::com::sun::star::uno::RuntimeException)
1471 {
1472     ResetableGuard aLock( m_aLock );
1473 
1474     ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.find( aName );
1475     return ( pIter != m_aModuleToFileHashMap.end() );
1476 }
1477 
1478 // XElementAccess
1479 Type SAL_CALL WindowStateConfiguration::getElementType()
1480 throw (::com::sun::star::uno::RuntimeException)
1481 {
1482     return( ::getCppuType( (const Reference< XNameAccess >*)NULL ) );
1483 }
1484 
1485 sal_Bool SAL_CALL WindowStateConfiguration::hasElements()
1486 throw (::com::sun::star::uno::RuntimeException)
1487 {
1488     // We always have at least one module. So it is valid to return true!
1489     return sal_True;
1490 }
1491 
1492 } // namespace framework
1493 
1494