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