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
= static_cast<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
= static_cast<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( *static_cast<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
= static_cast<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
= static_cast<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 VclPtr
<vcl::Window
> VCLXAccessibleComponent::GetWindow() const
361 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow()
362 : VclPtr
<vcl::Window
>();
365 void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper
& rRelationSet
)
367 VclPtr
<vcl::Window
> pWindow
= GetWindow();
370 vcl::Window
*pLabeledBy
= pWindow
->GetAccessibleRelationLabeledBy();
371 if ( pLabeledBy
&& pLabeledBy
!= pWindow
)
373 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
374 aSequence
[0] = pLabeledBy
->GetAccessible();
375 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY
, aSequence
) );
378 vcl::Window
* pLabelFor
= pWindow
->GetAccessibleRelationLabelFor();
379 if ( pLabelFor
&& pLabelFor
!= pWindow
)
381 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
382 aSequence
[0] = pLabelFor
->GetAccessible();
383 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR
, aSequence
) );
386 vcl::Window
* pMemberOf
= pWindow
->GetAccessibleRelationMemberOf();
387 if ( pMemberOf
&& pMemberOf
!= pWindow
)
389 uno::Sequence
< uno::Reference
< uno::XInterface
> > aSequence(1);
390 aSequence
[0] = pMemberOf
->GetAccessible();
391 rRelationSet
.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF
, aSequence
) );
396 void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
398 VclPtr
<vcl::Window
> pWindow
= GetWindow();
401 if ( pWindow
->IsVisible() )
403 rStateSet
.AddState( accessibility::AccessibleStateType::VISIBLE
);
404 rStateSet
.AddState( accessibility::AccessibleStateType::SHOWING
);
408 rStateSet
.AddState( accessibility::AccessibleStateType::INVALID
);
411 if ( pWindow
->IsEnabled() )
413 rStateSet
.AddState( accessibility::AccessibleStateType::ENABLED
);
414 rStateSet
.AddState( accessibility::AccessibleStateType::SENSITIVE
);
417 if ( pWindow
->HasChildPathFocus() &&
418 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||
419 getAccessibleRole() == accessibility::AccessibleRole::ALERT
||
420 getAccessibleRole() == accessibility::AccessibleRole::DIALOG
) ) // #i18891#
421 rStateSet
.AddState( accessibility::AccessibleStateType::ACTIVE
);
423 if ( pWindow
->HasFocus() || ( pWindow
->IsCompoundControl() && pWindow
->HasChildPathFocus() ) )
424 rStateSet
.AddState( accessibility::AccessibleStateType::FOCUSED
);
426 if ( pWindow
->IsWait() )
427 rStateSet
.AddState( accessibility::AccessibleStateType::BUSY
);
429 if ( pWindow
->GetStyle() & WB_SIZEABLE
)
430 rStateSet
.AddState( accessibility::AccessibleStateType::RESIZABLE
);
431 // 6. frame doesn't have MOVABLE state
432 // 10. for password text, where is the sensitive state?
433 if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME
||getAccessibleRole() == accessibility::AccessibleRole::DIALOG
)&& pWindow
->GetStyle() & WB_MOVEABLE
)
434 rStateSet
.AddState( accessibility::AccessibleStateType::MOVEABLE
);
435 if( pWindow
->IsDialog() )
437 Dialog
*pDlg
= static_cast< Dialog
* >( pWindow
.get() );
438 if( pDlg
->IsInExecute() )
439 rStateSet
.AddState( accessibility::AccessibleStateType::MODAL
);
441 //If a combobox or list's edit child isn't read-only,EDITABLE state
443 if( pWindow
&& pWindow
->GetType() == WINDOW_COMBOBOX
)
445 if( !( pWindow
->GetStyle() & WB_READONLY
) ||
446 !static_cast<Edit
*>(pWindow
.get())->IsReadOnly() )
447 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
450 VclPtr
<vcl::Window
> pChild
= pWindow
->GetWindow( GetWindowType::FirstChild
);
452 while( pWindow
&& pChild
)
454 VclPtr
<vcl::Window
> pWinTemp
= pChild
->GetWindow( GetWindowType::FirstChild
);
455 if( pWinTemp
&& pWinTemp
->GetType() == WINDOW_EDIT
)
457 if( !( pWinTemp
->GetStyle() & WB_READONLY
) ||
458 !static_cast<Edit
*>(pWinTemp
.get())->IsReadOnly() )
459 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
462 if( pChild
->GetType() == WINDOW_EDIT
)
464 if( !( pChild
->GetStyle() & WB_READONLY
) ||
465 !static_cast<Edit
*>(pChild
.get())->IsReadOnly())
466 rStateSet
.AddState( accessibility::AccessibleStateType::EDITABLE
);
469 pChild
= pChild
->GetWindow( GetWindowType::Next
);
474 rStateSet
.AddState( accessibility::AccessibleStateType::DEFUNC
);
479 MUST BE SET FROM DERIVED CLASSES:
502 // accessibility::XAccessibleContext
503 sal_Int32
VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException
, std::exception
)
505 OExternalLockGuard
aGuard( this );
507 sal_Int32 nChildren
= 0;
509 nChildren
= GetWindow()->GetAccessibleChildWindowCount();
514 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
516 OExternalLockGuard
aGuard( this );
518 if ( i
>= getAccessibleChildCount() )
519 throw lang::IndexOutOfBoundsException();
521 uno::Reference
< accessibility::XAccessible
> xAcc
;
524 vcl::Window
* pChild
= GetWindow()->GetAccessibleChildWindow( (sal_uInt16
)i
);
526 xAcc
= pChild
->GetAccessible();
532 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getVclParent() const
534 uno::Reference
< accessibility::XAccessible
> xAcc
;
537 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
539 xAcc
= pParent
->GetAccessible();
544 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleParent( ) throw (uno::RuntimeException
, std::exception
)
546 OExternalLockGuard
aGuard( this );
548 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
550 // we do _not_ have a foreign-controlled parent -> default to our VCL parent
551 xAcc
= getVclParent();
556 sal_Int32
VCLXAccessibleComponent::getAccessibleIndexInParent( ) throw (uno::RuntimeException
, std::exception
)
558 OExternalLockGuard
aGuard( this );
560 sal_Int32 nIndex
= -1;
562 uno::Reference
< accessibility::XAccessible
> xAcc( implGetForeignControlledParent() );
564 { // we _do_ have a foreign-controlled parent -> use the base class' implementation,
565 // which goes the UNO way
566 nIndex
= AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
572 vcl::Window
* pParent
= GetWindow()->GetAccessibleParentWindow();
575 // Iterate over all the parent's children and search for this object.
576 // this should be compatible with the code in SVX
577 uno::Reference
< accessibility::XAccessible
> xParentAcc( pParent
->GetAccessible() );
578 if ( xParentAcc
.is() )
580 uno::Reference
< accessibility::XAccessibleContext
> xParentContext ( xParentAcc
->getAccessibleContext() );
581 if ( xParentContext
.is() )
583 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
584 for ( sal_Int32 i
=0; i
<nChildCount
; i
++ )
586 uno::Reference
< accessibility::XAccessible
> xChild( xParentContext
->getAccessibleChild(i
) );
589 uno::Reference
< accessibility::XAccessibleContext
> xChildContext
= xChild
->getAccessibleContext();
590 if ( xChildContext
== (accessibility::XAccessibleContext
*) this )
605 sal_Int16
VCLXAccessibleComponent::getAccessibleRole( ) throw (uno::RuntimeException
, std::exception
)
607 OExternalLockGuard
aGuard( this );
612 nRole
= GetWindow()->GetAccessibleRole();
617 OUString
VCLXAccessibleComponent::getAccessibleDescription( ) throw (uno::RuntimeException
, std::exception
)
619 OExternalLockGuard
aGuard( this );
621 OUString aDescription
;
624 aDescription
= GetWindow()->GetAccessibleDescription();
629 OUString
VCLXAccessibleComponent::getAccessibleName( ) throw (uno::RuntimeException
, std::exception
)
631 OExternalLockGuard
aGuard( this );
636 aName
= GetWindow()->GetAccessibleName();
637 #if OSL_DEBUG_LEVEL > 1
638 aName
+= " (Type = ";
639 aName
+= OUString::number(static_cast<sal_Int32
>(GetWindow()->GetType()));
646 uno::Reference
< accessibility::XAccessibleRelationSet
> VCLXAccessibleComponent::getAccessibleRelationSet( ) throw (uno::RuntimeException
, std::exception
)
648 OExternalLockGuard
aGuard( this );
650 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
651 uno::Reference
< accessibility::XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
652 FillAccessibleRelationSet( *pRelationSetHelper
);
656 uno::Reference
< accessibility::XAccessibleStateSet
> VCLXAccessibleComponent::getAccessibleStateSet( ) throw (uno::RuntimeException
, std::exception
)
658 OExternalLockGuard
aGuard( this );
660 utl::AccessibleStateSetHelper
* pStateSetHelper
= new utl::AccessibleStateSetHelper
;
661 uno::Reference
< accessibility::XAccessibleStateSet
> xSet
= pStateSetHelper
;
662 FillAccessibleStateSet( *pStateSetHelper
);
666 lang::Locale
VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException
, uno::RuntimeException
, std::exception
)
668 OExternalLockGuard
aGuard( this );
670 return Application::GetSettings().GetLanguageTag().getLocale();
673 uno::Reference
< accessibility::XAccessible
> VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point
& rPoint
) throw (uno::RuntimeException
, std::exception
)
675 OExternalLockGuard
aGuard( this );
677 uno::Reference
< accessibility::XAccessible
> xChild
;
678 for ( sal_uInt32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
680 uno::Reference
< accessibility::XAccessible
> xAcc
= getAccessibleChild( i
);
683 uno::Reference
< accessibility::XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), uno::UNO_QUERY
);
686 Rectangle aRect
= VCLRectangle( xComp
->getBounds() );
687 Point aPos
= VCLPoint( rPoint
);
688 if ( aRect
.IsInside( aPos
) )
700 // accessibility::XAccessibleComponent
701 awt::Rectangle
VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException
)
703 awt::Rectangle
aBounds ( 0, 0, 0, 0 );
705 vcl::Window
* pWindow
= GetWindow();
708 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( NULL
);
709 aBounds
= AWTRectangle( aRect
);
710 vcl::Window
* pParent
= pWindow
->GetAccessibleParentWindow();
713 Rectangle aParentRect
= pParent
->GetWindowExtentsRelative( NULL
);
714 awt::Point aParentScreenLoc
= AWTPoint( aParentRect
.TopLeft() );
715 aBounds
.X
-= aParentScreenLoc
.X
;
716 aBounds
.Y
-= aParentScreenLoc
.Y
;
720 uno::Reference
< accessibility::XAccessible
> xParent( implGetForeignControlledParent() );
722 { // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
723 // us a parent which is different from our VCL parent
724 // (actually, we did not check if it's really different ...)
726 // the screen location of the foreign parent
727 uno::Reference
< accessibility::XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), uno::UNO_QUERY
);
728 DBG_ASSERT( xParentComponent
.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
730 awt::Point
aScreenLocForeign( 0, 0 );
731 if ( xParentComponent
.is() )
732 aScreenLocForeign
= xParentComponent
->getLocationOnScreen();
734 // the screen location of the VCL parent
735 xParent
= getVclParent();
737 xParentComponent
.set(xParent
->getAccessibleContext(), css::uno::UNO_QUERY
);
739 awt::Point
aScreenLocVCL( 0, 0 );
740 if ( xParentComponent
.is() )
741 aScreenLocVCL
= xParentComponent
->getLocationOnScreen();
743 // the difference between them
744 awt::Size
aOffset( aScreenLocVCL
.X
- aScreenLocForeign
.X
, aScreenLocVCL
.Y
- aScreenLocForeign
.Y
);
746 aBounds
.X
+= aOffset
.Width
;
747 aBounds
.Y
+= aOffset
.Height
;
753 awt::Point
VCLXAccessibleComponent::getLocationOnScreen( ) throw (uno::RuntimeException
, std::exception
)
755 OExternalLockGuard
aGuard( this );
760 Rectangle aRect
= GetWindow()->GetWindowExtentsRelative( NULL
);
761 aPos
.X
= aRect
.Left();
762 aPos
.Y
= aRect
.Top();
768 void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException
, std::exception
)
770 OExternalLockGuard
aGuard( this );
772 uno::Reference
< accessibility::XAccessibleStateSet
> xStates
= getAccessibleStateSet();
773 if ( mxWindow
.is() && xStates
.is() && xStates
->contains( accessibility::AccessibleStateType::FOCUSABLE
) )
774 mxWindow
->setFocus();
777 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException
, std::exception
)
779 OExternalLockGuard
aGuard( this );
781 sal_Int32 nColor
= 0;
782 vcl::Window
* pWindow
= GetWindow();
785 if ( pWindow
->IsControlForeground() )
786 nColor
= pWindow
->GetControlForeground().GetColor();
790 if ( pWindow
->IsControlFont() )
791 aFont
= pWindow
->GetControlFont();
793 aFont
= pWindow
->GetFont();
794 nColor
= aFont
.GetColor().GetColor();
795 // COL_AUTO is not very meaningful for AT
796 if ( nColor
== (sal_Int32
)COL_AUTO
)
797 nColor
= pWindow
->GetTextColor().GetColor();
804 sal_Int32 SAL_CALL
VCLXAccessibleComponent::getBackground( ) throw (uno::RuntimeException
, std::exception
)
806 OExternalLockGuard
aGuard( this );
808 sal_Int32 nColor
= 0;
809 vcl::Window
* pWindow
= GetWindow();
812 if ( pWindow
->IsControlBackground() )
813 nColor
= pWindow
->GetControlBackground().GetColor();
815 nColor
= pWindow
->GetBackground().GetColor().GetColor();
821 // XAccessibleExtendedComponent
823 uno::Reference
< awt::XFont
> SAL_CALL
VCLXAccessibleComponent::getFont( ) throw (uno::RuntimeException
, std::exception
)
825 OExternalLockGuard
aGuard( this );
827 uno::Reference
< awt::XFont
> xFont
;
828 vcl::Window
* pWindow
= GetWindow();
831 uno::Reference
< awt::XDevice
> xDev( pWindow
->GetComponentInterface(), uno::UNO_QUERY
);
835 if ( pWindow
->IsControlFont() )
836 aFont
= pWindow
->GetControlFont();
838 aFont
= pWindow
->GetFont();
839 VCLXFont
* pVCLXFont
= new VCLXFont
;
840 pVCLXFont
->Init( *xDev
.get(), aFont
);
848 OUString SAL_CALL
VCLXAccessibleComponent::getTitledBorderText( ) throw (uno::RuntimeException
, std::exception
)
850 OExternalLockGuard
aGuard( this );
854 sRet
= GetWindow()->GetText();
859 OUString SAL_CALL
VCLXAccessibleComponent::getToolTipText( ) throw (uno::RuntimeException
, std::exception
)
861 OExternalLockGuard
aGuard( this );
865 sRet
= GetWindow()->GetQuickHelpText();
870 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */