1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <uiconfiguration/windowstateproperties.hxx>
21 #include <helper/mischelper.hxx>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/configuration/theDefaultProvider.hpp>
26 #include <com/sun/star/container/XNameAccess.hpp>
27 #include <com/sun/star/container/XNameContainer.hpp>
28 #include <com/sun/star/container/XContainer.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
31 #include <com/sun/star/frame/ModuleManager.hpp>
32 #include <com/sun/star/frame/XModuleManager2.hpp>
33 #include <com/sun/star/awt/Point.hpp>
34 #include <com/sun/star/awt/Size.hpp>
35 #include <com/sun/star/ui/DockingArea.hpp>
36 #include <com/sun/star/util/XChangesBatch.hpp>
37 #include <com/sun/star/uno/XComponentContext.hpp>
39 #include <cppuhelper/basemutex.hxx>
40 #include <cppuhelper/compbase.hxx>
41 #include <cppuhelper/implbase.hxx>
42 #include <cppuhelper/supportsservice.hxx>
43 #include <comphelper/propertysequence.hxx>
44 #include <comphelper/sequence.hxx>
45 #include <sal/log.hxx>
47 #include <unordered_map>
50 using namespace com::sun::star::uno
;
51 using namespace com::sun::star::lang
;
52 using namespace com::sun::star::beans
;
53 using namespace com::sun::star::util
;
54 using namespace com::sun::star::configuration
;
55 using namespace com::sun::star::container
;
56 using namespace ::com::sun::star::frame
;
57 using namespace ::com::sun::star::ui
;
58 using namespace framework
;
62 // Zero based indexes, order must be the same as WindowStateMask && CONFIGURATION_PROPERTIES!
63 static const sal_Int16 PROPERTY_LOCKED
= 0;
64 static const sal_Int16 PROPERTY_DOCKED
= 1;
65 static const sal_Int16 PROPERTY_VISIBLE
= 2;
66 static const sal_Int16 PROPERTY_CONTEXT
= 3;
67 static const sal_Int16 PROPERTY_HIDEFROMMENU
= 4;
68 static const sal_Int16 PROPERTY_NOCLOSE
= 5;
69 static const sal_Int16 PROPERTY_SOFTCLOSE
= 6;
70 static const sal_Int16 PROPERTY_CONTEXTACTIVE
= 7;
71 static const sal_Int16 PROPERTY_DOCKINGAREA
= 8;
72 static const sal_Int16 PROPERTY_POS
= 9;
73 static const sal_Int16 PROPERTY_SIZE
= 10;
74 static const sal_Int16 PROPERTY_UINAME
= 11;
75 static const sal_Int16 PROPERTY_INTERNALSTATE
= 12;
76 static const sal_Int16 PROPERTY_STYLE
= 13;
77 static const sal_Int16 PROPERTY_DOCKPOS
= 14;
78 static const sal_Int16 PROPERTY_DOCKSIZE
= 15;
80 // Order must be the same as WindowStateMask!!
81 static const char* CONFIGURATION_PROPERTIES
[] =
83 WINDOWSTATE_PROPERTY_LOCKED
,
84 WINDOWSTATE_PROPERTY_DOCKED
,
85 WINDOWSTATE_PROPERTY_VISIBLE
,
86 WINDOWSTATE_PROPERTY_CONTEXT
,
87 WINDOWSTATE_PROPERTY_HIDEFROMENU
,
88 WINDOWSTATE_PROPERTY_NOCLOSE
,
89 WINDOWSTATE_PROPERTY_SOFTCLOSE
,
90 WINDOWSTATE_PROPERTY_CONTEXTACTIVE
,
91 WINDOWSTATE_PROPERTY_DOCKINGAREA
,
92 WINDOWSTATE_PROPERTY_POS
,
93 WINDOWSTATE_PROPERTY_SIZE
,
94 WINDOWSTATE_PROPERTY_UINAME
,
95 WINDOWSTATE_PROPERTY_INTERNALSTATE
,
96 WINDOWSTATE_PROPERTY_STYLE
,
97 WINDOWSTATE_PROPERTY_DOCKPOS
,
98 WINDOWSTATE_PROPERTY_DOCKSIZE
,
102 // Configuration access class for WindowState supplier implementation
104 class ConfigurationAccess_WindowState
: public ::cppu::WeakImplHelper
< XNameContainer
, XContainerListener
>
107 ConfigurationAccess_WindowState( const OUString
& aWindowStateConfigFile
, const Reference
< XComponentContext
>& rxContext
);
108 virtual ~ConfigurationAccess_WindowState() override
;
111 virtual css::uno::Any SAL_CALL
getByName( const OUString
& aName
) override
;
113 virtual css::uno::Sequence
< OUString
> SAL_CALL
getElementNames() override
;
115 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
;
118 virtual void SAL_CALL
removeByName( const OUString
& sName
) override
;
120 virtual void SAL_CALL
insertByName( const OUString
& sName
, const css::uno::Any
& aPropertySet
) override
;
123 virtual void SAL_CALL
replaceByName( const OUString
& sName
, const css::uno::Any
& aPropertySet
) override
;
126 virtual css::uno::Type SAL_CALL
getElementType() override
;
128 virtual sal_Bool SAL_CALL
hasElements() override
;
130 // container.XContainerListener
131 virtual void SAL_CALL
elementInserted( const ContainerEvent
& aEvent
) override
;
132 virtual void SAL_CALL
elementRemoved ( const ContainerEvent
& aEvent
) override
;
133 virtual void SAL_CALL
elementReplaced( const ContainerEvent
& aEvent
) override
;
135 // lang.XEventListener
136 virtual void SAL_CALL
disposing( const EventObject
& aEvent
) override
;
141 WINDOWSTATE_MASK_DOCKINGAREA
= 256,
142 WINDOWSTATE_MASK_POS
= 512,
143 WINDOWSTATE_MASK_SIZE
= 1024,
144 WINDOWSTATE_MASK_UINAME
= 2048,
145 WINDOWSTATE_MASK_INTERNALSTATE
= 4096,
146 WINDOWSTATE_MASK_STYLE
= 8192,
147 WINDOWSTATE_MASK_DOCKPOS
= 16384,
148 WINDOWSTATE_MASK_DOCKSIZE
= 32768
151 // Cache structure. Valid values are described by the eMask member. All other values should not be
152 // provided to outside code!
153 struct WindowStateInfo
160 , bHideFromMenu(false)
163 , bContextActive(false)
164 , aDockingArea(css::ui::DockingArea_DOCKINGAREA_TOP
)
182 css::ui::DockingArea aDockingArea
;
183 css::awt::Point aDockPos
;
184 css::awt::Size aDockSize
;
185 css::awt::Point aPos
;
186 css::awt::Size aSize
;
188 sal_uInt32 nInternalState
;
190 sal_uInt32 nMask
; // see WindowStateMask
193 void impl_putPropertiesFromStruct( const WindowStateInfo
& rWinStateInfo
, Reference
< XPropertySet
> const & xPropSet
);
194 Any
impl_insertCacheAndReturnSequence( const OUString
& rResourceURL
, Reference
< XNameAccess
> const & rNameAccess
);
195 WindowStateInfo
& impl_insertCacheAndReturnWinState( const OUString
& rResourceURL
, Reference
< XNameAccess
> const & rNameAccess
);
196 Any
impl_getSequenceFromStruct( const WindowStateInfo
& rWinStateInfo
);
197 void impl_fillStructFromSequence( WindowStateInfo
& rWinStateInfo
, const Sequence
< PropertyValue
>& rSeq
);
198 Any
impl_getWindowStateFromResourceURL( const OUString
& rResourceURL
);
199 void impl_initializeConfigAccess();
202 typedef std::unordered_map
< OUString
,
203 WindowStateInfo
> ResourceURLToInfoCache
;
206 OUString m_aConfigWindowAccess
;
207 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
208 Reference
< XNameAccess
> m_xConfigAccess
;
209 Reference
< XContainerListener
> m_xConfigListener
;
210 ResourceURLToInfoCache m_aResourceURLToInfoCache
;
211 bool m_bConfigAccessInitialized
: 1,
213 std::vector
< OUString
> m_aPropArray
;
216 ConfigurationAccess_WindowState::ConfigurationAccess_WindowState( const OUString
& aModuleName
, const Reference
< XComponentContext
>& rxContext
) :
217 m_aConfigWindowAccess( "/org.openoffice.Office.UI." ),
218 m_bConfigAccessInitialized( false ),
221 // Create configuration hierarchical access name
222 m_aConfigWindowAccess
+= aModuleName
223 + "/UIElements/States";
224 m_xConfigProvider
= theDefaultProvider::get( rxContext
);
226 // Initialize access array with property names.
228 while ( CONFIGURATION_PROPERTIES
[n
] )
230 m_aPropArray
.push_back( OUString::createFromAscii( CONFIGURATION_PROPERTIES
[n
] ));
235 ConfigurationAccess_WindowState::~ConfigurationAccess_WindowState()
238 osl::MutexGuard
g(m_aMutex
);
239 Reference
< XContainer
> xContainer( m_xConfigAccess
, UNO_QUERY
);
240 if ( xContainer
.is() )
241 xContainer
->removeContainerListener(m_xConfigListener
);
245 Any SAL_CALL
ConfigurationAccess_WindowState::getByName( const OUString
& rResourceURL
)
248 osl::MutexGuard
g(m_aMutex
);
250 ResourceURLToInfoCache::const_iterator pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
251 if ( pIter
!= m_aResourceURLToInfoCache
.end() )
252 return impl_getSequenceFromStruct( pIter
->second
);
255 Any
a( impl_getWindowStateFromResourceURL( rResourceURL
) );
257 throw NoSuchElementException();
262 Sequence
< OUString
> SAL_CALL
ConfigurationAccess_WindowState::getElementNames()
265 osl::MutexGuard
g(m_aMutex
);
267 if ( !m_bConfigAccessInitialized
)
269 impl_initializeConfigAccess();
270 m_bConfigAccessInitialized
= true;
273 if ( m_xConfigAccess
.is() )
274 return m_xConfigAccess
->getElementNames();
276 return Sequence
< OUString
> ();
279 sal_Bool SAL_CALL
ConfigurationAccess_WindowState::hasByName( const OUString
& rResourceURL
)
282 osl::MutexGuard
g(m_aMutex
);
284 ResourceURLToInfoCache::const_iterator pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
285 if ( pIter
!= m_aResourceURLToInfoCache
.end() )
289 Any
a( impl_getWindowStateFromResourceURL( rResourceURL
) );
298 Type SAL_CALL
ConfigurationAccess_WindowState::getElementType()
300 return cppu::UnoType
<Sequence
< PropertyValue
>>::get();
303 sal_Bool SAL_CALL
ConfigurationAccess_WindowState::hasElements()
306 osl::MutexGuard
g(m_aMutex
);
308 if ( !m_bConfigAccessInitialized
)
310 impl_initializeConfigAccess();
311 m_bConfigAccessInitialized
= true;
314 if ( m_xConfigAccess
.is() )
315 return m_xConfigAccess
->hasElements();
321 void SAL_CALL
ConfigurationAccess_WindowState::removeByName( const OUString
& rResourceURL
)
324 osl::ClearableMutexGuard
g(m_aMutex
);
326 ResourceURLToInfoCache::iterator pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
327 if ( pIter
!= m_aResourceURLToInfoCache
.end() )
328 m_aResourceURLToInfoCache
.erase( pIter
);
330 if ( !m_bConfigAccessInitialized
)
332 impl_initializeConfigAccess();
333 m_bConfigAccessInitialized
= true;
338 // Remove must be write-through => remove element from configuration
339 Reference
< XNameContainer
> xNameContainer( m_xConfigAccess
, UNO_QUERY
);
340 if ( xNameContainer
.is() )
344 xNameContainer
->removeByName( rResourceURL
);
345 Reference
< XChangesBatch
> xFlush( m_xConfigAccess
, UNO_QUERY
);
347 xFlush
->commitChanges();
350 catch ( const css::lang::WrappedTargetException
& )
355 void SAL_CALL
ConfigurationAccess_WindowState::insertByName( const OUString
& rResourceURL
, const css::uno::Any
& aPropertySet
)
358 osl::ClearableMutexGuard
g(m_aMutex
);
360 Sequence
< PropertyValue
> aPropSet
;
361 if ( !(aPropertySet
>>= aPropSet
) )
362 throw IllegalArgumentException();
364 ResourceURLToInfoCache::const_iterator pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
365 if ( pIter
!= m_aResourceURLToInfoCache
.end() )
366 throw ElementExistException();
368 if ( !m_bConfigAccessInitialized
)
370 impl_initializeConfigAccess();
371 m_bConfigAccessInitialized
= true;
374 // Try to ask our configuration access
375 if ( m_xConfigAccess
.is() )
377 if ( m_xConfigAccess
->hasByName( rResourceURL
) )
378 throw ElementExistException();
380 WindowStateInfo aWinStateInfo
;
381 impl_fillStructFromSequence( aWinStateInfo
, aPropSet
);
382 m_aResourceURLToInfoCache
.emplace( rResourceURL
, aWinStateInfo
);
384 // insert must be write-through => insert element into configuration
385 Reference
< XNameContainer
> xNameContainer( m_xConfigAccess
, UNO_QUERY
);
386 if ( xNameContainer
.is() )
388 Reference
< XSingleServiceFactory
> xFactory( m_xConfigAccess
, UNO_QUERY
);
393 Reference
< XPropertySet
> xPropSet( xFactory
->createInstance(), UNO_QUERY
);
397 impl_putPropertiesFromStruct( aWinStateInfo
, xPropSet
);
399 xNameContainer
->insertByName( rResourceURL
, a
);
400 Reference
< XChangesBatch
> xFlush( xFactory
, UNO_QUERY
);
402 xFlush
->commitChanges();
405 catch ( const Exception
& )
413 void SAL_CALL
ConfigurationAccess_WindowState::replaceByName( const OUString
& rResourceURL
, const css::uno::Any
& aPropertySet
)
416 osl::ClearableMutexGuard
g(m_aMutex
);
418 Sequence
< PropertyValue
> aPropSet
;
419 if ( !(aPropertySet
>>= aPropSet
) )
420 throw IllegalArgumentException();
422 ResourceURLToInfoCache::iterator pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
423 if ( pIter
!= m_aResourceURLToInfoCache
.end() )
425 WindowStateInfo
& rWinStateInfo
= pIter
->second
;
426 impl_fillStructFromSequence( rWinStateInfo
, aPropSet
);
431 if ( !m_bConfigAccessInitialized
)
433 impl_initializeConfigAccess();
434 m_bConfigAccessInitialized
= true;
437 // Try to ask our configuration access
438 Reference
< XNameAccess
> xNameAccess
;
439 Any
a( m_xConfigAccess
->getByName( rResourceURL
));
441 if ( !(a
>>= xNameAccess
) )
442 throw NoSuchElementException();
444 WindowStateInfo
& rWinStateInfo( impl_insertCacheAndReturnWinState( rResourceURL
, xNameAccess
));
445 impl_fillStructFromSequence( rWinStateInfo
, aPropSet
);
447 pIter
= m_aResourceURLToInfoCache
.find( rResourceURL
);
451 if ( m_bModified
&& pIter
!= m_aResourceURLToInfoCache
.end() )
453 Reference
< XNameContainer
> xNameContainer( m_xConfigAccess
, UNO_QUERY
);
454 if ( xNameContainer
.is() )
456 WindowStateInfo
aWinStateInfo( pIter
->second
);
457 OUString
aResourceURL( pIter
->first
);
463 Reference
< XPropertySet
> xPropSet
;
464 if ( xNameContainer
->getByName( aResourceURL
) >>= xPropSet
)
466 impl_putPropertiesFromStruct( aWinStateInfo
, xPropSet
);
468 Reference
< XChangesBatch
> xFlush( m_xConfigAccess
, UNO_QUERY
);
470 xFlush
->commitChanges();
473 catch ( const Exception
& )
481 // container.XContainerListener
482 void SAL_CALL
ConfigurationAccess_WindowState::elementInserted( const ContainerEvent
& )
484 // do nothing - next time someone wants to retrieve this node we will find it in the configuration
487 void SAL_CALL
ConfigurationAccess_WindowState::elementRemoved ( const ContainerEvent
& )
491 void SAL_CALL
ConfigurationAccess_WindowState::elementReplaced( const ContainerEvent
& )
495 // lang.XEventListener
496 void SAL_CALL
ConfigurationAccess_WindowState::disposing( const EventObject
& aEvent
)
499 // remove our reference to the config access
500 osl::MutexGuard
g(m_aMutex
);
502 Reference
< XInterface
> xIfac1( aEvent
.Source
, UNO_QUERY
);
503 Reference
< XInterface
> xIfac2( m_xConfigAccess
, UNO_QUERY
);
504 if ( xIfac1
== xIfac2
)
505 m_xConfigAccess
.clear();
508 // private helper methods
509 Any
ConfigurationAccess_WindowState::impl_getSequenceFromStruct( const WindowStateInfo
& rWinStateInfo
)
512 sal_Int32
nCount( m_aPropArray
.size() );
513 std::vector
< PropertyValue
> aPropVec
;
515 for ( i
= 0; i
< nCount
; i
++ )
517 if ( rWinStateInfo
.nMask
& ( 1 << i
))
519 // put value into the return sequence
521 pv
.Name
= m_aPropArray
[i
];
525 case PROPERTY_LOCKED
:
526 pv
.Value
<<= rWinStateInfo
.bLocked
; break;
527 case PROPERTY_DOCKED
:
528 pv
.Value
<<= rWinStateInfo
.bDocked
; break;
529 case PROPERTY_VISIBLE
:
530 pv
.Value
<<= rWinStateInfo
.bVisible
; break;
531 case PROPERTY_CONTEXT
:
532 pv
.Value
<<= rWinStateInfo
.bContext
; break;
533 case PROPERTY_HIDEFROMMENU
:
534 pv
.Value
<<= rWinStateInfo
.bHideFromMenu
; break;
535 case PROPERTY_NOCLOSE
:
536 pv
.Value
<<= rWinStateInfo
.bNoClose
; break;
537 case PROPERTY_SOFTCLOSE
:
538 pv
.Value
<<= rWinStateInfo
.bSoftClose
; break;
539 case PROPERTY_CONTEXTACTIVE
:
540 pv
.Value
<<= rWinStateInfo
.bContextActive
; break;
541 case PROPERTY_DOCKINGAREA
:
542 pv
.Value
<<= rWinStateInfo
.aDockingArea
; break;
544 pv
.Value
<<= rWinStateInfo
.aPos
; break;
546 pv
.Value
<<= rWinStateInfo
.aSize
; break;
547 case PROPERTY_UINAME
:
548 pv
.Value
<<= rWinStateInfo
.aUIName
; break;
549 case PROPERTY_INTERNALSTATE
:
550 pv
.Value
<<= sal_Int32( rWinStateInfo
.nInternalState
); break;
552 pv
.Value
<<= sal_Int16( rWinStateInfo
.nStyle
); break;
553 case PROPERTY_DOCKPOS
:
554 pv
.Value
<<= rWinStateInfo
.aDockPos
; break;
555 case PROPERTY_DOCKSIZE
:
556 pv
.Value
<<= rWinStateInfo
.aDockSize
; break;
558 assert( false && "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
560 aPropVec
.push_back(pv
);
564 return makeAny( comphelper::containerToSequence(aPropVec
) );
567 Any
ConfigurationAccess_WindowState::impl_insertCacheAndReturnSequence( const OUString
& rResourceURL
, Reference
< XNameAccess
> const & xNameAccess
)
569 sal_Int32
nMask( 0 );
570 sal_Int32
nCount( m_aPropArray
.size() );
572 std::vector
< PropertyValue
> aPropVec
;
573 WindowStateInfo aWindowStateInfo
;
575 for ( i
= 0; i
< nCount
; i
++ )
579 bool bAddToSeq( false );
580 Any
a( xNameAccess
->getByName( m_aPropArray
[i
] ) );
583 case PROPERTY_LOCKED
:
584 case PROPERTY_DOCKED
:
585 case PROPERTY_VISIBLE
:
586 case PROPERTY_CONTEXT
:
587 case PROPERTY_HIDEFROMMENU
:
588 case PROPERTY_NOCLOSE
:
589 case PROPERTY_SOFTCLOSE
:
590 case PROPERTY_CONTEXTACTIVE
:
595 sal_Int32
nValue( 1 << i
);
600 case PROPERTY_LOCKED
:
601 aWindowStateInfo
.bLocked
= bValue
; break;
602 case PROPERTY_DOCKED
:
603 aWindowStateInfo
.bDocked
= bValue
; break;
604 case PROPERTY_VISIBLE
:
605 aWindowStateInfo
.bVisible
= bValue
; break;
606 case PROPERTY_CONTEXT
:
607 aWindowStateInfo
.bContext
= bValue
; break;
608 case PROPERTY_HIDEFROMMENU
:
609 aWindowStateInfo
.bHideFromMenu
= bValue
; break;
610 case PROPERTY_NOCLOSE
:
611 aWindowStateInfo
.bNoClose
= bValue
; break;
612 case PROPERTY_SOFTCLOSE
:
613 aWindowStateInfo
.bSoftClose
= bValue
; break;
614 case PROPERTY_CONTEXTACTIVE
:
615 aWindowStateInfo
.bContextActive
= bValue
; break;
621 case PROPERTY_DOCKINGAREA
:
623 sal_Int32 nDockingArea
= 0;
624 if ( a
>>= nDockingArea
)
626 if (( nDockingArea
>= 0 ) &&
627 ( nDockingArea
<= sal_Int32( DockingArea_DOCKINGAREA_RIGHT
)))
629 aWindowStateInfo
.aDockingArea
= static_cast<DockingArea
>(nDockingArea
);
630 nMask
|= WINDOWSTATE_MASK_DOCKINGAREA
;
631 a
<<= aWindowStateInfo
.aDockingArea
;
639 case PROPERTY_DOCKPOS
:
644 sal_Int32
nToken( 0 );
645 OUString aXStr
= aString
.getToken( 0, ',', nToken
);
648 css::awt::Point aPos
;
649 aPos
.X
= aXStr
.toInt32();
650 aPos
.Y
= aString
.getToken( 0, ',', nToken
).toInt32();
652 if ( i
== PROPERTY_POS
)
654 aWindowStateInfo
.aPos
= aPos
;
655 nMask
|= WINDOWSTATE_MASK_POS
;
659 aWindowStateInfo
.aDockPos
= aPos
;
660 nMask
|= WINDOWSTATE_MASK_DOCKPOS
;
671 case PROPERTY_DOCKSIZE
:
676 sal_Int32
nToken( 0 );
677 OUString aStr
= aString
.getToken( 0, ',', nToken
);
680 css::awt::Size aSize
;
681 aSize
.Width
= aStr
.toInt32();
682 aSize
.Height
= aString
.getToken( 0, ',', nToken
).toInt32();
683 if ( i
== PROPERTY_SIZE
)
685 aWindowStateInfo
.aSize
= aSize
;
686 nMask
|= WINDOWSTATE_MASK_SIZE
;
690 aWindowStateInfo
.aDockSize
= aSize
;
691 nMask
|= WINDOWSTATE_MASK_DOCKSIZE
;
701 case PROPERTY_UINAME
:
706 nMask
|= WINDOWSTATE_MASK_UINAME
;
707 aWindowStateInfo
.aUIName
= aValue
;
713 case PROPERTY_INTERNALSTATE
:
715 sal_uInt32 nValue
= 0;
718 nMask
|= WINDOWSTATE_MASK_INTERNALSTATE
;
719 aWindowStateInfo
.nInternalState
= nValue
;
727 sal_Int32 nValue
= 0;
730 nMask
|= WINDOWSTATE_MASK_STYLE
;
731 aWindowStateInfo
.nStyle
= sal_uInt16( nValue
);
738 assert( false && "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
743 // put value into the return sequence
745 pv
.Name
= m_aPropArray
[i
];
747 aPropVec
.push_back(pv
);
750 catch( const css::container::NoSuchElementException
& )
753 catch ( const css::lang::WrappedTargetException
& )
758 aWindowStateInfo
.nMask
= nMask
;
759 m_aResourceURLToInfoCache
.emplace( rResourceURL
, aWindowStateInfo
);
760 return makeAny( comphelper::containerToSequence(aPropVec
) );
763 ConfigurationAccess_WindowState::WindowStateInfo
& ConfigurationAccess_WindowState::impl_insertCacheAndReturnWinState( const OUString
& rResourceURL
, Reference
< XNameAccess
> const & rNameAccess
)
765 sal_Int32
nMask( 0 );
766 sal_Int32
nCount( m_aPropArray
.size() );
768 WindowStateInfo aWindowStateInfo
;
770 for ( i
= 0; i
< nCount
; i
++ )
774 Any
a( rNameAccess
->getByName( m_aPropArray
[i
] ) );
777 case PROPERTY_LOCKED
:
778 case PROPERTY_DOCKED
:
779 case PROPERTY_VISIBLE
:
780 case PROPERTY_CONTEXT
:
781 case PROPERTY_HIDEFROMMENU
:
782 case PROPERTY_NOCLOSE
:
783 case PROPERTY_SOFTCLOSE
:
784 case PROPERTY_CONTEXTACTIVE
:
789 sal_Int32
nValue( 1 << i
);
793 case PROPERTY_LOCKED
:
794 aWindowStateInfo
.bLocked
= bValue
; break;
795 case PROPERTY_DOCKED
:
796 aWindowStateInfo
.bDocked
= bValue
; break;
797 case PROPERTY_VISIBLE
:
798 aWindowStateInfo
.bVisible
= bValue
; break;
799 case PROPERTY_CONTEXT
:
800 aWindowStateInfo
.bContext
= bValue
; break;
801 case PROPERTY_HIDEFROMMENU
:
802 aWindowStateInfo
.bHideFromMenu
= bValue
; break;
803 case PROPERTY_NOCLOSE
:
804 aWindowStateInfo
.bNoClose
= bValue
; break;
805 case PROPERTY_SOFTCLOSE
:
806 aWindowStateInfo
.bNoClose
= bValue
; break;
807 case PROPERTY_CONTEXTACTIVE
:
808 aWindowStateInfo
.bContextActive
= bValue
; break;
810 SAL_WARN( "fwk.uiconfiguration", "Unknown boolean property in WindowState found!" );
816 case PROPERTY_DOCKINGAREA
:
818 sal_Int32 nDockingArea
= 0;
819 if ( a
>>= nDockingArea
)
821 if (( nDockingArea
>= 0 ) &&
822 ( nDockingArea
<= sal_Int32( DockingArea_DOCKINGAREA_RIGHT
)))
824 aWindowStateInfo
.aDockingArea
= static_cast<DockingArea
>(nDockingArea
);
825 nMask
|= WINDOWSTATE_MASK_DOCKINGAREA
;
832 case PROPERTY_DOCKPOS
:
837 sal_Int32
nToken( 0 );
838 OUString aXStr
= aString
.getToken( 0, ',', nToken
);
841 css::awt::Point aPos
;
842 aPos
.X
= aXStr
.toInt32();
843 aPos
.Y
= aString
.getToken( 0, ',', nToken
).toInt32();
845 if ( i
== PROPERTY_POS
)
847 aWindowStateInfo
.aPos
= aPos
;
848 nMask
|= WINDOWSTATE_MASK_POS
;
852 aWindowStateInfo
.aDockPos
= aPos
;
853 nMask
|= WINDOWSTATE_MASK_DOCKPOS
;
861 case PROPERTY_DOCKSIZE
:
866 sal_Int32
nToken( 0 );
867 OUString aStr
= aString
.getToken( 0, ',', nToken
);
870 css::awt::Size aSize
;
871 aSize
.Width
= aStr
.toInt32();
872 aSize
.Height
= aString
.getToken( 0, ',', nToken
).toInt32();
873 if ( i
== PROPERTY_SIZE
)
875 aWindowStateInfo
.aSize
= aSize
;
876 nMask
|= WINDOWSTATE_MASK_SIZE
;
880 aWindowStateInfo
.aDockSize
= aSize
;
881 nMask
|= WINDOWSTATE_MASK_DOCKSIZE
;
888 case PROPERTY_UINAME
:
893 nMask
|= WINDOWSTATE_MASK_UINAME
;
894 aWindowStateInfo
.aUIName
= aValue
;
899 case PROPERTY_INTERNALSTATE
:
901 sal_Int32 nValue
= 0;
904 nMask
|= WINDOWSTATE_MASK_INTERNALSTATE
;
905 aWindowStateInfo
.nInternalState
= sal_uInt32( nValue
);
912 sal_Int32 nValue
= 0;
915 nMask
|= WINDOWSTATE_MASK_STYLE
;
916 aWindowStateInfo
.nStyle
= sal_uInt16( nValue
);
922 assert( false && "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
925 catch( const css::container::NoSuchElementException
& )
928 catch ( const css::lang::WrappedTargetException
& )
933 aWindowStateInfo
.nMask
= nMask
;
934 ResourceURLToInfoCache::iterator pIter
= m_aResourceURLToInfoCache
.emplace( rResourceURL
, aWindowStateInfo
).first
;
935 return pIter
->second
;
938 Any
ConfigurationAccess_WindowState::impl_getWindowStateFromResourceURL( const OUString
& rResourceURL
)
940 if ( !m_bConfigAccessInitialized
)
942 impl_initializeConfigAccess();
943 m_bConfigAccessInitialized
= true;
948 // Try to ask our configuration access
949 if ( m_xConfigAccess
.is() && m_xConfigAccess
->hasByName( rResourceURL
) )
952 Reference
< XNameAccess
> xNameAccess( m_xConfigAccess
->getByName( rResourceURL
), UNO_QUERY
);
953 if ( xNameAccess
.is() )
954 return impl_insertCacheAndReturnSequence( rResourceURL
, xNameAccess
);
957 catch( const css::container::NoSuchElementException
& )
960 catch ( const css::lang::WrappedTargetException
& )
967 void ConfigurationAccess_WindowState::impl_fillStructFromSequence( WindowStateInfo
& rWinStateInfo
, const Sequence
< PropertyValue
>& rSeq
)
969 sal_Int32
nCompareCount( m_aPropArray
.size() );
970 sal_Int32
nCount( rSeq
.getLength() );
973 for ( i
= 0; i
< nCount
; i
++ )
975 for ( sal_Int32 j
= 0; j
< nCompareCount
; j
++ )
977 if ( rSeq
[i
].Name
== m_aPropArray
[j
] )
981 case PROPERTY_LOCKED
:
982 case PROPERTY_DOCKED
:
983 case PROPERTY_VISIBLE
:
984 case PROPERTY_CONTEXT
:
985 case PROPERTY_HIDEFROMMENU
:
986 case PROPERTY_NOCLOSE
:
987 case PROPERTY_SOFTCLOSE
:
988 case PROPERTY_CONTEXTACTIVE
:
991 if ( rSeq
[i
].Value
>>= bValue
)
993 sal_Int32
nValue( 1 << j
);
994 rWinStateInfo
.nMask
|= nValue
;
997 case PROPERTY_LOCKED
:
998 rWinStateInfo
.bLocked
= bValue
;
1000 case PROPERTY_DOCKED
:
1001 rWinStateInfo
.bDocked
= bValue
;
1003 case PROPERTY_VISIBLE
:
1004 rWinStateInfo
.bVisible
= bValue
;
1006 case PROPERTY_CONTEXT
:
1007 rWinStateInfo
.bContext
= bValue
;
1009 case PROPERTY_HIDEFROMMENU
:
1010 rWinStateInfo
.bHideFromMenu
= bValue
;
1012 case PROPERTY_NOCLOSE
:
1013 rWinStateInfo
.bNoClose
= bValue
;
1015 case PROPERTY_SOFTCLOSE
:
1016 rWinStateInfo
.bSoftClose
= bValue
;
1018 case PROPERTY_CONTEXTACTIVE
:
1019 rWinStateInfo
.bContextActive
= bValue
;
1026 case PROPERTY_DOCKINGAREA
:
1028 css::ui::DockingArea eDockingArea
;
1029 if ( rSeq
[i
].Value
>>= eDockingArea
)
1031 rWinStateInfo
.aDockingArea
= eDockingArea
;
1032 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_DOCKINGAREA
;
1038 case PROPERTY_DOCKPOS
:
1040 css::awt::Point aPoint
;
1041 if ( rSeq
[i
].Value
>>= aPoint
)
1043 if ( j
== PROPERTY_POS
)
1045 rWinStateInfo
.aPos
= aPoint
;
1046 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_POS
;
1050 rWinStateInfo
.aDockPos
= aPoint
;
1051 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_DOCKPOS
;
1058 case PROPERTY_DOCKSIZE
:
1060 css::awt::Size aSize
;
1061 if ( rSeq
[i
].Value
>>= aSize
)
1063 if ( j
== PROPERTY_SIZE
)
1065 rWinStateInfo
.aSize
= aSize
;
1066 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_SIZE
;
1070 rWinStateInfo
.aDockSize
= aSize
;
1071 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_DOCKSIZE
;
1077 case PROPERTY_UINAME
:
1080 if ( rSeq
[i
].Value
>>= aValue
)
1082 rWinStateInfo
.aUIName
= aValue
;
1083 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_UINAME
;
1088 case PROPERTY_INTERNALSTATE
:
1090 sal_Int32 nValue
= 0;
1091 if ( rSeq
[i
].Value
>>= nValue
)
1093 rWinStateInfo
.nInternalState
= sal_uInt32( nValue
);
1094 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_INTERNALSTATE
;
1099 case PROPERTY_STYLE
:
1101 sal_Int32 nValue
= 0;
1102 if ( rSeq
[i
].Value
>>= nValue
)
1104 rWinStateInfo
.nStyle
= sal_uInt16( nValue
);
1105 rWinStateInfo
.nMask
|= WINDOWSTATE_MASK_STYLE
;
1111 assert( false && "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
1120 void ConfigurationAccess_WindowState::impl_putPropertiesFromStruct( const WindowStateInfo
& rWinStateInfo
, Reference
< XPropertySet
> const & xPropSet
)
1123 sal_Int32
nCount( m_aPropArray
.size() );
1124 OUString
aDelim( "," );
1126 for ( i
= 0; i
< nCount
; i
++ )
1128 if ( rWinStateInfo
.nMask
& ( 1 << i
))
1132 // put values into the property set
1135 case PROPERTY_LOCKED
:
1136 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bLocked
) ); break;
1137 case PROPERTY_DOCKED
:
1138 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bDocked
) ); break;
1139 case PROPERTY_VISIBLE
:
1140 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bVisible
) ); break;
1141 case PROPERTY_CONTEXT
:
1142 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bContext
) ); break;
1143 case PROPERTY_HIDEFROMMENU
:
1144 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bHideFromMenu
) ); break;
1145 case PROPERTY_NOCLOSE
:
1146 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bNoClose
) ); break;
1147 case PROPERTY_SOFTCLOSE
:
1148 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bSoftClose
) ); break;
1149 case PROPERTY_CONTEXTACTIVE
:
1150 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.bContextActive
) ); break;
1151 case PROPERTY_DOCKINGAREA
:
1152 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( sal_Int16( rWinStateInfo
.aDockingArea
) ) ); break;
1154 case PROPERTY_DOCKPOS
:
1157 if ( i
== PROPERTY_POS
)
1158 aPosStr
= OUString::number( rWinStateInfo
.aPos
.X
);
1160 aPosStr
= OUString::number( rWinStateInfo
.aDockPos
.X
);
1162 if ( i
== PROPERTY_POS
)
1163 aPosStr
+= OUString::number( rWinStateInfo
.aPos
.Y
);
1165 aPosStr
+= OUString::number( rWinStateInfo
.aDockPos
.Y
);
1166 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( aPosStr
) );
1170 case PROPERTY_DOCKSIZE
:
1173 if ( i
== PROPERTY_SIZE
)
1174 aSizeStr
= OUString::number( rWinStateInfo
.aSize
.Width
);
1176 aSizeStr
= OUString::number( rWinStateInfo
.aDockSize
.Width
);
1178 if ( i
== PROPERTY_SIZE
)
1179 aSizeStr
+= OUString::number( rWinStateInfo
.aSize
.Height
);
1181 aSizeStr
+= OUString::number( rWinStateInfo
.aDockSize
.Height
);
1182 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( aSizeStr
) );
1185 case PROPERTY_UINAME
:
1186 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( rWinStateInfo
.aUIName
) ); break;
1187 case PROPERTY_INTERNALSTATE
:
1188 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( sal_Int32( rWinStateInfo
.nInternalState
)) ); break;
1189 case PROPERTY_STYLE
:
1190 xPropSet
->setPropertyValue( m_aPropArray
[i
], makeAny( sal_Int32( rWinStateInfo
.nStyle
)) ); break;
1192 assert( false && "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
1195 catch( const Exception
& )
1202 void ConfigurationAccess_WindowState::impl_initializeConfigAccess()
1206 Sequence
<Any
> aArgs(comphelper::InitAnyPropertySequence(
1208 {"nodepath", Any(m_aConfigWindowAccess
)}
1210 m_xConfigAccess
.set( m_xConfigProvider
->createInstanceWithArguments(
1211 "com.sun.star.configuration.ConfigurationUpdateAccess", aArgs
), UNO_QUERY
);
1212 if ( m_xConfigAccess
.is() )
1214 // Add as container listener
1215 Reference
< XContainer
> xContainer( m_xConfigAccess
, UNO_QUERY
);
1216 if ( xContainer
.is() )
1218 m_xConfigListener
= new WeakContainerListener(this);
1219 xContainer
->addContainerListener(m_xConfigListener
);
1223 catch ( const WrappedTargetException
& )
1226 catch ( const Exception
& )
1231 typedef ::cppu::WeakComponentImplHelper
< css::container::XNameAccess
,
1232 css::lang::XServiceInfo
> WindowStateConfiguration_BASE
;
1234 class WindowStateConfiguration
: private cppu::BaseMutex
,
1235 public WindowStateConfiguration_BASE
1238 explicit WindowStateConfiguration( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
);
1239 virtual ~WindowStateConfiguration() override
;
1241 virtual OUString SAL_CALL
getImplementationName() override
1243 return "com.sun.star.comp.framework.WindowStateConfiguration";
1246 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
1248 return cppu::supportsService(this, ServiceName
);
1251 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
1253 return {"com.sun.star.ui.WindowStateConfiguration"};
1257 virtual css::uno::Any SAL_CALL
getByName( const OUString
& aName
) override
;
1259 virtual css::uno::Sequence
< OUString
> SAL_CALL
getElementNames() override
;
1261 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
;
1264 virtual css::uno::Type SAL_CALL
getElementType() override
;
1265 virtual sal_Bool SAL_CALL
hasElements() override
;
1267 typedef std::unordered_map
< OUString
,
1268 OUString
> ModuleToWindowStateFileMap
;
1270 typedef std::unordered_map
< OUString
,
1271 css::uno::Reference
< css::container::XNameAccess
> > ModuleToWindowStateConfigHashMap
;
1274 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
1275 ModuleToWindowStateFileMap m_aModuleToFileHashMap
;
1276 ModuleToWindowStateConfigHashMap m_aModuleToWindowStateHashMap
;
1279 WindowStateConfiguration::WindowStateConfiguration( const Reference
< XComponentContext
>& rxContext
) :
1280 WindowStateConfiguration_BASE(m_aMutex
),
1281 m_xContext( rxContext
)
1283 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager
=
1284 ModuleManager::create( m_xContext
);
1285 Reference
< XNameAccess
> xEmptyNameAccess
;
1286 Sequence
< OUString
> aElementNames
;
1289 aElementNames
= xModuleManager
->getElementNames();
1291 catch (const css::uno::RuntimeException
&)
1294 Sequence
< PropertyValue
> aSeq
;
1295 OUString aModuleIdentifier
;
1297 for ( sal_Int32 i
= 0; i
< aElementNames
.getLength(); i
++ )
1299 aModuleIdentifier
= aElementNames
[i
];
1300 if ( xModuleManager
->getByName( aModuleIdentifier
) >>= aSeq
)
1302 OUString aWindowStateFileStr
;
1303 for ( sal_Int32 y
= 0; y
< aSeq
.getLength(); y
++ )
1305 if ( aSeq
[y
].Name
== "ooSetupFactoryWindowStateConfigRef" )
1307 aSeq
[y
].Value
>>= aWindowStateFileStr
;
1312 if ( !aWindowStateFileStr
.isEmpty() )
1314 // Create first mapping ModuleIdentifier ==> Window state configuration file
1315 m_aModuleToFileHashMap
.emplace( aModuleIdentifier
, aWindowStateFileStr
);
1317 // Create second mapping Command File ==> Window state configuration instance
1318 ModuleToWindowStateConfigHashMap::iterator pIter
= m_aModuleToWindowStateHashMap
.find( aWindowStateFileStr
);
1319 if ( pIter
== m_aModuleToWindowStateHashMap
.end() )
1320 m_aModuleToWindowStateHashMap
.emplace( aWindowStateFileStr
, xEmptyNameAccess
);
1326 WindowStateConfiguration::~WindowStateConfiguration()
1328 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1329 m_aModuleToFileHashMap
.clear();
1330 m_aModuleToWindowStateHashMap
.clear();
1333 Any SAL_CALL
WindowStateConfiguration::getByName( const OUString
& aModuleIdentifier
)
1335 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1337 ModuleToWindowStateFileMap::const_iterator pIter
= m_aModuleToFileHashMap
.find( aModuleIdentifier
);
1338 if ( pIter
!= m_aModuleToFileHashMap
.end() )
1341 OUString
aWindowStateConfigFile( pIter
->second
);
1343 ModuleToWindowStateConfigHashMap::iterator pModuleIter
= m_aModuleToWindowStateHashMap
.find( aWindowStateConfigFile
);
1344 if ( pModuleIter
!= m_aModuleToWindowStateHashMap
.end() )
1346 if ( pModuleIter
->second
.is() )
1347 a
<<= pModuleIter
->second
;
1350 Reference
< XNameAccess
> xResourceURLWindowState
;
1351 ConfigurationAccess_WindowState
* pModuleWindowState
= new ConfigurationAccess_WindowState( aWindowStateConfigFile
, m_xContext
);
1352 xResourceURLWindowState
.set( static_cast< cppu::OWeakObject
* >( pModuleWindowState
),UNO_QUERY
);
1353 pModuleIter
->second
= xResourceURLWindowState
;
1354 a
<<= xResourceURLWindowState
;
1361 throw NoSuchElementException();
1364 Sequence
< OUString
> SAL_CALL
WindowStateConfiguration::getElementNames()
1366 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1368 return comphelper::mapKeysToSequence( m_aModuleToFileHashMap
);
1371 sal_Bool SAL_CALL
WindowStateConfiguration::hasByName( const OUString
& aName
)
1373 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1375 ModuleToWindowStateFileMap::const_iterator pIter
= m_aModuleToFileHashMap
.find( aName
);
1376 return ( pIter
!= m_aModuleToFileHashMap
.end() );
1380 Type SAL_CALL
WindowStateConfiguration::getElementType()
1382 return cppu::UnoType
<XNameAccess
>::get();
1385 sal_Bool SAL_CALL
WindowStateConfiguration::hasElements()
1387 // We always have at least one module. So it is valid to return true!
1393 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
1394 instance(static_cast<cppu::OWeakObject
*>(
1395 new WindowStateConfiguration(context
)))
1399 css::uno::Reference
<css::uno::XInterface
> instance
;
1403 public rtl::StaticWithArg
<
1404 Instance
, css::uno::Reference
<css::uno::XComponentContext
>, Singleton
>
1409 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1410 com_sun_star_comp_framework_WindowStateConfiguration_get_implementation(
1411 css::uno::XComponentContext
*context
,
1412 css::uno::Sequence
<css::uno::Any
> const &)
1414 return cppu::acquire(static_cast<cppu::OWeakObject
*>(
1415 Singleton::get(context
).instance
.get()));
1418 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */