1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <extended/accessibletabbarpagelist.hxx>
21 #include <svtools/tabbar.hxx>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleRole.hpp>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <comphelper/accessiblecontexthelper.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <o3tl/safeint.hxx>
29 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/settings.hxx>
32 #include <vcl/unohelp.hxx>
33 #include <i18nlangtag/languagetag.hxx>
36 namespace accessibility
40 using namespace ::com::sun::star::accessibility
;
41 using namespace ::com::sun::star::uno
;
42 using namespace ::com::sun::star::lang
;
43 using namespace ::com::sun::star
;
44 using namespace ::comphelper
;
49 AccessibleTabBarPageList::AccessibleTabBarPageList( TabBar
* pTabBar
, sal_Int32 nIndexInParent
)
50 :ImplInheritanceHelper( pTabBar
)
51 ,m_nIndexInParent( nIndexInParent
)
54 m_aAccessibleChildren
.assign( m_pTabBar
->GetPageCount(), rtl::Reference
< AccessibleTabBarPage
>() );
58 void AccessibleTabBarPageList::UpdateShowing( bool bShowing
)
60 for (const rtl::Reference
<AccessibleTabBarPage
>& xChild
: m_aAccessibleChildren
)
63 xChild
->SetShowing( bShowing
);
68 void AccessibleTabBarPageList::UpdateSelected( sal_Int32 i
, bool bSelected
)
70 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
72 if ( i
>= 0 && o3tl::make_unsigned(i
) < m_aAccessibleChildren
.size() )
74 rtl::Reference
< AccessibleTabBarPage
> xChild( m_aAccessibleChildren
[i
] );
76 xChild
->SetSelected( bSelected
);
81 void AccessibleTabBarPageList::UpdatePageText( sal_Int32 i
)
83 if ( i
< 0 || o3tl::make_unsigned(i
) >= m_aAccessibleChildren
.size() )
88 rtl::Reference
< AccessibleTabBarPage
> pAccessibleTabBarPage( m_aAccessibleChildren
[i
] );
89 if ( pAccessibleTabBarPage
.is() )
91 OUString sPageText
= m_pTabBar
->GetPageText( m_pTabBar
->GetPageId( static_cast<sal_uInt16
>(i
) ) );
92 pAccessibleTabBarPage
->SetPageText( sPageText
);
98 void AccessibleTabBarPageList::InsertChild( sal_Int32 i
)
100 if ( i
< 0 || o3tl::make_unsigned(i
) > m_aAccessibleChildren
.size() )
103 // insert entry in child list
104 m_aAccessibleChildren
.insert( m_aAccessibleChildren
.begin() + i
, rtl::Reference
< AccessibleTabBarPage
>() );
106 // send accessible child event
107 Reference
< XAccessible
> xChild( getAccessibleChild( i
) );
110 Any aOldValue
, aNewValue
;
111 aNewValue
<<= xChild
;
112 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
117 void AccessibleTabBarPageList::RemoveChild( sal_Int32 i
)
119 if ( i
< 0 || o3tl::make_unsigned(i
) >= m_aAccessibleChildren
.size() )
122 // get the accessible of the removed page
123 rtl::Reference
< AccessibleTabBarPage
> xChild( m_aAccessibleChildren
[i
] );
125 // remove entry in child list
126 m_aAccessibleChildren
.erase( m_aAccessibleChildren
.begin() + i
);
128 // send accessible child event
131 Any aOldValue
, aNewValue
;
132 aOldValue
<<= uno::Reference
<XAccessible
>(xChild
);
133 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
140 void AccessibleTabBarPageList::MoveChild( sal_Int32 i
, sal_Int32 j
)
142 if ( !(i
>= 0 && o3tl::make_unsigned(i
) < m_aAccessibleChildren
.size() &&
143 j
>= 0 && o3tl::make_unsigned(j
) <= m_aAccessibleChildren
.size()) )
149 // get the accessible of the moved page
150 rtl::Reference
< AccessibleTabBarPage
> xChild( m_aAccessibleChildren
[i
] );
152 // remove entry in child list at old position
153 m_aAccessibleChildren
.erase( m_aAccessibleChildren
.begin() + i
);
155 // insert entry in child list at new position
156 m_aAccessibleChildren
.insert( m_aAccessibleChildren
.begin() + j
, xChild
);
160 void AccessibleTabBarPageList::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
162 switch ( rVclWindowEvent
.GetId() )
164 case VclEventId::WindowEnabled
:
167 aNewValue
<<= AccessibleStateType::SENSITIVE
;
168 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, Any(), aNewValue
);
169 aNewValue
<<= AccessibleStateType::ENABLED
;
170 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, Any(), aNewValue
);
173 case VclEventId::WindowDisabled
:
176 aOldValue
<<= AccessibleStateType::ENABLED
;
177 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, aOldValue
, Any() );
178 aOldValue
<<= AccessibleStateType::SENSITIVE
;
179 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, aOldValue
, Any() );
182 case VclEventId::WindowShow
:
184 Any aOldValue
, aNewValue
;
185 aNewValue
<<= AccessibleStateType::SHOWING
;
186 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
187 UpdateShowing( true );
190 case VclEventId::WindowHide
:
192 Any aOldValue
, aNewValue
;
193 aOldValue
<<= AccessibleStateType::SHOWING
;
194 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
, aOldValue
, aNewValue
);
195 UpdateShowing( false );
198 case VclEventId::TabbarPageSelected
:
203 case VclEventId::TabbarPageActivated
:
207 sal_uInt16 nPageId
= static_cast<sal_uInt16
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
208 sal_uInt16 nPagePos
= m_pTabBar
->GetPagePos( nPageId
);
209 UpdateSelected( nPagePos
, true );
213 case VclEventId::TabbarPageDeactivated
:
217 sal_uInt16 nPageId
= static_cast<sal_uInt16
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
218 sal_uInt16 nPagePos
= m_pTabBar
->GetPagePos( nPageId
);
219 UpdateSelected( nPagePos
, false );
223 case VclEventId::TabbarPageInserted
:
227 sal_uInt16 nPageId
= static_cast<sal_uInt16
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
228 sal_uInt16 nPagePos
= m_pTabBar
->GetPagePos( nPageId
);
229 InsertChild( nPagePos
);
233 case VclEventId::TabbarPageRemoved
:
237 sal_uInt16 nPageId
= static_cast<sal_uInt16
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
239 OExternalLockGuard
aGuard( this );
241 if ( nPageId
== TabBar::PAGE_NOT_FOUND
)
243 for ( sal_Int32 i
= m_aAccessibleChildren
.size() - 1; i
>= 0; --i
)
248 for ( sal_Int64 i
= 0, nCount
= m_aAccessibleChildren
.size(); i
< nCount
; ++i
)
250 sal_uInt16 nChildPageId
= m_pTabBar
->GetPageId( static_cast<sal_uInt16
>(i
) );
251 if (nPageId
== nChildPageId
)
261 case VclEventId::TabbarPageMoved
:
263 Pair
* pPair
= static_cast<Pair
*>(rVclWindowEvent
.GetData());
265 MoveChild( pPair
->A(), pPair
->B() );
268 case VclEventId::TabbarPageTextChanged
:
270 sal_uInt16 nPageId
= static_cast<sal_uInt16
>(reinterpret_cast<sal_IntPtr
>(rVclWindowEvent
.GetData()));
271 sal_uInt16 nPagePos
= m_pTabBar
->GetPagePos( nPageId
);
272 UpdatePageText( nPagePos
);
277 AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent
);
284 void AccessibleTabBarPageList::FillAccessibleStateSet( sal_Int64
& rStateSet
)
289 if ( m_pTabBar
->IsEnabled() )
291 rStateSet
|= AccessibleStateType::ENABLED
;
292 rStateSet
|= AccessibleStateType::SENSITIVE
;
295 rStateSet
|= AccessibleStateType::VISIBLE
;
297 if ( m_pTabBar
->IsVisible() )
298 rStateSet
|= AccessibleStateType::SHOWING
;
302 // OCommonAccessibleComponent
305 awt::Rectangle
AccessibleTabBarPageList::implGetBounds()
307 awt::Rectangle aBounds
;
309 aBounds
= vcl::unohelper::ConvertToAWTRect(m_pTabBar
->GetPageArea());
318 void AccessibleTabBarPageList::disposing()
320 AccessibleTabBarBase::disposing();
322 // dispose all children
323 for (const rtl::Reference
<AccessibleTabBarPage
>& xComponent
: m_aAccessibleChildren
)
325 if ( xComponent
.is() )
326 xComponent
->dispose();
328 m_aAccessibleChildren
.clear();
335 OUString
AccessibleTabBarPageList::getImplementationName()
337 return u
"com.sun.star.comp.svtools.AccessibleTabBarPageList"_ustr
;
341 sal_Bool
AccessibleTabBarPageList::supportsService( const OUString
& rServiceName
)
343 return cppu::supportsService(this, rServiceName
);
347 Sequence
< OUString
> AccessibleTabBarPageList::getSupportedServiceNames()
349 return { u
"com.sun.star.awt.AccessibleTabBarPageList"_ustr
};
356 Reference
< XAccessibleContext
> AccessibleTabBarPageList::getAccessibleContext( )
358 OExternalLockGuard
aGuard( this );
364 // XAccessibleContext
367 sal_Int64
AccessibleTabBarPageList::getAccessibleChildCount()
369 OExternalLockGuard
aGuard( this );
371 return m_aAccessibleChildren
.size();
375 Reference
< XAccessible
> AccessibleTabBarPageList::getAccessibleChild( sal_Int64 i
)
377 OExternalLockGuard
aGuard( this );
379 return getAccessibleChildImpl(i
);
382 rtl::Reference
< AccessibleTabBarPage
> AccessibleTabBarPageList::getAccessibleChildImpl( sal_Int64 i
)
384 if ( i
< 0 || i
>= getAccessibleChildCount() )
385 throw IndexOutOfBoundsException();
387 rtl::Reference
< AccessibleTabBarPage
> xChild
= m_aAccessibleChildren
[i
];
392 sal_uInt16 nPageId
= m_pTabBar
->GetPageId( static_cast<sal_uInt16
>(i
) );
394 xChild
= new AccessibleTabBarPage( m_pTabBar
, nPageId
, this );
396 // insert into child list
397 m_aAccessibleChildren
[i
] = xChild
;
405 Reference
< XAccessible
> AccessibleTabBarPageList::getAccessibleParent( )
407 OExternalLockGuard
aGuard( this );
409 Reference
< XAccessible
> xParent
;
411 xParent
= m_pTabBar
->GetAccessible();
417 sal_Int64
AccessibleTabBarPageList::getAccessibleIndexInParent( )
419 OExternalLockGuard
aGuard( this );
421 return m_nIndexInParent
;
425 sal_Int16
AccessibleTabBarPageList::getAccessibleRole( )
427 return AccessibleRole::PAGE_TAB_LIST
;
431 OUString
AccessibleTabBarPageList::getAccessibleDescription( )
437 OUString
AccessibleTabBarPageList::getAccessibleName( )
443 Reference
< XAccessibleRelationSet
> AccessibleTabBarPageList::getAccessibleRelationSet( )
445 OExternalLockGuard
aGuard( this );
447 return new utl::AccessibleRelationSetHelper
;
451 sal_Int64
AccessibleTabBarPageList::getAccessibleStateSet( )
453 OExternalLockGuard
aGuard( this );
455 sal_Int64 nStateSet
= 0;
457 if ( !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
459 FillAccessibleStateSet( nStateSet
);
463 nStateSet
|= AccessibleStateType::DEFUNC
;
470 Locale
AccessibleTabBarPageList::getLocale( )
472 OExternalLockGuard
aGuard( this );
474 return Application::GetSettings().GetLanguageTag().getLocale();
478 // XAccessibleComponent
481 Reference
< XAccessible
> AccessibleTabBarPageList::getAccessibleAtPoint( const awt::Point
& rPoint
)
483 OExternalLockGuard
aGuard( this );
485 Reference
< XAccessible
> xChild
;
486 for ( size_t i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
488 rtl::Reference
< AccessibleTabBarPage
> xAcc
= getAccessibleChildImpl( i
);
491 Reference
< XAccessibleComponent
> xComp( xAcc
->getAccessibleContext(), UNO_QUERY
);
494 tools::Rectangle aRect
= vcl::unohelper::ConvertToVCLRect(xComp
->getBounds());
495 Point aPos
= vcl::unohelper::ConvertToVCLPoint(rPoint
);
496 if ( aRect
.Contains( aPos
) )
509 void AccessibleTabBarPageList::grabFocus( )
515 sal_Int32
AccessibleTabBarPageList::getForeground( )
517 OExternalLockGuard
aGuard( this );
519 sal_Int32 nColor
= 0;
520 Reference
< XAccessible
> xParent
= getAccessibleParent();
523 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
524 if ( xParentComp
.is() )
525 nColor
= xParentComp
->getForeground();
532 sal_Int32
AccessibleTabBarPageList::getBackground( )
534 OExternalLockGuard
aGuard( this );
536 sal_Int32 nColor
= 0;
537 Reference
< XAccessible
> xParent
= getAccessibleParent();
540 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
541 if ( xParentComp
.is() )
542 nColor
= xParentComp
->getBackground();
549 // XAccessibleExtendedComponent
551 OUString
AccessibleTabBarPageList::getTitledBorderText( )
557 OUString
AccessibleTabBarPageList::getToolTipText( )
563 // XAccessibleSelection
566 void AccessibleTabBarPageList::selectAccessibleChild( sal_Int64 nChildIndex
)
568 OExternalLockGuard
aGuard( this );
570 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
571 throw IndexOutOfBoundsException();
575 m_pTabBar
->SetCurPageId( m_pTabBar
->GetPageId( static_cast<sal_uInt16
>(nChildIndex
) ) );
576 m_pTabBar
->PaintImmediately();
577 m_pTabBar
->ActivatePage();
583 sal_Bool
AccessibleTabBarPageList::isAccessibleChildSelected( sal_Int64 nChildIndex
)
585 OExternalLockGuard
aGuard( this );
587 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
588 throw IndexOutOfBoundsException();
590 bool bSelected
= false;
591 if ( m_pTabBar
&& m_pTabBar
->GetCurPageId() == m_pTabBar
->GetPageId( static_cast<sal_uInt16
>(nChildIndex
) ) )
598 void AccessibleTabBarPageList::clearAccessibleSelection( )
600 // This method makes no sense in a TabBar, and so does nothing.
604 void AccessibleTabBarPageList::selectAllAccessibleChildren( )
606 selectAccessibleChild( 0 );
610 sal_Int64
AccessibleTabBarPageList::getSelectedAccessibleChildCount( )
616 Reference
< XAccessible
> AccessibleTabBarPageList::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex
)
618 OExternalLockGuard
aGuard( this );
620 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
621 throw IndexOutOfBoundsException();
623 Reference
< XAccessible
> xChild
;
625 for ( sal_Int64 i
= 0, j
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
627 if ( isAccessibleChildSelected( i
) && ( j
++ == nSelectedChildIndex
) )
629 xChild
= getAccessibleChild( i
);
638 void AccessibleTabBarPageList::deselectAccessibleChild( sal_Int64 nChildIndex
)
640 OExternalLockGuard
aGuard( this );
642 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
643 throw IndexOutOfBoundsException();
645 // This method makes no sense in a TabBar, and so does nothing.
649 } // namespace accessibility
652 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */