xref: /AOO41X/main/toolkit/source/awt/vclxaccessiblecomponent.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_toolkit.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
37*cdf0e10cSrcweir #include <toolkit/awt/vclxaccessiblecomponent.hxx>
38*cdf0e10cSrcweir #include <toolkit/helper/externallock.hxx>
39*cdf0e10cSrcweir #include <toolkit/awt/vclxwindow.hxx>
40*cdf0e10cSrcweir #include <toolkit/helper/convert.hxx>
41*cdf0e10cSrcweir #include <toolkit/awt/vclxfont.hxx>
42*cdf0e10cSrcweir #include <vcl/dialog.hxx>
43*cdf0e10cSrcweir #include <vcl/window.hxx>
44*cdf0e10cSrcweir #include <tools/debug.hxx>
45*cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
46*cdf0e10cSrcweir #include <unotools/accessiblerelationsethelper.hxx>
47*cdf0e10cSrcweir #include <vcl/svapp.hxx>
48*cdf0e10cSrcweir #include <vcl/menu.hxx>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #ifndef VCLEVENT_WINDOW_FRAMETITLECHANGED
51*cdf0e10cSrcweir #define VCLEVENT_WINDOW_FRAMETITLECHANGED   1018    // pData = XubString* = oldTitle
52*cdf0e10cSrcweir #endif
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir using namespace ::com::sun::star;
55*cdf0e10cSrcweir using namespace ::comphelper;
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir DBG_NAME(VCLXAccessibleComponent)
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir //	----------------------------------------------------
62*cdf0e10cSrcweir //	class VCLXAccessibleComponent
63*cdf0e10cSrcweir //	----------------------------------------------------
64*cdf0e10cSrcweir VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow )
65*cdf0e10cSrcweir 	: AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
66*cdf0e10cSrcweir 	, OAccessibleImplementationAccess( )
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir 	DBG_CTOR( VCLXAccessibleComponent, 0 );
69*cdf0e10cSrcweir 	mpVCLXindow = pVCLXindow;
70*cdf0e10cSrcweir 	mxWindow = pVCLXindow;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 	m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) );
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir 	DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
75*cdf0e10cSrcweir 	if ( pVCLXindow->GetWindow() )
76*cdf0e10cSrcweir     {
77*cdf0e10cSrcweir 	  pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
78*cdf0e10cSrcweir 	  pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
79*cdf0e10cSrcweir     }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 	// announce the XAccessible of our creator to the base class
82*cdf0e10cSrcweir 	lateInit( pVCLXindow );
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir VCLXAccessibleComponent::~VCLXAccessibleComponent()
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir 	DBG_DTOR( VCLXAccessibleComponent, 0 );
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir     ensureDisposed();
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 	if ( mpVCLXindow && mpVCLXindow->GetWindow() )
92*cdf0e10cSrcweir     {
93*cdf0e10cSrcweir 		mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
94*cdf0e10cSrcweir 		mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
95*cdf0e10cSrcweir     }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	delete m_pSolarLock;
98*cdf0e10cSrcweir 	m_pSolarLock = NULL;
99*cdf0e10cSrcweir 	// This is not completely safe. If we assume that the base class dtor calls some method which
100*cdf0e10cSrcweir 	// uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
101*cdf0e10cSrcweir 	// virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
102*cdf0e10cSrcweir 	// lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
103*cdf0e10cSrcweir 	// let's assume it keeps this way.
104*cdf0e10cSrcweir 	// @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
105*cdf0e10cSrcweir }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )
108*cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir ::rtl::OUString VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException)
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir 	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleWindow" );
113*cdf0e10cSrcweir }
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir sal_Bool VCLXAccessibleComponent::supportsService( const ::rtl::OUString& rServiceName ) throw (uno::RuntimeException)
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir 	uno::Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
118*cdf0e10cSrcweir 	const ::rtl::OUString* pNames = aNames.getConstArray();
119*cdf0e10cSrcweir 	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
120*cdf0e10cSrcweir 	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
121*cdf0e10cSrcweir 		;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 	return pNames != pEnd;
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException)
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir 	uno::Sequence< ::rtl::OUString > aNames(1);
129*cdf0e10cSrcweir 	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleWindow" );
130*cdf0e10cSrcweir 	return aNames;
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent )
134*cdf0e10cSrcweir {
135*cdf0e10cSrcweir 	DBG_CHKTHIS(VCLXAccessibleComponent,0);
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 	DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir         /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
140*cdf0e10cSrcweir          * might have been destroyed by the previous VCLEventListener (if no AT tool
141*cdf0e10cSrcweir          * is running), e.g. sub-toolbars in impress.
142*cdf0e10cSrcweir          */
143*cdf0e10cSrcweir 	if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
144*cdf0e10cSrcweir 	{
145*cdf0e10cSrcweir 		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
146*cdf0e10cSrcweir         if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
147*cdf0e10cSrcweir 		{
148*cdf0e10cSrcweir 		    ProcessWindowEvent( *(VclWindowEvent*)pEvent );
149*cdf0e10cSrcweir 		}
150*cdf0e10cSrcweir 	}
151*cdf0e10cSrcweir 	return 0;
152*cdf0e10cSrcweir }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclSimpleEvent*, pEvent )
155*cdf0e10cSrcweir {
156*cdf0e10cSrcweir 	DBG_CHKTHIS(VCLXAccessibleComponent,0);
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir     DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
159*cdf0e10cSrcweir 	if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #i68079# */ )
160*cdf0e10cSrcweir 	{
161*cdf0e10cSrcweir 		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
162*cdf0e10cSrcweir         if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() )
163*cdf0e10cSrcweir 		{
164*cdf0e10cSrcweir 			// #103087# to prevent an early release of the component
165*cdf0e10cSrcweir 			uno::Reference< accessibility::XAccessibleContext > xTmp = this;
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 		    ProcessWindowChildEvent( *(VclWindowEvent*)pEvent );
168*cdf0e10cSrcweir 		}
169*cdf0e10cSrcweir 	}
170*cdf0e10cSrcweir 	return 0;
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir     // checks if the data in the window event is our direct child
176*cdf0e10cSrcweir     // and returns its accessible
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     // MT: Change this later, normaly a show/hide event shouldn't have the Window* in pData.
179*cdf0e10cSrcweir     Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
180*cdf0e10cSrcweir     if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() )
181*cdf0e10cSrcweir         return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VCLEVENT_WINDOW_SHOW );
182*cdf0e10cSrcweir     else
183*cdf0e10cSrcweir         return uno::Reference< accessibility::XAccessible > ();
184*cdf0e10cSrcweir }
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
187*cdf0e10cSrcweir {
188*cdf0e10cSrcweir 	uno::Any aOldValue, aNewValue;
189*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAcc;
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
192*cdf0e10cSrcweir 	{
193*cdf0e10cSrcweir         case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
194*cdf0e10cSrcweir         {
195*cdf0e10cSrcweir             xAcc = GetChildAccessible( rVclWindowEvent );
196*cdf0e10cSrcweir             if( xAcc.is() )
197*cdf0e10cSrcweir             {
198*cdf0e10cSrcweir                 aNewValue <<= xAcc;
199*cdf0e10cSrcweir                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
200*cdf0e10cSrcweir             }
201*cdf0e10cSrcweir         }
202*cdf0e10cSrcweir         break;
203*cdf0e10cSrcweir         case VCLEVENT_WINDOW_HIDE:  // send destroy on hide for direct accessible children
204*cdf0e10cSrcweir         {
205*cdf0e10cSrcweir             xAcc = GetChildAccessible( rVclWindowEvent );
206*cdf0e10cSrcweir             if( xAcc.is() )
207*cdf0e10cSrcweir             {
208*cdf0e10cSrcweir                 aOldValue <<= xAcc;
209*cdf0e10cSrcweir                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
210*cdf0e10cSrcweir             }
211*cdf0e10cSrcweir         }
212*cdf0e10cSrcweir         break;
213*cdf0e10cSrcweir 	}
214*cdf0e10cSrcweir }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
217*cdf0e10cSrcweir {
218*cdf0e10cSrcweir 	uno::Any aOldValue, aNewValue;
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir 	Window* pAccWindow = rVclWindowEvent.GetWindow();
221*cdf0e10cSrcweir 	DBG_ASSERT( pAccWindow, "VCLXAccessibleComponent::ProcessWindowEvent - Window?" );
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
224*cdf0e10cSrcweir 	{
225*cdf0e10cSrcweir         case VCLEVENT_OBJECT_DYING:
226*cdf0e10cSrcweir         {
227*cdf0e10cSrcweir 		    pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
228*cdf0e10cSrcweir 		    pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
229*cdf0e10cSrcweir 	        mxWindow.clear();
230*cdf0e10cSrcweir 	        mpVCLXindow = NULL;
231*cdf0e10cSrcweir         }
232*cdf0e10cSrcweir         break;
233*cdf0e10cSrcweir         //
234*cdf0e10cSrcweir         // dont handle CHILDCREATED events here
235*cdf0e10cSrcweir         // they are handled separately as child events, see ProcessWindowChildEvent above
236*cdf0e10cSrcweir         //
237*cdf0e10cSrcweir         /*
238*cdf0e10cSrcweir         case VCLEVENT_WINDOW_CHILDCREATED:
239*cdf0e10cSrcweir         {
240*cdf0e10cSrcweir             Window* pWindow = (Window*) rVclWindowEvent.GetData();
241*cdf0e10cSrcweir             DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDCREATED - Window=?" );
242*cdf0e10cSrcweir             aNewValue <<= pWindow->GetAccessible();
243*cdf0e10cSrcweir             NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
244*cdf0e10cSrcweir         }
245*cdf0e10cSrcweir         break;
246*cdf0e10cSrcweir         */
247*cdf0e10cSrcweir         case VCLEVENT_WINDOW_CHILDDESTROYED:
248*cdf0e10cSrcweir         {
249*cdf0e10cSrcweir             Window* pWindow = (Window*) rVclWindowEvent.GetData();
250*cdf0e10cSrcweir             DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
251*cdf0e10cSrcweir             if ( pWindow->GetAccessible( sal_False ).is() )
252*cdf0e10cSrcweir             {
253*cdf0e10cSrcweir                 aOldValue <<= pWindow->GetAccessible( sal_False );
254*cdf0e10cSrcweir                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
255*cdf0e10cSrcweir             }
256*cdf0e10cSrcweir         }
257*cdf0e10cSrcweir         break;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir         //
260*cdf0e10cSrcweir         // show and hide will be handled as child events only and are
261*cdf0e10cSrcweir         // responsible for sending create/destroy events, see ProcessWindowChildEvent above
262*cdf0e10cSrcweir         //
263*cdf0e10cSrcweir         /*
264*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_SHOW:
265*cdf0e10cSrcweir 		{
266*cdf0e10cSrcweir 			aNewValue <<= accessibility::AccessibleStateType::VISIBLE;
267*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 			aNewValue <<= accessibility::AccessibleStateType::SHOWING;
270*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 			aNewValue.clear();
273*cdf0e10cSrcweir 			aOldValue <<= accessibility::AccessibleStateType::INVALID;
274*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
275*cdf0e10cSrcweir 		}
276*cdf0e10cSrcweir 		break;
277*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_HIDE:
278*cdf0e10cSrcweir 		{
279*cdf0e10cSrcweir 			aOldValue <<= accessibility::AccessibleStateType::VISIBLE;
280*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir 			aOldValue <<= accessibility::AccessibleStateType::SHOWING;
283*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 			aOldValue.clear();
286*cdf0e10cSrcweir 			aNewValue <<= accessibility::AccessibleStateType::INVALID;
287*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
288*cdf0e10cSrcweir 		}
289*cdf0e10cSrcweir 		break;
290*cdf0e10cSrcweir         */
291*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_ACTIVATE:
292*cdf0e10cSrcweir 		{
293*cdf0e10cSrcweir             // avoid notification if a child frame is already active
294*cdf0e10cSrcweir             // only one frame may be active at a given time
295*cdf0e10cSrcweir             if ( !pAccWindow->HasActiveChildFrame() &&
296*cdf0e10cSrcweir                  ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
297*cdf0e10cSrcweir                    getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
298*cdf0e10cSrcweir                    getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
299*cdf0e10cSrcweir             {
300*cdf0e10cSrcweir 			    aNewValue <<= accessibility::AccessibleStateType::ACTIVE;
301*cdf0e10cSrcweir 			    NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
302*cdf0e10cSrcweir             }
303*cdf0e10cSrcweir 		}
304*cdf0e10cSrcweir 		break;
305*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_DEACTIVATE:
306*cdf0e10cSrcweir 		{
307*cdf0e10cSrcweir             if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
308*cdf0e10cSrcweir                  getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
309*cdf0e10cSrcweir                  getAccessibleRole() == accessibility::AccessibleRole::DIALOG )  // #i18891#
310*cdf0e10cSrcweir             {
311*cdf0e10cSrcweir                 aOldValue <<= accessibility::AccessibleStateType::ACTIVE;
312*cdf0e10cSrcweir                 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
313*cdf0e10cSrcweir             }
314*cdf0e10cSrcweir 		}
315*cdf0e10cSrcweir 		break;
316*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_GETFOCUS:
317*cdf0e10cSrcweir 		case VCLEVENT_CONTROL_GETFOCUS:
318*cdf0e10cSrcweir 		{
319*cdf0e10cSrcweir             if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_GETFOCUS) ||
320*cdf0e10cSrcweir                 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_GETFOCUS) )
321*cdf0e10cSrcweir             {
322*cdf0e10cSrcweir                 // if multiple listeners were registered it is possible that the
323*cdf0e10cSrcweir                 // focus was changed during event processing (eg SfxTopWindow )
324*cdf0e10cSrcweir                 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
325*cdf0e10cSrcweir                 if( (pAccWindow->IsCompoundControl() && pAccWindow->HasChildPathFocus()) ||
326*cdf0e10cSrcweir                     (!pAccWindow->IsCompoundControl() && pAccWindow->HasFocus()) )
327*cdf0e10cSrcweir                 {
328*cdf0e10cSrcweir 			        aNewValue <<= accessibility::AccessibleStateType::FOCUSED;
329*cdf0e10cSrcweir 			        NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
330*cdf0e10cSrcweir                 }
331*cdf0e10cSrcweir             }
332*cdf0e10cSrcweir 		}
333*cdf0e10cSrcweir 		break;
334*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_LOSEFOCUS:
335*cdf0e10cSrcweir 		case VCLEVENT_CONTROL_LOSEFOCUS:
336*cdf0e10cSrcweir 		{
337*cdf0e10cSrcweir             if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_LOSEFOCUS) ||
338*cdf0e10cSrcweir                 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_LOSEFOCUS) )
339*cdf0e10cSrcweir             {
340*cdf0e10cSrcweir 			    aOldValue <<= accessibility::AccessibleStateType::FOCUSED;
341*cdf0e10cSrcweir 			    NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
342*cdf0e10cSrcweir             }
343*cdf0e10cSrcweir 		}
344*cdf0e10cSrcweir 		break;
345*cdf0e10cSrcweir         case VCLEVENT_WINDOW_FRAMETITLECHANGED:
346*cdf0e10cSrcweir         {
347*cdf0e10cSrcweir             ::rtl::OUString aOldName( *((::rtl::OUString*) rVclWindowEvent.GetData()) );
348*cdf0e10cSrcweir             ::rtl::OUString aNewName( getAccessibleName() );
349*cdf0e10cSrcweir 			aOldValue <<= aOldName;
350*cdf0e10cSrcweir             aNewValue <<= aNewName;
351*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue );
352*cdf0e10cSrcweir         }
353*cdf0e10cSrcweir         break;
354*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_ENABLED:
355*cdf0e10cSrcweir 		{
356*cdf0e10cSrcweir 			aNewValue <<= accessibility::AccessibleStateType::ENABLED;
357*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
358*cdf0e10cSrcweir             aNewValue <<= accessibility::AccessibleStateType::SENSITIVE;
359*cdf0e10cSrcweir             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
360*cdf0e10cSrcweir 		}
361*cdf0e10cSrcweir 		break;
362*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_DISABLED:
363*cdf0e10cSrcweir 		{
364*cdf0e10cSrcweir             aOldValue <<= accessibility::AccessibleStateType::SENSITIVE;
365*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir             aOldValue <<= accessibility::AccessibleStateType::ENABLED;
368*cdf0e10cSrcweir             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
369*cdf0e10cSrcweir 		}
370*cdf0e10cSrcweir 		break;
371*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_MOVE:
372*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_RESIZE:
373*cdf0e10cSrcweir 		{
374*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
375*cdf0e10cSrcweir 		}
376*cdf0e10cSrcweir 		break;
377*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_MENUBARADDED:
378*cdf0e10cSrcweir 		{
379*cdf0e10cSrcweir             MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
380*cdf0e10cSrcweir 			if ( pMenuBar )
381*cdf0e10cSrcweir 			{
382*cdf0e10cSrcweir 				uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
383*cdf0e10cSrcweir 				if ( xChild.is() )
384*cdf0e10cSrcweir 				{
385*cdf0e10cSrcweir 					aNewValue <<= xChild;
386*cdf0e10cSrcweir 					NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
387*cdf0e10cSrcweir 				}
388*cdf0e10cSrcweir 			}
389*cdf0e10cSrcweir 		}
390*cdf0e10cSrcweir 		break;
391*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_MENUBARREMOVED:
392*cdf0e10cSrcweir 		{
393*cdf0e10cSrcweir             MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
394*cdf0e10cSrcweir 			if ( pMenuBar )
395*cdf0e10cSrcweir 			{
396*cdf0e10cSrcweir 				uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
397*cdf0e10cSrcweir 				if ( xChild.is() )
398*cdf0e10cSrcweir 				{
399*cdf0e10cSrcweir 					aOldValue <<= xChild;
400*cdf0e10cSrcweir 					NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
401*cdf0e10cSrcweir 				}
402*cdf0e10cSrcweir 			}
403*cdf0e10cSrcweir 		}
404*cdf0e10cSrcweir 		break;
405*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_MINIMIZE:
406*cdf0e10cSrcweir 		{
407*cdf0e10cSrcweir 			aNewValue <<= accessibility::AccessibleStateType::ICONIFIED;
408*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
409*cdf0e10cSrcweir 		}
410*cdf0e10cSrcweir 		break;
411*cdf0e10cSrcweir 		case VCLEVENT_WINDOW_NORMALIZE:
412*cdf0e10cSrcweir 		{
413*cdf0e10cSrcweir 			aOldValue <<= accessibility::AccessibleStateType::ICONIFIED;
414*cdf0e10cSrcweir 			NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
415*cdf0e10cSrcweir 		}
416*cdf0e10cSrcweir 		break;
417*cdf0e10cSrcweir 		default:
418*cdf0e10cSrcweir 		{
419*cdf0e10cSrcweir 		}
420*cdf0e10cSrcweir 		break;
421*cdf0e10cSrcweir 	}
422*cdf0e10cSrcweir }
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir void VCLXAccessibleComponent::disposing()
425*cdf0e10cSrcweir {
426*cdf0e10cSrcweir 	if ( mpVCLXindow && mpVCLXindow->GetWindow() )
427*cdf0e10cSrcweir     {
428*cdf0e10cSrcweir 		mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
429*cdf0e10cSrcweir 		mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
430*cdf0e10cSrcweir     }
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 	AccessibleExtendedComponentHelper_BASE::disposing();
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir 	mxWindow.clear();
435*cdf0e10cSrcweir 	mpVCLXindow = NULL;
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir Window* VCLXAccessibleComponent::GetWindow() const
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir 	return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL;
441*cdf0e10cSrcweir }
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
444*cdf0e10cSrcweir {
445*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
446*cdf0e10cSrcweir 	if ( pWindow )
447*cdf0e10cSrcweir 	{
448*cdf0e10cSrcweir 		Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
449*cdf0e10cSrcweir 		if ( pLabeledBy && pLabeledBy != pWindow )
450*cdf0e10cSrcweir 		{
451*cdf0e10cSrcweir 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
452*cdf0e10cSrcweir 			aSequence[0] = pLabeledBy->GetAccessible();
453*cdf0e10cSrcweir 			rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
454*cdf0e10cSrcweir 		}
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir 		Window* pLabelFor = pWindow->GetAccessibleRelationLabelFor();
457*cdf0e10cSrcweir 		if ( pLabelFor && pLabelFor != pWindow )
458*cdf0e10cSrcweir 		{
459*cdf0e10cSrcweir 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
460*cdf0e10cSrcweir 			aSequence[0] = pLabelFor->GetAccessible();
461*cdf0e10cSrcweir 			rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR, aSequence ) );
462*cdf0e10cSrcweir 		}
463*cdf0e10cSrcweir 	}
464*cdf0e10cSrcweir }
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
467*cdf0e10cSrcweir {
468*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
469*cdf0e10cSrcweir 	if ( pWindow )
470*cdf0e10cSrcweir 	{
471*cdf0e10cSrcweir 		if ( pWindow->IsVisible() )
472*cdf0e10cSrcweir 		{
473*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::VISIBLE );
474*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::SHOWING );
475*cdf0e10cSrcweir 		}
476*cdf0e10cSrcweir 		else
477*cdf0e10cSrcweir 		{
478*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::INVALID );
479*cdf0e10cSrcweir 		}
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir 		if ( pWindow->IsEnabled() )
482*cdf0e10cSrcweir         {
483*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::ENABLED );
484*cdf0e10cSrcweir             rStateSet.AddState( accessibility::AccessibleStateType::SENSITIVE );
485*cdf0e10cSrcweir         }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir         if ( pWindow->HasChildPathFocus() &&
488*cdf0e10cSrcweir              ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
489*cdf0e10cSrcweir                getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
490*cdf0e10cSrcweir                getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
491*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::ACTIVE );
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir         // #104290# MT: This way, a ComboBox doesn't get state FOCUSED.
494*cdf0e10cSrcweir         // I also don't understand
495*cdf0e10cSrcweir         // a) why WINDOW_FIRSTCHILD is used here (which btw is a border window in the case of a combo box)
496*cdf0e10cSrcweir         // b) why HasFocus() is nout "enough" for a compound control
497*cdf0e10cSrcweir         /*
498*cdf0e10cSrcweir 		Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
499*cdf0e10cSrcweir 		if ( ( !pWindow->IsCompoundControl() && pWindow->HasFocus() ) ||
500*cdf0e10cSrcweir 		     ( pWindow->IsCompoundControl() && pChild && pChild->HasFocus() ) )
501*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
502*cdf0e10cSrcweir 	    */
503*cdf0e10cSrcweir 		if ( pWindow->HasFocus() || ( pWindow->IsCompoundControl() && pWindow->HasChildPathFocus() ) )
504*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir 		if ( pWindow->IsWait() )
507*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::BUSY );
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir 		if ( pWindow->GetStyle() & WB_SIZEABLE )
510*cdf0e10cSrcweir 			rStateSet.AddState( accessibility::AccessibleStateType::RESIZABLE );
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir         if( pWindow->IsDialog() )
513*cdf0e10cSrcweir         {
514*cdf0e10cSrcweir             Dialog *pDlg = static_cast< Dialog* >( pWindow );
515*cdf0e10cSrcweir             if( pDlg->IsInExecute() )
516*cdf0e10cSrcweir 			    rStateSet.AddState( accessibility::AccessibleStateType::MODAL );
517*cdf0e10cSrcweir         }
518*cdf0e10cSrcweir 	}
519*cdf0e10cSrcweir 	else
520*cdf0e10cSrcweir 	{
521*cdf0e10cSrcweir 		rStateSet.AddState( accessibility::AccessibleStateType::DEFUNC );
522*cdf0e10cSrcweir 	}
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir /*
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir MUST BE SET FROM DERIVED CLASSES:
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir CHECKED
529*cdf0e10cSrcweir COLLAPSED
530*cdf0e10cSrcweir EXPANDED
531*cdf0e10cSrcweir EXPANDABLE
532*cdf0e10cSrcweir EDITABLE
533*cdf0e10cSrcweir FOCUSABLE
534*cdf0e10cSrcweir HORIZONTAL
535*cdf0e10cSrcweir VERTICAL
536*cdf0e10cSrcweir ICONIFIED
537*cdf0e10cSrcweir MULTILINE
538*cdf0e10cSrcweir MULTI_SELECTABLE
539*cdf0e10cSrcweir PRESSED
540*cdf0e10cSrcweir SELECTABLE
541*cdf0e10cSrcweir SELECTED
542*cdf0e10cSrcweir SINGLE_LINE
543*cdf0e10cSrcweir TRANSIENT
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir 	*/
546*cdf0e10cSrcweir }
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir // accessibility::XAccessibleContext
550*cdf0e10cSrcweir sal_Int32 VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException)
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir 	sal_Int32 nChildren = 0;
555*cdf0e10cSrcweir 	if ( GetWindow() )
556*cdf0e10cSrcweir 		nChildren = GetWindow()->GetAccessibleChildWindowCount();
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir 	return nChildren;
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
562*cdf0e10cSrcweir {
563*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir 	if ( i >= getAccessibleChildCount() )
566*cdf0e10cSrcweir 		throw lang::IndexOutOfBoundsException();
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessible > xAcc;
569*cdf0e10cSrcweir 	if ( GetWindow() )
570*cdf0e10cSrcweir 	{
571*cdf0e10cSrcweir 		Window* pChild = GetWindow()->GetAccessibleChildWindow( (sal_uInt16)i );
572*cdf0e10cSrcweir 		if ( pChild )
573*cdf0e10cSrcweir 			xAcc = pChild->GetAccessible();
574*cdf0e10cSrcweir 	}
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir 	return xAcc;
577*cdf0e10cSrcweir }
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getVclParent() const
580*cdf0e10cSrcweir {
581*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessible > xAcc;
582*cdf0e10cSrcweir 	if ( GetWindow() )
583*cdf0e10cSrcweir 	{
584*cdf0e10cSrcweir 		Window* pParent = GetWindow()->GetAccessibleParentWindow();
585*cdf0e10cSrcweir 		if ( pParent )
586*cdf0e10cSrcweir 			xAcc = pParent->GetAccessible();
587*cdf0e10cSrcweir 	}
588*cdf0e10cSrcweir 	return xAcc;
589*cdf0e10cSrcweir }
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleParent(	) throw (uno::RuntimeException)
592*cdf0e10cSrcweir {
593*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
596*cdf0e10cSrcweir 	if ( !xAcc.is() )
597*cdf0e10cSrcweir 		// we do _not_ have a foreign-controlled parent -> default to our VCL parent
598*cdf0e10cSrcweir 		xAcc = getVclParent();
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 	return xAcc;
601*cdf0e10cSrcweir }
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir sal_Int32 VCLXAccessibleComponent::getAccessibleIndexInParent(	) throw (uno::RuntimeException)
604*cdf0e10cSrcweir {
605*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir 	sal_Int32 nIndex = -1;
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
610*cdf0e10cSrcweir 	if ( xAcc.is() )
611*cdf0e10cSrcweir 	{	// we _do_ have a foreign-controlled parent -> use the base class' implementation,
612*cdf0e10cSrcweir 		// which goes the UNO way
613*cdf0e10cSrcweir 		nIndex = AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
614*cdf0e10cSrcweir 	}
615*cdf0e10cSrcweir 	else
616*cdf0e10cSrcweir 	{
617*cdf0e10cSrcweir 		if ( GetWindow() )
618*cdf0e10cSrcweir 		{
619*cdf0e10cSrcweir 			Window* pParent = GetWindow()->GetAccessibleParentWindow();
620*cdf0e10cSrcweir 			if ( pParent )
621*cdf0e10cSrcweir 			{
622*cdf0e10cSrcweir                 /*
623*cdf0e10cSrcweir 				for ( sal_uInt16 n = pParent->GetAccessibleChildWindowCount(); n; )
624*cdf0e10cSrcweir 				{
625*cdf0e10cSrcweir 					Window* pChild = pParent->GetAccessibleChildWindow( --n );
626*cdf0e10cSrcweir 					if ( pChild == GetWindow() )
627*cdf0e10cSrcweir 					{
628*cdf0e10cSrcweir 						nIndex = n;
629*cdf0e10cSrcweir 						break;
630*cdf0e10cSrcweir 					}
631*cdf0e10cSrcweir 				}
632*cdf0e10cSrcweir                 */
633*cdf0e10cSrcweir                 //	Iterate over all the parent's children and search for this object.
634*cdf0e10cSrcweir                 // this should be compatible with the code in SVX
635*cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessible > xParentAcc( pParent->GetAccessible() );
636*cdf0e10cSrcweir                 if ( xParentAcc.is() )
637*cdf0e10cSrcweir                 {
638*cdf0e10cSrcweir                     uno::Reference< accessibility::XAccessibleContext > xParentContext ( xParentAcc->getAccessibleContext() );
639*cdf0e10cSrcweir                     if ( xParentContext.is() )
640*cdf0e10cSrcweir                     {
641*cdf0e10cSrcweir                         sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
642*cdf0e10cSrcweir                         for ( sal_Int32 i=0; i<nChildCount; i++ )
643*cdf0e10cSrcweir                         {
644*cdf0e10cSrcweir                             uno::Reference< accessibility::XAccessible > xChild( xParentContext->getAccessibleChild(i) );
645*cdf0e10cSrcweir                             if ( xChild.is() )
646*cdf0e10cSrcweir                             {
647*cdf0e10cSrcweir                                 uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext();
648*cdf0e10cSrcweir 	                            if ( xChildContext == (accessibility::XAccessibleContext*) this )
649*cdf0e10cSrcweir                                 {
650*cdf0e10cSrcweir                                     nIndex = i;
651*cdf0e10cSrcweir                                     break;
652*cdf0e10cSrcweir                                 }
653*cdf0e10cSrcweir                             }
654*cdf0e10cSrcweir                         }
655*cdf0e10cSrcweir                     }
656*cdf0e10cSrcweir                 }
657*cdf0e10cSrcweir 			}
658*cdf0e10cSrcweir 		}
659*cdf0e10cSrcweir 	}
660*cdf0e10cSrcweir 	return nIndex;
661*cdf0e10cSrcweir }
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir sal_Int16 VCLXAccessibleComponent::getAccessibleRole(  ) throw (uno::RuntimeException)
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 	sal_Int16 nRole = 0;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir 	if ( GetWindow() )
670*cdf0e10cSrcweir 		nRole = GetWindow()->GetAccessibleRole();
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir 	return nRole;
673*cdf0e10cSrcweir }
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir ::rtl::OUString VCLXAccessibleComponent::getAccessibleDescription(	) throw (uno::RuntimeException)
676*cdf0e10cSrcweir {
677*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir 	::rtl::OUString aDescription;
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir 	if ( GetWindow() )
682*cdf0e10cSrcweir 		aDescription = GetWindow()->GetAccessibleDescription();
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir 	return aDescription;
685*cdf0e10cSrcweir }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir ::rtl::OUString VCLXAccessibleComponent::getAccessibleName(  ) throw (uno::RuntimeException)
688*cdf0e10cSrcweir {
689*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir 	::rtl::OUString aName;
692*cdf0e10cSrcweir 	if ( GetWindow() )
693*cdf0e10cSrcweir 	{
694*cdf0e10cSrcweir 		aName = GetWindow()->GetAccessibleName();
695*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
696*cdf0e10cSrcweir 		aName += String( RTL_CONSTASCII_USTRINGPARAM( " (Type = " ) );
697*cdf0e10cSrcweir 		aName += String::CreateFromInt32( GetWindow()->GetType() );
698*cdf0e10cSrcweir 		aName += String( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
699*cdf0e10cSrcweir #endif
700*cdf0e10cSrcweir 	}
701*cdf0e10cSrcweir 	return aName;
702*cdf0e10cSrcweir }
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir uno::Reference< accessibility::XAccessibleRelationSet > VCLXAccessibleComponent::getAccessibleRelationSet(	) throw (uno::RuntimeException)
705*cdf0e10cSrcweir {
706*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
709*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
710*cdf0e10cSrcweir 	FillAccessibleRelationSet( *pRelationSetHelper );
711*cdf0e10cSrcweir     return xSet;
712*cdf0e10cSrcweir }
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir uno::Reference< accessibility::XAccessibleStateSet > VCLXAccessibleComponent::getAccessibleStateSet(  ) throw (uno::RuntimeException)
715*cdf0e10cSrcweir {
716*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir 	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
719*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessibleStateSet > xSet = pStateSetHelper;
720*cdf0e10cSrcweir 	FillAccessibleStateSet( *pStateSetHelper );
721*cdf0e10cSrcweir 	return xSet;
722*cdf0e10cSrcweir }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir lang::Locale VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
725*cdf0e10cSrcweir {
726*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
727*cdf0e10cSrcweir 
728*cdf0e10cSrcweir 	return Application::GetSettings().GetLocale();
729*cdf0e10cSrcweir }
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
732*cdf0e10cSrcweir {
733*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xChild;
736*cdf0e10cSrcweir 	for ( sal_uInt32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
737*cdf0e10cSrcweir 	{
738*cdf0e10cSrcweir 		uno::Reference< accessibility::XAccessible > xAcc = getAccessibleChild( i );
739*cdf0e10cSrcweir 		if ( xAcc.is() )
740*cdf0e10cSrcweir 		{
741*cdf0e10cSrcweir 			uno::Reference< accessibility::XAccessibleComponent > xComp( xAcc->getAccessibleContext(), uno::UNO_QUERY );
742*cdf0e10cSrcweir 			if ( xComp.is() )
743*cdf0e10cSrcweir 			{
744*cdf0e10cSrcweir 				Rectangle aRect = VCLRectangle( xComp->getBounds() );
745*cdf0e10cSrcweir 				Point aPos = VCLPoint( rPoint );
746*cdf0e10cSrcweir 				if ( aRect.IsInside( aPos ) )
747*cdf0e10cSrcweir 				{
748*cdf0e10cSrcweir 					xChild = xAcc;
749*cdf0e10cSrcweir 					break;
750*cdf0e10cSrcweir 				}
751*cdf0e10cSrcweir 			}
752*cdf0e10cSrcweir 		}
753*cdf0e10cSrcweir 	}
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir 	return xChild;
756*cdf0e10cSrcweir }
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir // accessibility::XAccessibleComponent
759*cdf0e10cSrcweir awt::Rectangle VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException)
760*cdf0e10cSrcweir {
761*cdf0e10cSrcweir 	awt::Rectangle aBounds ( 0, 0, 0, 0 );
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
764*cdf0e10cSrcweir 	if ( pWindow )
765*cdf0e10cSrcweir 	{
766*cdf0e10cSrcweir 		Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL );
767*cdf0e10cSrcweir 		aBounds = AWTRectangle( aRect );
768*cdf0e10cSrcweir 		Window* pParent = pWindow->GetAccessibleParentWindow();
769*cdf0e10cSrcweir 		if ( pParent )
770*cdf0e10cSrcweir 		{
771*cdf0e10cSrcweir 			Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
772*cdf0e10cSrcweir 			awt::Point aParentScreenLoc = AWTPoint( aParentRect.TopLeft() );
773*cdf0e10cSrcweir 			aBounds.X -= aParentScreenLoc.X;
774*cdf0e10cSrcweir 			aBounds.Y -= aParentScreenLoc.Y;
775*cdf0e10cSrcweir 		}
776*cdf0e10cSrcweir 	}
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessible > xParent( implGetForeignControlledParent() );
779*cdf0e10cSrcweir 	if ( xParent.is() )
780*cdf0e10cSrcweir 	{	// hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
781*cdf0e10cSrcweir 		// us a parent which is different from our VCL parent
782*cdf0e10cSrcweir 		// (actually, we did not check if it's really different ...)
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir 		// the screen location of the foreign parent
785*cdf0e10cSrcweir 		uno::Reference< accessibility::XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
786*cdf0e10cSrcweir 		DBG_ASSERT( xParentComponent.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir 		awt::Point aScreenLocForeign( 0, 0 );
789*cdf0e10cSrcweir 		if ( xParentComponent.is() )
790*cdf0e10cSrcweir 			aScreenLocForeign = xParentComponent->getLocationOnScreen();
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir 		// the screen location of the VCL parent
793*cdf0e10cSrcweir 		xParent = getVclParent();
794*cdf0e10cSrcweir 		if ( xParent.is() )
795*cdf0e10cSrcweir 			xParentComponent = xParentComponent.query( xParent->getAccessibleContext() );
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir 		awt::Point aScreenLocVCL( 0, 0 );
798*cdf0e10cSrcweir 		if ( xParentComponent.is() )
799*cdf0e10cSrcweir 			aScreenLocVCL = xParentComponent->getLocationOnScreen();
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir 		// the difference between them
802*cdf0e10cSrcweir 		awt::Size aOffset( aScreenLocVCL.X - aScreenLocForeign.X, aScreenLocVCL.Y - aScreenLocForeign.Y );
803*cdf0e10cSrcweir 		// move the bounds
804*cdf0e10cSrcweir 		aBounds.X += aOffset.Width;
805*cdf0e10cSrcweir 		aBounds.Y += aOffset.Height;
806*cdf0e10cSrcweir 	}
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir 	return aBounds;
809*cdf0e10cSrcweir }
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir awt::Point VCLXAccessibleComponent::getLocationOnScreen(  ) throw (uno::RuntimeException)
812*cdf0e10cSrcweir {
813*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir 	awt::Point aPos;
816*cdf0e10cSrcweir 	if ( GetWindow() )
817*cdf0e10cSrcweir 	{
818*cdf0e10cSrcweir 		Rectangle aRect = GetWindow()->GetWindowExtentsRelative( NULL );
819*cdf0e10cSrcweir 		aPos.X = aRect.Left();
820*cdf0e10cSrcweir 		aPos.Y = aRect.Top();
821*cdf0e10cSrcweir 	}
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir 	return aPos;
824*cdf0e10cSrcweir }
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir void VCLXAccessibleComponent::grabFocus(  ) throw (uno::RuntimeException)
827*cdf0e10cSrcweir {
828*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir 	uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet();
831*cdf0e10cSrcweir 	if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
832*cdf0e10cSrcweir 		mxWindow->setFocus();
833*cdf0e10cSrcweir }
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground(	) throw (uno::RuntimeException)
836*cdf0e10cSrcweir {
837*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir 	sal_Int32 nColor = 0;
840*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
841*cdf0e10cSrcweir 	if ( pWindow )
842*cdf0e10cSrcweir 	{
843*cdf0e10cSrcweir 		if ( pWindow->IsControlForeground() )
844*cdf0e10cSrcweir 			nColor = pWindow->GetControlForeground().GetColor();
845*cdf0e10cSrcweir 		else
846*cdf0e10cSrcweir 		{
847*cdf0e10cSrcweir 			Font aFont;
848*cdf0e10cSrcweir 			if ( pWindow->IsControlFont() )
849*cdf0e10cSrcweir 				aFont = pWindow->GetControlFont();
850*cdf0e10cSrcweir 			else
851*cdf0e10cSrcweir 				aFont = pWindow->GetFont();
852*cdf0e10cSrcweir 			nColor = aFont.GetColor().GetColor();
853*cdf0e10cSrcweir 		}
854*cdf0e10cSrcweir 	}
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir 	return nColor;
857*cdf0e10cSrcweir }
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleComponent::getBackground(	) throw (uno::RuntimeException)
860*cdf0e10cSrcweir {
861*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir 	sal_Int32 nColor = 0;
864*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
865*cdf0e10cSrcweir 	if ( pWindow )
866*cdf0e10cSrcweir 	{
867*cdf0e10cSrcweir 		if ( pWindow->IsControlBackground() )
868*cdf0e10cSrcweir 			nColor = pWindow->GetControlBackground().GetColor();
869*cdf0e10cSrcweir 		else
870*cdf0e10cSrcweir 			nColor = pWindow->GetBackground().GetColor().GetColor();
871*cdf0e10cSrcweir 	}
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir 	return nColor;
874*cdf0e10cSrcweir }
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir // XAccessibleExtendedComponent
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir uno::Reference< awt::XFont > SAL_CALL VCLXAccessibleComponent::getFont(  ) throw (uno::RuntimeException)
879*cdf0e10cSrcweir {
880*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
881*cdf0e10cSrcweir 
882*cdf0e10cSrcweir 	uno::Reference< awt::XFont > xFont;
883*cdf0e10cSrcweir 	Window* pWindow = GetWindow();
884*cdf0e10cSrcweir 	if ( pWindow )
885*cdf0e10cSrcweir 	{
886*cdf0e10cSrcweir 		uno::Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), uno::UNO_QUERY );
887*cdf0e10cSrcweir 		if ( xDev.is() )
888*cdf0e10cSrcweir 		{
889*cdf0e10cSrcweir 			Font aFont;
890*cdf0e10cSrcweir 			if ( pWindow->IsControlFont() )
891*cdf0e10cSrcweir 				aFont = pWindow->GetControlFont();
892*cdf0e10cSrcweir 			else
893*cdf0e10cSrcweir 				aFont = pWindow->GetFont();
894*cdf0e10cSrcweir 			VCLXFont* pVCLXFont = new VCLXFont;
895*cdf0e10cSrcweir 			pVCLXFont->Init( *xDev.get(), aFont );
896*cdf0e10cSrcweir 			xFont = pVCLXFont;
897*cdf0e10cSrcweir 		}
898*cdf0e10cSrcweir 	}
899*cdf0e10cSrcweir 
900*cdf0e10cSrcweir 	return xFont;
901*cdf0e10cSrcweir }
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir ::rtl::OUString SAL_CALL VCLXAccessibleComponent::getTitledBorderText(	) throw (uno::RuntimeException)
904*cdf0e10cSrcweir {
905*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir 	::rtl::OUString sRet;
908*cdf0e10cSrcweir 	if ( GetWindow() )
909*cdf0e10cSrcweir 		sRet = GetWindow()->GetText();
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 	return sRet;
912*cdf0e10cSrcweir }
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir ::rtl::OUString SAL_CALL VCLXAccessibleComponent::getToolTipText(  ) throw (uno::RuntimeException)
915*cdf0e10cSrcweir {
916*cdf0e10cSrcweir 	OExternalLockGuard aGuard( this );
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir 	::rtl::OUString sRet;
919*cdf0e10cSrcweir 	if ( GetWindow() )
920*cdf0e10cSrcweir 		sRet = GetWindow()->GetQuickHelpText();
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir 	return sRet;
923*cdf0e10cSrcweir }
924*cdf0e10cSrcweir 
925