1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vclxaccessiblecomponent.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_toolkit.hxx"
35 #include <com/sun/star/accessibility/AccessibleRole.hpp>
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
39 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
40 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
41 #include <toolkit/helper/externallock.hxx>
42 #include <toolkit/awt/vclxwindow.hxx>
43 #include <toolkit/helper/convert.hxx>
44 #include <toolkit/awt/vclxfont.hxx>
45 #include <vcl/dialog.hxx>
46 #include <vcl/window.hxx>
47 #include <tools/debug.hxx>
48 #include <unotools/accessiblestatesethelper.hxx>
49 #include <unotools/accessiblerelationsethelper.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/menu.hxx>
53 #ifndef VCLEVENT_WINDOW_FRAMETITLECHANGED
54 #define VCLEVENT_WINDOW_FRAMETITLECHANGED 1018 // pData = XubString* = oldTitle
57 using namespace ::com::sun::star
;
58 using namespace ::comphelper
;
61 DBG_NAME(VCLXAccessibleComponent
)
64 // ----------------------------------------------------
65 // class VCLXAccessibleComponent
66 // ----------------------------------------------------
67 VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow
* pVCLXindow
)
68 : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
69 , OAccessibleImplementationAccess( )
71 DBG_CTOR( VCLXAccessibleComponent
, 0 );
72 mpVCLXindow
= pVCLXindow
;
73 mxWindow
= pVCLXindow
;
75 m_pSolarLock
= static_cast< VCLExternalSolarLock
* >( getExternalLock( ) );
77 DBG_ASSERT( pVCLXindow
->GetWindow(), "VCLXAccessibleComponent - no window!" );
78 if ( pVCLXindow
->GetWindow() )
80 pVCLXindow
->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
81 pVCLXindow
->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
84 // announce the XAccessible of our creator to the base class
85 lateInit( pVCLXindow
);
88 VCLXAccessibleComponent::~VCLXAccessibleComponent()
90 DBG_DTOR( VCLXAccessibleComponent
, 0 );
94 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
96 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
97 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
102 // This is not completely safe. If we assume that the base class dtor calls some method which
103 // uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
104 // virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
105 // lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
106 // let's assume it keeps this way.
107 // @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
110 IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
111 IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
113 ::rtl::OUString
VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException
)
115 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleWindow" );
118 sal_Bool
VCLXAccessibleComponent::supportsService( const ::rtl::OUString
& rServiceName
) throw (uno::RuntimeException
)
120 uno::Sequence
< ::rtl::OUString
> aNames( getSupportedServiceNames() );
121 const ::rtl::OUString
* pNames
= aNames
.getConstArray();
122 const ::rtl::OUString
* pEnd
= pNames
+ aNames
.getLength();
123 for ( ; pNames
!= pEnd
&& !pNames
->equals( rServiceName
); ++pNames
)
126 return pNames
!= pEnd
;
129 uno::Sequence
< ::rtl::OUString
> VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException
)
131 uno::Sequence
< ::rtl::OUString
> aNames(1);
132 aNames
[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleWindow" );
136 IMPL_LINK( VCLXAccessibleComponent
, WindowEventListener
, VclSimpleEvent
*, pEvent
)
138 DBG_CHKTHIS(VCLXAccessibleComponent
,0);
140 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
142 /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
143 * might have been destroyed by the previous VCLEventListener (if no AT tool
144 * is running), e.g. sub-toolbars in impress.
146 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #122218# */ && (pEvent
->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE
) )
148 DBG_ASSERT( ((VclWindowEvent
*)pEvent
)->GetWindow(), "Window???" );
149 if( !((VclWindowEvent
*)pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent
->GetId() == VCLEVENT_OBJECT_DYING
) )
151 ProcessWindowEvent( *(VclWindowEvent
*)pEvent
);
157 IMPL_LINK( VCLXAccessibleComponent
, WindowChildEventListener
, VclSimpleEvent
*, pEvent
)
159 DBG_CHKTHIS(VCLXAccessibleComponent
,0);
161 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
162 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #i68079# */ )
164 DBG_ASSERT( ((VclWindowEvent
*)pEvent
)->GetWindow(), "Window???" );
165 if( !((VclWindowEvent
*)pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() )
167 // #103087# to prevent an early release of the component
168 uno::Reference
< accessibility::XAccessibleContext
> xTmp
= this;
170 ProcessWindowChildEvent( *(VclWindowEvent
*)pEvent
);
176 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
178 // checks if the data in the window event is our direct child
179 // and returns its accessible
181 // MT: Change this later, normaly a show/hide event shouldn't have the Window* in pData.
182 Window
* pChildWindow
= (Window
*) rVclWindowEvent
.GetData();
183 if( pChildWindow
&& GetWindow() == pChildWindow
->GetAccessibleParentWindow() )
184 return pChildWindow
->GetAccessible( rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
186 return uno::Reference
< accessibility::XAccessible
> ();
189 void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
191 uno::Any aOldValue
, aNewValue
;
192 uno::Reference
< accessibility::XAccessible
> xAcc
;
194 switch ( rVclWindowEvent
.GetId() )
196 case VCLEVENT_WINDOW_SHOW
: // send create on show for direct accessible children
198 xAcc
= GetChildAccessible( rVclWindowEvent
);
202 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
206 case VCLEVENT_WINDOW_HIDE
: // send destroy on hide for direct accessible children
208 xAcc
= GetChildAccessible( rVclWindowEvent
);
212 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
219 void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
221 uno::Any aOldValue
, aNewValue
;
223 Window
* pAccWindow
= rVclWindowEvent
.GetWindow();
224 DBG_ASSERT( pAccWindow
, "VCLXAccessibleComponent::ProcessWindowEvent - Window?" );
226 switch ( rVclWindowEvent
.GetId() )
228 case VCLEVENT_OBJECT_DYING
:
230 pAccWindow
->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
231 pAccWindow
->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
237 // dont handle CHILDCREATED events here
238 // they are handled separately as child events, see ProcessWindowChildEvent above
241 case VCLEVENT_WINDOW_CHILDCREATED:
243 Window* pWindow = (Window*) rVclWindowEvent.GetData();
244 DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDCREATED - Window=?" );
245 aNewValue <<= pWindow->GetAccessible();
246 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
250 case VCLEVENT_WINDOW_CHILDDESTROYED
:
252 Window
* pWindow
= (Window
*) rVclWindowEvent
.GetData();
253 DBG_ASSERT( pWindow
, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
254 if ( pWindow
->GetAccessible( FALSE
).is() )
256 aOldValue
<<= pWindow
->GetAccessible( FALSE
);
257 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
263 // show and hide will be handled as child events only and are
264 // responsible for sending create/destroy events, see ProcessWindowChildEvent above
267 case VCLEVENT_WINDOW_SHOW:
269 aNewValue <<= accessibility::AccessibleStateType::VISIBLE;
270 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
272 aNewValue <<= accessibility::AccessibleStateType::SHOWING;
273 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
276 aOldValue <<= accessibility::AccessibleStateType::INVALID;
277 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
280 case VCLEVENT_WINDOW_HIDE:
282 aOldValue <<= accessibility::AccessibleStateType::VISIBLE;
283 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
285 aOldValue <<= accessibility::AccessibleStateType::SHOWING;
286 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
289 aNewValue <<= accessibility::AccessibleStateType::INVALID;
290 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
294 case VCLEVENT_WINDOW_ACTIVATE
:
296 // avoid notification if a child frame is already active
297 // only one frame may be active at a given time
298 if ( !pAccWindow
->HasActiveChildFrame() &&
299 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
300 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
301 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
303 aNewValue
<<= accessibility::AccessibleStateType::ACTIVE
;
304 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
308 case VCLEVENT_WINDOW_DEACTIVATE
:
310 if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
311 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
312 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) // #i18891#
314 aOldValue
<<= accessibility::AccessibleStateType::ACTIVE
;
315 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
319 case VCLEVENT_WINDOW_GETFOCUS
:
320 case VCLEVENT_CONTROL_GETFOCUS
:
322 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_GETFOCUS
) ||
323 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_GETFOCUS
) )
325 // if multiple listeners were registered it is possible that the
326 // focus was changed during event processing (eg SfxTopWindow )
327 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
328 if( (pAccWindow
->IsCompoundControl() && pAccWindow
->HasChildPathFocus()) ||
329 (!pAccWindow
->IsCompoundControl() && pAccWindow
->HasFocus()) )
331 aNewValue
<<= accessibility::AccessibleStateType::FOCUSED
;
332 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
337 case VCLEVENT_WINDOW_LOSEFOCUS
:
338 case VCLEVENT_CONTROL_LOSEFOCUS
:
340 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_LOSEFOCUS
) ||
341 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_LOSEFOCUS
) )
343 aOldValue
<<= accessibility::AccessibleStateType::FOCUSED
;
344 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
348 case VCLEVENT_WINDOW_FRAMETITLECHANGED
:
350 ::rtl::OUString
aOldName( *((::rtl::OUString
*) rVclWindowEvent
.GetData()) );
351 ::rtl::OUString
aNewName( getAccessibleName() );
352 aOldValue
<<= aOldName
;
353 aNewValue
<<= aNewName
;
354 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
357 case VCLEVENT_WINDOW_ENABLED
:
359 aNewValue
<<= accessibility::AccessibleStateType::ENABLED
;
360 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
361 aNewValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
362 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
365 case VCLEVENT_WINDOW_DISABLED
:
367 aOldValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
368 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
370 aOldValue
<<= accessibility::AccessibleStateType::ENABLED
;
371 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
374 case VCLEVENT_WINDOW_MOVE
:
375 case VCLEVENT_WINDOW_RESIZE
:
377 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED
, aOldValue
, aNewValue
);
380 case VCLEVENT_WINDOW_MENUBARADDED
:
382 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
385 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
388 aNewValue
<<= xChild
;
389 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
394 case VCLEVENT_WINDOW_MENUBARREMOVED
:
396 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
399 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
402 aOldValue
<<= xChild
;
403 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
408 case VCLEVENT_WINDOW_MINIMIZE
:
410 aNewValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
411 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
414 case VCLEVENT_WINDOW_NORMALIZE
:
416 aOldValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
417 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
427 void VCLXAccessibleComponent::disposing()
429 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
431 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
432 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
435 AccessibleExtendedComponentHelper_BASE::disposing();
441 Window
* VCLXAccessibleComponent::GetWindow() const
443 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL
;
446 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
448 Window
* pWindow
= GetWindow();
451 Window
*pLabeledBy
= pWindow
->GetLabeledBy();
452 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
454 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
455 aSequence
[0] = pLabeledBy
->GetAccessible();
456 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
459 Window
* pLabelFor
= pWindow
->GetLabelFor();
460 if ( pLabelFor
&& pLabelFor
!= pWindow
)
462 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
463 aSequence
[0] = pLabelFor
->GetAccessible();
464 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
469 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
471 Window
* pWindow
= GetWindow();
474 if ( pWindow
->IsVisible() )
476 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
477 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
481 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
484 if ( pWindow
->IsEnabled() )
486 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
487 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
490 if ( pWindow
->HasChildPathFocus() &&
491 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
492 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
493 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
494 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
496 Window
* pChild
= pWindow
->GetWindow( WINDOW_FIRSTCHILD
);
497 if ( ( !pWindow
->IsCompoundControl() && pWindow
->HasFocus() ) ||
498 ( pWindow
->IsCompoundControl() && pChild
&& pChild
->HasFocus() ) )
499 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
501 if ( pWindow
->IsWait() )
502 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
504 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
505 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
507 if( pWindow
->IsDialog() )
509 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
);
510 if( pDlg
->IsInExecute() )
511 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
516 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
521 MUST BE SET FROM DERIVED CLASSES:
544 // accessibility::XAccessibleContext
545 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException
)
547 OExternalLockGuard
aGuard( this );
549 sal_Int32 nChildren
= 0;
551 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
556 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
558 OExternalLockGuard
aGuard( this );
560 if ( i
>= getAccessibleChildCount() )
561 throw lang::IndexOutOfBoundsException();
563 uno::Reference
< accessibility::XAccessible
> xAcc
;
566 Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (USHORT
)i
);
568 xAcc
= pChild
->GetAccessible();
574 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
576 uno::Reference
< accessibility::XAccessible
> xAcc
;
579 Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
581 xAcc
= pParent
->GetAccessible();
586 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( ) throw (uno::RuntimeException
)
588 OExternalLockGuard
aGuard( this );
590 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
592 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
593 xAcc
= getVclParent();
598 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( ) throw (uno::RuntimeException
)
600 OExternalLockGuard
aGuard( this );
602 sal_Int32 nIndex
= -1;
604 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
606 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
607 // which goes the UNO way
608 nIndex
= AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
614 Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
618 for ( USHORT n = pParent->GetAccessibleChildWindowCount(); n; )
620 Window* pChild = pParent->GetAccessibleChildWindow( --n );
621 if ( pChild == GetWindow() )
628 // Iterate over all the parent's children and search for this object.
629 // this should be compatible with the code in SVX
630 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
631 if ( xParentAcc
.is() )
633 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
634 if ( xParentContext
.is() )
636 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
637 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
639 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
642 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
643 if ( xChildContext
== (accessibility::XAccessibleContext
*) this )
658 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( ) throw (uno::RuntimeException
)
660 OExternalLockGuard
aGuard( this );
665 nRole
= GetWindow()->GetAccessibleRole();
670 ::rtl::OUString
VCLXAccessibleComponent::getAccessibleDescription( ) throw (uno::RuntimeException
)
672 OExternalLockGuard
aGuard( this );
674 ::rtl::OUString aDescription
;
677 aDescription
= GetWindow()->GetAccessibleDescription();
682 ::rtl::OUString
VCLXAccessibleComponent::getAccessibleName( ) throw (uno::RuntimeException
)
684 OExternalLockGuard
aGuard( this );
686 ::rtl::OUString aName
;
689 aName
= GetWindow()->GetAccessibleName();
690 #if OSL_DEBUG_LEVEL > 1
691 aName
+= String( RTL_CONSTASCII_USTRINGPARAM( " (Type = " ) );
692 aName
+= String::CreateFromInt32( GetWindow()->GetType() );
693 aName
+= String( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
699 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( ) throw (uno::RuntimeException
)
701 OExternalLockGuard
aGuard( this );
703 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
704 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
705 FillAccessibleRelationSet( *pRelationSetHelper
);
709 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( ) throw (uno::RuntimeException
)
711 OExternalLockGuard
aGuard( this );
713 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
714 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
715 FillAccessibleStateSet( *pStateSetHelper
);
719 lang::Locale
VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException
, uno::RuntimeException
)
721 OExternalLockGuard
aGuard( this );
723 return Application::GetSettings().GetLocale();
726 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
) throw (uno::RuntimeException
)
728 OExternalLockGuard
aGuard( this );
730 uno::Reference
< accessibility::XAccessible
> xChild
;
731 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
733 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
736 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
739 Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
740 Point aPos
= VCLPoint( rPoint
);
741 if ( aRect
.IsInside( aPos
) )
753 // accessibility::XAccessibleComponent
754 awt::Rectangle
VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException
)
756 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
758 Window
* pWindow
= GetWindow();
761 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( NULL
);
762 aBounds
= AWTRectangle( aRect
);
763 Window
* pParent
= pWindow
->GetAccessibleParentWindow();
766 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( NULL
);
767 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
768 aBounds
.X
-= aParentScreenLoc
.X
;
769 aBounds
.Y
-= aParentScreenLoc
.Y
;
773 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
775 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
776 // us a parent which is different from our VCL parent
777 // (actually, we did not check if it's really different ...)
779 // the screen location of the foreign parent
780 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
781 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
783 awt::Point
aScreenLocForeign( 0, 0 );
784 if ( xParentComponent
.is() )
785 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
787 // the screen location of the VCL parent
788 xParent
= getVclParent();
790 xParentComponent
= xParentComponent
.query( xParent
->getAccessibleContext() );
792 awt::Point
aScreenLocVCL( 0, 0 );
793 if ( xParentComponent
.is() )
794 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
796 // the difference between them
797 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
799 aBounds
.X
+= aOffset
.Width
;
800 aBounds
.Y
+= aOffset
.Height
;
806 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( ) throw (uno::RuntimeException
)
808 OExternalLockGuard
aGuard( this );
813 Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( NULL
);
814 aPos
.X
= aRect
.Left();
815 aPos
.Y
= aRect
.Top();
821 void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException
)
823 OExternalLockGuard
aGuard( this );
825 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
826 if ( mxWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
827 mxWindow
->setFocus();
830 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException
)
832 OExternalLockGuard
aGuard( this );
834 sal_Int32 nColor
= 0;
835 Window
* pWindow
= GetWindow();
838 if ( pWindow
->IsControlForeground() )
839 nColor
= pWindow
->GetControlForeground().GetColor();
843 if ( pWindow
->IsControlFont() )
844 aFont
= pWindow
->GetControlFont();
846 aFont
= pWindow
->GetFont();
847 nColor
= aFont
.GetColor().GetColor();
854 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( ) throw (uno::RuntimeException
)
856 OExternalLockGuard
aGuard( this );
858 sal_Int32 nColor
= 0;
859 Window
* pWindow
= GetWindow();
862 if ( pWindow
->IsControlBackground() )
863 nColor
= pWindow
->GetControlBackground().GetColor();
865 nColor
= pWindow
->GetBackground().GetColor().GetColor();
871 // XAccessibleExtendedComponent
873 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( ) throw (uno::RuntimeException
)
875 OExternalLockGuard
aGuard( this );
877 uno::Reference
< awt::XFont
> xFont
;
878 Window
* pWindow
= GetWindow();
881 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
885 if ( pWindow
->IsControlFont() )
886 aFont
= pWindow
->GetControlFont();
888 aFont
= pWindow
->GetFont();
889 VCLXFont
* pVCLXFont
= new VCLXFont
;
890 pVCLXFont
->Init( *xDev
.get(), aFont
);
898 ::rtl::OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( ) throw (uno::RuntimeException
)
900 OExternalLockGuard
aGuard( this );
902 ::rtl::OUString sRet
;
904 sRet
= GetWindow()->GetText();
909 ::rtl::OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( ) throw (uno::RuntimeException
)
911 OExternalLockGuard
aGuard( this );
913 ::rtl::OUString sRet
;
915 sRet
= GetWindow()->GetQuickHelpText();