1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vclxaccessibletabcontrol.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_accessibility.hxx"
33 #include <accessibility/standard/vclxaccessibletabcontrol.hxx>
34 #include <accessibility/standard/vclxaccessibletabpage.hxx>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #include <unotools/accessiblestatesethelper.hxx>
40 #include <vcl/tabctrl.hxx>
41 #include <vcl/tabpage.hxx>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::uno
;
47 using namespace ::com::sun::star::lang
;
48 using namespace ::com::sun::star::accessibility
;
49 using namespace ::comphelper
;
52 // ----------------------------------------------------
53 // class VCLXAccessibleTabControl
54 // ----------------------------------------------------
56 VCLXAccessibleTabControl::VCLXAccessibleTabControl( VCLXWindow
* pVCLXWindow
)
57 :VCLXAccessibleComponent( pVCLXWindow
)
59 m_pTabControl
= static_cast< TabControl
* >( GetWindow() );
62 m_aAccessibleChildren
.assign( m_pTabControl
->GetPageCount(), Reference
< XAccessible
>() );
65 // -----------------------------------------------------------------------------
67 VCLXAccessibleTabControl::~VCLXAccessibleTabControl()
71 // -----------------------------------------------------------------------------
73 void VCLXAccessibleTabControl::UpdateFocused()
75 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
77 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
80 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
81 if ( pVCLXAccessibleTabPage
)
82 pVCLXAccessibleTabPage
->SetFocused( pVCLXAccessibleTabPage
->IsFocused() );
87 // -----------------------------------------------------------------------------
89 void VCLXAccessibleTabControl::UpdateSelected( sal_Int32 i
, bool bSelected
)
91 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
93 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
95 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
98 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
99 if ( pVCLXAccessibleTabPage
)
100 pVCLXAccessibleTabPage
->SetSelected( bSelected
);
105 // -----------------------------------------------------------------------------
107 void VCLXAccessibleTabControl::UpdatePageText( sal_Int32 i
)
109 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
111 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
114 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
115 if ( pVCLXAccessibleTabPage
)
116 pVCLXAccessibleTabPage
->SetPageText( pVCLXAccessibleTabPage
->GetPageText() );
121 // -----------------------------------------------------------------------------
123 void VCLXAccessibleTabControl::UpdateTabPage( sal_Int32 i
, bool bNew
)
125 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
127 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
130 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
131 if ( pVCLXAccessibleTabPage
)
132 pVCLXAccessibleTabPage
->Update( bNew
);
137 // -----------------------------------------------------------------------------
139 void VCLXAccessibleTabControl::InsertChild( sal_Int32 i
)
141 if ( i
>= 0 && i
<= (sal_Int32
)m_aAccessibleChildren
.size() )
143 // insert entry in child list
144 m_aAccessibleChildren
.insert( m_aAccessibleChildren
.begin() + i
, Reference
< XAccessible
>() );
146 // send accessible child event
147 Reference
< XAccessible
> xChild( getAccessibleChild( i
) );
150 Any aOldValue
, aNewValue
;
151 aNewValue
<<= xChild
;
152 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
157 // -----------------------------------------------------------------------------
159 void VCLXAccessibleTabControl::RemoveChild( sal_Int32 i
)
161 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
163 // get the accessible of the removed page
164 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
166 // remove entry in child list
167 m_aAccessibleChildren
.erase( m_aAccessibleChildren
.begin() + i
);
169 // send accessible child event
172 Any aOldValue
, aNewValue
;
173 aOldValue
<<= xChild
;
174 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
176 Reference
< XComponent
> xComponent( xChild
, UNO_QUERY
);
177 if ( xComponent
.is() )
178 xComponent
->dispose();
183 // -----------------------------------------------------------------------------
185 void VCLXAccessibleTabControl::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
187 switch ( rVclWindowEvent
.GetId() )
189 case VCLEVENT_TABPAGE_ACTIVATE
:
190 case VCLEVENT_TABPAGE_DEACTIVATE
:
194 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
195 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
197 UpdateSelected( nPagePos
, rVclWindowEvent
.GetId() == VCLEVENT_TABPAGE_ACTIVATE
);
201 case VCLEVENT_TABPAGE_PAGETEXTCHANGED
:
205 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
206 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
207 UpdatePageText( nPagePos
);
211 case VCLEVENT_TABPAGE_INSERTED
:
215 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
216 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
217 InsertChild( nPagePos
);
221 case VCLEVENT_TABPAGE_REMOVED
:
225 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
226 for ( sal_Int32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
228 Reference
< XAccessible
> xChild( getAccessibleChild( i
) );
231 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
232 if ( pVCLXAccessibleTabPage
&& pVCLXAccessibleTabPage
->GetPageId() == nPageId
)
242 case VCLEVENT_TABPAGE_REMOVEDALL
:
244 for ( sal_Int32 i
= m_aAccessibleChildren
.size() - 1; i
>= 0; --i
)
248 case VCLEVENT_WINDOW_GETFOCUS
:
249 case VCLEVENT_WINDOW_LOSEFOCUS
:
254 case VCLEVENT_OBJECT_DYING
:
258 m_pTabControl
= NULL
;
260 // dispose all tab pages
261 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
263 Reference
< XComponent
> xComponent( m_aAccessibleChildren
[i
], UNO_QUERY
);
264 if ( xComponent
.is() )
265 xComponent
->dispose();
267 m_aAccessibleChildren
.clear();
270 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
274 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
278 // -----------------------------------------------------------------------------
280 void VCLXAccessibleTabControl::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
282 switch ( rVclWindowEvent
.GetId() )
284 case VCLEVENT_WINDOW_SHOW
:
285 case VCLEVENT_WINDOW_HIDE
:
289 Window
* pChild
= static_cast< Window
* >( rVclWindowEvent
.GetData() );
290 if ( pChild
&& pChild
->GetType() == WINDOW_TABPAGE
)
292 for ( sal_Int32 i
= 0, nCount
= m_pTabControl
->GetPageCount(); i
< nCount
; ++i
)
294 sal_uInt16 nPageId
= m_pTabControl
->GetPageId( (USHORT
)i
);
295 TabPage
* pTabPage
= m_pTabControl
->GetTabPage( nPageId
);
296 if ( pTabPage
== (TabPage
*) pChild
)
297 UpdateTabPage( i
, rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
304 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
309 // -----------------------------------------------------------------------------
311 void VCLXAccessibleTabControl::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
313 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
316 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
319 // -----------------------------------------------------------------------------
321 // -----------------------------------------------------------------------------
323 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleTabControl
, VCLXAccessibleComponent
, VCLXAccessibleTabControl_BASE
)
325 // -----------------------------------------------------------------------------
327 // -----------------------------------------------------------------------------
329 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleTabControl
, VCLXAccessibleComponent
, VCLXAccessibleTabControl_BASE
)
331 // -----------------------------------------------------------------------------
333 // -----------------------------------------------------------------------------
335 void VCLXAccessibleTabControl::disposing()
337 VCLXAccessibleComponent::disposing();
341 m_pTabControl
= NULL
;
343 // dispose all tab pages
344 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
346 Reference
< XComponent
> xComponent( m_aAccessibleChildren
[i
], UNO_QUERY
);
347 if ( xComponent
.is() )
348 xComponent
->dispose();
350 m_aAccessibleChildren
.clear();
354 // -----------------------------------------------------------------------------
356 // -----------------------------------------------------------------------------
358 ::rtl::OUString
VCLXAccessibleTabControl::getImplementationName() throw (RuntimeException
)
360 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleTabControl" );
363 // -----------------------------------------------------------------------------
365 Sequence
< ::rtl::OUString
> VCLXAccessibleTabControl::getSupportedServiceNames() throw (RuntimeException
)
367 Sequence
< ::rtl::OUString
> aNames(1);
368 aNames
[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleTabControl" );
372 // -----------------------------------------------------------------------------
373 // XAccessibleContext
374 // -----------------------------------------------------------------------------
376 sal_Int32
VCLXAccessibleTabControl::getAccessibleChildCount() throw (RuntimeException
)
378 OExternalLockGuard
aGuard( this );
380 return m_aAccessibleChildren
.size();
383 // -----------------------------------------------------------------------------
385 Reference
< XAccessible
> VCLXAccessibleTabControl::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
)
387 OExternalLockGuard
aGuard( this );
389 if ( i
< 0 || i
>= getAccessibleChildCount() )
390 throw IndexOutOfBoundsException();
392 Reference
< XAccessible
> xChild
= m_aAccessibleChildren
[i
];
397 sal_uInt16 nPageId
= m_pTabControl
->GetPageId( (USHORT
)i
);
399 xChild
= new VCLXAccessibleTabPage( m_pTabControl
, nPageId
);
401 // insert into tab page list
402 m_aAccessibleChildren
[i
] = xChild
;
409 // -----------------------------------------------------------------------------
411 sal_Int16
VCLXAccessibleTabControl::getAccessibleRole( ) throw (RuntimeException
)
413 OExternalLockGuard
aGuard( this );
415 return AccessibleRole::PAGE_TAB_LIST
;
418 // -----------------------------------------------------------------------------
420 ::rtl::OUString
VCLXAccessibleTabControl::getAccessibleName( ) throw (RuntimeException
)
422 OExternalLockGuard
aGuard( this );
424 return ::rtl::OUString();
427 // -----------------------------------------------------------------------------
428 // XAccessibleSelection
429 // -----------------------------------------------------------------------------
431 void VCLXAccessibleTabControl::selectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
433 OExternalLockGuard
aGuard( this );
435 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
436 throw IndexOutOfBoundsException();
439 m_pTabControl
->SelectTabPage( m_pTabControl
->GetPageId( (USHORT
)nChildIndex
) );
442 // -----------------------------------------------------------------------------
444 sal_Bool
VCLXAccessibleTabControl::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
446 OExternalLockGuard
aGuard( this );
448 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
449 throw IndexOutOfBoundsException();
451 sal_Bool bSelected
= sal_False
;
452 if ( m_pTabControl
&& m_pTabControl
->GetCurPageId() == m_pTabControl
->GetPageId( (USHORT
)nChildIndex
) )
453 bSelected
= sal_True
;
458 // -----------------------------------------------------------------------------
460 void VCLXAccessibleTabControl::clearAccessibleSelection( ) throw (RuntimeException
)
462 // This method makes no sense in a tab control, and so does nothing.
465 // -----------------------------------------------------------------------------
467 void VCLXAccessibleTabControl::selectAllAccessibleChildren( ) throw (RuntimeException
)
469 OExternalLockGuard
aGuard( this );
471 selectAccessibleChild( 0 );
474 // -----------------------------------------------------------------------------
476 sal_Int32
VCLXAccessibleTabControl::getSelectedAccessibleChildCount( ) throw (RuntimeException
)
478 OExternalLockGuard
aGuard( this );
483 // -----------------------------------------------------------------------------
485 Reference
< XAccessible
> VCLXAccessibleTabControl::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
487 OExternalLockGuard
aGuard( this );
489 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
490 throw IndexOutOfBoundsException();
492 Reference
< XAccessible
> xChild
;
494 for ( sal_Int32 i
= 0, j
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
496 if ( isAccessibleChildSelected( i
) && ( j
++ == nSelectedChildIndex
) )
498 xChild
= getAccessibleChild( i
);
506 // -----------------------------------------------------------------------------
508 void VCLXAccessibleTabControl::deselectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
510 OExternalLockGuard
aGuard( this );
512 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
513 throw IndexOutOfBoundsException();
515 // This method makes no sense in a tab control, and so does nothing.
518 // -----------------------------------------------------------------------------