lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / accessibility / source / extended / accessibletabbarpagelist.cxx
blob02cdad44cd49621f9d1c293bf33435e1c40b29e0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <extended/accessibletabbarpage.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>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <unotools/accessiblestatesethelper.hxx>
29 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/settings.hxx>
32 #include <toolkit/helper/convert.hxx>
35 namespace accessibility
39 using namespace ::com::sun::star::accessibility;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::lang;
42 using namespace ::com::sun::star;
43 using namespace ::comphelper;
46 // class AccessibleTabBarPageList
49 AccessibleTabBarPageList::AccessibleTabBarPageList( TabBar* pTabBar, sal_Int32 nIndexInParent )
50 :AccessibleTabBarBase( pTabBar )
51 ,m_nIndexInParent( nIndexInParent )
53 if ( m_pTabBar )
54 m_aAccessibleChildren.assign( m_pTabBar->GetPageCount(), Reference< XAccessible >() );
58 void AccessibleTabBarPageList::UpdateShowing( bool bShowing )
60 for (Reference<XAccessible>& xChild : m_aAccessibleChildren)
62 if ( xChild.is() )
64 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
65 if ( pAccessibleTabBarPage )
66 pAccessibleTabBarPage->SetShowing( bShowing );
72 void AccessibleTabBarPageList::UpdateSelected( sal_Int32 i, bool bSelected )
74 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
76 if ( i >= 0 && i < static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
78 Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
79 if ( xChild.is() )
81 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
82 if ( pAccessibleTabBarPage )
83 pAccessibleTabBarPage->SetSelected( bSelected );
89 void AccessibleTabBarPageList::UpdatePageText( sal_Int32 i )
91 if ( i >= 0 && i < static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
93 Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
94 if ( xChild.is() )
96 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
97 if ( pAccessibleTabBarPage && m_pTabBar )
99 OUString sPageText = m_pTabBar->GetPageText( m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) ) );
100 pAccessibleTabBarPage->SetPageText( sPageText );
107 void AccessibleTabBarPageList::InsertChild( sal_Int32 i )
109 if ( i >= 0 && i <= static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
111 // insert entry in child list
112 m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, Reference< XAccessible >() );
114 // send accessible child event
115 Reference< XAccessible > xChild( getAccessibleChild( i ) );
116 if ( xChild.is() )
118 Any aOldValue, aNewValue;
119 aNewValue <<= xChild;
120 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
126 void AccessibleTabBarPageList::RemoveChild( sal_Int32 i )
128 if ( i >= 0 && i < static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
130 // get the accessible of the removed page
131 Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
133 // remove entry in child list
134 m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i );
136 // send accessible child event
137 if ( xChild.is() )
139 Any aOldValue, aNewValue;
140 aOldValue <<= xChild;
141 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
143 Reference< XComponent > xComponent( xChild, UNO_QUERY );
144 if ( xComponent.is() )
145 xComponent->dispose();
151 void AccessibleTabBarPageList::MoveChild( sal_Int32 i, sal_Int32 j )
153 if ( i >= 0 && i < static_cast<sal_Int32>(m_aAccessibleChildren.size()) &&
154 j >= 0 && j <= static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
156 if ( i < j )
157 --j;
159 // get the accessible of the moved page
160 Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
162 // remove entry in child list at old position
163 m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i );
165 // insert entry in child list at new position
166 m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + j, xChild );
171 void AccessibleTabBarPageList::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
173 switch ( rVclWindowEvent.GetId() )
175 case VclEventId::WindowEnabled:
177 Any aNewValue;
178 aNewValue <<= AccessibleStateType::SENSITIVE;
179 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue );
180 aNewValue <<= AccessibleStateType::ENABLED;
181 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), aNewValue );
183 break;
184 case VclEventId::WindowDisabled:
186 Any aOldValue;
187 aOldValue <<= AccessibleStateType::ENABLED;
188 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() );
189 aOldValue <<= AccessibleStateType::SENSITIVE;
190 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, Any() );
192 break;
193 case VclEventId::WindowShow:
195 Any aOldValue, aNewValue;
196 aNewValue <<= AccessibleStateType::SHOWING;
197 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
198 UpdateShowing( true );
200 break;
201 case VclEventId::WindowHide:
203 Any aOldValue, aNewValue;
204 aOldValue <<= AccessibleStateType::SHOWING;
205 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
206 UpdateShowing( false );
208 break;
209 case VclEventId::TabbarPageSelected:
211 // do nothing
213 break;
214 case VclEventId::TabbarPageActivated:
216 if ( m_pTabBar )
218 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
219 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
220 UpdateSelected( nPagePos, true );
223 break;
224 case VclEventId::TabbarPageDeactivated:
226 if ( m_pTabBar )
228 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
229 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
230 UpdateSelected( nPagePos, false );
233 break;
234 case VclEventId::TabbarPageInserted:
236 if ( m_pTabBar )
238 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
239 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
240 InsertChild( nPagePos );
243 break;
244 case VclEventId::TabbarPageRemoved:
246 if ( m_pTabBar )
248 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
250 if ( nPageId == TabBar::PAGE_NOT_FOUND )
252 for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i )
253 RemoveChild( i );
255 else
257 for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
259 Reference< XAccessible > xChild( getAccessibleChild( i ) );
260 if ( xChild.is() )
262 AccessibleTabBarPage* pAccessibleTabBarPage = static_cast< AccessibleTabBarPage* >( xChild.get() );
263 if ( pAccessibleTabBarPage && pAccessibleTabBarPage->GetPageId() == nPageId )
265 RemoveChild( i );
266 break;
273 break;
274 case VclEventId::TabbarPageMoved:
276 Pair* pPair = static_cast<Pair*>(rVclWindowEvent.GetData());
277 if ( pPair )
278 MoveChild( pPair->A(), pPair->B() );
280 break;
281 case VclEventId::TabbarPageTextChanged:
283 sal_uInt16 nPageId = static_cast<sal_uInt16>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
284 sal_uInt16 nPagePos = m_pTabBar->GetPagePos( nPageId );
285 UpdatePageText( nPagePos );
287 break;
288 default:
290 AccessibleTabBarBase::ProcessWindowEvent( rVclWindowEvent );
292 break;
297 void AccessibleTabBarPageList::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
299 if ( m_pTabBar )
301 if ( m_pTabBar->IsEnabled() )
303 rStateSet.AddState( AccessibleStateType::ENABLED );
304 rStateSet.AddState( AccessibleStateType::SENSITIVE );
307 rStateSet.AddState( AccessibleStateType::VISIBLE );
309 if ( m_pTabBar->IsVisible() )
310 rStateSet.AddState( AccessibleStateType::SHOWING );
315 // OCommonAccessibleComponent
318 awt::Rectangle AccessibleTabBarPageList::implGetBounds()
320 awt::Rectangle aBounds;
321 if ( m_pTabBar )
322 aBounds = AWTRectangle( m_pTabBar->GetPageArea() );
324 return aBounds;
328 // XInterface
331 IMPLEMENT_FORWARD_XINTERFACE2( AccessibleTabBarPageList, OAccessibleExtendedComponentHelper, AccessibleTabBarPageList_BASE )
334 // XTypeProvider
337 IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleTabBarPageList, OAccessibleExtendedComponentHelper, AccessibleTabBarPageList_BASE )
340 // XComponent
343 void AccessibleTabBarPageList::disposing()
345 AccessibleTabBarBase::disposing();
347 // dispose all children
348 for (Reference<XAccessible>& i : m_aAccessibleChildren)
350 Reference< XComponent > xComponent( i, UNO_QUERY );
351 if ( xComponent.is() )
352 xComponent->dispose();
354 m_aAccessibleChildren.clear();
358 // XServiceInfo
361 OUString AccessibleTabBarPageList::getImplementationName()
363 return OUString( "com.sun.star.comp.svtools.AccessibleTabBarPageList" );
367 sal_Bool AccessibleTabBarPageList::supportsService( const OUString& rServiceName )
369 return cppu::supportsService(this, rServiceName);
373 Sequence< OUString > AccessibleTabBarPageList::getSupportedServiceNames()
375 return { "com.sun.star.awt.AccessibleTabBarPageList" };
379 // XAccessible
382 Reference< XAccessibleContext > AccessibleTabBarPageList::getAccessibleContext( )
384 OExternalLockGuard aGuard( this );
386 return this;
390 // XAccessibleContext
393 sal_Int32 AccessibleTabBarPageList::getAccessibleChildCount()
395 OExternalLockGuard aGuard( this );
397 return m_aAccessibleChildren.size();
401 Reference< XAccessible > AccessibleTabBarPageList::getAccessibleChild( sal_Int32 i )
403 OExternalLockGuard aGuard( this );
405 if ( i < 0 || i >= getAccessibleChildCount() )
406 throw IndexOutOfBoundsException();
408 Reference< XAccessible > xChild = m_aAccessibleChildren[i];
409 if ( !xChild.is() )
411 if ( m_pTabBar )
413 sal_uInt16 nPageId = m_pTabBar->GetPageId( static_cast<sal_uInt16>(i) );
415 xChild = new AccessibleTabBarPage( m_pTabBar, nPageId, this );
417 // insert into child list
418 m_aAccessibleChildren[i] = xChild;
422 return xChild;
426 Reference< XAccessible > AccessibleTabBarPageList::getAccessibleParent( )
428 OExternalLockGuard aGuard( this );
430 Reference< XAccessible > xParent;
431 if ( m_pTabBar )
432 xParent = m_pTabBar->GetAccessible();
434 return xParent;
438 sal_Int32 AccessibleTabBarPageList::getAccessibleIndexInParent( )
440 OExternalLockGuard aGuard( this );
442 return m_nIndexInParent;
446 sal_Int16 AccessibleTabBarPageList::getAccessibleRole( )
448 return AccessibleRole::PAGE_TAB_LIST;
452 OUString AccessibleTabBarPageList::getAccessibleDescription( )
454 return OUString();
458 OUString AccessibleTabBarPageList::getAccessibleName( )
460 return OUString();
464 Reference< XAccessibleRelationSet > AccessibleTabBarPageList::getAccessibleRelationSet( )
466 OExternalLockGuard aGuard( this );
468 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
469 Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
470 return xSet;
474 Reference< XAccessibleStateSet > AccessibleTabBarPageList::getAccessibleStateSet( )
476 OExternalLockGuard aGuard( this );
478 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
479 Reference< XAccessibleStateSet > xSet = pStateSetHelper;
481 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
483 FillAccessibleStateSet( *pStateSetHelper );
485 else
487 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
490 return xSet;
494 Locale AccessibleTabBarPageList::getLocale( )
496 OExternalLockGuard aGuard( this );
498 return Application::GetSettings().GetLanguageTag().getLocale();
502 // XAccessibleComponent
505 Reference< XAccessible > AccessibleTabBarPageList::getAccessibleAtPoint( const awt::Point& rPoint )
507 OExternalLockGuard aGuard( this );
509 Reference< XAccessible > xChild;
510 for ( size_t i = 0; i < m_aAccessibleChildren.size(); ++i )
512 Reference< XAccessible > xAcc = getAccessibleChild( i );
513 if ( xAcc.is() )
515 Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY );
516 if ( xComp.is() )
518 tools::Rectangle aRect = VCLRectangle( xComp->getBounds() );
519 Point aPos = VCLPoint( rPoint );
520 if ( aRect.IsInside( aPos ) )
522 xChild = xAcc;
523 break;
529 return xChild;
533 void AccessibleTabBarPageList::grabFocus( )
535 // no focus
539 sal_Int32 AccessibleTabBarPageList::getForeground( )
541 OExternalLockGuard aGuard( this );
543 sal_Int32 nColor = 0;
544 Reference< XAccessible > xParent = getAccessibleParent();
545 if ( xParent.is() )
547 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
548 if ( xParentComp.is() )
549 nColor = xParentComp->getForeground();
552 return nColor;
556 sal_Int32 AccessibleTabBarPageList::getBackground( )
558 OExternalLockGuard aGuard( this );
560 sal_Int32 nColor = 0;
561 Reference< XAccessible > xParent = getAccessibleParent();
562 if ( xParent.is() )
564 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
565 if ( xParentComp.is() )
566 nColor = xParentComp->getBackground();
569 return nColor;
573 // XAccessibleExtendedComponent
576 Reference< awt::XFont > AccessibleTabBarPageList::getFont( )
578 OExternalLockGuard aGuard( this );
580 Reference< awt::XFont > xFont;
581 Reference< XAccessible > xParent = getAccessibleParent();
582 if ( xParent.is() )
584 Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
585 if ( xParentComp.is() )
586 xFont = xParentComp->getFont();
589 return xFont;
593 OUString AccessibleTabBarPageList::getTitledBorderText( )
595 return OUString();
599 OUString AccessibleTabBarPageList::getToolTipText( )
601 return OUString();
605 // XAccessibleSelection
608 void AccessibleTabBarPageList::selectAccessibleChild( sal_Int32 nChildIndex )
610 OExternalLockGuard aGuard( this );
612 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
613 throw IndexOutOfBoundsException();
615 if ( m_pTabBar )
617 m_pTabBar->SetCurPageId( m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) );
618 m_pTabBar->Update();
619 m_pTabBar->ActivatePage();
620 m_pTabBar->Select();
625 sal_Bool AccessibleTabBarPageList::isAccessibleChildSelected( sal_Int32 nChildIndex )
627 OExternalLockGuard aGuard( this );
629 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
630 throw IndexOutOfBoundsException();
632 bool bSelected = false;
633 if ( m_pTabBar && m_pTabBar->GetCurPageId() == m_pTabBar->GetPageId( static_cast<sal_uInt16>(nChildIndex) ) )
634 bSelected = true;
636 return bSelected;
640 void AccessibleTabBarPageList::clearAccessibleSelection( )
642 // This method makes no sense in a TabBar, and so does nothing.
646 void AccessibleTabBarPageList::selectAllAccessibleChildren( )
648 selectAccessibleChild( 0 );
652 sal_Int32 AccessibleTabBarPageList::getSelectedAccessibleChildCount( )
654 return 1;
658 Reference< XAccessible > AccessibleTabBarPageList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
660 OExternalLockGuard aGuard( this );
662 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
663 throw IndexOutOfBoundsException();
665 Reference< XAccessible > xChild;
667 for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
669 if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
671 xChild = getAccessibleChild( i );
672 break;
676 return xChild;
680 void AccessibleTabBarPageList::deselectAccessibleChild( sal_Int32 nChildIndex )
682 OExternalLockGuard aGuard( this );
684 if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
685 throw IndexOutOfBoundsException();
687 // This method makes no sense in a TabBar, and so does nothing.
691 } // namespace accessibility
694 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */