LibreOffice Module accessibility (master) 1
accessibletabbarpagelist.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
21#include <svtools/tabbar.hxx>
23#include <com/sun/star/accessibility/AccessibleEventId.hpp>
24#include <com/sun/star/accessibility/AccessibleRole.hpp>
25#include <com/sun/star/accessibility/AccessibleStateType.hpp>
26#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29#include <o3tl/safeint.hxx>
31#include <vcl/svapp.hxx>
32#include <vcl/settings.hxx>
35
36
37namespace accessibility
38{
39
40
41 using namespace ::com::sun::star::accessibility;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star;
45 using namespace ::comphelper;
46
47
48
49
50 AccessibleTabBarPageList::AccessibleTabBarPageList( TabBar* pTabBar, sal_Int32 nIndexInParent )
51 :ImplInheritanceHelper( pTabBar )
52 ,m_nIndexInParent( nIndexInParent )
53 {
54 if ( m_pTabBar )
55 m_aAccessibleChildren.assign( m_pTabBar->GetPageCount(), Reference< XAccessible >() );
56 }
57
58
60 {
62 {
63 if ( xChild.is() )
64 {
65 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
66 if ( pAccessibleTabBarPage )
67 pAccessibleTabBarPage->SetShowing( bShowing );
68 }
69 }
70 }
71
72
73 void AccessibleTabBarPageList::UpdateSelected( sal_Int32 i, bool bSelected )
74 {
75 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
76
77 if ( i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() )
78 {
80 if ( xChild.is() )
81 {
82 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
83 if ( pAccessibleTabBarPage )
84 pAccessibleTabBarPage->SetSelected( bSelected );
85 }
86 }
87 }
88
89
91 {
92 if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() )
93 return;
94
96 if ( xChild.is() )
97 {
98 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
99 if ( pAccessibleTabBarPage && m_pTabBar )
100 {
101 OUString sPageText = m_pTabBar->GetPageText( m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) ) );
102 pAccessibleTabBarPage->SetPageText( sPageText );
103 }
104 }
105 }
106
107
109 {
110 if ( i < 0 || o3tl::make_unsigned(i) > m_aAccessibleChildren.size() )
111 return;
112
113 // insert entry in child list
115
116 // send accessible child event
118 if ( xChild.is() )
119 {
120 Any aOldValue, aNewValue;
121 aNewValue <<= xChild;
122 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
123 }
124 }
125
126
128 {
129 if ( i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size() )
130 return;
131
132 // get the accessible of the removed page
134
135 // remove entry in child list
137
138 // send accessible child event
139 if ( xChild.is() )
140 {
141 Any aOldValue, aNewValue;
142 aOldValue <<= xChild;
143 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
144
145 Reference< XComponent > xComponent( xChild, UNO_QUERY );
146 if ( xComponent.is() )
147 xComponent->dispose();
148 }
149 }
150
151
152 void AccessibleTabBarPageList::MoveChild( sal_Int32 i, sal_Int32 j )
153 {
154 if ( !(i >= 0 && o3tl::make_unsigned(i) < m_aAccessibleChildren.size() &&
155 j >= 0 && o3tl::make_unsigned(j) <= m_aAccessibleChildren.size()) )
156 return;
157
158 if ( i < j )
159 --j;
160
161 // get the accessible of the moved page
163
164 // remove entry in child list at old position
166
167 // insert entry in child list at new position
168 m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + j, xChild );
169 }
170
171
173 {
174 switch ( rVclWindowEvent.GetId() )
175 {
176 case VclEventId::WindowEnabled:
177 {
178 Any aNewValue;
179 aNewValue <<= AccessibleStateType::SENSITIVE;
180 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue );
181 aNewValue <<= AccessibleStateType::ENABLED;
182 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue );
183 }
184 break;
185 case VclEventId::WindowDisabled:
186 {
187 Any aOldValue;
188 aOldValue <<= AccessibleStateType::ENABLED;
189 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() );
190 aOldValue <<= AccessibleStateType::SENSITIVE;
191 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() );
192 }
193 break;
194 case VclEventId::WindowShow:
195 {
196 Any aOldValue, aNewValue;
197 aNewValue <<= AccessibleStateType::SHOWING;
198 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
199 UpdateShowing( true );
200 }
201 break;
202 case VclEventId::WindowHide:
203 {
204 Any aOldValue, aNewValue;
205 aOldValue <<= AccessibleStateType::SHOWING;
206 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
207 UpdateShowing( false );
208 }
209 break;
210 case VclEventId::TabbarPageSelected:
211 {
212 // do nothing
213 }
214 break;
215 case VclEventId::TabbarPageActivated:
216 {
217 if ( m_pTabBar )
218 {
219 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
220 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
221 UpdateSelected( nPagePos, true );
222 }
223 }
224 break;
225 case VclEventId::TabbarPageDeactivated:
226 {
227 if ( m_pTabBar )
228 {
229 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
230 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
231 UpdateSelected( nPagePos, false );
232 }
233 }
234 break;
235 case VclEventId::TabbarPageInserted:
236 {
237 if ( m_pTabBar )
238 {
239 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
240 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
241 InsertChild( nPagePos );
242 }
243 }
244 break;
245 case VclEventId::TabbarPageRemoved:
246 {
247 if ( m_pTabBar )
248 {
249 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
250
252 {
253 for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i )
254 RemoveChild( i );
255 }
256 else
257 {
258 for ( sal_Int64 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
259 {
261 if ( xChild.is() )
262 {
263 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
264 if ( pAccessibleTabBarPage && pAccessibleTabBarPage->GetPageId() == nPageId )
265 {
266 RemoveChild( i );
267 break;
268 }
269 }
270 }
271 }
272 }
273 }
274 break;
275 case VclEventId::TabbarPageMoved:
276 {
277 Pair* pPair = static_cast<Pair*>(rVclWindowEvent.GetData());
278 if ( pPair )
279 MoveChild( pPair->A(), pPair->B() );
280 }
281 break;
282 case VclEventId::TabbarPageTextChanged:
283 {
284 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
285 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
286 UpdatePageText( nPagePos );
287 }
288 break;
289 default:
290 {
292 }
293 break;
294 }
295 }
296
297
299 {
300 if ( !m_pTabBar )
301 return;
302
303 if ( m_pTabBar->IsEnabled() )
304 {
305 rStateSet |= AccessibleStateType::ENABLED;
306 rStateSet |= AccessibleStateType::SENSITIVE;
307 }
308
309 rStateSet |= AccessibleStateType::VISIBLE;
310
311 if ( m_pTabBar->IsVisible() )
312 rStateSet |= AccessibleStateType::SHOWING;
313 }
314
315
316 // OCommonAccessibleComponent
317
318
320 {
321 awt::Rectangle aBounds;
322 if ( m_pTabBar )
323 aBounds = AWTRectangle( m_pTabBar->GetPageArea() );
324
325 return aBounds;
326 }
327
328
329 // XComponent
330
331
333 {
335
336 // dispose all children
338 {
339 Reference< XComponent > xComponent( i, UNO_QUERY );
340 if ( xComponent.is() )
341 xComponent->dispose();
342 }
343 m_aAccessibleChildren.clear();
344 }
345
346
347 // XServiceInfo
348
349
351 {
352 return "com.sun.star.comp.svtools.AccessibleTabBarPageList";
353 }
354
355
357 {
358 return cppu::supportsService(this, rServiceName);
359 }
360
361
363 {
364 return { "com.sun.star.awt.AccessibleTabBarPageList" };
365 }
366
367
368 // XAccessible
369
370
372 {
373 OExternalLockGuard aGuard( this );
374
375 return this;
376 }
377
378
379 // XAccessibleContext
380
381
383 {
384 OExternalLockGuard aGuard( this );
385
386 return m_aAccessibleChildren.size();
387 }
388
389
391 {
392 OExternalLockGuard aGuard( this );
393
394 if ( i < 0 || i >= getAccessibleChildCount() )
395 throw IndexOutOfBoundsException();
396
398 if ( !xChild.is() )
399 {
400 if ( m_pTabBar )
401 {
402 sal_uInt16 nPageId = m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) );
403
404 xChild = new AccessibleTabBarPage( m_pTabBar, nPageId, this );
405
406 // insert into child list
407 m_aAccessibleChildren[i] = xChild;
408 }
409 }
410
411 return xChild;
412 }
413
414
416 {
417 OExternalLockGuard aGuard( this );
418
420 if ( m_pTabBar )
421 xParent = m_pTabBar->GetAccessible();
422
423 return xParent;
424 }
425
426
428 {
429 OExternalLockGuard aGuard( this );
430
431 return m_nIndexInParent;
432 }
433
434
436 {
437 return AccessibleRole::PAGE_TAB_LIST;
438 }
439
440
442 {
443 return OUString();
444 }
445
446
448 {
449 return OUString();
450 }
451
452
454 {
455 OExternalLockGuard aGuard( this );
456
458 }
459
460
462 {
463 OExternalLockGuard aGuard( this );
464
465 sal_Int64 nStateSet = 0;
466
467 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
468 {
469 FillAccessibleStateSet( nStateSet );
470 }
471 else
472 {
473 nStateSet |= AccessibleStateType::DEFUNC;
474 }
475
476 return nStateSet;
477 }
478
479
481 {
482 OExternalLockGuard aGuard( this );
483
485 }
486
487
488 // XAccessibleComponent
489
490
492 {
493 OExternalLockGuard aGuard( this );
494
496 for ( size_t i = 0; i < m_aAccessibleChildren.size(); ++i )
497 {
499 if ( xAcc.is() )
500 {
501 Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY );
502 if ( xComp.is() )
503 {
504 tools::Rectangle aRect = VCLRectangle( xComp->getBounds() );
505 Point aPos = VCLPoint( rPoint );
506 if ( aRect.Contains( aPos ) )
507 {
508 xChild = xAcc;
509 break;
510 }
511 }
512 }
513 }
514
515 return xChild;
516 }
517
518
520 {
521 // no focus
522 }
523
524
526 {
527 OExternalLockGuard aGuard( this );
528
529 sal_Int32 nColor = 0;
531 if ( xParent.is() )
532 {
533 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
534 if ( xParentComp.is() )
535 nColor = xParentComp->getForeground();
536 }
537
538 return nColor;
539 }
540
541
543 {
544 OExternalLockGuard aGuard( this );
545
546 sal_Int32 nColor = 0;
548 if ( xParent.is() )
549 {
550 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
551 if ( xParentComp.is() )
552 nColor = xParentComp->getBackground();
553 }
554
555 return nColor;
556 }
557
558
559 // XAccessibleExtendedComponent
560
561
563 {
564 OExternalLockGuard aGuard( this );
565
568 if ( xParent.is() )
569 {
570 Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
571 if ( xParentComp.is() )
572 xFont = xParentComp->getFont();
573 }
574
575 return xFont;
576 }
577
578
580 {
581 return OUString();
582 }
583
584
586 {
587 return OUString();
588 }
589
590
591 // XAccessibleSelection
592
593
595 {
596 OExternalLockGuard aGuard( this );
597
598 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
599 throw IndexOutOfBoundsException();
600
601 if ( m_pTabBar )
602 {
603 m_pTabBar->SetCurPageId( m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) );
604 m_pTabBar->PaintImmediately();
605 m_pTabBar->ActivatePage();
606 m_pTabBar->Select();
607 }
608 }
609
610
612 {
613 OExternalLockGuard aGuard( this );
614
615 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
616 throw IndexOutOfBoundsException();
617
618 bool bSelected = false;
619 if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) )
620 bSelected = true;
621
622 return bSelected;
623 }
624
625
627 {
628 // This method makes no sense in a TabBar, and so does nothing.
629 }
630
631
633 {
635 }
636
637
639 {
640 return 1;
641 }
642
643
645 {
646 OExternalLockGuard aGuard( this );
647
648 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
649 throw IndexOutOfBoundsException();
650
652
653 for ( sal_Int64 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
654 {
655 if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
656 {
657 xChild = getAccessibleChild( i );
658 break;
659 }
660 }
661
662 return xChild;
663 }
664
665
667 {
668 OExternalLockGuard aGuard( this );
669
670 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
671 throw IndexOutOfBoundsException();
672
673 // This method makes no sense in a TabBar, and so does nothing.
674 }
675
676
677} // namespace accessibility
678
679
680/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 nPageId
const LanguageTag & GetLanguageTag() const
static const AllSettings & GetSettings()
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
tools::Long A() const
tools::Long B() const
static const sal_uInt16 PAGE_NOT_FOUND
VclEventId GetId() const
void * GetData() const
virtual void SAL_CALL disposing() override
virtual void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent)
virtual OUString SAL_CALL getAccessibleName() override
virtual css::lang::Locale SAL_CALL getLocale() override
virtual OUString SAL_CALL getToolTipText() override
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int64 nSelectedChildIndex) override
virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont() override
virtual sal_Int64 SAL_CALL getAccessibleChildCount() override
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override
virtual void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent) override
virtual OUString SAL_CALL getTitledBorderText() override
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int64 nChildIndex) override
virtual void SAL_CALL deselectAccessibleChild(sal_Int64 nChildIndex) override
virtual void SAL_CALL selectAccessibleChild(sal_Int64 nChildIndex) override
void UpdateSelected(sal_Int32 i, bool bSelected)
virtual void SAL_CALL clearAccessibleSelection() override
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext() override
virtual void SAL_CALL selectAllAccessibleChildren() override
virtual OUString SAL_CALL getAccessibleDescription() override
virtual sal_Int64 SAL_CALL getAccessibleStateSet() override
virtual css::awt::Rectangle implGetBounds() override
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
virtual sal_Int32 SAL_CALL getBackground() override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
AccessibleTabBarPageList(TabBar *pTabBar, sal_Int32 nIndexInParent)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual sal_Int16 SAL_CALL getAccessibleRole() override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64 i) override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const css::awt::Point &aPoint) override
virtual OUString SAL_CALL getImplementationName() override
virtual sal_Int32 SAL_CALL getForeground() override
void SetPageText(const OUString &sPageText)
bool Contains(const Point &rPOINT) const
css::awt::Rectangle AWTRectangle(const ::tools::Rectangle &rVCLRect)
inline ::tools::Rectangle VCLRectangle(const css::awt::Rectangle &rAWTRect)
inline ::Point VCLPoint(const css::awt::Point &rAWTPoint)
int nCount
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
unsigned char sal_Bool