LibreOffice Module toolkit (master) 1
vclxaccessiblecomponent.cxx
Go to the documentation of this file.
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/AccessibleRelationType.hpp>
24#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33#include <vcl/vclevent.hxx>
34#include <vcl/window.hxx>
35#include <vcl/toolkit/edit.hxx>
36#include <vcl/settings.hxx>
37#include <tools/debug.hxx>
39#include <vcl/svapp.hxx>
40#include <vcl/menu.hxx>
41
42using namespace ::com::sun::star;
43using namespace ::comphelper;
44
45VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXWindow )
46{
47 m_xVCLXWindow = pVCLXWindow;
48
49 DBG_ASSERT( pVCLXWindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
50 m_xEventSource = pVCLXWindow->GetWindow();
51 if ( m_xEventSource )
52 {
53 m_xEventSource->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
54 m_xEventSource->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
55 }
56
57 // announce the XAccessible of our creator to the base class
58 lateInit( pVCLXWindow );
59}
60
61VCLXWindow* VCLXAccessibleComponent::GetVCLXWindow() const
62{
63 return m_xVCLXWindow.get();
64}
65
66void VCLXAccessibleComponent::DisconnectEvents()
67{
68 if ( m_xEventSource )
69 {
70 m_xEventSource->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
71 m_xEventSource->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
72 m_xEventSource.clear();
73 }
74}
75
76VCLXAccessibleComponent::~VCLXAccessibleComponent()
77{
78 ensureDisposed();
79 DisconnectEvents();
80}
81
82OUString VCLXAccessibleComponent::getImplementationName()
83{
84 return "com.sun.star.comp.toolkit.AccessibleWindow";
85}
86
87sal_Bool VCLXAccessibleComponent::supportsService( const OUString& rServiceName )
88{
89 return cppu::supportsService(this, rServiceName);
90}
91
92uno::Sequence< OUString > VCLXAccessibleComponent::getSupportedServiceNames()
93{
94 uno::Sequence< OUString > aNames { "com.sun.star.awt.AccessibleWindow" };
95 return aNames;
96}
97
98IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclWindowEvent&, rEvent, void )
99{
100 /* Ignore VclEventId::WindowEndPopupMode, because the UNO accessibility wrapper
101 * might have been destroyed by the previous VCLEventListener (if no AT tool
102 * is running), e.g. sub-toolbars in impress.
103 */
104 if ( m_xVCLXWindow.is() /* #122218# */ && (rEvent.GetId() != VclEventId::WindowEndPopupMode) )
105 {
106 DBG_ASSERT( rEvent.GetWindow(), "Window???" );
107 if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || ( rEvent.GetId() == VclEventId::ObjectDying ) )
108 {
109 ProcessWindowEvent( rEvent );
110 }
111 }
112}
113
114IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclWindowEvent&, rEvent, void )
115{
116 if ( m_xVCLXWindow.is() /* #i68079# */ )
117 {
118 DBG_ASSERT( rEvent.GetWindow(), "Window???" );
119 if( !rEvent.GetWindow()->IsAccessibilityEventsSuppressed() )
120 {
121 // #103087# to prevent an early release of the component
122 uno::Reference< accessibility::XAccessibleContext > xHoldAlive = this;
123
124 ProcessWindowChildEvent( rEvent );
125 }
126 }
127}
128
129uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
130{
131 // checks if the data in the window event is our direct child
132 // and returns its accessible
133
134 // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData.
135 vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData());
136 if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() )
137 return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VclEventId::WindowShow );
138 else
139 return uno::Reference< accessibility::XAccessible > ();
140}
141
142void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
143{
144 uno::Any aOldValue, aNewValue;
145 uno::Reference< accessibility::XAccessible > xAcc;
146
147 switch ( rVclWindowEvent.GetId() )
148 {
149 case VclEventId::WindowShow: // send create on show for direct accessible children
150 {
151 xAcc = GetChildAccessible( rVclWindowEvent );
152 if( xAcc.is() )
153 {
154 aNewValue <<= xAcc;
155 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
156
157 // CHILD event above results in a11y event listeners getting registered,
158 // so send state change event for SHOWING event after that
159 uno::Reference<XAccessibleContext> xChildContext = xAcc->getAccessibleContext();
160 if (xChildContext.is())
161 {
162 VCLXAccessibleComponent* pChildComponent = dynamic_cast<VCLXAccessibleComponent*>(xChildContext.get());
163 if (pChildComponent)
164 {
165 css::uno::Any aNewStateValue;
166 aNewStateValue <<= accessibility::AccessibleStateType::SHOWING;
167 pChildComponent->NotifyAccessibleEvent(accessibility::AccessibleEventId::STATE_CHANGED, css::uno::Any(), aNewStateValue);
168 }
169 }
170 }
171 }
172 break;
173 case VclEventId::WindowHide: // send destroy on hide for direct accessible children
174 {
175 xAcc = GetChildAccessible( rVclWindowEvent );
176 if( xAcc.is() )
177 {
178 // send state change event for SHOWING before sending the CHILD event below,
179 // since that one results in a11y event listeners getting removed
180 uno::Reference<XAccessibleContext> xChildContext = xAcc->getAccessibleContext();
181 if (xChildContext.is())
182 {
183 VCLXAccessibleComponent* pChildComponent = dynamic_cast<VCLXAccessibleComponent*>(xChildContext.get());
184 if (pChildComponent)
185 {
186 css::uno::Any aOldStateValue;
187 aOldStateValue <<= accessibility::AccessibleStateType::SHOWING;
188 pChildComponent->NotifyAccessibleEvent(accessibility::AccessibleEventId::STATE_CHANGED, aOldStateValue, css::uno::Any());
189 }
190 }
191
192 aOldValue <<= xAcc;
193 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
194 }
195 }
196 break;
197 default: break;
198 }
199}
200
201void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
202{
203 uno::Any aOldValue, aNewValue;
204
205 vcl::Window* pAccWindow = rVclWindowEvent.GetWindow();
206 assert(pAccWindow && "VCLXAccessibleComponent::ProcessWindowEvent - Window?");
207
208 switch ( rVclWindowEvent.GetId() )
209 {
210 case VclEventId::ObjectDying:
211 {
212 DisconnectEvents();
213 m_xVCLXWindow.clear();
214 }
215 break;
216 case VclEventId::WindowChildDestroyed:
217 {
218 vcl::Window* pWindow = static_cast<vcl::Window*>(rVclWindowEvent.GetData());
219 DBG_ASSERT( pWindow, "VclEventId::WindowChildDestroyed - Window=?" );
220 if ( pWindow->GetAccessible( false ).is() )
221 {
222 aOldValue <<= pWindow->GetAccessible( false );
223 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
224 }
225 }
226 break;
227 case VclEventId::WindowActivate:
228 {
229 sal_Int16 aAccessibleRole = getAccessibleRole();
230 // avoid notification if a child frame is already active
231 // only one frame may be active at a given time
232 if ( !pAccWindow->HasActiveChildFrame() &&
233 ( aAccessibleRole == accessibility::AccessibleRole::FRAME ||
234 aAccessibleRole == accessibility::AccessibleRole::ALERT ||
235 aAccessibleRole == accessibility::AccessibleRole::DIALOG ) ) // #i18891#
236 {
237 aNewValue <<= accessibility::AccessibleStateType::ACTIVE;
238 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
239 }
240 }
241 break;
242 case VclEventId::WindowDeactivate:
243 {
244 sal_Int16 aAccessibleRole = getAccessibleRole();
245 if ( aAccessibleRole == accessibility::AccessibleRole::FRAME ||
246 aAccessibleRole == accessibility::AccessibleRole::ALERT ||
247 aAccessibleRole == accessibility::AccessibleRole::DIALOG ) // #i18891#
248 {
249 aOldValue <<= accessibility::AccessibleStateType::ACTIVE;
250 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
251 }
252 }
253 break;
254 case VclEventId::WindowGetFocus:
255 case VclEventId::ControlGetFocus:
256 {
257 if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::ControlGetFocus) ||
258 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::WindowGetFocus) )
259 {
260 // if multiple listeners were registered it is possible that the
261 // focus was changed during event processing (eg SfxTopWindow )
262 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
263 if( (pAccWindow->IsCompoundControl() && pAccWindow->HasChildPathFocus()) ||
264 (!pAccWindow->IsCompoundControl() && pAccWindow->HasFocus()) )
265 {
266 aNewValue <<= accessibility::AccessibleStateType::FOCUSED;
267 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
268 }
269 }
270 }
271 break;
272 case VclEventId::WindowLoseFocus:
273 case VclEventId::ControlLoseFocus:
274 {
275 if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus) ||
276 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus) )
277 {
278 aOldValue <<= accessibility::AccessibleStateType::FOCUSED;
279 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
280 }
281 }
282 break;
283 case VclEventId::WindowFrameTitleChanged:
284 {
285 OUString aOldName( *static_cast<OUString*>(rVclWindowEvent.GetData()) );
286 OUString aNewName( getAccessibleName() );
287 aOldValue <<= aOldName;
288 aNewValue <<= aNewName;
289 NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue );
290 }
291 break;
292 case VclEventId::WindowEnabled:
293 {
294 aNewValue <<= accessibility::AccessibleStateType::ENABLED;
295 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
296 aNewValue <<= accessibility::AccessibleStateType::SENSITIVE;
297 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
298 }
299 break;
300 case VclEventId::WindowDisabled:
301 {
302 aOldValue <<= accessibility::AccessibleStateType::SENSITIVE;
303 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
304
305 aOldValue <<= accessibility::AccessibleStateType::ENABLED;
306 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
307 }
308 break;
309 case VclEventId::WindowMove:
310 case VclEventId::WindowResize:
311 {
312 NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
313 }
314 break;
315 case VclEventId::WindowMenubarAdded:
316 {
317 MenuBar* pMenuBar = static_cast<MenuBar*>(rVclWindowEvent.GetData());
318 if ( pMenuBar )
319 {
320 uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
321 if ( xChild.is() )
322 {
323 aNewValue <<= xChild;
324 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
325 }
326 }
327 }
328 break;
329 case VclEventId::WindowMenubarRemoved:
330 {
331 MenuBar* pMenuBar = static_cast<MenuBar*>(rVclWindowEvent.GetData());
332 if ( pMenuBar )
333 {
334 uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
335 if ( xChild.is() )
336 {
337 aOldValue <<= xChild;
338 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
339 }
340 }
341 }
342 break;
343 case VclEventId::WindowMinimize:
344 {
345 aNewValue <<= accessibility::AccessibleStateType::ICONIFIED;
346 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
347 }
348 break;
349 case VclEventId::WindowNormalize:
350 {
351 aOldValue <<= accessibility::AccessibleStateType::ICONIFIED;
352 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
353 }
354 break;
355 case VclEventId::WindowHide:
356 case VclEventId::WindowShow:
357 // WindowHide and WindowShow are handled in ProcessWindowChildEvent so the right order
358 // regarding the CHILD event can be taken into account
359 default:
360 {
361 }
362 break;
363 }
364}
365
366void VCLXAccessibleComponent::disposing()
367{
368 DisconnectEvents();
369
370 OAccessibleExtendedComponentHelper::disposing();
371
372 m_xVCLXWindow.clear();
373}
374
375vcl::Window* VCLXAccessibleComponent::GetWindow() const
376{
377 return GetVCLXWindow() ? GetVCLXWindow()->GetWindow()
378 : nullptr;
379}
380
381void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
382{
383 VclPtr<vcl::Window> pWindow = GetWindow();
384 if ( !pWindow )
385 return;
386
387 vcl::Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
388 if ( pLabeledBy && pLabeledBy != pWindow )
389 {
390 uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pLabeledBy->GetAccessible() };
391 rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
392 }
393
394 vcl::Window* pLabelFor = pWindow->GetAccessibleRelationLabelFor();
395 if ( pLabelFor && pLabelFor != pWindow )
396 {
397 uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pLabelFor->GetAccessible() };
398 rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR, aSequence ) );
399 }
400
401 vcl::Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
402 if ( pMemberOf && pMemberOf != pWindow )
403 {
404 uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pMemberOf->GetAccessible() };
405 rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
406 }
407}
408
409void VCLXAccessibleComponent::FillAccessibleStateSet( sal_Int64& rStateSet )
410{
411 VclPtr<vcl::Window> pWindow = GetWindow();
412 if ( pWindow )
413 {
414 if ( pWindow->IsVisible() )
415 {
416 rStateSet |= accessibility::AccessibleStateType::VISIBLE;
417 rStateSet |= accessibility::AccessibleStateType::SHOWING;
418 }
419 else
420 {
421 rStateSet |= accessibility::AccessibleStateType::INVALID;
422 }
423
424 if ( pWindow->IsEnabled() )
425 {
426 rStateSet |= accessibility::AccessibleStateType::ENABLED;
427 rStateSet |= accessibility::AccessibleStateType::SENSITIVE;
428 }
429
430 if ( pWindow->HasChildPathFocus() &&
431 ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
432 getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
433 getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) ) // #i18891#
434 rStateSet |= accessibility::AccessibleStateType::ACTIVE;
435
436 if ( pWindow->HasFocus() || ( pWindow->IsCompoundControl() && pWindow->HasChildPathFocus() ) )
437 rStateSet |= accessibility::AccessibleStateType::FOCUSED;
438
439 if ( pWindow->IsWait() )
440 rStateSet |= accessibility::AccessibleStateType::BUSY;
441
442 if ( pWindow->GetStyle() & WB_SIZEABLE )
443 rStateSet |= accessibility::AccessibleStateType::RESIZABLE;
444 // 6. frame doesn't have MOVABLE state
445 // 10. for password text, where is the sensitive state?
446 if( ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||getAccessibleRole() == accessibility::AccessibleRole::DIALOG )&& pWindow->GetStyle() & WB_MOVEABLE )
447 rStateSet |= accessibility::AccessibleStateType::MOVEABLE;
448 if( pWindow->IsDialog() )
449 {
450 Dialog *pDlg = static_cast< Dialog* >( pWindow.get() );
451 if( pDlg->IsInExecute() )
452 rStateSet |= accessibility::AccessibleStateType::MODAL;
453 }
454 //If a combobox or list's edit child isn't read-only,EDITABLE state
455 //should be set.
456 if( pWindow && pWindow->GetType() == WindowType::COMBOBOX )
457 {
458 if( !( pWindow->GetStyle() & WB_READONLY) ||
459 !static_cast<Edit*>(pWindow.get())->IsReadOnly() )
460 rStateSet |= accessibility::AccessibleStateType::EDITABLE;
461 }
462
463 VclPtr<vcl::Window> pChild = pWindow->GetWindow( GetWindowType::FirstChild );
464
465 while( pWindow && pChild )
466 {
467 VclPtr<vcl::Window> pWinTemp = pChild->GetWindow( GetWindowType::FirstChild );
468 if( pWinTemp && pWinTemp->GetType() == WindowType::EDIT )
469 {
470 if( !( pWinTemp->GetStyle() & WB_READONLY) ||
471 !static_cast<Edit*>(pWinTemp.get())->IsReadOnly() )
472 rStateSet |= accessibility::AccessibleStateType::EDITABLE;
473 break;
474 }
475 if( pChild->GetType() == WindowType::EDIT )
476 {
477 if( !( pChild->GetStyle() & WB_READONLY) ||
478 !static_cast<Edit*>(pChild.get())->IsReadOnly())
479 rStateSet |= accessibility::AccessibleStateType::EDITABLE;
480 break;
481 }
482 pChild = pChild->GetWindow( GetWindowType::Next );
483 }
484 }
485 else
486 {
487 rStateSet |= accessibility::AccessibleStateType::DEFUNC;
488 }
489
490/*
491
492MUST BE SET FROM DERIVED CLASSES:
493
494CHECKED
495COLLAPSED
496EXPANDED
497EXPANDABLE
498EDITABLE
499FOCUSABLE
500HORIZONTAL
501VERTICAL
502ICONIFIED
503MULTILINE
504MULTI_SELECTABLE
505PRESSED
506SELECTABLE
507SELECTED
508SINGLE_LINE
509TRANSIENT
510
511 */
512}
513
514
515// accessibility::XAccessibleContext
516sal_Int64 VCLXAccessibleComponent::getAccessibleChildCount()
517{
518 OExternalLockGuard aGuard( this );
519
520 sal_Int64 nChildren = 0;
521 if ( GetWindow() )
522 nChildren = GetWindow()->GetAccessibleChildWindowCount();
523
524 return nChildren;
525}
526
527uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleChild( sal_Int64 i )
528{
529 OExternalLockGuard aGuard( this );
530
531 if ( i >= getAccessibleChildCount() )
532 throw lang::IndexOutOfBoundsException();
533
534 uno::Reference< accessibility::XAccessible > xAcc;
535 if ( GetWindow() )
536 {
537 vcl::Window* pChild = GetWindow()->GetAccessibleChildWindow( static_cast<sal_uInt16>(i) );
538 if ( pChild )
539 xAcc = pChild->GetAccessible();
540 }
541
542 return xAcc;
543}
544
545uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleParent( )
546{
547 OExternalLockGuard aGuard( this );
548
549 uno::Reference< accessibility::XAccessible > xAcc;
550 if ( GetWindow() )
551 {
552 vcl::Window* pParent = GetWindow()->GetAccessibleParentWindow();
553 if ( pParent )
554 xAcc = pParent->GetAccessible();
555 }
556 return xAcc;
557}
558
559sal_Int64 VCLXAccessibleComponent::getAccessibleIndexInParent( )
560{
561 OExternalLockGuard aGuard( this );
562
563 sal_Int64 nIndex = -1;
564
565 if ( GetWindow() )
566 {
567 vcl::Window* pParent = GetWindow()->GetAccessibleParentWindow();
568 if ( pParent )
569 {
570 // Iterate over all the parent's children and search for this object.
571 // this should be compatible with the code in SVX
572 uno::Reference< accessibility::XAccessible > xParentAcc( pParent->GetAccessible() );
573 if ( xParentAcc.is() )
574 {
575 uno::Reference< accessibility::XAccessibleContext > xParentContext ( xParentAcc->getAccessibleContext() );
576 if ( xParentContext.is() )
577 {
578 sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
579 for ( sal_Int64 i = 0; i < nChildCount; i++ )
580 {
581 uno::Reference< accessibility::XAccessible > xChild( xParentContext->getAccessibleChild(i) );
582 if ( xChild.is() )
583 {
584 uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext();
585 if ( xChildContext == static_cast<accessibility::XAccessibleContext*>(this) )
586 {
587 nIndex = i;
588 break;
589 }
590 }
591 }
592 }
593 }
594 }
595 }
596 return nIndex;
597}
598
599sal_Int16 VCLXAccessibleComponent::getAccessibleRole( )
600{
601 OExternalLockGuard aGuard( this );
602
603 sal_Int16 nRole = 0;
604
605 if ( GetWindow() )
606 nRole = GetWindow()->GetAccessibleRole();
607
608 return nRole;
609}
610
611OUString VCLXAccessibleComponent::getAccessibleDescription( )
612{
613 OExternalLockGuard aGuard( this );
614
615 OUString aDescription;
616
617 if ( GetWindow() )
618 aDescription = GetWindow()->GetAccessibleDescription();
619
620 return aDescription;
621}
622
623OUString VCLXAccessibleComponent::getAccessibleName( )
624{
625 OExternalLockGuard aGuard( this );
626
627 OUString aName;
628 if ( GetWindow() )
629 {
630 aName = GetWindow()->GetAccessibleName();
631#if OSL_DEBUG_LEVEL > 0
632 aName += " (Type = " + OUString::number(static_cast<sal_Int32>(GetWindow()->GetType())) + ")";
633#endif
634 }
635 return aName;
636}
637
638OUString VCLXAccessibleComponent::getAccessibleId( )
639{
640 OExternalLockGuard aGuard( this );
641
642 OUString aId;
643 if ( GetWindow() )
644 {
645 const OUString &aWindowId = GetWindow()->get_id();
646 aId = aWindowId;
647 }
648 return aId;
649}
650
651uno::Reference< accessibility::XAccessibleRelationSet > VCLXAccessibleComponent::getAccessibleRelationSet( )
652{
653 OExternalLockGuard aGuard( this );
654
656 FillAccessibleRelationSet( *pRelationSetHelper );
657 return pRelationSetHelper;
658}
659
660sal_Int64 VCLXAccessibleComponent::getAccessibleStateSet( )
661{
662 OExternalLockGuard aGuard( this );
663
664 sal_Int64 nStateSet = 0;
665 FillAccessibleStateSet( nStateSet );
666 return nStateSet;
667}
668
669lang::Locale VCLXAccessibleComponent::getLocale()
670{
671 OExternalLockGuard aGuard( this );
672
674}
675
676uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point& rPoint )
677{
678 OExternalLockGuard aGuard( this );
679
680 uno::Reference< accessibility::XAccessible > xChild;
681 for ( sal_Int64 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
682 {
683 uno::Reference< accessibility::XAccessible > xAcc = getAccessibleChild( i );
684 if ( xAcc.is() )
685 {
686 uno::Reference< accessibility::XAccessibleComponent > xComp( xAcc->getAccessibleContext(), uno::UNO_QUERY );
687 if ( xComp.is() )
688 {
689 tools::Rectangle aRect = VCLRectangle( xComp->getBounds() );
690 Point aPos = VCLPoint( rPoint );
691 if ( aRect.Contains( aPos ) )
692 {
693 xChild = xAcc;
694 break;
695 }
696 }
697 }
698 }
699
700 return xChild;
701}
702
703// accessibility::XAccessibleComponent
704awt::Rectangle VCLXAccessibleComponent::implGetBounds()
705{
706 awt::Rectangle aBounds ( 0, 0, 0, 0 );
707
708 VclPtr<vcl::Window> pWindow = GetWindow();
709 if ( pWindow )
710 {
711 tools::Rectangle aRect = pWindow->GetWindowExtentsAbsolute();
712 aBounds = AWTRectangle( aRect );
713 vcl::Window* pParent = pWindow->GetAccessibleParentWindow();
714 if ( pParent )
715 {
716 tools::Rectangle aParentRect = pParent->GetWindowExtentsAbsolute();
717 awt::Point aParentScreenLoc = AWTPoint( aParentRect.TopLeft() );
718 aBounds.X -= aParentScreenLoc.X;
719 aBounds.Y -= aParentScreenLoc.Y;
720 }
721 }
722
723 return aBounds;
724}
725
726awt::Point VCLXAccessibleComponent::getLocationOnScreen( )
727{
728 OExternalLockGuard aGuard( this );
729
730 awt::Point aPos;
731 if ( GetWindow() )
732 {
733 tools::Rectangle aRect = GetWindow()->GetWindowExtentsAbsolute();
734 aPos.X = aRect.Left();
735 aPos.Y = aRect.Top();
736 }
737
738 return aPos;
739}
740
741void VCLXAccessibleComponent::grabFocus( )
742{
743 OExternalLockGuard aGuard( this );
744
745 sal_Int64 nStates = getAccessibleStateSet();
746 if ( m_xVCLXWindow.is() && ( nStates & accessibility::AccessibleStateType::FOCUSABLE ) )
747 m_xVCLXWindow->setFocus();
748}
749
750sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( )
751{
752 OExternalLockGuard aGuard( this );
753
754 Color nColor;
755 VclPtr<vcl::Window> pWindow = GetWindow();
756 if ( pWindow )
757 {
758 if ( pWindow->IsControlForeground() )
759 nColor = pWindow->GetControlForeground();
760 else
761 {
762 vcl::Font aFont;
763 if ( pWindow->IsControlFont() )
764 aFont = pWindow->GetControlFont();
765 else
766 aFont = pWindow->GetFont();
767 nColor = aFont.GetColor();
768 // COL_AUTO is not very meaningful for AT
769 if ( nColor == COL_AUTO)
770 nColor = pWindow->GetTextColor();
771 }
772 }
773
774 return sal_Int32(nColor);
775}
776
777sal_Int32 SAL_CALL VCLXAccessibleComponent::getBackground( )
778{
779 OExternalLockGuard aGuard( this );
780
781 Color nColor;
782 VclPtr<vcl::Window> pWindow = GetWindow();
783 if ( pWindow )
784 {
785 if ( pWindow->IsControlBackground() )
786 nColor = pWindow->GetControlBackground();
787 else
788 nColor = pWindow->GetBackground().GetColor();
789 }
790
791 return sal_Int32(nColor);
792}
793
794// XAccessibleExtendedComponent
795
796uno::Reference< awt::XFont > SAL_CALL VCLXAccessibleComponent::getFont( )
797{
798 OExternalLockGuard aGuard( this );
799
800 uno::Reference< awt::XFont > xFont;
801 VclPtr<vcl::Window> pWindow = GetWindow();
802 if ( pWindow )
803 {
804 uno::Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), uno::UNO_QUERY );
805 if ( xDev.is() )
806 {
807 vcl::Font aFont;
808 if ( pWindow->IsControlFont() )
809 aFont = pWindow->GetControlFont();
810 else
811 aFont = pWindow->GetFont();
812 rtl::Reference<VCLXFont> pVCLXFont = new VCLXFont;
813 pVCLXFont->Init( *xDev, aFont );
814 xFont = pVCLXFont;
815 }
816 }
817
818 return xFont;
819}
820
821OUString SAL_CALL VCLXAccessibleComponent::getTitledBorderText( )
822{
823 OExternalLockGuard aGuard( this );
824
825 OUString sRet;
826 if ( GetWindow() )
827 sRet = GetWindow()->GetText();
828
829 return sRet;
830}
831
832OUString SAL_CALL VCLXAccessibleComponent::getToolTipText( )
833{
834 OExternalLockGuard aGuard( this );
835
836 OUString sRet;
837 if ( GetWindow() )
838 sRet = GetWindow()->GetQuickHelpText();
839
840 return sRet;
841}
842
843/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const LanguageTag & GetLanguageTag() const
static const AllSettings & GetSettings()
bool IsInExecute() const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
css::uno::Reference< css::accessibility::XAccessible > GetAccessible()
vcl::Window * GetWindow() const
Definition: vclxwindow.hxx:131
reference_type * get() const
VclEventId GetId() const
void * GetData() const
vcl::Window * GetWindow() const
bool Contains(const Point &rPOINT) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr tools::Long Left() const
void AddRelation(const css::accessibility::AccessibleRelation &rRelation)
const Color & GetColor() const
tools::Rectangle GetWindowExtentsAbsolute() const
bool HasActiveChildFrame() const
bool HasChildPathFocus(bool bSystemWindow=false) const
bool IsCompoundControl() const
bool HasFocus() const
vcl::Window * GetAccessibleParentWindow() const
void AddEventListener(const Link< VclWindowEvent &, void > &rEventListener)
css::uno::Reference< css::accessibility::XAccessible > GetAccessible(bool bCreate=true)
bool lateInit
css::awt::Point AWTPoint(const ::Point &rVCLPoint)
Definition: convert.hxx:39
css::awt::Rectangle AWTRectangle(const ::tools::Rectangle &rVCLRect)
Definition: convert.hxx:49
inline ::tools::Rectangle VCLRectangle(const css::awt::Rectangle &rAWTRect)
Definition: convert.hxx:54
inline ::Point VCLPoint(const css::awt::Point &rAWTPoint)
Definition: convert.hxx:44
int nCount
#define DBG_ASSERT(sCon, aError)
constexpr OUStringLiteral IsReadOnly(u"IsReadOnly")
sal_Int32 nIndex
OUString aName
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
unsigned char sal_Bool
IMPL_LINK(VCLXAccessibleComponent, WindowEventListener, VclWindowEvent &, rEvent, void)
WinBits const WB_READONLY