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
* pVCLXindow
)
46 : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
47 , OAccessibleImplementationAccess( )
49 mpVCLXindow
= pVCLXindow
;
50 mxWindow
= pVCLXindow
;
52 m_pSolarLock
= static_cast< VCLExternalSolarLock
* >( getExternalLock( ) );
54 DBG_ASSERT( pVCLXindow
->GetWindow(), "VCLXAccessibleComponent - no window!" );
55 if ( pVCLXindow
->GetWindow() )
57 pVCLXindow
->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
58 pVCLXindow
->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
61 // announce the XAccessible of our creator to the base class
62 lateInit( pVCLXindow
);
65 VCLXAccessibleComponent::~VCLXAccessibleComponent()
69 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
71 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
72 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
77 // This is not completely safe. If we assume that the base class dtor calls some method which
78 // uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
79 // virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
80 // lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
81 // let's assume it keeps this way.
82 // @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
85 IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
86 IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
88 OUString
VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException
, std::exception
)
90 return OUString("com.sun.star.comp.toolkit.AccessibleWindow");
93 sal_Bool
VCLXAccessibleComponent::supportsService( const OUString
& rServiceName
) throw (uno::RuntimeException
, std::exception
)
95 return cppu::supportsService(this, rServiceName
);
98 uno::Sequence
< OUString
> VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException
, std::exception
)
100 uno::Sequence
< OUString
> aNames(1);
101 aNames
[0] = "com.sun.star.awt.AccessibleWindow";
105 IMPL_LINK( VCLXAccessibleComponent
, WindowEventListener
, VclSimpleEvent
*, pEvent
)
107 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
109 /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
110 * might have been destroyed by the previous VCLEventListener (if no AT tool
111 * is running), e.g. sub-toolbars in impress.
113 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #122218# */ && (pEvent
->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE
) )
115 DBG_ASSERT( static_cast<VclWindowEvent
*>(pEvent
)->GetWindow(), "Window???" );
116 if( !static_cast<VclWindowEvent
*>(pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent
->GetId() == VCLEVENT_OBJECT_DYING
) )
118 ProcessWindowEvent( *static_cast<VclWindowEvent
*>(pEvent
) );
124 IMPL_LINK( VCLXAccessibleComponent
, WindowChildEventListener
, VclSimpleEvent
*, pEvent
)
126 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
127 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #i68079# */ )
129 DBG_ASSERT( static_cast<VclWindowEvent
*>(pEvent
)->GetWindow(), "Window???" );
130 if( !static_cast<VclWindowEvent
*>(pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() )
132 // #103087# to prevent an early release of the component
133 uno::Reference
< accessibility::XAccessibleContext
> xTmp
= this;
135 ProcessWindowChildEvent( *static_cast<VclWindowEvent
*>(pEvent
) );
141 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
143 // checks if the data in the window event is our direct child
144 // and returns its accessible
146 // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData.
147 vcl::Window
* pChildWindow
= (vcl::Window
*) rVclWindowEvent
.GetData();
148 if( pChildWindow
&& GetWindow() == pChildWindow
->GetAccessibleParentWindow() )
149 return pChildWindow
->GetAccessible( rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
151 return uno::Reference
< accessibility::XAccessible
> ();
154 void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
156 uno::Any aOldValue
, aNewValue
;
157 uno::Reference
< accessibility::XAccessible
> xAcc
;
159 switch ( rVclWindowEvent
.GetId() )
161 case VCLEVENT_WINDOW_SHOW
: // send create on show for direct accessible children
163 xAcc
= GetChildAccessible( rVclWindowEvent
);
167 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
171 case VCLEVENT_WINDOW_HIDE
: // send destroy on hide for direct accessible children
173 xAcc
= GetChildAccessible( rVclWindowEvent
);
177 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
184 void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
186 uno::Any aOldValue
, aNewValue
;
188 vcl::Window
* pAccWindow
= rVclWindowEvent
.GetWindow();
189 assert(pAccWindow
&& "VCLXAccessibleComponent::ProcessWindowEvent - Window?");
191 switch ( rVclWindowEvent
.GetId() )
193 case VCLEVENT_OBJECT_DYING
:
195 pAccWindow
->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
196 pAccWindow
->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
201 case VCLEVENT_WINDOW_CHILDDESTROYED
:
203 vcl::Window
* pWindow
= (vcl::Window
*) rVclWindowEvent
.GetData();
204 DBG_ASSERT( pWindow
, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
205 if ( pWindow
->GetAccessible( false ).is() )
207 aOldValue
<<= pWindow
->GetAccessible( false );
208 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
212 case VCLEVENT_WINDOW_ACTIVATE
:
214 // avoid notification if a child frame is already active
215 // only one frame may be active at a given time
216 if ( !pAccWindow
->HasActiveChildFrame() &&
217 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
218 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
219 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
221 aNewValue
<<= accessibility::AccessibleStateType::ACTIVE
;
222 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
226 case VCLEVENT_WINDOW_DEACTIVATE
:
228 if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
229 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
230 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) // #i18891#
232 aOldValue
<<= accessibility::AccessibleStateType::ACTIVE
;
233 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
237 case VCLEVENT_WINDOW_GETFOCUS
:
238 case VCLEVENT_CONTROL_GETFOCUS
:
240 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_GETFOCUS
) ||
241 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_GETFOCUS
) )
243 // if multiple listeners were registered it is possible that the
244 // focus was changed during event processing (eg SfxTopWindow )
245 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
246 if( (pAccWindow
->IsCompoundControl() && pAccWindow
->HasChildPathFocus()) ||
247 (!pAccWindow
->IsCompoundControl() && pAccWindow
->HasFocus()) )
249 aNewValue
<<= accessibility::AccessibleStateType::FOCUSED
;
250 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
255 case VCLEVENT_WINDOW_LOSEFOCUS
:
256 case VCLEVENT_CONTROL_LOSEFOCUS
:
258 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_LOSEFOCUS
) ||
259 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_LOSEFOCUS
) )
261 aOldValue
<<= accessibility::AccessibleStateType::FOCUSED
;
262 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
266 case VCLEVENT_WINDOW_FRAMETITLECHANGED
:
268 OUString
aOldName( *((OUString
*) rVclWindowEvent
.GetData()) );
269 OUString
aNewName( getAccessibleName() );
270 aOldValue
<<= aOldName
;
271 aNewValue
<<= aNewName
;
272 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
275 case VCLEVENT_WINDOW_ENABLED
:
277 aNewValue
<<= accessibility::AccessibleStateType::ENABLED
;
278 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
279 aNewValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
280 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
283 case VCLEVENT_WINDOW_DISABLED
:
285 aOldValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
286 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
288 aOldValue
<<= accessibility::AccessibleStateType::ENABLED
;
289 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
292 case VCLEVENT_WINDOW_MOVE
:
293 case VCLEVENT_WINDOW_RESIZE
:
295 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED
, aOldValue
, aNewValue
);
298 case VCLEVENT_WINDOW_MENUBARADDED
:
300 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
303 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
306 aNewValue
<<= xChild
;
307 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
312 case VCLEVENT_WINDOW_MENUBARREMOVED
:
314 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
317 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
320 aOldValue
<<= xChild
;
321 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
326 case VCLEVENT_WINDOW_MINIMIZE
:
328 aNewValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
329 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
332 case VCLEVENT_WINDOW_NORMALIZE
:
334 aOldValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
335 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
345 void VCLXAccessibleComponent::disposing()
347 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
349 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
350 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
353 AccessibleExtendedComponentHelper_BASE::disposing();
359 vcl::Window
* VCLXAccessibleComponent::GetWindow() const
361 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL
;
364 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
366 vcl::Window
* pWindow
= GetWindow();
369 vcl::Window
*pLabeledBy
= pWindow
->GetAccessibleRelationLabeledBy();
370 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
372 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
373 aSequence
[0] = pLabeledBy
->GetAccessible();
374 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
377 vcl::Window
* pLabelFor
= pWindow
->GetAccessibleRelationLabelFor();
378 if ( pLabelFor
&& pLabelFor
!= pWindow
)
380 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
381 aSequence
[0] = pLabelFor
->GetAccessible();
382 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
385 vcl::Window
* pMemberOf
= pWindow
->GetAccessibleRelationMemberOf();
386 if ( pMemberOf
&& pMemberOf
!= pWindow
)
388 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
389 aSequence
[0] = pMemberOf
->GetAccessible();
390 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF
, aSequence
) );
395 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
397 vcl::Window
* pWindow
= GetWindow();
400 if ( pWindow
->IsVisible() )
402 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
403 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
407 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
410 if ( pWindow
->IsEnabled() )
412 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
413 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
416 if ( pWindow
->HasChildPathFocus() &&
417 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
418 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
419 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
420 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
422 if ( pWindow
->HasFocus() || ( pWindow
->IsCompoundControl() && pWindow
->HasChildPathFocus() ) )
423 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
425 if ( pWindow
->IsWait() )
426 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
428 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
429 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
430 // 6. frame doesn't have MOVABLE state
431 // 10. for password text, where is the sensitive state?
432 if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||getAccessibleRole() == accessibility::AccessibleRole::DIALOG
)&& pWindow
->GetStyle() & WB_MOVEABLE
)
433 rStateSet
.AddState( accessibility::AccessibleStateType::MOVEABLE
);
434 if( pWindow
->IsDialog() )
436 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
);
437 if( pDlg
->IsInExecute() )
438 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
440 //If a combobox or list's edit child isn't read-only,EDITABLE state
442 if( pWindow
&& pWindow
->GetType() == WINDOW_COMBOBOX
)
444 if( !( pWindow
->GetStyle() & WB_READONLY
) ||
445 !static_cast<Edit
*>(pWindow
)->IsReadOnly() )
446 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
449 vcl::Window
* pChild
= pWindow
->GetWindow( WINDOW_FIRSTCHILD
);
451 while( pWindow
&& pChild
)
453 vcl::Window
* pWinTemp
= pChild
->GetWindow( WINDOW_FIRSTCHILD
);
454 if( pWinTemp
&& pWinTemp
->GetType() == WINDOW_EDIT
)
456 if( !( pWinTemp
->GetStyle() & WB_READONLY
) ||
457 !static_cast<Edit
*>(pWinTemp
)->IsReadOnly() )
458 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
461 if( pChild
->GetType() == WINDOW_EDIT
)
463 if( !( pChild
->GetStyle() & WB_READONLY
) ||
464 !static_cast<Edit
*>(pChild
)->IsReadOnly())
465 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
468 pChild
= pChild
->GetWindow( WINDOW_NEXT
);
473 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
478 MUST BE SET FROM DERIVED CLASSES:
501 // accessibility::XAccessibleContext
502 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException
, std::exception
)
504 OExternalLockGuard
aGuard( this );
506 sal_Int32 nChildren
= 0;
508 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
513 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
515 OExternalLockGuard
aGuard( this );
517 if ( i
>= getAccessibleChildCount() )
518 throw lang::IndexOutOfBoundsException();
520 uno::Reference
< accessibility::XAccessible
> xAcc
;
523 vcl::Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (sal_uInt16
)i
);
525 xAcc
= pChild
->GetAccessible();
531 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
533 uno::Reference
< accessibility::XAccessible
> xAcc
;
536 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
538 xAcc
= pParent
->GetAccessible();
543 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( ) throw (uno::RuntimeException
, std::exception
)
545 OExternalLockGuard
aGuard( this );
547 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
549 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
550 xAcc
= getVclParent();
555 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( ) throw (uno::RuntimeException
, std::exception
)
557 OExternalLockGuard
aGuard( this );
559 sal_Int32 nIndex
= -1;
561 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
563 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
564 // which goes the UNO way
565 nIndex
= AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
571 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
574 // Iterate over all the parent's children and search for this object.
575 // this should be compatible with the code in SVX
576 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
577 if ( xParentAcc
.is() )
579 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
580 if ( xParentContext
.is() )
582 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
583 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
585 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
588 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
589 if ( xChildContext
== (accessibility::XAccessibleContext
*) this )
604 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( ) throw (uno::RuntimeException
, std::exception
)
606 OExternalLockGuard
aGuard( this );
611 nRole
= GetWindow()->GetAccessibleRole();
616 OUString
VCLXAccessibleComponent::getAccessibleDescription( ) throw (uno::RuntimeException
, std::exception
)
618 OExternalLockGuard
aGuard( this );
620 OUString aDescription
;
623 aDescription
= GetWindow()->GetAccessibleDescription();
628 OUString
VCLXAccessibleComponent::getAccessibleName( ) throw (uno::RuntimeException
, std::exception
)
630 OExternalLockGuard
aGuard( this );
635 aName
= GetWindow()->GetAccessibleName();
636 #if OSL_DEBUG_LEVEL > 1
637 aName
+= " (Type = ";
638 aName
+= OUString::number(static_cast<sal_Int32
>(GetWindow()->GetType()));
645 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( ) throw (uno::RuntimeException
, std::exception
)
647 OExternalLockGuard
aGuard( this );
649 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
650 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
651 FillAccessibleRelationSet( *pRelationSetHelper
);
655 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( ) throw (uno::RuntimeException
, std::exception
)
657 OExternalLockGuard
aGuard( this );
659 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
660 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
661 FillAccessibleStateSet( *pStateSetHelper
);
665 lang::Locale
VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException
, uno::RuntimeException
, std::exception
)
667 OExternalLockGuard
aGuard( this );
669 return Application::GetSettings().GetLanguageTag().getLocale();
672 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
) throw (uno::RuntimeException
, std::exception
)
674 OExternalLockGuard
aGuard( this );
676 uno::Reference
< accessibility::XAccessible
> xChild
;
677 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
679 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
682 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
685 Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
686 Point aPos
= VCLPoint( rPoint
);
687 if ( aRect
.IsInside( aPos
) )
699 // accessibility::XAccessibleComponent
700 awt::Rectangle
VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException
)
702 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
704 vcl::Window
* pWindow
= GetWindow();
707 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( NULL
);
708 aBounds
= AWTRectangle( aRect
);
709 vcl::Window
* pParent
= pWindow
->GetAccessibleParentWindow();
712 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( NULL
);
713 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
714 aBounds
.X
-= aParentScreenLoc
.X
;
715 aBounds
.Y
-= aParentScreenLoc
.Y
;
719 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
721 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
722 // us a parent which is different from our VCL parent
723 // (actually, we did not check if it's really different ...)
725 // the screen location of the foreign parent
726 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
727 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
729 awt::Point
aScreenLocForeign( 0, 0 );
730 if ( xParentComponent
.is() )
731 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
733 // the screen location of the VCL parent
734 xParent
= getVclParent();
736 xParentComponent
.set(xParent
->getAccessibleContext(), css::uno::UNO_QUERY
);
738 awt::Point
aScreenLocVCL( 0, 0 );
739 if ( xParentComponent
.is() )
740 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
742 // the difference between them
743 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
745 aBounds
.X
+= aOffset
.Width
;
746 aBounds
.Y
+= aOffset
.Height
;
752 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( ) throw (uno::RuntimeException
, std::exception
)
754 OExternalLockGuard
aGuard( this );
759 Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( NULL
);
760 aPos
.X
= aRect
.Left();
761 aPos
.Y
= aRect
.Top();
767 void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException
, std::exception
)
769 OExternalLockGuard
aGuard( this );
771 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
772 if ( mxWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
773 mxWindow
->setFocus();
776 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException
, std::exception
)
778 OExternalLockGuard
aGuard( this );
780 sal_Int32 nColor
= 0;
781 vcl::Window
* pWindow
= GetWindow();
784 if ( pWindow
->IsControlForeground() )
785 nColor
= pWindow
->GetControlForeground().GetColor();
789 if ( pWindow
->IsControlFont() )
790 aFont
= pWindow
->GetControlFont();
792 aFont
= pWindow
->GetFont();
793 nColor
= aFont
.GetColor().GetColor();
794 // COL_AUTO is not very meaningful for AT
795 if ( nColor
== (sal_Int32
)COL_AUTO
)
796 nColor
= pWindow
->GetTextColor().GetColor();
803 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( ) throw (uno::RuntimeException
, std::exception
)
805 OExternalLockGuard
aGuard( this );
807 sal_Int32 nColor
= 0;
808 vcl::Window
* pWindow
= GetWindow();
811 if ( pWindow
->IsControlBackground() )
812 nColor
= pWindow
->GetControlBackground().GetColor();
814 nColor
= pWindow
->GetBackground().GetColor().GetColor();
820 // XAccessibleExtendedComponent
822 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( ) throw (uno::RuntimeException
, std::exception
)
824 OExternalLockGuard
aGuard( this );
826 uno::Reference
< awt::XFont
> xFont
;
827 vcl::Window
* pWindow
= GetWindow();
830 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
834 if ( pWindow
->IsControlFont() )
835 aFont
= pWindow
->GetControlFont();
837 aFont
= pWindow
->GetFont();
838 VCLXFont
* pVCLXFont
= new VCLXFont
;
839 pVCLXFont
->Init( *xDev
.get(), aFont
);
847 OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( ) throw (uno::RuntimeException
, std::exception
)
849 OExternalLockGuard
aGuard( this );
853 sRet
= GetWindow()->GetText();
858 OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( ) throw (uno::RuntimeException
, std::exception
)
860 OExternalLockGuard
aGuard( this );
864 sRet
= GetWindow()->GetQuickHelpText();
869 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */