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 <cppuhelper/supportsservice.hxx>
26 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
27 #include <toolkit/helper/externallock.hxx>
28 #include <toolkit/awt/vclxwindow.hxx>
29 #include <toolkit/helper/convert.hxx>
30 #include <toolkit/awt/vclxfont.hxx>
31 #include <vcl/dialog.hxx>
32 #include <vcl/vclevent.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/edit.hxx>
35 #include <vcl/settings.hxx>
36 #include <tools/debug.hxx>
37 #include <unotools/accessiblestatesethelper.hxx>
38 #include <unotools/accessiblerelationsethelper.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/menu.hxx>
42 using namespace ::com::sun::star
;
43 using namespace ::comphelper
;
45 VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow
* pVCLXWindow
)
46 : OAccessibleExtendedComponentHelper( new VCLExternalSolarLock() )
47 , OAccessibleImplementationAccess( )
49 m_xVCLXWindow
= pVCLXWindow
;
51 m_pSolarLock
= static_cast< VCLExternalSolarLock
* >( getExternalLock( ) );
53 DBG_ASSERT( pVCLXWindow
->GetWindow(), "VCLXAccessibleComponent - no window!" );
54 m_xEventSource
= pVCLXWindow
->GetWindow();
57 m_xEventSource
->AddEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
58 m_xEventSource
->AddChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
61 // announce the XAccessible of our creator to the base class
62 lateInit( pVCLXWindow
);
65 VCLXWindow
* VCLXAccessibleComponent::GetVCLXWindow() const
67 return m_xVCLXWindow
.get();
70 void VCLXAccessibleComponent::DisconnectEvents()
74 m_xEventSource
->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
75 m_xEventSource
->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
76 m_xEventSource
.clear();
80 VCLXAccessibleComponent::~VCLXAccessibleComponent()
86 m_pSolarLock
= nullptr;
87 // This is not completely safe. If we assume that the base class dtor calls some method which
88 // uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
89 // virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
90 // lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
91 // let's assume it keeps this way.
92 // @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
95 IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent
, OAccessibleExtendedComponentHelper
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
96 IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent
, OAccessibleExtendedComponentHelper
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
98 OUString
VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException
, std::exception
)
100 return OUString("com.sun.star.comp.toolkit.AccessibleWindow");
103 sal_Bool
VCLXAccessibleComponent::supportsService( const OUString
& rServiceName
) throw (uno::RuntimeException
, std::exception
)
105 return cppu::supportsService(this, rServiceName
);
108 uno::Sequence
< OUString
> VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException
, std::exception
)
110 uno::Sequence
< OUString
> aNames
{ "com.sun.star.awt.AccessibleWindow" };
114 IMPL_LINK_TYPED( VCLXAccessibleComponent
, WindowEventListener
, VclWindowEvent
&, rEvent
, void )
116 /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
117 * might have been destroyed by the previous VCLEventListener (if no AT tool
118 * is running), e.g. sub-toolbars in impress.
120 if ( m_xVCLXWindow
.is() /* #122218# */ && (rEvent
.GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE
) )
122 DBG_ASSERT( rEvent
.GetWindow(), "Window???" );
123 if( !rEvent
.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent
.GetId() == VCLEVENT_OBJECT_DYING
) )
125 ProcessWindowEvent( rEvent
);
130 IMPL_LINK_TYPED( VCLXAccessibleComponent
, WindowChildEventListener
, VclWindowEvent
&, rEvent
, void )
132 if ( m_xVCLXWindow
.is() /* #i68079# */ )
134 DBG_ASSERT( rEvent
.GetWindow(), "Window???" );
135 if( !rEvent
.GetWindow()->IsAccessibilityEventsSuppressed() )
137 // #103087# to prevent an early release of the component
138 uno::Reference
< accessibility::XAccessibleContext
> xTmp
= this;
140 ProcessWindowChildEvent( rEvent
);
145 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
147 // checks if the data in the window event is our direct child
148 // and returns its accessible
150 // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData.
151 vcl::Window
* pChildWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
152 if( pChildWindow
&& GetWindow() == pChildWindow
->GetAccessibleParentWindow() )
153 return pChildWindow
->GetAccessible( rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
155 return uno::Reference
< accessibility::XAccessible
> ();
158 void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
160 uno::Any aOldValue
, aNewValue
;
161 uno::Reference
< accessibility::XAccessible
> xAcc
;
163 switch ( rVclWindowEvent
.GetId() )
165 case VCLEVENT_WINDOW_SHOW
: // send create on show for direct accessible children
167 xAcc
= GetChildAccessible( rVclWindowEvent
);
171 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
175 case VCLEVENT_WINDOW_HIDE
: // send destroy on hide for direct accessible children
177 xAcc
= GetChildAccessible( rVclWindowEvent
);
181 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
188 void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
190 uno::Any aOldValue
, aNewValue
;
192 vcl::Window
* pAccWindow
= rVclWindowEvent
.GetWindow();
193 assert(pAccWindow
&& "VCLXAccessibleComponent::ProcessWindowEvent - Window?");
195 switch ( rVclWindowEvent
.GetId() )
197 case VCLEVENT_OBJECT_DYING
:
200 m_xVCLXWindow
.clear();
203 case VCLEVENT_WINDOW_CHILDDESTROYED
:
205 vcl::Window
* pWindow
= static_cast<vcl::Window
*>(rVclWindowEvent
.GetData());
206 DBG_ASSERT( pWindow
, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
207 if ( pWindow
->GetAccessible( false ).is() )
209 aOldValue
<<= pWindow
->GetAccessible( false );
210 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
214 case VCLEVENT_WINDOW_ACTIVATE
:
216 // avoid notification if a child frame is already active
217 // only one frame may be active at a given time
218 if ( !pAccWindow
->HasActiveChildFrame() &&
219 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
220 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
221 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
223 aNewValue
<<= accessibility::AccessibleStateType::ACTIVE
;
224 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
228 case VCLEVENT_WINDOW_DEACTIVATE
:
230 if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
231 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
232 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) // #i18891#
234 aOldValue
<<= accessibility::AccessibleStateType::ACTIVE
;
235 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
239 case VCLEVENT_WINDOW_GETFOCUS
:
240 case VCLEVENT_CONTROL_GETFOCUS
:
242 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_GETFOCUS
) ||
243 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_GETFOCUS
) )
245 // if multiple listeners were registered it is possible that the
246 // focus was changed during event processing (eg SfxTopWindow )
247 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
248 if( (pAccWindow
->IsCompoundControl() && pAccWindow
->HasChildPathFocus()) ||
249 (!pAccWindow
->IsCompoundControl() && pAccWindow
->HasFocus()) )
251 aNewValue
<<= accessibility::AccessibleStateType::FOCUSED
;
252 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
257 case VCLEVENT_WINDOW_LOSEFOCUS
:
258 case VCLEVENT_CONTROL_LOSEFOCUS
:
260 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_LOSEFOCUS
) ||
261 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_LOSEFOCUS
) )
263 aOldValue
<<= accessibility::AccessibleStateType::FOCUSED
;
264 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
268 case VCLEVENT_WINDOW_FRAMETITLECHANGED
:
270 OUString
aOldName( *static_cast<OUString
*>(rVclWindowEvent
.GetData()) );
271 OUString
aNewName( getAccessibleName() );
272 aOldValue
<<= aOldName
;
273 aNewValue
<<= aNewName
;
274 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
277 case VCLEVENT_WINDOW_ENABLED
:
279 aNewValue
<<= accessibility::AccessibleStateType::ENABLED
;
280 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
281 aNewValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
282 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
285 case VCLEVENT_WINDOW_DISABLED
:
287 aOldValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
288 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
290 aOldValue
<<= accessibility::AccessibleStateType::ENABLED
;
291 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
294 case VCLEVENT_WINDOW_MOVE
:
295 case VCLEVENT_WINDOW_RESIZE
:
297 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED
, aOldValue
, aNewValue
);
300 case VCLEVENT_WINDOW_MENUBARADDED
:
302 MenuBar
* pMenuBar
= static_cast<MenuBar
*>(rVclWindowEvent
.GetData());
305 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
308 aNewValue
<<= xChild
;
309 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
314 case VCLEVENT_WINDOW_MENUBARREMOVED
:
316 MenuBar
* pMenuBar
= static_cast<MenuBar
*>(rVclWindowEvent
.GetData());
319 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
322 aOldValue
<<= xChild
;
323 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
328 case VCLEVENT_WINDOW_MINIMIZE
:
330 aNewValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
331 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
334 case VCLEVENT_WINDOW_NORMALIZE
:
336 aOldValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
337 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
347 void VCLXAccessibleComponent::disposing()
351 OAccessibleExtendedComponentHelper::disposing();
353 m_xVCLXWindow
.clear();
356 VclPtr
<vcl::Window
> VCLXAccessibleComponent::GetWindow() const
358 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow()
359 : VclPtr
<vcl::Window
>();
362 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
364 VclPtr
<vcl::Window
> pWindow
= GetWindow();
367 vcl::Window
*pLabeledBy
= pWindow
->GetAccessibleRelationLabeledBy();
368 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
370 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pLabeledBy
->GetAccessible() };
371 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
374 vcl::Window
* pLabelFor
= pWindow
->GetAccessibleRelationLabelFor();
375 if ( pLabelFor
&& pLabelFor
!= pWindow
)
377 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pLabelFor
->GetAccessible() };
378 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
381 vcl::Window
* pMemberOf
= pWindow
->GetAccessibleRelationMemberOf();
382 if ( pMemberOf
&& pMemberOf
!= pWindow
)
384 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence
{ pMemberOf
->GetAccessible() };
385 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF
, aSequence
) );
390 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
392 VclPtr
<vcl::Window
> pWindow
= GetWindow();
395 if ( pWindow
->IsVisible() )
397 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
398 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
402 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
405 if ( pWindow
->IsEnabled() )
407 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
408 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
411 if ( pWindow
->HasChildPathFocus() &&
412 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
413 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
414 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
415 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
417 if ( pWindow
->HasFocus() || ( pWindow
->IsCompoundControl() && pWindow
->HasChildPathFocus() ) )
418 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
420 if ( pWindow
->IsWait() )
421 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
423 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
424 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
425 // 6. frame doesn't have MOVABLE state
426 // 10. for password text, where is the sensitive state?
427 if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||getAccessibleRole() == accessibility::AccessibleRole::DIALOG
)&& pWindow
->GetStyle() & WB_MOVEABLE
)
428 rStateSet
.AddState( accessibility::AccessibleStateType::MOVEABLE
);
429 if( pWindow
->IsDialog() )
431 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
.get() );
432 if( pDlg
->IsInExecute() )
433 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
435 //If a combobox or list's edit child isn't read-only,EDITABLE state
437 if( pWindow
&& pWindow
->GetType() == WINDOW_COMBOBOX
)
439 if( !( pWindow
->GetStyle() & WB_READONLY
) ||
440 !static_cast<Edit
*>(pWindow
.get())->IsReadOnly() )
441 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
444 VclPtr
<vcl::Window
> pChild
= pWindow
->GetWindow( GetWindowType::FirstChild
);
446 while( pWindow
&& pChild
)
448 VclPtr
<vcl::Window
> pWinTemp
= pChild
->GetWindow( GetWindowType::FirstChild
);
449 if( pWinTemp
&& pWinTemp
->GetType() == WINDOW_EDIT
)
451 if( !( pWinTemp
->GetStyle() & WB_READONLY
) ||
452 !static_cast<Edit
*>(pWinTemp
.get())->IsReadOnly() )
453 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
456 if( pChild
->GetType() == WINDOW_EDIT
)
458 if( !( pChild
->GetStyle() & WB_READONLY
) ||
459 !static_cast<Edit
*>(pChild
.get())->IsReadOnly())
460 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
463 pChild
= pChild
->GetWindow( GetWindowType::Next
);
468 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
473 MUST BE SET FROM DERIVED CLASSES:
496 // accessibility::XAccessibleContext
497 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException
, std::exception
)
499 OExternalLockGuard
aGuard( this );
501 sal_Int32 nChildren
= 0;
503 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
508 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
510 OExternalLockGuard
aGuard( this );
512 if ( i
>= getAccessibleChildCount() )
513 throw lang::IndexOutOfBoundsException();
515 uno::Reference
< accessibility::XAccessible
> xAcc
;
518 vcl::Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (sal_uInt16
)i
);
520 xAcc
= pChild
->GetAccessible();
526 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
528 uno::Reference
< accessibility::XAccessible
> xAcc
;
531 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
533 xAcc
= pParent
->GetAccessible();
538 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( ) throw (uno::RuntimeException
, std::exception
)
540 OExternalLockGuard
aGuard( this );
542 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
544 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
545 xAcc
= getVclParent();
550 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( ) throw (uno::RuntimeException
, std::exception
)
552 OExternalLockGuard
aGuard( this );
554 sal_Int32 nIndex
= -1;
556 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
558 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
559 // which goes the UNO way
560 nIndex
= OAccessibleExtendedComponentHelper::getAccessibleIndexInParent( );
566 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
569 // Iterate over all the parent's children and search for this object.
570 // this should be compatible with the code in SVX
571 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
572 if ( xParentAcc
.is() )
574 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
575 if ( xParentContext
.is() )
577 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
578 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
580 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
583 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
584 if ( xChildContext
== static_cast<accessibility::XAccessibleContext
*>(this) )
599 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( ) throw (uno::RuntimeException
, std::exception
)
601 OExternalLockGuard
aGuard( this );
606 nRole
= GetWindow()->GetAccessibleRole();
611 OUString
VCLXAccessibleComponent::getAccessibleDescription( ) throw (uno::RuntimeException
, std::exception
)
613 OExternalLockGuard
aGuard( this );
615 OUString aDescription
;
618 aDescription
= GetWindow()->GetAccessibleDescription();
623 OUString
VCLXAccessibleComponent::getAccessibleName( ) throw (uno::RuntimeException
, std::exception
)
625 OExternalLockGuard
aGuard( this );
630 aName
= GetWindow()->GetAccessibleName();
631 #if OSL_DEBUG_LEVEL > 0
632 aName
+= " (Type = ";
633 aName
+= OUString::number(static_cast<sal_Int32
>(GetWindow()->GetType()));
640 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( ) throw (uno::RuntimeException
, std::exception
)
642 OExternalLockGuard
aGuard( this );
644 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
645 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
646 FillAccessibleRelationSet( *pRelationSetHelper
);
650 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( ) throw (uno::RuntimeException
, std::exception
)
652 OExternalLockGuard
aGuard( this );
654 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
655 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
656 FillAccessibleStateSet( *pStateSetHelper
);
660 lang::Locale
VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException
, uno::RuntimeException
, std::exception
)
662 OExternalLockGuard
aGuard( this );
664 return Application::GetSettings().GetLanguageTag().getLocale();
667 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
) throw (uno::RuntimeException
, std::exception
)
669 OExternalLockGuard
aGuard( this );
671 uno::Reference
< accessibility::XAccessible
> xChild
;
672 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
674 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
677 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
680 Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
681 Point aPos
= VCLPoint( rPoint
);
682 if ( aRect
.IsInside( aPos
) )
694 // accessibility::XAccessibleComponent
695 awt::Rectangle
VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException
)
697 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
699 vcl::Window
* pWindow
= GetWindow();
702 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( nullptr );
703 aBounds
= AWTRectangle( aRect
);
704 vcl::Window
* pParent
= pWindow
->GetAccessibleParentWindow();
707 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( nullptr );
708 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
709 aBounds
.X
-= aParentScreenLoc
.X
;
710 aBounds
.Y
-= aParentScreenLoc
.Y
;
714 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
716 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
717 // us a parent which is different from our VCL parent
718 // (actually, we did not check if it's really different ...)
720 // the screen location of the foreign parent
721 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
722 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
724 awt::Point
aScreenLocForeign( 0, 0 );
725 if ( xParentComponent
.is() )
726 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
728 // the screen location of the VCL parent
729 xParent
= getVclParent();
731 xParentComponent
.set(xParent
->getAccessibleContext(), css::uno::UNO_QUERY
);
733 awt::Point
aScreenLocVCL( 0, 0 );
734 if ( xParentComponent
.is() )
735 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
737 // the difference between them
738 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
740 aBounds
.X
+= aOffset
.Width
;
741 aBounds
.Y
+= aOffset
.Height
;
747 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( ) throw (uno::RuntimeException
, std::exception
)
749 OExternalLockGuard
aGuard( this );
754 Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( nullptr );
755 aPos
.X
= aRect
.Left();
756 aPos
.Y
= aRect
.Top();
762 void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException
, std::exception
)
764 OExternalLockGuard
aGuard( this );
766 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
767 if ( m_xVCLXWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
768 m_xVCLXWindow
->setFocus();
771 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException
, std::exception
)
773 OExternalLockGuard
aGuard( this );
775 sal_Int32 nColor
= 0;
776 vcl::Window
* pWindow
= GetWindow();
779 if ( pWindow
->IsControlForeground() )
780 nColor
= pWindow
->GetControlForeground().GetColor();
784 if ( pWindow
->IsControlFont() )
785 aFont
= pWindow
->GetControlFont();
787 aFont
= pWindow
->GetFont();
788 nColor
= aFont
.GetColor().GetColor();
789 // COL_AUTO is not very meaningful for AT
790 if ( nColor
== (sal_Int32
)COL_AUTO
)
791 nColor
= pWindow
->GetTextColor().GetColor();
798 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( ) throw (uno::RuntimeException
, std::exception
)
800 OExternalLockGuard
aGuard( this );
802 sal_Int32 nColor
= 0;
803 vcl::Window
* pWindow
= GetWindow();
806 if ( pWindow
->IsControlBackground() )
807 nColor
= pWindow
->GetControlBackground().GetColor();
809 nColor
= pWindow
->GetBackground().GetColor().GetColor();
815 // XAccessibleExtendedComponent
817 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( ) throw (uno::RuntimeException
, std::exception
)
819 OExternalLockGuard
aGuard( this );
821 uno::Reference
< awt::XFont
> xFont
;
822 vcl::Window
* pWindow
= GetWindow();
825 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
829 if ( pWindow
->IsControlFont() )
830 aFont
= pWindow
->GetControlFont();
832 aFont
= pWindow
->GetFont();
833 VCLXFont
* pVCLXFont
= new VCLXFont
;
834 pVCLXFont
->Init( *xDev
.get(), aFont
);
842 OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( ) throw (uno::RuntimeException
, std::exception
)
844 OExternalLockGuard
aGuard( this );
848 sRet
= GetWindow()->GetText();
853 OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( ) throw (uno::RuntimeException
, std::exception
)
855 OExternalLockGuard
aGuard( this );
859 sRet
= GetWindow()->GetQuickHelpText();
864 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */