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 <toolkit/awt/vclxaccessiblecomponent.hxx>
26 #include <toolkit/helper/externallock.hxx>
27 #include <toolkit/awt/vclxwindow.hxx>
28 #include <toolkit/helper/convert.hxx>
29 #include <toolkit/awt/vclxfont.hxx>
30 #include <vcl/dialog.hxx>
31 #include <vcl/window.hxx>
32 #include <tools/debug.hxx>
33 #include <unotools/accessiblestatesethelper.hxx>
34 #include <unotools/accessiblerelationsethelper.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/menu.hxx>
38 #ifndef VCLEVENT_WINDOW_FRAMETITLECHANGED
39 #define VCLEVENT_WINDOW_FRAMETITLECHANGED 1018 // pData = XubString* = oldTitle
42 using namespace ::com::sun::star
;
43 using namespace ::comphelper
;
46 DBG_NAME(VCLXAccessibleComponent
)
49 // ----------------------------------------------------
50 // class VCLXAccessibleComponent
51 // ----------------------------------------------------
52 VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow
* pVCLXindow
)
53 : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
54 , OAccessibleImplementationAccess( )
56 DBG_CTOR( VCLXAccessibleComponent
, 0 );
57 mpVCLXindow
= pVCLXindow
;
58 mxWindow
= pVCLXindow
;
60 m_pSolarLock
= static_cast< VCLExternalSolarLock
* >( getExternalLock( ) );
62 DBG_ASSERT( pVCLXindow
->GetWindow(), "VCLXAccessibleComponent - no window!" );
63 if ( pVCLXindow
->GetWindow() )
65 pVCLXindow
->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
66 pVCLXindow
->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
69 // announce the XAccessible of our creator to the base class
70 lateInit( pVCLXindow
);
73 VCLXAccessibleComponent::~VCLXAccessibleComponent()
75 DBG_DTOR( VCLXAccessibleComponent
, 0 );
79 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
81 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
82 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
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
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
96 IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent
, AccessibleExtendedComponentHelper_BASE
, OAccessibleImplementationAccess
, VCLXAccessibleComponent_BASE
)
98 ::rtl::OUString
VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException
)
100 return ::rtl::OUString("com.sun.star.comp.toolkit.AccessibleWindow");
103 sal_Bool
VCLXAccessibleComponent::supportsService( const ::rtl::OUString
& rServiceName
) throw (uno::RuntimeException
)
105 uno::Sequence
< ::rtl::OUString
> aNames( getSupportedServiceNames() );
106 const ::rtl::OUString
* pNames
= aNames
.getConstArray();
107 const ::rtl::OUString
* pEnd
= pNames
+ aNames
.getLength();
108 for ( ; pNames
!= pEnd
&& !pNames
->equals( rServiceName
); ++pNames
)
111 return pNames
!= pEnd
;
114 uno::Sequence
< ::rtl::OUString
> VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException
)
116 uno::Sequence
< ::rtl::OUString
> aNames(1);
117 aNames
[0] = ::rtl::OUString("com.sun.star.awt.AccessibleWindow");
121 IMPL_LINK( VCLXAccessibleComponent
, WindowEventListener
, VclSimpleEvent
*, pEvent
)
123 DBG_CHKTHIS(VCLXAccessibleComponent
,0);
125 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
127 /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
128 * might have been destroyed by the previous VCLEventListener (if no AT tool
129 * is running), e.g. sub-toolbars in impress.
131 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #122218# */ && (pEvent
->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE
) )
133 DBG_ASSERT( ((VclWindowEvent
*)pEvent
)->GetWindow(), "Window???" );
134 if( !((VclWindowEvent
*)pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent
->GetId() == VCLEVENT_OBJECT_DYING
) )
136 ProcessWindowEvent( *(VclWindowEvent
*)pEvent
);
142 IMPL_LINK( VCLXAccessibleComponent
, WindowChildEventListener
, VclSimpleEvent
*, pEvent
)
144 DBG_CHKTHIS(VCLXAccessibleComponent
,0);
146 DBG_ASSERT( pEvent
&& pEvent
->ISA( VclWindowEvent
), "Unknown WindowEvent!" );
147 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
) && mxWindow
.is() /* #i68079# */ )
149 DBG_ASSERT( ((VclWindowEvent
*)pEvent
)->GetWindow(), "Window???" );
150 if( !((VclWindowEvent
*)pEvent
)->GetWindow()->IsAccessibilityEventsSuppressed() )
152 // #103087# to prevent an early release of the component
153 uno::Reference
< accessibility::XAccessibleContext
> xTmp
= this;
155 ProcessWindowChildEvent( *(VclWindowEvent
*)pEvent
);
161 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent
& rVclWindowEvent
)
163 // checks if the data in the window event is our direct child
164 // and returns its accessible
166 // MT: Change this later, normaly a show/hide event shouldn't have the Window* in pData.
167 Window
* pChildWindow
= (Window
*) rVclWindowEvent
.GetData();
168 if( pChildWindow
&& GetWindow() == pChildWindow
->GetAccessibleParentWindow() )
169 return pChildWindow
->GetAccessible( rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
171 return uno::Reference
< accessibility::XAccessible
> ();
174 void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
176 uno::Any aOldValue
, aNewValue
;
177 uno::Reference
< accessibility::XAccessible
> xAcc
;
179 switch ( rVclWindowEvent
.GetId() )
181 case VCLEVENT_WINDOW_SHOW
: // send create on show for direct accessible children
183 xAcc
= GetChildAccessible( rVclWindowEvent
);
187 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
191 case VCLEVENT_WINDOW_HIDE
: // send destroy on hide for direct accessible children
193 xAcc
= GetChildAccessible( rVclWindowEvent
);
197 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
204 void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
206 uno::Any aOldValue
, aNewValue
;
208 Window
* pAccWindow
= rVclWindowEvent
.GetWindow();
209 DBG_ASSERT( pAccWindow
, "VCLXAccessibleComponent::ProcessWindowEvent - Window?" );
211 switch ( rVclWindowEvent
.GetId() )
213 case VCLEVENT_OBJECT_DYING
:
215 pAccWindow
->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
216 pAccWindow
->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
222 // dont handle CHILDCREATED events here
223 // they are handled separately as child events, see ProcessWindowChildEvent above
226 case VCLEVENT_WINDOW_CHILDCREATED:
228 Window* pWindow = (Window*) rVclWindowEvent.GetData();
229 DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDCREATED - Window=?" );
230 aNewValue <<= pWindow->GetAccessible();
231 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
235 case VCLEVENT_WINDOW_CHILDDESTROYED
:
237 Window
* pWindow
= (Window
*) rVclWindowEvent
.GetData();
238 DBG_ASSERT( pWindow
, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
239 if ( pWindow
->GetAccessible( sal_False
).is() )
241 aOldValue
<<= pWindow
->GetAccessible( sal_False
);
242 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
248 // show and hide will be handled as child events only and are
249 // responsible for sending create/destroy events, see ProcessWindowChildEvent above
252 case VCLEVENT_WINDOW_SHOW:
254 aNewValue <<= accessibility::AccessibleStateType::VISIBLE;
255 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
257 aNewValue <<= accessibility::AccessibleStateType::SHOWING;
258 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
261 aOldValue <<= accessibility::AccessibleStateType::INVALID;
262 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
265 case VCLEVENT_WINDOW_HIDE:
267 aOldValue <<= accessibility::AccessibleStateType::VISIBLE;
268 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
270 aOldValue <<= accessibility::AccessibleStateType::SHOWING;
271 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
274 aNewValue <<= accessibility::AccessibleStateType::INVALID;
275 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
279 case VCLEVENT_WINDOW_ACTIVATE
:
281 // avoid notification if a child frame is already active
282 // only one frame may be active at a given time
283 if ( !pAccWindow
->HasActiveChildFrame() &&
284 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
285 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
286 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
288 aNewValue
<<= accessibility::AccessibleStateType::ACTIVE
;
289 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
293 case VCLEVENT_WINDOW_DEACTIVATE
:
295 if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
296 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
297 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) // #i18891#
299 aOldValue
<<= accessibility::AccessibleStateType::ACTIVE
;
300 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
304 case VCLEVENT_WINDOW_GETFOCUS
:
305 case VCLEVENT_CONTROL_GETFOCUS
:
307 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_GETFOCUS
) ||
308 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_GETFOCUS
) )
310 // if multiple listeners were registered it is possible that the
311 // focus was changed during event processing (eg SfxTopWindow )
312 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
313 if( (pAccWindow
->IsCompoundControl() && pAccWindow
->HasChildPathFocus()) ||
314 (!pAccWindow
->IsCompoundControl() && pAccWindow
->HasFocus()) )
316 aNewValue
<<= accessibility::AccessibleStateType::FOCUSED
;
317 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
322 case VCLEVENT_WINDOW_LOSEFOCUS
:
323 case VCLEVENT_CONTROL_LOSEFOCUS
:
325 if( (pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_CONTROL_LOSEFOCUS
) ||
326 (!pAccWindow
->IsCompoundControl() && rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_LOSEFOCUS
) )
328 aOldValue
<<= accessibility::AccessibleStateType::FOCUSED
;
329 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
333 case VCLEVENT_WINDOW_FRAMETITLECHANGED
:
335 ::rtl::OUString
aOldName( *((::rtl::OUString
*) rVclWindowEvent
.GetData()) );
336 ::rtl::OUString
aNewName( getAccessibleName() );
337 aOldValue
<<= aOldName
;
338 aNewValue
<<= aNewName
;
339 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
342 case VCLEVENT_WINDOW_ENABLED
:
344 aNewValue
<<= accessibility::AccessibleStateType::ENABLED
;
345 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
346 aNewValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
347 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
350 case VCLEVENT_WINDOW_DISABLED
:
352 aOldValue
<<= accessibility::AccessibleStateType::SENSITIVE
;
353 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
355 aOldValue
<<= accessibility::AccessibleStateType::ENABLED
;
356 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
359 case VCLEVENT_WINDOW_MOVE
:
360 case VCLEVENT_WINDOW_RESIZE
:
362 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED
, aOldValue
, aNewValue
);
365 case VCLEVENT_WINDOW_MENUBARADDED
:
367 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
370 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
373 aNewValue
<<= xChild
;
374 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
379 case VCLEVENT_WINDOW_MENUBARREMOVED
:
381 MenuBar
* pMenuBar
= (MenuBar
*) rVclWindowEvent
.GetData();
384 uno::Reference
< accessibility::XAccessible
> xChild( pMenuBar
->GetAccessible() );
387 aOldValue
<<= xChild
;
388 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
393 case VCLEVENT_WINDOW_MINIMIZE
:
395 aNewValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
396 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
399 case VCLEVENT_WINDOW_NORMALIZE
:
401 aOldValue
<<= accessibility::AccessibleStateType::ICONIFIED
;
402 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
412 void VCLXAccessibleComponent::disposing()
414 if ( mpVCLXindow
&& mpVCLXindow
->GetWindow() )
416 mpVCLXindow
->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent
, WindowEventListener
) );
417 mpVCLXindow
->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent
, WindowChildEventListener
) );
420 AccessibleExtendedComponentHelper_BASE::disposing();
426 Window
* VCLXAccessibleComponent::GetWindow() const
428 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL
;
431 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
433 Window
* pWindow
= GetWindow();
436 Window
*pLabeledBy
= pWindow
->GetAccessibleRelationLabeledBy();
437 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
439 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
440 aSequence
[0] = pLabeledBy
->GetAccessible();
441 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
444 Window
* pLabelFor
= pWindow
->GetAccessibleRelationLabelFor();
445 if ( pLabelFor
&& pLabelFor
!= pWindow
)
447 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
448 aSequence
[0] = pLabelFor
->GetAccessible();
449 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
454 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
456 Window
* pWindow
= GetWindow();
459 if ( pWindow
->IsVisible() )
461 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
462 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
466 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
469 if ( pWindow
->IsEnabled() )
471 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
472 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
475 if ( pWindow
->HasChildPathFocus() &&
476 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
477 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
478 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
479 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
481 // #104290# MT: This way, a ComboBox doesn't get state FOCUSED.
482 // I also don't understand
483 // a) why WINDOW_FIRSTCHILD is used here (which btw is a border window in the case of a combo box)
484 // b) why HasFocus() is nout "enough" for a compound control
486 Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
487 if ( ( !pWindow->IsCompoundControl() && pWindow->HasFocus() ) ||
488 ( pWindow->IsCompoundControl() && pChild && pChild->HasFocus() ) )
489 rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
491 if ( pWindow
->HasFocus() || ( pWindow
->IsCompoundControl() && pWindow
->HasChildPathFocus() ) )
492 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
494 if ( pWindow
->IsWait() )
495 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
497 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
498 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
500 if( pWindow
->IsDialog() )
502 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
);
503 if( pDlg
->IsInExecute() )
504 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
509 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
514 MUST BE SET FROM DERIVED CLASSES:
537 // accessibility::XAccessibleContext
538 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException
)
540 OExternalLockGuard
aGuard( this );
542 sal_Int32 nChildren
= 0;
544 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
549 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
551 OExternalLockGuard
aGuard( this );
553 if ( i
>= getAccessibleChildCount() )
554 throw lang::IndexOutOfBoundsException();
556 uno::Reference
< accessibility::XAccessible
> xAcc
;
559 Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (sal_uInt16
)i
);
561 xAcc
= pChild
->GetAccessible();
567 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
569 uno::Reference
< accessibility::XAccessible
> xAcc
;
572 Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
574 xAcc
= pParent
->GetAccessible();
579 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( ) throw (uno::RuntimeException
)
581 OExternalLockGuard
aGuard( this );
583 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
585 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
586 xAcc
= getVclParent();
591 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( ) throw (uno::RuntimeException
)
593 OExternalLockGuard
aGuard( this );
595 sal_Int32 nIndex
= -1;
597 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
599 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
600 // which goes the UNO way
601 nIndex
= AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
607 Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
611 for ( sal_uInt16 n = pParent->GetAccessibleChildWindowCount(); n; )
613 Window* pChild = pParent->GetAccessibleChildWindow( --n );
614 if ( pChild == GetWindow() )
621 // Iterate over all the parent's children and search for this object.
622 // this should be compatible with the code in SVX
623 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
624 if ( xParentAcc
.is() )
626 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
627 if ( xParentContext
.is() )
629 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
630 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
632 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
635 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
636 if ( xChildContext
== (accessibility::XAccessibleContext
*) this )
651 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( ) throw (uno::RuntimeException
)
653 OExternalLockGuard
aGuard( this );
658 nRole
= GetWindow()->GetAccessibleRole();
663 ::rtl::OUString
VCLXAccessibleComponent::getAccessibleDescription( ) throw (uno::RuntimeException
)
665 OExternalLockGuard
aGuard( this );
667 ::rtl::OUString aDescription
;
670 aDescription
= GetWindow()->GetAccessibleDescription();
675 ::rtl::OUString
VCLXAccessibleComponent::getAccessibleName( ) throw (uno::RuntimeException
)
677 OExternalLockGuard
aGuard( this );
679 ::rtl::OUString aName
;
682 aName
= GetWindow()->GetAccessibleName();
683 #if OSL_DEBUG_LEVEL > 1
684 aName
+= rtl::OUString(" (Type = ");
685 aName
+= rtl::OUString::valueOf(static_cast<sal_Int32
>(GetWindow()->GetType()));
686 aName
+= rtl::OUString( ")");
692 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( ) throw (uno::RuntimeException
)
694 OExternalLockGuard
aGuard( this );
696 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
697 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
698 FillAccessibleRelationSet( *pRelationSetHelper
);
702 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( ) throw (uno::RuntimeException
)
704 OExternalLockGuard
aGuard( this );
706 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
707 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
708 FillAccessibleStateSet( *pStateSetHelper
);
712 lang::Locale
VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException
, uno::RuntimeException
)
714 OExternalLockGuard
aGuard( this );
716 return Application::GetSettings().GetLanguageTag().getLocale();
719 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
) throw (uno::RuntimeException
)
721 OExternalLockGuard
aGuard( this );
723 uno::Reference
< accessibility::XAccessible
> xChild
;
724 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
726 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
729 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
732 Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
733 Point aPos
= VCLPoint( rPoint
);
734 if ( aRect
.IsInside( aPos
) )
746 // accessibility::XAccessibleComponent
747 awt::Rectangle
VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException
)
749 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
751 Window
* pWindow
= GetWindow();
754 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( NULL
);
755 aBounds
= AWTRectangle( aRect
);
756 Window
* pParent
= pWindow
->GetAccessibleParentWindow();
759 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( NULL
);
760 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
761 aBounds
.X
-= aParentScreenLoc
.X
;
762 aBounds
.Y
-= aParentScreenLoc
.Y
;
766 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
768 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
769 // us a parent which is different from our VCL parent
770 // (actually, we did not check if it's really different ...)
772 // the screen location of the foreign parent
773 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
774 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
776 awt::Point
aScreenLocForeign( 0, 0 );
777 if ( xParentComponent
.is() )
778 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
780 // the screen location of the VCL parent
781 xParent
= getVclParent();
783 xParentComponent
= xParentComponent
.query( xParent
->getAccessibleContext() );
785 awt::Point
aScreenLocVCL( 0, 0 );
786 if ( xParentComponent
.is() )
787 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
789 // the difference between them
790 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
792 aBounds
.X
+= aOffset
.Width
;
793 aBounds
.Y
+= aOffset
.Height
;
799 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( ) throw (uno::RuntimeException
)
801 OExternalLockGuard
aGuard( this );
806 Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( NULL
);
807 aPos
.X
= aRect
.Left();
808 aPos
.Y
= aRect
.Top();
814 void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException
)
816 OExternalLockGuard
aGuard( this );
818 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
819 if ( mxWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
820 mxWindow
->setFocus();
823 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException
)
825 OExternalLockGuard
aGuard( this );
827 sal_Int32 nColor
= 0;
828 Window
* pWindow
= GetWindow();
831 if ( pWindow
->IsControlForeground() )
832 nColor
= pWindow
->GetControlForeground().GetColor();
836 if ( pWindow
->IsControlFont() )
837 aFont
= pWindow
->GetControlFont();
839 aFont
= pWindow
->GetFont();
840 nColor
= aFont
.GetColor().GetColor();
847 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( ) throw (uno::RuntimeException
)
849 OExternalLockGuard
aGuard( this );
851 sal_Int32 nColor
= 0;
852 Window
* pWindow
= GetWindow();
855 if ( pWindow
->IsControlBackground() )
856 nColor
= pWindow
->GetControlBackground().GetColor();
858 nColor
= pWindow
->GetBackground().GetColor().GetColor();
864 // XAccessibleExtendedComponent
866 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( ) throw (uno::RuntimeException
)
868 OExternalLockGuard
aGuard( this );
870 uno::Reference
< awt::XFont
> xFont
;
871 Window
* pWindow
= GetWindow();
874 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
878 if ( pWindow
->IsControlFont() )
879 aFont
= pWindow
->GetControlFont();
881 aFont
= pWindow
->GetFont();
882 VCLXFont
* pVCLXFont
= new VCLXFont
;
883 pVCLXFont
->Init( *xDev
.get(), aFont
);
891 ::rtl::OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( ) throw (uno::RuntimeException
)
893 OExternalLockGuard
aGuard( this );
895 ::rtl::OUString sRet
;
897 sRet
= GetWindow()->GetText();
902 ::rtl::OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( ) throw (uno::RuntimeException
)
904 OExternalLockGuard
aGuard( this );
906 ::rtl::OUString sRet
;
908 sRet
= GetWindow()->GetQuickHelpText();
913 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */