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 <sal/config.h>
22 #include <com/sun/star/awt/XControlContainer.hpp>
23 #include <com/sun/star/awt/WindowAttribute.hpp>
24 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
25 #include <com/sun/star/awt/PosSize.hpp>
26 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/beans/XMultiPropertySet.hpp>
29 #include <com/sun/star/lang/NoSupportException.hpp>
30 #include <com/sun/star/resource/XStringResourceResolver.hpp>
31 #include <toolkit/controls/unocontrol.hxx>
32 #include <toolkit/helper/vclunohelper.hxx>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <osl/mutex.hxx>
35 #include <tools/debug.hxx>
36 #include <comphelper/diagnose_ex.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/window.hxx>
39 #include <helper/property.hxx>
40 #include <toolkit/awt/vclxwindow.hxx>
41 #include <controls/accessiblecontrolcontext.hxx>
45 #include <string_view>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star::awt
;
51 using namespace ::com::sun::star::beans
;
52 using namespace ::com::sun::star::lang
;
53 using namespace ::com::sun::star::util
;
55 using ::com::sun::star::accessibility::XAccessibleContext
;
56 using ::com::sun::star::accessibility::XAccessible
;
60 struct LanguageDependentProp
62 const char* pPropName
;
63 sal_Int32 nPropNameLength
;
68 const LanguageDependentProp aLanguageDependentProp
[] =
74 { "CurrencySymbol", 14 },
75 { "StringItemList", 14 },
79 static Sequence
< OUString
> lcl_ImplGetPropertyNames( const Reference
< XMultiPropertySet
> & rxModel
)
81 Sequence
< OUString
> aNames
;
82 Reference
< XPropertySetInfo
> xPSInf
= rxModel
->getPropertySetInfo();
83 DBG_ASSERT( xPSInf
.is(), "UpdateFromModel: No PropertySetInfo!" );
86 const Sequence
< Property
> aProps
= xPSInf
->getProperties();
87 sal_Int32 nLen
= aProps
.getLength();
88 aNames
= Sequence
< OUString
>( nLen
);
89 std::transform(aProps
.begin(), aProps
.end(), aNames
.getArray(),
90 [](const Property
& rProp
) -> OUString
{ return rProp
.Name
; });
100 VCLXWindow
* m_pLockWindow
;
103 explicit VclListenerLock( VCLXWindow
* _pLockWindow
)
104 : m_pLockWindow( _pLockWindow
)
107 m_pLockWindow
->suspendVclEventListening( );
112 m_pLockWindow
->resumeVclEventListening( );
114 VclListenerLock(const VclListenerLock
&) = delete;
115 VclListenerLock
& operator=(const VclListenerLock
&) = delete;
120 typedef ::std::map
< OUString
, sal_Int32
> MapString2Int
;
121 struct UnoControl_Data
123 MapString2Int aSuspendedPropertyNotifications
;
124 /// true if and only if our model has a property ResourceResolver
125 bool bLocalizationSupport
;
128 :bLocalizationSupport( false )
133 UnoControl::UnoControl() :
134 maDisposeListeners( *this )
135 , maWindowListeners( *this )
136 , maFocusListeners( *this )
137 , maKeyListeners( *this )
138 , maMouseListeners( *this )
139 , maMouseMotionListeners( *this )
140 , maPaintListeners( *this )
141 , maModeChangeListeners( GetMutex() )
142 , mpData( new UnoControl_Data
)
144 mbDisposePeer
= true;
145 mbRefreshingPeer
= false;
146 mbCreatingPeer
= false;
147 mbCreatingCompatiblePeer
= false;
148 mbDesignMode
= false;
151 UnoControl::~UnoControl()
155 OUString
UnoControl::GetComponentServiceName() const
160 Reference
< XVclWindowPeer
> UnoControl::ImplGetCompatiblePeer()
162 DBG_ASSERT( !mbCreatingCompatiblePeer
, "ImplGetCompatiblePeer - recursive?" );
164 mbCreatingCompatiblePeer
= true;
166 Reference
< XVclWindowPeer
> xCompatiblePeer
= getVclWindowPeer();
168 if ( !xCompatiblePeer
.is() )
170 // Create the pair as invisible
171 bool bVis
= maComponentInfos
.bVisible
;
173 maComponentInfos
.bVisible
= false;
175 Reference
< XVclWindowPeer
> xCurrentPeer
= getVclWindowPeer();
178 // queryInterface ourself, to allow aggregation
179 Reference
< XControl
> xMe
;
180 OWeakAggObject::queryInterface( cppu::UnoType
<decltype(xMe
)>::get() ) >>= xMe
;
182 vcl::Window
* pParentWindow( nullptr );
184 SolarMutexGuard aGuard
;
185 auto pDefaultDevice
= Application::GetDefaultDevice();
187 pParentWindow
= pDefaultDevice
->GetOwnerWindow();
188 ENSURE_OR_THROW( pParentWindow
!= nullptr, "could obtain a default parent window!" );
192 xMe
->createPeer( nullptr, pParentWindow
->GetComponentInterface() );
194 catch( const Exception
& )
196 mbCreatingCompatiblePeer
= false;
199 xCompatiblePeer
= getVclWindowPeer();
200 setPeer( xCurrentPeer
);
202 if ( xCompatiblePeer
.is() && mxGraphics
.is() )
204 Reference
< XView
> xPeerView( xCompatiblePeer
, UNO_QUERY
);
205 if ( xPeerView
.is() )
206 xPeerView
->setGraphics( mxGraphics
);
210 maComponentInfos
.bVisible
= true;
213 mbCreatingCompatiblePeer
= false;
215 return xCompatiblePeer
;
218 bool UnoControl::ImplCheckLocalize( OUString
& _rPossiblyLocalizable
)
220 if ( !mpData
->bLocalizationSupport
221 || ( _rPossiblyLocalizable
.isEmpty() )
222 || ( _rPossiblyLocalizable
[0] != '&' )
223 // TODO: make this reasonable. At the moment, everything which by accident starts with a & is considered
224 // localizable, which is probably wrong.
230 Reference
< XPropertySet
> xPropSet( mxModel
, UNO_QUERY_THROW
);
231 Reference
< resource::XStringResourceResolver
> xStringResourceResolver(
232 xPropSet
->getPropertyValue("ResourceResolver"),
235 if ( xStringResourceResolver
.is() )
237 OUString
aLocalizationKey( _rPossiblyLocalizable
.copy( 1 ) );
238 _rPossiblyLocalizable
= xStringResourceResolver
->resolveString( aLocalizationKey
);
242 catch( const Exception
& )
244 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
249 void UnoControl::ImplSetPeerProperty( const OUString
& rPropName
, const Any
& rVal
)
251 // since a change made in propertiesChange, we can't be sure that this is called with a valid getPeer(),
252 // this assumption may be false in some (seldom) multi-threading scenarios (cause propertiesChange
253 // releases our mutex before calling here in)
254 // That's why this additional check
256 if ( !mxVclWindowPeer
.is() )
259 Any
aConvertedValue( rVal
);
261 if ( mpData
->bLocalizationSupport
)
263 // We now support a mapping for language dependent properties. This is the
264 // central method to implement it.
265 if( rPropName
== "Text" ||
266 rPropName
== "Label" ||
267 rPropName
== "Title" ||
268 rPropName
== "HelpText" ||
269 rPropName
== "CurrencySymbol" ||
270 rPropName
== "StringItemList" )
273 uno::Sequence
< OUString
> aSeqValue
;
274 if ( aConvertedValue
>>= aValue
)
276 if ( ImplCheckLocalize( aValue
) )
277 aConvertedValue
<<= aValue
;
279 else if ( aConvertedValue
>>= aSeqValue
)
281 for ( auto& rValue
: asNonConstRange(aSeqValue
) )
282 ImplCheckLocalize( rValue
);
283 aConvertedValue
<<= aSeqValue
;
288 mxVclWindowPeer
->setProperty( rPropName
, aConvertedValue
);
291 void UnoControl::PrepareWindowDescriptor( WindowDescriptor
& )
295 Reference
< XWindow
> UnoControl::getParentPeer() const
297 Reference
< XWindow
> xPeer
;
300 Reference
< XControl
> xContComp( mxContext
, UNO_QUERY
);
301 if ( xContComp
.is() )
303 Reference
< XWindowPeer
> xP
= xContComp
->getPeer();
305 xPeer
.set( xP
, UNO_QUERY
);
311 void UnoControl::updateFromModel()
313 // Read default properties and hand over to peer
316 Reference
< XMultiPropertySet
> xPropSet( mxModel
, UNO_QUERY
);
319 Sequence
< OUString
> aNames
= lcl_ImplGetPropertyNames( xPropSet
);
320 xPropSet
->firePropertiesChangeEvent( aNames
, this );
327 IMPL_IMPLEMENTATION_ID( UnoControl
)
330 UnoControl::DisposeAccessibleContext(Reference
<XComponent
> const& xContextComp
)
332 if (xContextComp
.is())
336 xContextComp
->removeEventListener( this );
337 xContextComp
->dispose();
339 catch( const Exception
& )
341 OSL_FAIL( "UnoControl::disposeAccessibleContext: could not dispose my AccessibleContext!" );
346 void UnoControl::dispose( )
348 Reference
< XVclWindowPeer
> xPeer
;
349 Reference
<XComponent
> xAccessibleComp
;
351 ::osl::MutexGuard
aGuard( GetMutex() );
354 xPeer
= mxVclWindowPeer
;
357 xAccessibleComp
.set(maAccessibleContext
, UNO_QUERY
);
358 maAccessibleContext
.clear();
365 // dispose our AccessibleContext - without Mutex locked
366 DisposeAccessibleContext(xAccessibleComp
);
368 EventObject aDisposeEvent
;
369 aDisposeEvent
.Source
= static_cast< XAggregation
* >( this );
371 maDisposeListeners
.disposeAndClear( aDisposeEvent
);
372 maWindowListeners
.disposeAndClear( aDisposeEvent
);
373 maFocusListeners
.disposeAndClear( aDisposeEvent
);
374 maKeyListeners
.disposeAndClear( aDisposeEvent
);
375 maMouseListeners
.disposeAndClear( aDisposeEvent
);
376 maMouseMotionListeners
.disposeAndClear( aDisposeEvent
);
377 maPaintListeners
.disposeAndClear( aDisposeEvent
);
378 maModeChangeListeners
.disposeAndClear( aDisposeEvent
);
380 // release Model again
381 setModel( Reference
< XControlModel
> () );
382 setContext( Reference
< XInterface
> () );
385 void UnoControl::addEventListener( const Reference
< XEventListener
>& rxListener
)
387 ::osl::MutexGuard
aGuard( GetMutex() );
389 maDisposeListeners
.addInterface( rxListener
);
392 void UnoControl::removeEventListener( const Reference
< XEventListener
>& rxListener
)
394 ::osl::MutexGuard
aGuard( GetMutex() );
396 maDisposeListeners
.removeInterface( rxListener
);
399 bool UnoControl::requiresNewPeer( const OUString
& /* _rPropertyName */ ) const
404 // XPropertiesChangeListener
405 void UnoControl::propertiesChange( const Sequence
< PropertyChangeEvent
>& rEvents
)
407 Sequence
< PropertyChangeEvent
> aEvents( rEvents
);
409 ::osl::MutexGuard
aGuard( GetMutex() );
411 if ( !mpData
->aSuspendedPropertyNotifications
.empty() )
413 // strip the property which we are currently updating (somewhere up the stack)
414 PropertyChangeEvent
* pEvents
= aEvents
.getArray();
415 PropertyChangeEvent
* pEventsEnd
= pEvents
+ aEvents
.getLength();
416 for ( ; pEvents
< pEventsEnd
; )
417 if ( mpData
->aSuspendedPropertyNotifications
.find( pEvents
->PropertyName
) != mpData
->aSuspendedPropertyNotifications
.end() )
419 std::copy(pEvents
+ 1, pEventsEnd
, pEvents
);
424 aEvents
.realloc( pEventsEnd
- aEvents
.getConstArray() );
426 if ( !aEvents
.hasElements() )
431 ImplModelPropertiesChanged( aEvents
);
434 void UnoControl::ImplLockPropertyChangeNotification( const OUString
& rPropertyName
, bool bLock
)
436 MapString2Int::iterator pos
= mpData
->aSuspendedPropertyNotifications
.find( rPropertyName
);
439 if ( pos
== mpData
->aSuspendedPropertyNotifications
.end() )
440 pos
= mpData
->aSuspendedPropertyNotifications
.emplace( rPropertyName
, 0 ).first
;
445 OSL_ENSURE( pos
!= mpData
->aSuspendedPropertyNotifications
.end(), "UnoControl::ImplLockPropertyChangeNotification: property not locked!" );
446 if ( pos
!= mpData
->aSuspendedPropertyNotifications
.end() )
448 OSL_ENSURE( pos
->second
> 0, "UnoControl::ImplLockPropertyChangeNotification: invalid suspension counter!" );
449 if ( 0 == --pos
->second
)
450 mpData
->aSuspendedPropertyNotifications
.erase( pos
);
455 void UnoControl::ImplLockPropertyChangeNotifications( const Sequence
< OUString
>& rPropertyNames
, bool bLock
)
457 for ( auto const & propertyName
: rPropertyNames
)
458 ImplLockPropertyChangeNotification( propertyName
, bLock
);
461 void UnoControl::ImplModelPropertiesChanged( const Sequence
< PropertyChangeEvent
>& rEvents
)
463 ::osl::ClearableGuard
< ::osl::Mutex
> aGuard( GetMutex() );
465 if( !getPeer().is() )
468 std::vector
< PropertyValue
> aPeerPropertiesToSet
;
469 sal_Int32 nIndependentPos
= 0;
470 bool bResourceResolverSet( false );
471 // position where to insert the independent properties into aPeerPropertiesToSet,
472 // dependent ones are inserted at the end of the vector
474 bool bNeedNewPeer
= false;
475 // some properties require a re-creation of the peer, 'cause they can't be changed on the fly
477 Reference
< XControlModel
> xOwnModel
= getModel();
478 // our own model for comparison
479 Reference
< XPropertySet
> xPS( xOwnModel
, UNO_QUERY
);
480 Reference
< XPropertySetInfo
> xPSI
= xPS
->getPropertySetInfo();
481 OSL_ENSURE( xPSI
.is(), "UnoControl::ImplModelPropertiesChanged: should have property set meta data!" );
483 sal_Int32 nLen
= rEvents
.getLength();
484 aPeerPropertiesToSet
.reserve(nLen
);
486 for( const PropertyChangeEvent
& rEvent
: rEvents
)
488 Reference
< XControlModel
> xModel( rEvent
.Source
, UNO_QUERY
);
489 bool bOwnModel
= xModel
.get() == xOwnModel
.get();
493 // Detect changes on our resource resolver which invalidates
494 // automatically some language dependent properties.
495 if ( rEvent
.PropertyName
== "ResourceResolver" )
497 Reference
< resource::XStringResourceResolver
> xStrResolver
;
498 if ( rEvent
.NewValue
>>= xStrResolver
)
499 bResourceResolverSet
= xStrResolver
.is();
502 sal_uInt16 nPType
= GetPropertyId( rEvent
.PropertyName
);
503 if ( mbDesignMode
&& mbDisposePeer
&& !mbRefreshingPeer
&& !mbCreatingPeer
)
505 // if we're in design mode, then some properties can change which
506 // require creating a *new* peer (since these properties cannot
507 // be switched at existing peers)
509 bNeedNewPeer
= ( nPType
== BASEPROPERTY_BORDER
)
510 || ( nPType
== BASEPROPERTY_MULTILINE
)
511 || ( nPType
== BASEPROPERTY_DROPDOWN
)
512 || ( nPType
== BASEPROPERTY_HSCROLL
)
513 || ( nPType
== BASEPROPERTY_VSCROLL
)
514 || ( nPType
== BASEPROPERTY_AUTOHSCROLL
)
515 || ( nPType
== BASEPROPERTY_AUTOVSCROLL
)
516 || ( nPType
== BASEPROPERTY_ORIENTATION
)
517 || ( nPType
== BASEPROPERTY_SPIN
)
518 || ( nPType
== BASEPROPERTY_ALIGN
)
519 || ( nPType
== BASEPROPERTY_PAINTTRANSPARENT
);
521 bNeedNewPeer
= requiresNewPeer( rEvent
.PropertyName
);
527 if ( nPType
&& ( nLen
> 1 ) && DoesDependOnOthers( nPType
) )
529 // Add properties with dependencies on other properties last
530 // since they're dependent on properties added later (such as
531 // VALUE dependency on VALUEMIN/MAX)
532 aPeerPropertiesToSet
.emplace_back(rEvent
.PropertyName
, 0, rEvent
.NewValue
, PropertyState_DIRECT_VALUE
);
536 if ( bResourceResolverSet
)
538 // The resource resolver property change should be one of the first ones.
539 // All language dependent properties are dependent on this property.
540 // As BASEPROPERTY_NATIVE_WIDGET_LOOK is not dependent on resource
541 // resolver. We don't need to handle a special order for these two props.
542 aPeerPropertiesToSet
.insert(
543 aPeerPropertiesToSet
.begin(),
544 PropertyValue( rEvent
.PropertyName
, 0, rEvent
.NewValue
, PropertyState_DIRECT_VALUE
) );
547 else if ( nPType
== BASEPROPERTY_NATIVE_WIDGET_LOOK
)
549 // since *a lot* of other properties might be overruled by this one, we need
550 // a special handling:
551 // NativeWidgetLook needs to be set first: If it is set to ON, all other
552 // properties describing the look (e.g. BackgroundColor) are ignored, anyway.
553 // If it is switched OFF, then we need to do it first because else it will
554 // overrule other look-related properties, and re-initialize them from system
556 aPeerPropertiesToSet
.insert(
557 aPeerPropertiesToSet
.begin(),
558 PropertyValue( rEvent
.PropertyName
, 0, rEvent
.NewValue
, PropertyState_DIRECT_VALUE
) );
563 aPeerPropertiesToSet
.insert(aPeerPropertiesToSet
.begin() + nIndependentPos
,
564 PropertyValue(rEvent
.PropertyName
, 0, rEvent
.NewValue
, PropertyState_DIRECT_VALUE
));
570 Reference
< XWindow
> xParent
= getParentPeer();
571 Reference
< XControl
> xThis(this);
572 // call createPeer via an interface got from queryInterface, so the aggregating class can intercept it
574 DBG_ASSERT( !bNeedNewPeer
|| xParent
.is(), "Need new peer, but don't have a parent!" );
576 // Check if we have to update language dependent properties
577 if ( !bNeedNewPeer
&& bResourceResolverSet
)
579 // Add language dependent properties into the peer property set.
580 // Our resource resolver has been changed and we must be sure
581 // that language dependent props use the new resolver.
582 const LanguageDependentProp
* pLangDepProp
= aLanguageDependentProp
;
583 while ( pLangDepProp
->pPropName
!= nullptr )
585 bool bMustBeInserted( true );
586 for (const PropertyValue
& i
: aPeerPropertiesToSet
)
588 if ( i
.Name
.equalsAsciiL(
589 pLangDepProp
->pPropName
, pLangDepProp
->nPropNameLength
))
591 bMustBeInserted
= false;
596 if ( bMustBeInserted
)
598 // Add language dependent props at the end
599 OUString
aPropName( OUString::createFromAscii( pLangDepProp
->pPropName
));
600 if ( xPSI
.is() && xPSI
->hasPropertyByName( aPropName
) )
602 aPeerPropertiesToSet
.emplace_back( aPropName
, 0, xPS
->getPropertyValue( aPropName
), PropertyState_DIRECT_VALUE
);
611 // clear the guard before creating a new peer - as usual, our peer implementations use the SolarMutex
613 if (bNeedNewPeer
&& xParent
.is())
615 SolarMutexGuard aVclGuard
;
616 // and now this is the final withdrawal:
617 // I have no other idea than locking the SolarMutex here...
618 // I really hate the fact that VCL is not threadsafe...
620 // Doesn't work for Container!
621 getPeer()->dispose();
622 mxVclWindowPeer
.clear();
623 mbRefreshingPeer
= true;
624 Reference
< XWindowPeer
> xP( xParent
, UNO_QUERY
);
625 xThis
->createPeer( Reference
< XToolkit
> (), xP
);
626 mbRefreshingPeer
= false;
627 aPeerPropertiesToSet
.clear();
630 // lock the multiplexing of VCL events to our UNO listeners
631 // this is for compatibility reasons: in OOo 1.0.x, changes which were done at the
632 // model did not cause the listeners of the controls/peers to be called
633 // Since the implementations for the listeners changed a lot towards 1.1, this
634 // would not be the case anymore, if we would not do this listener-lock below
639 VclPtr
<vcl::Window
> pVclPeer
= VCLUnoHelper::GetWindow( getPeer() );
640 pPeer
= pVclPeer
? pVclPeer
->GetWindowPeer() : nullptr;
642 VclListenerLock
aNoVclEventMultiplexing( pPeer
);
644 // setting peer properties may result in an attempt to acquire the solar mutex, 'cause the peers
645 // usually don't have an own mutex but use the SolarMutex instead.
646 // To prevent deadlocks resulting from this, we do this without our own mutex locked
647 for (const auto& rProp
: aPeerPropertiesToSet
)
649 ImplSetPeerProperty( rProp
.Name
, rProp
.Value
);
654 void UnoControl::disposing( const EventObject
& rEvt
)
656 ::osl::ClearableMutexGuard
aGuard( GetMutex() );
657 // do not compare differing types in case of multiple inheritance
659 if ( maAccessibleContext
.get() == rEvt
.Source
)
661 // just in case the context is disposed, but not released - ensure that we do not re-use it in the future
662 maAccessibleContext
.clear();
664 else if( mxModel
.get() == Reference
< XControlModel
>(rEvt
.Source
,UNO_QUERY
).get() )
666 // #62337# if the model dies, it does not make sense for us to live ...
667 Reference
< XControl
> xThis
= this;
672 DBG_ASSERT( !mxModel
.is(), "UnoControl::disposing: invalid dispose behaviour!" );
678 void SAL_CALL
UnoControl::setOutputSize( const awt::Size
& aSize
)
680 Reference
< XWindow2
> xPeerWindow
;
682 ::osl::MutexGuard
aGuard( GetMutex() );
683 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
686 if ( xPeerWindow
.is() )
687 xPeerWindow
->setOutputSize( aSize
);
692 template < typename RETVALTYPE
, typename DEFAULTTYPE
>
693 RETVALTYPE
lcl_askPeer( const uno::Reference
< awt::XWindowPeer
>& _rxPeer
, RETVALTYPE (SAL_CALL
XWindow2::*_pMethod
)(), DEFAULTTYPE _aDefault
)
695 RETVALTYPE
aReturn( _aDefault
);
697 Reference
< XWindow2
> xPeerWindow( _rxPeer
, UNO_QUERY
);
698 if ( xPeerWindow
.is() )
699 aReturn
= (xPeerWindow
.get()->*_pMethod
)();
705 awt::Size SAL_CALL
UnoControl::getOutputSize( )
707 return lcl_askPeer( getPeer(), &XWindow2::getOutputSize
, awt::Size() );
710 sal_Bool SAL_CALL
UnoControl::isVisible( )
712 return lcl_askPeer( getPeer(), &XWindow2::isVisible
, maComponentInfos
.bVisible
);
715 sal_Bool SAL_CALL
UnoControl::isActive( )
717 return lcl_askPeer( getPeer(), &XWindow2::isActive
, false );
720 sal_Bool SAL_CALL
UnoControl::isEnabled( )
722 return lcl_askPeer( getPeer(), &XWindow2::isEnabled
, maComponentInfos
.bEnable
);
725 sal_Bool SAL_CALL
UnoControl::hasFocus( )
727 return lcl_askPeer( getPeer(), &XWindow2::hasFocus
, false );
731 void UnoControl::setPosSize( sal_Int32 X
, sal_Int32 Y
, sal_Int32 Width
, sal_Int32 Height
, sal_Int16 Flags
)
733 Reference
< XWindow
> xWindow
;
735 ::osl::MutexGuard
aGuard( GetMutex() );
737 if ( Flags
& awt::PosSize::X
)
738 maComponentInfos
.nX
= X
;
739 if ( Flags
& awt::PosSize::Y
)
740 maComponentInfos
.nY
= Y
;
741 if ( Flags
& awt::PosSize::WIDTH
)
742 maComponentInfos
.nWidth
= Width
;
743 if ( Flags
& awt::PosSize::HEIGHT
)
744 maComponentInfos
.nHeight
= Height
;
745 maComponentInfos
.nFlags
|= Flags
;
747 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
751 xWindow
->setPosSize( X
, Y
, Width
, Height
, Flags
);
754 awt::Rectangle
UnoControl::getPosSize( )
756 awt::Rectangle
aRect( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
);
757 Reference
< XWindow
> xWindow
;
760 ::osl::MutexGuard
aGuard( GetMutex() );
761 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
765 aRect
= xWindow
->getPosSize();
769 void UnoControl::setVisible( sal_Bool bVisible
)
771 Reference
< XWindow
> xWindow
;
773 ::osl::MutexGuard
aGuard( GetMutex() );
775 // Visible status is handled by View
776 maComponentInfos
.bVisible
= bVisible
;
777 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
780 xWindow
->setVisible( bVisible
);
783 void UnoControl::setEnable( sal_Bool bEnable
)
785 Reference
< XWindow
> xWindow
;
787 ::osl::MutexGuard
aGuard( GetMutex() );
789 // Enable status is handled by View
790 maComponentInfos
.bEnable
= bEnable
;
791 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
794 xWindow
->setEnable( bEnable
);
797 void UnoControl::setFocus( )
799 Reference
< XWindow
> xWindow
;
801 ::osl::MutexGuard
aGuard( GetMutex() );
802 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
808 void UnoControl::addWindowListener( const Reference
< XWindowListener
>& rxListener
)
810 Reference
< XWindow
> xPeerWindow
;
812 ::osl::MutexGuard
aGuard( GetMutex() );
813 maWindowListeners
.addInterface( rxListener
);
814 if ( maWindowListeners
.getLength() == 1 )
815 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
817 if ( xPeerWindow
.is() )
818 xPeerWindow
->addWindowListener( &maWindowListeners
);
821 void UnoControl::removeWindowListener( const Reference
< XWindowListener
>& rxListener
)
823 Reference
< XWindow
> xPeerWindow
;
825 ::osl::MutexGuard
aGuard( GetMutex() );
826 if ( maWindowListeners
.getLength() == 1 )
827 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
828 maWindowListeners
.removeInterface( rxListener
);
830 if ( xPeerWindow
.is() )
831 xPeerWindow
->removeWindowListener( &maWindowListeners
);
834 void UnoControl::addFocusListener( const Reference
< XFocusListener
>& rxListener
)
836 Reference
< XWindow
> xPeerWindow
;
838 ::osl::MutexGuard
aGuard( GetMutex() );
839 maFocusListeners
.addInterface( rxListener
);
840 if ( maFocusListeners
.getLength() == 1 )
841 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
843 if ( xPeerWindow
.is() )
844 xPeerWindow
->addFocusListener( &maFocusListeners
);
847 void UnoControl::removeFocusListener( const Reference
< XFocusListener
>& rxListener
)
849 Reference
< XWindow
> xPeerWindow
;
851 ::osl::MutexGuard
aGuard( GetMutex() );
852 if ( maFocusListeners
.getLength() == 1 )
853 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
854 maFocusListeners
.removeInterface( rxListener
);
856 if ( xPeerWindow
.is() )
857 xPeerWindow
->removeFocusListener( &maFocusListeners
);
860 void UnoControl::addKeyListener( const Reference
< XKeyListener
>& rxListener
)
862 Reference
< XWindow
> xPeerWindow
;
864 ::osl::MutexGuard
aGuard( GetMutex() );
865 maKeyListeners
.addInterface( rxListener
);
866 if ( maKeyListeners
.getLength() == 1 )
867 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
869 if ( xPeerWindow
.is() )
870 xPeerWindow
->addKeyListener( &maKeyListeners
);
873 void UnoControl::removeKeyListener( const Reference
< XKeyListener
>& rxListener
)
875 Reference
< XWindow
> xPeerWindow
;
877 ::osl::MutexGuard
aGuard( GetMutex() );
878 if ( maKeyListeners
.getLength() == 1 )
879 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
880 maKeyListeners
.removeInterface( rxListener
);
882 if ( xPeerWindow
.is() )
883 xPeerWindow
->removeKeyListener( &maKeyListeners
);
886 void UnoControl::addMouseListener( const Reference
< XMouseListener
>& rxListener
)
888 Reference
< XWindow
> xPeerWindow
;
890 ::osl::MutexGuard
aGuard( GetMutex() );
891 maMouseListeners
.addInterface( rxListener
);
892 if ( maMouseListeners
.getLength() == 1 )
893 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
895 if ( xPeerWindow
.is() )
896 xPeerWindow
->addMouseListener( &maMouseListeners
);
899 void UnoControl::removeMouseListener( const Reference
< XMouseListener
>& rxListener
)
901 Reference
< XWindow
> xPeerWindow
;
903 ::osl::MutexGuard
aGuard( GetMutex() );
904 if ( maMouseListeners
.getLength() == 1 )
905 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
906 maMouseListeners
.removeInterface( rxListener
);
908 if ( xPeerWindow
.is() )
909 xPeerWindow
->removeMouseListener( &maMouseListeners
);
912 void UnoControl::addMouseMotionListener( const Reference
< XMouseMotionListener
>& rxListener
)
914 Reference
< XWindow
> xPeerWindow
;
916 ::osl::MutexGuard
aGuard( GetMutex() );
917 maMouseMotionListeners
.addInterface( rxListener
);
918 if ( maMouseMotionListeners
.getLength() == 1 )
919 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
921 if ( xPeerWindow
.is() )
922 xPeerWindow
->addMouseMotionListener( &maMouseMotionListeners
);
925 void UnoControl::removeMouseMotionListener( const Reference
< XMouseMotionListener
>& rxListener
)
927 Reference
< XWindow
> xPeerWindow
;
929 ::osl::MutexGuard
aGuard( GetMutex() );
930 if ( maMouseMotionListeners
.getLength() == 1 )
931 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
932 maMouseMotionListeners
.removeInterface( rxListener
);
934 if ( xPeerWindow
.is() )
935 xPeerWindow
->removeMouseMotionListener( &maMouseMotionListeners
);
938 void UnoControl::addPaintListener( const Reference
< XPaintListener
>& rxListener
)
940 Reference
< XWindow
> xPeerWindow
;
942 ::osl::MutexGuard
aGuard( GetMutex() );
943 maPaintListeners
.addInterface( rxListener
);
944 if ( maPaintListeners
.getLength() == 1 )
945 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
947 if ( xPeerWindow
.is() )
948 xPeerWindow
->addPaintListener( &maPaintListeners
);
951 void UnoControl::removePaintListener( const Reference
< XPaintListener
>& rxListener
)
953 Reference
< XWindow
> xPeerWindow
;
955 ::osl::MutexGuard
aGuard( GetMutex() );
956 if ( maPaintListeners
.getLength() == 1 )
957 xPeerWindow
.set(getPeer(), css::uno::UNO_QUERY
);
958 maPaintListeners
.removeInterface( rxListener
);
960 if ( xPeerWindow
.is() )
961 xPeerWindow
->removePaintListener( &maPaintListeners
);
965 sal_Bool
UnoControl::setGraphics( const Reference
< XGraphics
>& rDevice
)
967 Reference
< XView
> xView
;
969 ::osl::MutexGuard
aGuard( GetMutex() );
971 mxGraphics
= rDevice
;
972 xView
.set(getPeer(), css::uno::UNO_QUERY
);
974 return !xView
.is() || xView
->setGraphics( rDevice
);
977 Reference
< XGraphics
> UnoControl::getGraphics( )
982 awt::Size
UnoControl::getSize( )
984 ::osl::MutexGuard
aGuard( GetMutex() );
985 return awt::Size( maComponentInfos
.nWidth
, maComponentInfos
.nHeight
);
988 void UnoControl::draw( sal_Int32 x
, sal_Int32 y
)
990 Reference
< XWindowPeer
> xDrawPeer
;
991 Reference
< XView
> xDrawPeerView
;
993 bool bDisposeDrawPeer( false );
995 ::osl::MutexGuard
aGuard( GetMutex() );
997 xDrawPeer
= ImplGetCompatiblePeer();
998 bDisposeDrawPeer
= xDrawPeer
.is() && ( xDrawPeer
!= getPeer() );
1000 xDrawPeerView
.set( xDrawPeer
, UNO_QUERY
);
1001 DBG_ASSERT( xDrawPeerView
.is(), "UnoControl::draw: no peer!" );
1004 if ( xDrawPeerView
.is() )
1006 Reference
< XVclWindowPeer
> xWindowPeer
;
1007 xWindowPeer
.set( xDrawPeer
, UNO_QUERY
);
1008 if ( xWindowPeer
.is() )
1009 xWindowPeer
->setDesignMode( mbDesignMode
);
1010 xDrawPeerView
->draw( x
, y
);
1013 if ( bDisposeDrawPeer
)
1014 xDrawPeer
->dispose();
1017 void UnoControl::setZoom( float fZoomX
, float fZoomY
)
1019 Reference
< XView
> xView
;
1021 ::osl::MutexGuard
aGuard( GetMutex() );
1023 maComponentInfos
.nZoomX
= fZoomX
;
1024 maComponentInfos
.nZoomY
= fZoomY
;
1026 xView
.set(getPeer(), css::uno::UNO_QUERY
);
1029 xView
->setZoom( fZoomX
, fZoomY
);
1033 void UnoControl::setContext( const Reference
< XInterface
>& rxContext
)
1035 ::osl::MutexGuard
aGuard( GetMutex() );
1037 mxContext
= rxContext
;
1040 Reference
< XInterface
> UnoControl::getContext( )
1042 ::osl::MutexGuard
aGuard( GetMutex() );
1047 void UnoControl::peerCreated()
1049 Reference
< XWindow
> xWindow( getPeer(), UNO_QUERY
);
1050 if ( !xWindow
.is() )
1053 if ( maWindowListeners
.getLength() )
1054 xWindow
->addWindowListener( &maWindowListeners
);
1056 if ( maFocusListeners
.getLength() )
1057 xWindow
->addFocusListener( &maFocusListeners
);
1059 if ( maKeyListeners
.getLength() )
1060 xWindow
->addKeyListener( &maKeyListeners
);
1062 if ( maMouseListeners
.getLength() )
1063 xWindow
->addMouseListener( &maMouseListeners
);
1065 if ( maMouseMotionListeners
.getLength() )
1066 xWindow
->addMouseMotionListener( &maMouseMotionListeners
);
1068 if ( maPaintListeners
.getLength() )
1069 xWindow
->addPaintListener( &maPaintListeners
);
1072 void UnoControl::createPeer( const Reference
< XToolkit
>& rxToolkit
, const Reference
< XWindowPeer
>& rParentPeer
)
1074 ::osl::ClearableMutexGuard
aGuard( GetMutex() );
1075 if ( !mxModel
.is() )
1077 throw RuntimeException("createPeer: no model!", getXWeak());
1080 if( getPeer().is() )
1083 mbCreatingPeer
= true;
1086 Reference
< XToolkit
> xToolkit
= rxToolkit
;
1087 if( rParentPeer
.is() && mxContext
.is() )
1090 if ( !xToolkit
.is() )
1091 xToolkit
= rParentPeer
->getToolkit();
1092 Any aAny
= OWeakAggObject::queryInterface( cppu::UnoType
<XControlContainer
>::get());
1093 Reference
< XControlContainer
> xC
;
1097 eType
= WindowClass_CONTAINER
;
1099 eType
= WindowClass_SIMPLE
;
1102 { // This is only correct for Top Window
1103 if( rParentPeer
.is() )
1105 if ( !xToolkit
.is() )
1106 xToolkit
= rParentPeer
->getToolkit();
1107 eType
= WindowClass_CONTAINER
;
1111 if ( !xToolkit
.is() )
1112 xToolkit
= VCLUnoHelper::CreateToolkit();
1113 eType
= WindowClass_TOP
;
1116 WindowDescriptor aDescr
;
1117 aDescr
.Type
= eType
;
1118 aDescr
.WindowServiceName
= GetComponentServiceName();
1119 aDescr
.Parent
= rParentPeer
;
1120 aDescr
.Bounds
= getPosSize();
1121 aDescr
.WindowAttributes
= 0;
1124 Reference
< XPropertySet
> xPSet( mxModel
, UNO_QUERY
);
1125 Reference
< XPropertySetInfo
> xInfo
= xPSet
->getPropertySetInfo();
1128 OUString aPropName
= GetPropertyName( BASEPROPERTY_BORDER
);
1129 if ( xInfo
->hasPropertyByName( aPropName
) )
1131 aVal
= xPSet
->getPropertyValue( aPropName
);
1132 sal_Int16 n
= sal_Int16();
1136 aDescr
.WindowAttributes
|= WindowAttribute::BORDER
;
1138 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::NOBORDER
;
1142 // DESKTOP_AS_PARENT
1143 if ( aDescr
.Type
== WindowClass_TOP
)
1145 aPropName
= GetPropertyName( BASEPROPERTY_DESKTOP_AS_PARENT
);
1146 if ( xInfo
->hasPropertyByName( aPropName
) )
1148 aVal
= xPSet
->getPropertyValue( aPropName
);
1150 if ( ( aVal
>>= b
) && b
)
1151 aDescr
.ParentIndex
= -1;
1155 aPropName
= GetPropertyName( BASEPROPERTY_MOVEABLE
);
1156 if ( xInfo
->hasPropertyByName( aPropName
) )
1158 aVal
= xPSet
->getPropertyValue( aPropName
);
1160 if ( ( aVal
>>= b
) && b
)
1161 aDescr
.WindowAttributes
|= WindowAttribute::MOVEABLE
;
1165 aPropName
= GetPropertyName( BASEPROPERTY_SIZEABLE
);
1166 if ( xInfo
->hasPropertyByName( aPropName
) )
1168 aVal
= xPSet
->getPropertyValue( aPropName
);
1170 if ( ( aVal
>>= b
) && b
)
1171 aDescr
.WindowAttributes
|= WindowAttribute::SIZEABLE
;
1175 aPropName
= GetPropertyName( BASEPROPERTY_CLOSEABLE
);
1176 if ( xInfo
->hasPropertyByName( aPropName
) )
1178 aVal
= xPSet
->getPropertyValue( aPropName
);
1180 if ( ( aVal
>>= b
) && b
)
1181 aDescr
.WindowAttributes
|= WindowAttribute::CLOSEABLE
;
1185 aPropName
= GetPropertyName( BASEPROPERTY_DROPDOWN
);
1186 if ( xInfo
->hasPropertyByName( aPropName
) )
1188 aVal
= xPSet
->getPropertyValue( aPropName
);
1190 if ( ( aVal
>>= b
) && b
)
1191 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::DROPDOWN
;
1195 aPropName
= GetPropertyName( BASEPROPERTY_SPIN
);
1196 if ( xInfo
->hasPropertyByName( aPropName
) )
1198 aVal
= xPSet
->getPropertyValue( aPropName
);
1200 if ( ( aVal
>>= b
) && b
)
1201 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::SPIN
;
1205 aPropName
= GetPropertyName( BASEPROPERTY_HSCROLL
);
1206 if ( xInfo
->hasPropertyByName( aPropName
) )
1208 aVal
= xPSet
->getPropertyValue( aPropName
);
1210 if ( ( aVal
>>= b
) && b
)
1211 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::HSCROLL
;
1215 aPropName
= GetPropertyName( BASEPROPERTY_VSCROLL
);
1216 if ( xInfo
->hasPropertyByName( aPropName
) )
1218 aVal
= xPSet
->getPropertyValue( aPropName
);
1220 if ( ( aVal
>>= b
) && b
)
1221 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::VSCROLL
;
1225 aPropName
= GetPropertyName( BASEPROPERTY_AUTOHSCROLL
);
1226 if ( xInfo
->hasPropertyByName( aPropName
) )
1228 aVal
= xPSet
->getPropertyValue( aPropName
);
1230 if ( ( aVal
>>= b
) && b
)
1231 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::AUTOHSCROLL
;
1235 aPropName
= GetPropertyName( BASEPROPERTY_AUTOVSCROLL
);
1236 if ( xInfo
->hasPropertyByName( aPropName
) )
1238 aVal
= xPSet
->getPropertyValue( aPropName
);
1240 if ( ( aVal
>>= b
) && b
)
1241 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::AUTOVSCROLL
;
1244 //added for issue79712
1246 aPropName
= GetPropertyName( BASEPROPERTY_NOLABEL
);
1247 if ( xInfo
->hasPropertyByName( aPropName
) )
1249 aVal
= xPSet
->getPropertyValue( aPropName
);
1251 if ( ( aVal
>>=b
) && b
)
1252 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::NOLABEL
;
1257 aPropName
= GetPropertyName( BASEPROPERTY_ALIGN
);
1258 if ( xInfo
->hasPropertyByName( aPropName
) )
1260 aVal
= xPSet
->getPropertyValue( aPropName
);
1261 sal_Int16 n
= sal_Int16();
1264 if ( n
== PROPERTY_ALIGN_LEFT
)
1265 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::LEFT
;
1266 else if ( n
== PROPERTY_ALIGN_CENTER
)
1267 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::CENTER
;
1269 aDescr
.WindowAttributes
|= VclWindowPeerAttribute::RIGHT
;
1273 // Allow derivates to manipulate attributes
1274 PrepareWindowDescriptor(aDescr
);
1277 Reference
<XWindowPeer
> xTemp
= xToolkit
->createWindow( aDescr
);
1278 mxVclWindowPeer
.set(xTemp
, UNO_QUERY
);
1279 assert(mxVclWindowPeer
);
1281 // release the mutex guard (and work with copies of our members)
1282 // this is necessary as our peer may lock the SolarMutex (actually, all currently known peers do), so calling
1283 // into the peer with our own mutex locked may cause deadlocks
1284 // (We _really_ need peers which do not use the SolarMutex. It's really pissing me off that from time to
1285 // time deadlocks pop up because the low-level components like our peers use a mutex which usually
1286 // is locked at the top of the stack (it protects the global message looping). This is always dangerous, and
1287 // can not always be solved by tampering with other mutexes.
1288 // Unfortunately, the VCL used in the peers is not threadsafe, and by definition needs a locked SolarMutex.)
1289 // 82300 - 12/21/00 - FS
1290 UnoControlComponentInfos
aComponentInfos(maComponentInfos
);
1291 bool bDesignMode(mbDesignMode
);
1293 Reference
< XGraphics
> xGraphics( mxGraphics
);
1294 Reference
< XView
> xView ( getPeer(), UNO_QUERY_THROW
);
1295 Reference
< XWindow
> xWindow ( getPeer(), UNO_QUERY_THROW
);
1299 // tdf#150886 if false use the same settings for widgets regardless of theme
1300 // for consistency of document across platforms and in pdf/print output
1301 // note: tdf#155029 do this before updateFromModel
1302 if (xInfo
->hasPropertyByName("StandardTheme"))
1304 aVal
= xPSet
->getPropertyValue("StandardTheme");
1305 bool bUseStandardTheme
= false;
1306 aVal
>>= bUseStandardTheme
;
1307 if (bUseStandardTheme
)
1309 VclPtr
<vcl::Window
> pVclPeer
= VCLUnoHelper::GetWindow(getPeer());
1310 AllSettings aAllSettings
= pVclPeer
->GetSettings();
1311 StyleSettings aStyleSettings
= aAllSettings
.GetStyleSettings();
1312 aStyleSettings
.SetStandardStyles();
1313 aAllSettings
.SetStyleSettings(aStyleSettings
);
1314 pVclPeer
->SetSettings(aAllSettings
);
1318 // the updateFromModel is done without a locked mutex, too.
1319 // The reason is that the only thing this method does is firing property changes, and this in general has
1320 // to be done without locked mutexes (as every notification to external listeners).
1321 // 82300 - 12/21/00 - FS
1324 xView
->setZoom( aComponentInfos
.nZoomX
, aComponentInfos
.nZoomY
);
1326 setPosSize( aComponentInfos
.nX
, aComponentInfos
.nY
, aComponentInfos
.nWidth
, aComponentInfos
.nHeight
, aComponentInfos
.nFlags
);
1328 if( aComponentInfos
.bVisible
&& !bDesignMode
)
1329 // Show only after setting the data
1330 xWindow
->setVisible( aComponentInfos
.bVisible
);
1332 if( !aComponentInfos
.bEnable
)
1333 xWindow
->setEnable( aComponentInfos
.bEnable
);
1335 xView
->setGraphics( xGraphics
);
1339 mbCreatingPeer
= false;
1343 Reference
< XWindowPeer
> UnoControl::getPeer()
1345 ::osl::MutexGuard
aGuard( GetMutex() );
1346 return mxVclWindowPeer
;
1349 Reference
< XVclWindowPeer
> UnoControl::getVclWindowPeer()
1351 ::osl::MutexGuard
aGuard( GetMutex() );
1352 return mxVclWindowPeer
;
1355 sal_Bool
UnoControl::setModel( const Reference
< XControlModel
>& rxModel
)
1357 ::osl::MutexGuard
aGuard( GetMutex() );
1359 Reference
< XMultiPropertySet
> xPropSet( mxModel
, UNO_QUERY
);
1361 // query for the XPropertiesChangeListener - our delegator is allowed to overwrite this interface
1362 Reference
< XPropertiesChangeListener
> xListener
;
1363 queryInterface( cppu::UnoType
<decltype(xListener
)>::get() ) >>= xListener
;
1366 xPropSet
->removePropertiesChangeListener( xListener
);
1368 mpData
->bLocalizationSupport
= false;
1375 xPropSet
.set( mxModel
, UNO_QUERY_THROW
);
1376 Reference
< XPropertySetInfo
> xPSI( xPropSet
->getPropertySetInfo(), UNO_SET_THROW
);
1378 Sequence
< OUString
> aNames
= lcl_ImplGetPropertyNames( xPropSet
);
1379 xPropSet
->addPropertiesChangeListener( aNames
, xListener
);
1381 mpData
->bLocalizationSupport
= xPSI
->hasPropertyByName("ResourceResolver");
1383 catch( const Exception
& )
1385 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
1390 return mxModel
.is();
1393 Reference
< XControlModel
> UnoControl::getModel( )
1398 Reference
< XView
> UnoControl::getView( )
1400 return static_cast< XView
* >( this );
1403 void UnoControl::setDesignMode( sal_Bool bOn
)
1405 ModeChangeEvent aModeChangeEvent
;
1407 Reference
< XWindow
> xWindow
;
1408 Reference
<XComponent
> xAccessibleComp
;
1410 ::osl::MutexGuard
aGuard( GetMutex() );
1411 if ( bool(bOn
) == mbDesignMode
)
1416 xWindow
.set(getPeer(), css::uno::UNO_QUERY
);
1418 xAccessibleComp
.set(maAccessibleContext
, UNO_QUERY
);
1419 maAccessibleContext
.clear();
1421 aModeChangeEvent
.Source
= *this;
1422 aModeChangeEvent
.NewMode
= mbDesignMode
? std::u16string_view(u
"design") : std::u16string_view(u
"alive" );
1425 // dispose current AccessibleContext, if we have one - without Mutex lock
1426 // (changing the design mode implies having a new implementation for this context,
1427 // so the old one must be declared DEFUNC)
1428 DisposeAccessibleContext(xAccessibleComp
);
1430 // adjust the visibility of our window
1432 xWindow
->setVisible( !bOn
);
1434 // and notify our mode listeners
1435 maModeChangeListeners
.notifyEach( &XModeChangeListener::modeChanged
, aModeChangeEvent
);
1438 sal_Bool
UnoControl::isDesignMode( )
1440 return mbDesignMode
;
1443 sal_Bool
UnoControl::isTransparent( )
1449 OUString
UnoControl::getImplementationName( )
1451 OSL_FAIL( "This method should be overridden!" );
1455 sal_Bool
UnoControl::supportsService( const OUString
& rServiceName
)
1457 return cppu::supportsService(this, rServiceName
);
1460 Sequence
< OUString
> UnoControl::getSupportedServiceNames( )
1462 return { "com.sun.star.awt.UnoControl" };
1466 Reference
< XAccessibleContext
> SAL_CALL
UnoControl::getAccessibleContext( )
1468 // creation of the context will certainly require the SolarMutex ...
1469 SolarMutexGuard aSolarGuard
;
1470 ::osl::MutexGuard
aGuard( GetMutex() );
1472 Reference
< XAccessibleContext
> xCurrentContext( maAccessibleContext
.get(), UNO_QUERY
);
1473 if ( !xCurrentContext
.is() )
1475 if ( !mbDesignMode
)
1476 { // in alive mode, use the AccessibleContext of the peer
1477 Reference
< XAccessible
> xPeerAcc( getPeer(), UNO_QUERY
);
1478 if ( xPeerAcc
.is() )
1479 xCurrentContext
= xPeerAcc
->getAccessibleContext( );
1482 // in design mode, use a fallback
1483 xCurrentContext
= ::toolkit::OAccessibleControlContext::create( this );
1485 DBG_ASSERT( xCurrentContext
.is(), "UnoControl::getAccessibleContext: invalid context (invalid peer?)!" );
1486 maAccessibleContext
= xCurrentContext
;
1488 // get notified when the context is disposed
1489 Reference
< XComponent
> xContextComp( xCurrentContext
, UNO_QUERY
);
1490 if ( xContextComp
.is() )
1491 xContextComp
->addEventListener( this );
1492 // In an ideal world, this is not necessary - there the object would be released as soon as it has been
1493 // disposed, and thus our weak reference would be empty, too.
1494 // But 'til this ideal world comes (means 'til we do never have any refcount/lifetime bugs anymore), we
1495 // need to listen for disposal and reset our weak reference then.
1498 return xCurrentContext
;
1501 void SAL_CALL
UnoControl::addModeChangeListener( const Reference
< XModeChangeListener
>& _rxListener
)
1503 ::osl::MutexGuard
aGuard( GetMutex() );
1504 maModeChangeListeners
.addInterface( _rxListener
);
1507 void SAL_CALL
UnoControl::removeModeChangeListener( const Reference
< XModeChangeListener
>& _rxListener
)
1509 ::osl::MutexGuard
aGuard( GetMutex() );
1510 maModeChangeListeners
.removeInterface( _rxListener
);
1513 void SAL_CALL
UnoControl::addModeChangeApproveListener( const Reference
< XModeChangeApproveListener
>& )
1515 throw NoSupportException( );
1518 void SAL_CALL
UnoControl::removeModeChangeApproveListener( const Reference
< XModeChangeApproveListener
>& )
1520 throw NoSupportException( );
1524 awt::Point SAL_CALL
UnoControl::convertPointToLogic( const awt::Point
& i_Point
, ::sal_Int16 i_TargetUnit
)
1526 Reference
< XUnitConversion
> xPeerConversion
;
1528 ::osl::MutexGuard
aGuard( GetMutex() );
1529 xPeerConversion
.set(getPeer(), css::uno::UNO_QUERY
);
1531 if ( xPeerConversion
.is() )
1532 return xPeerConversion
->convertPointToLogic( i_Point
, i_TargetUnit
);
1533 return awt::Point( );
1537 awt::Point SAL_CALL
UnoControl::convertPointToPixel( const awt::Point
& i_Point
, ::sal_Int16 i_SourceUnit
)
1539 Reference
< XUnitConversion
> xPeerConversion
;
1541 ::osl::MutexGuard
aGuard( GetMutex() );
1542 xPeerConversion
.set(getPeer(), css::uno::UNO_QUERY
);
1544 if ( xPeerConversion
.is() )
1545 return xPeerConversion
->convertPointToPixel( i_Point
, i_SourceUnit
);
1546 return awt::Point( );
1550 awt::Size SAL_CALL
UnoControl::convertSizeToLogic( const awt::Size
& i_Size
, ::sal_Int16 i_TargetUnit
)
1552 Reference
< XUnitConversion
> xPeerConversion
;
1554 ::osl::MutexGuard
aGuard( GetMutex() );
1555 xPeerConversion
.set(getPeer(), css::uno::UNO_QUERY
);
1557 if ( xPeerConversion
.is() )
1558 return xPeerConversion
->convertSizeToLogic( i_Size
, i_TargetUnit
);
1559 return awt::Size( );
1563 awt::Size SAL_CALL
UnoControl::convertSizeToPixel( const awt::Size
& i_Size
, ::sal_Int16 i_SourceUnit
)
1565 Reference
< XUnitConversion
> xPeerConversion
;
1567 ::osl::MutexGuard
aGuard( GetMutex() );
1568 xPeerConversion
.set(getPeer(), css::uno::UNO_QUERY
);
1570 if ( xPeerConversion
.is() )
1571 return xPeerConversion
->convertSizeToPixel( i_Size
, i_SourceUnit
);
1572 return awt::Size( );
1576 uno::Reference
< awt::XStyleSettings
> SAL_CALL
UnoControl::getStyleSettings()
1578 Reference
< awt::XStyleSettingsSupplier
> xPeerSupplier
;
1580 ::osl::MutexGuard
aGuard( GetMutex() );
1581 xPeerSupplier
.set(getPeer(), css::uno::UNO_QUERY
);
1583 if ( xPeerSupplier
.is() )
1584 return xPeerSupplier
->getStyleSettings();
1588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */