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 <com/sun/star/accessibility/AccessibleRole.hpp>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
24 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
28 #include <toolkit/helper/externallock.hxx>
29 #include <toolkit/awt/vclxwindow.hxx>
30 #include <toolkit/helper/convert.hxx>
31 #include <toolkit/awt/vclxfont.hxx>
32 #include <vcl/dialog.hxx>
33 #include <vcl/vclevent.hxx>
34 #include <vcl/window.hxx>
35 #include <vcl/edit.hxx>
36 #include <vcl/settings.hxx>
37 #include <tools/debug.hxx>
38 #include <unotools/accessiblestatesethelper.hxx>
39 #include <unotools/accessiblerelationsethelper.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/menu.hxx>
43 using namespace ::com::sun::star
;
44 using namespace ::comphelper
;
46 VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow
* pVCLXWindow
)
47 : OAccessibleExtendedComponentHelper( new VCLExternalSolarLock
)
48 , OAccessibleImplementationAccess( )
50 m_xVCLXWindow
= pVCLXWindow
;
52 m_pSolarLock
= static_cast< VCLExternalSolarLock
* >( getExternalLock( ) );
54 DBG_ASSERT( pVCLXWindow
->GetWindow(), "VCLXAccessibleComponent - no window!" );
55 m_xEventSource
= pVCLXWindow
->GetWindow();
58 m_xEventSource
->AddEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
59 m_xEventSource
->AddChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
62 // announce the XAccessible of our creator to the base class
63 lateInit( pVCLXWindow
);
66 VCLXWindow
* VCLXAccessibleComponent::GetVCLXWindow() const
68 return m_xVCLXWindow
.get();
71 void VCLXAccessibleComponent::DisconnectEvents()
75 m_xEventSource
->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
76 m_xEventSource
->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
77 m_xEventSource
.clear();
81 VCLXAccessibleComponent::~VCLXAccessibleComponent()
87 m_pSolarLock
= nullptr;
88 // This is not completely safe. If we assume that the base class dtor calls some method which
89 // uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
90 // virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
91 // lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
92 // let's assume it keeps this way.
93 // @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
96 IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent
, OAccessibleExtendedComponentHelper
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
97 IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent
, OAccessibleExtendedComponentHelper
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
99 OUString
VCLXAccessibleComponent::getImplementationName()
101 return OUString("com.sun.star.comp.toolkit.AccessibleWindow");
104 sal_Bool
VCLXAccessibleComponent::supportsService( const OUString
& rServiceName
)
106 return cppu::supportsService(this, rServiceName
);
109 uno::Sequence
< OUString
> VCLXAccessibleComponent::getSupportedServiceNames()
111 uno::Sequence
< OUString
> aNames
{ "com.sun.star.awt.AccessibleWindow" };
115 IMPL_LINK( VCLXAccessibleComponent
, WindowEventListener
, VclWindowEvent
&, rEvent
, void )
117 /* Ignore VclEventId::WindowEndPopupMode, because the UNO accessibility wrapper
118 * might have been destroyed by the previous VCLEventListener (if no AT tool
119 * is running), e.g. sub-toolbars in impress.
121 if ( m_xVCLXWindow
.is() /* #122218# */ && (rEvent
.GetId() != VclEventId::WindowEndPopupMode
) )
123 DBG_ASSERT( rEvent
.GetWindow(), "Window???" );
124 if( !rEvent
.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent
.GetId() == VclEventId::ObjectDying
) )
126 ProcessWindowEvent( rEvent
);
131 IMPL_LINK( VCLXAccessibleComponent
, WindowChildEventListener
, VclWindowEvent
&, rEvent
, void )
133 if ( m_xVCLXWindow
.is() /* #i68079# */ )
135 DBG_ASSERT( rEvent
.GetWindow(), "Window???" );
136 if( !rEvent
.GetWindow()->IsAccessibilityEventsSuppressed() )
138 // #103087# to prevent an early release of the component
139 uno::Reference
< accessibility::XAccessibleContext
> xTmp
= this;
141 ProcessWindowChildEvent( rEvent
);
146 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
148 // checks if the data in the window event is our direct child
149 // and returns its accessible
151 // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData.
152 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
153 if( pChildWindow
&& GetWindow() == pChildWindow
->GetAccessibleParentWindow() )
154 return pChildWindow
->GetAccessible( rVclWindowEvent
.GetId() == VclEventId::WindowShow
);
156 return uno::Reference
< accessibility::XAccessible
> ();
159 void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
161 uno::Any aOldValue
, aNewValue
;
162 uno::Reference
< accessibility::XAccessible
> xAcc
;
164 switch ( rVclWindowEvent
.GetId() )
166 case VclEventId::WindowShow
: // send create on show for direct accessible children
168 xAcc
= GetChildAccessible( rVclWindowEvent
);
172 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
176 case VclEventId::WindowHide
: // send destroy on hide for direct accessible children
178 xAcc
= GetChildAccessible( rVclWindowEvent
);
182 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
190 void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
192 uno::Any aOldValue
, aNewValue
;
194 vcl::Window
* pAccWindow
= rVclWindowEvent
.GetWindow();
195 assert(pAccWindow
&& "VCLXAccessibleComponent::ProcessWindowEvent - Window?");
197 switch ( rVclWindowEvent
.GetId() )
199 case VclEventId::ObjectDying
:
202 m_xVCLXWindow
.clear();
205 case VclEventId::WindowChildDestroyed
:
207 vcl::Window
* pWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
208 DBG_ASSERT( pWindow
, "VclEventId::WindowChildDestroyed - Window=?" );
209 if ( pWindow
->GetAccessible( false ).is() )
211 aOldValue
<<= pWindow
->GetAccessible( false );
212 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
216 case VclEventId::WindowActivate
:
218 // avoid notification if a child frame is already active
219 // only one frame may be active at a given time
220 if ( !pAccWindow
->HasActiveChildFrame() &&
221 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
222 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
223 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
225 aNewValue
<<= accessibility::AccessibleStateType::ACTIVE
;
226 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
230 case VclEventId::WindowDeactivate
:
232 if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
233 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
234 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) // #i18891#
236 aOldValue
<<= accessibility::AccessibleStateType::ACTIVE
;
237 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
241 case VclEventId::WindowGetFocus
:
242 case VclEventId::ControlGetFocus
:
244 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VclEventId::ControlGetFocus
) ||
245 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VclEventId::WindowGetFocus
) )
247 // if multiple listeners were registered it is possible that the
248 // focus was changed during event processing (eg SfxTopWindow )
249 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
250 if( (pAccWindow
->IsCompoundControl() && pAccWindow
->HasChildPathFocus()) ||
251 (!pAccWindow
->IsCompoundControl() && pAccWindow
->HasFocus()) )
253 aNewValue
<<= accessibility::AccessibleStateType::FOCUSED
;
254 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
259 case VclEventId::WindowLoseFocus
:
260 case VclEventId::ControlLoseFocus
:
262 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VclEventId::ControlLoseFocus
) ||
263 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VclEventId::WindowLoseFocus
) )
265 aOldValue
<<= accessibility::AccessibleStateType::FOCUSED
;
266 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
270 case VclEventId::WindowFrameTitleChanged
:
272 OUString
aOldName( *static_cast<OUString
*>(rVclWindowEvent
.GetData()) );
273 OUString
aNewName( getAccessibleName() );
274 aOldValue
<<= aOldName
;
275 aNewValue
<<= aNewName
;
276 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
279 case VclEventId::WindowEnabled
:
281 aNewValue
<<= accessibility::AccessibleStateType::ENABLED
;
282 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
283 aNewValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
284 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
287 case VclEventId::WindowDisabled
:
289 aOldValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
290 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
292 aOldValue
<<= accessibility::AccessibleStateType::ENABLED
;
293 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
296 case VclEventId::WindowMove
:
297 case VclEventId::WindowResize
:
299 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED
, aOldValue
, aNewValue
);
302 case VclEventId::WindowMenubarAdded
:
304 MenuBar
* pMenuBar
= static_cast<MenuBar
*>(rVclWindowEvent
.GetData());
307 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
310 aNewValue
<<= xChild
;
311 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
316 case VclEventId::WindowMenubarRemoved
:
318 MenuBar
* pMenuBar
= static_cast<MenuBar
*>(rVclWindowEvent
.GetData());
321 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
324 aOldValue
<<= xChild
;
325 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
330 case VclEventId::WindowMinimize
:
332 aNewValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
333 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
336 case VclEventId::WindowNormalize
:
338 aOldValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
339 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
349 void VCLXAccessibleComponent::disposing()
353 OAccessibleExtendedComponentHelper::disposing();
355 m_xVCLXWindow
.clear();
358 VclPtr
<vcl::Window
> VCLXAccessibleComponent::GetWindow() const
360 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow()
361 : VclPtr
<vcl::Window
>();
364 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
366 VclPtr
<vcl::Window
> pWindow
= GetWindow();
369 vcl::Window
*pLabeledBy
= pWindow
->GetAccessibleRelationLabeledBy();
370 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
372 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pLabeledBy
->GetAccessible() };
373 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
376 vcl::Window
* pLabelFor
= pWindow
->GetAccessibleRelationLabelFor();
377 if ( pLabelFor
&& pLabelFor
!= pWindow
)
379 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pLabelFor
->GetAccessible() };
380 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
383 vcl::Window
* pMemberOf
= pWindow
->GetAccessibleRelationMemberOf();
384 if ( pMemberOf
&& pMemberOf
!= pWindow
)
386 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pMemberOf
->GetAccessible() };
387 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF
, aSequence
) );
392 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
394 VclPtr
<vcl::Window
> pWindow
= GetWindow();
397 if ( pWindow
->IsVisible() )
399 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
400 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
404 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
407 if ( pWindow
->IsEnabled() )
409 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
410 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
413 if ( pWindow
->HasChildPathFocus() &&
414 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
415 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
416 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
417 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
419 if ( pWindow
->HasFocus() || ( pWindow
->IsCompoundControl() && pWindow
->HasChildPathFocus() ) )
420 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
422 if ( pWindow
->IsWait() )
423 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
425 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
426 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
427 // 6. frame doesn't have MOVABLE state
428 // 10. for password text, where is the sensitive state?
429 if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||getAccessibleRole() == accessibility::AccessibleRole::DIALOG
)&& pWindow
->GetStyle() & WB_MOVEABLE
)
430 rStateSet
.AddState( accessibility::AccessibleStateType::MOVEABLE
);
431 if( pWindow
->IsDialog() )
433 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
.get() );
434 if( pDlg
->IsInExecute() )
435 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
437 //If a combobox or list's edit child isn't read-only,EDITABLE state
439 if( pWindow
&& pWindow
->GetType() == WindowType::COMBOBOX
)
441 if( !( pWindow
->GetStyle() & WB_READONLY
) ||
442 !static_cast<Edit
*>(pWindow
.get())->IsReadOnly() )
443 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
446 VclPtr
<vcl::Window
> pChild
= pWindow
->GetWindow( GetWindowType::FirstChild
);
448 while( pWindow
&& pChild
)
450 VclPtr
<vcl::Window
> pWinTemp
= pChild
->GetWindow( GetWindowType::FirstChild
);
451 if( pWinTemp
&& pWinTemp
->GetType() == WindowType::EDIT
)
453 if( !( pWinTemp
->GetStyle() & WB_READONLY
) ||
454 !static_cast<Edit
*>(pWinTemp
.get())->IsReadOnly() )
455 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
458 if( pChild
->GetType() == WindowType::EDIT
)
460 if( !( pChild
->GetStyle() & WB_READONLY
) ||
461 !static_cast<Edit
*>(pChild
.get())->IsReadOnly())
462 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
465 pChild
= pChild
->GetWindow( GetWindowType::Next
);
470 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
475 MUST BE SET FROM DERIVED CLASSES:
498 // accessibility::XAccessibleContext
499 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount()
501 OExternalLockGuard
aGuard( this );
503 sal_Int32 nChildren
= 0;
505 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
510 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
)
512 OExternalLockGuard
aGuard( this );
514 if ( i
>= getAccessibleChildCount() )
515 throw lang::IndexOutOfBoundsException();
517 uno::Reference
< accessibility::XAccessible
> xAcc
;
520 vcl::Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (sal_uInt16
)i
);
522 xAcc
= pChild
->GetAccessible();
528 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
530 uno::Reference
< accessibility::XAccessible
> xAcc
;
533 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
535 xAcc
= pParent
->GetAccessible();
540 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( )
542 OExternalLockGuard
aGuard( this );
544 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
546 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
547 xAcc
= getVclParent();
552 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( )
554 OExternalLockGuard
aGuard( this );
556 sal_Int32 nIndex
= -1;
558 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
560 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
561 // which goes the UNO way
562 nIndex
= OAccessibleExtendedComponentHelper::getAccessibleIndexInParent( );
568 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
571 // Iterate over all the parent's children and search for this object.
572 // this should be compatible with the code in SVX
573 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
574 if ( xParentAcc
.is() )
576 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
577 if ( xParentContext
.is() )
579 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
580 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
582 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
585 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
586 if ( xChildContext
== static_cast<accessibility::XAccessibleContext
*>(this) )
601 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( )
603 OExternalLockGuard
aGuard( this );
608 nRole
= GetWindow()->GetAccessibleRole();
613 OUString
VCLXAccessibleComponent::getAccessibleDescription( )
615 OExternalLockGuard
aGuard( this );
617 OUString aDescription
;
620 aDescription
= GetWindow()->GetAccessibleDescription();
625 OUString
VCLXAccessibleComponent::getAccessibleName( )
627 OExternalLockGuard
aGuard( this );
632 aName
= GetWindow()->GetAccessibleName();
633 #if OSL_DEBUG_LEVEL > 0
634 aName
+= " (Type = ";
635 aName
+= OUString::number(static_cast<sal_Int32
>(GetWindow()->GetType()));
642 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( )
644 OExternalLockGuard
aGuard( this );
646 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
647 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
648 FillAccessibleRelationSet( *pRelationSetHelper
);
652 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( )
654 OExternalLockGuard
aGuard( this );
656 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
657 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
658 FillAccessibleStateSet( *pStateSetHelper
);
662 lang::Locale
VCLXAccessibleComponent::getLocale()
664 OExternalLockGuard
aGuard( this );
666 return Application::GetSettings().GetLanguageTag().getLocale();
669 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
)
671 OExternalLockGuard
aGuard( this );
673 uno::Reference
< accessibility::XAccessible
> xChild
;
674 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
676 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
679 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
682 tools::Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
683 Point aPos
= VCLPoint( rPoint
);
684 if ( aRect
.IsInside( aPos
) )
696 // accessibility::XAccessibleComponent
697 awt::Rectangle
VCLXAccessibleComponent::implGetBounds()
699 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
701 VclPtr
<vcl::Window
> pWindow
= GetWindow();
704 tools::Rectangle aRect
= pWindow
->GetWindowExtentsRelative( nullptr );
705 aBounds
= AWTRectangle( aRect
);
706 vcl::Window
* pParent
= pWindow
->GetAccessibleParentWindow();
709 tools::Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( nullptr );
710 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
711 aBounds
.X
-= aParentScreenLoc
.X
;
712 aBounds
.Y
-= aParentScreenLoc
.Y
;
716 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
718 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
719 // us a parent which is different from our VCL parent
720 // (actually, we did not check if it's really different ...)
722 // the screen location of the foreign parent
723 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
724 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
726 awt::Point
aScreenLocForeign( 0, 0 );
727 if ( xParentComponent
.is() )
728 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
730 // the screen location of the VCL parent
731 xParent
= getVclParent();
733 xParentComponent
.set(xParent
->getAccessibleContext(), css::uno::UNO_QUERY
);
735 awt::Point
aScreenLocVCL( 0, 0 );
736 if ( xParentComponent
.is() )
737 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
739 // the difference between them
740 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
742 aBounds
.X
+= aOffset
.Width
;
743 aBounds
.Y
+= aOffset
.Height
;
749 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( )
751 OExternalLockGuard
aGuard( this );
756 tools::Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( nullptr );
757 aPos
.X
= aRect
.Left();
758 aPos
.Y
= aRect
.Top();
764 void VCLXAccessibleComponent::grabFocus( )
766 OExternalLockGuard
aGuard( this );
768 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
769 if ( m_xVCLXWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
770 m_xVCLXWindow
->setFocus();
773 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( )
775 OExternalLockGuard
aGuard( this );
777 sal_Int32 nColor
= 0;
778 VclPtr
<vcl::Window
> pWindow
= GetWindow();
781 if ( pWindow
->IsControlForeground() )
782 nColor
= pWindow
->GetControlForeground().GetColor();
786 if ( pWindow
->IsControlFont() )
787 aFont
= pWindow
->GetControlFont();
789 aFont
= pWindow
->GetFont();
790 nColor
= aFont
.GetColor().GetColor();
791 // COL_AUTO is not very meaningful for AT
792 if ( nColor
== (sal_Int32
)COL_AUTO
)
793 nColor
= pWindow
->GetTextColor().GetColor();
800 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( )
802 OExternalLockGuard
aGuard( this );
804 sal_Int32 nColor
= 0;
805 VclPtr
<vcl::Window
> pWindow
= GetWindow();
808 if ( pWindow
->IsControlBackground() )
809 nColor
= pWindow
->GetControlBackground().GetColor();
811 nColor
= pWindow
->GetBackground().GetColor().GetColor();
817 // XAccessibleExtendedComponent
819 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( )
821 OExternalLockGuard
aGuard( this );
823 uno::Reference
< awt::XFont
> xFont
;
824 VclPtr
<vcl::Window
> pWindow
= GetWindow();
827 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
831 if ( pWindow
->IsControlFont() )
832 aFont
= pWindow
->GetControlFont();
834 aFont
= pWindow
->GetFont();
835 VCLXFont
* pVCLXFont
= new VCLXFont
;
836 pVCLXFont
->Init( *xDev
.get(), aFont
);
844 OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( )
846 OExternalLockGuard
aGuard( this );
850 sRet
= GetWindow()->GetText();
855 OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( )
857 OExternalLockGuard
aGuard( this );
861 sRet
= GetWindow()->GetQuickHelpText();
866 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */