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