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