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