1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_accessibility.hxx"
30 #include <accessibility/standard/vclxaccessibletabcontrol.hxx>
31 #include <accessibility/standard/vclxaccessibletabpage.hxx>
33 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <unotools/accessiblestatesethelper.hxx>
37 #include <vcl/tabctrl.hxx>
38 #include <vcl/tabpage.hxx>
42 using namespace ::com::sun::star
;
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::lang
;
45 using namespace ::com::sun::star::accessibility
;
46 using namespace ::comphelper
;
49 // ----------------------------------------------------
50 // class VCLXAccessibleTabControl
51 // ----------------------------------------------------
53 VCLXAccessibleTabControl::VCLXAccessibleTabControl( VCLXWindow
* pVCLXWindow
)
54 :VCLXAccessibleComponent( pVCLXWindow
)
56 m_pTabControl
= static_cast< TabControl
* >( GetWindow() );
59 m_aAccessibleChildren
.assign( m_pTabControl
->GetPageCount(), Reference
< XAccessible
>() );
62 // -----------------------------------------------------------------------------
64 VCLXAccessibleTabControl::~VCLXAccessibleTabControl()
68 // -----------------------------------------------------------------------------
70 void VCLXAccessibleTabControl::UpdateFocused()
72 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
74 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
77 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
78 if ( pVCLXAccessibleTabPage
)
79 pVCLXAccessibleTabPage
->SetFocused( pVCLXAccessibleTabPage
->IsFocused() );
84 // -----------------------------------------------------------------------------
86 void VCLXAccessibleTabControl::UpdateSelected( sal_Int32 i
, bool bSelected
)
88 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
90 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
92 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
95 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
96 if ( pVCLXAccessibleTabPage
)
97 pVCLXAccessibleTabPage
->SetSelected( bSelected
);
102 // -----------------------------------------------------------------------------
104 void VCLXAccessibleTabControl::UpdatePageText( sal_Int32 i
)
106 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
108 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
111 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
112 if ( pVCLXAccessibleTabPage
)
113 pVCLXAccessibleTabPage
->SetPageText( pVCLXAccessibleTabPage
->GetPageText() );
118 // -----------------------------------------------------------------------------
120 void VCLXAccessibleTabControl::UpdateTabPage( sal_Int32 i
, bool bNew
)
122 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
124 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
127 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
128 if ( pVCLXAccessibleTabPage
)
129 pVCLXAccessibleTabPage
->Update( bNew
);
134 // -----------------------------------------------------------------------------
136 void VCLXAccessibleTabControl::InsertChild( sal_Int32 i
)
138 if ( i
>= 0 && i
<= (sal_Int32
)m_aAccessibleChildren
.size() )
140 // insert entry in child list
141 m_aAccessibleChildren
.insert( m_aAccessibleChildren
.begin() + i
, Reference
< XAccessible
>() );
143 // send accessible child event
144 Reference
< XAccessible
> xChild( getAccessibleChild( i
) );
147 Any aOldValue
, aNewValue
;
148 aNewValue
<<= xChild
;
149 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
154 // -----------------------------------------------------------------------------
156 void VCLXAccessibleTabControl::RemoveChild( sal_Int32 i
)
158 if ( i
>= 0 && i
< (sal_Int32
)m_aAccessibleChildren
.size() )
160 // get the accessible of the removed page
161 Reference
< XAccessible
> xChild( m_aAccessibleChildren
[i
] );
163 // remove entry in child list
164 m_aAccessibleChildren
.erase( m_aAccessibleChildren
.begin() + i
);
166 // send accessible child event
169 Any aOldValue
, aNewValue
;
170 aOldValue
<<= xChild
;
171 NotifyAccessibleEvent( AccessibleEventId::CHILD
, aOldValue
, aNewValue
);
173 Reference
< XComponent
> xComponent( xChild
, UNO_QUERY
);
174 if ( xComponent
.is() )
175 xComponent
->dispose();
180 // -----------------------------------------------------------------------------
182 void VCLXAccessibleTabControl::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
184 switch ( rVclWindowEvent
.GetId() )
186 case VCLEVENT_TABPAGE_ACTIVATE
:
187 case VCLEVENT_TABPAGE_DEACTIVATE
:
191 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
192 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
194 UpdateSelected( nPagePos
, rVclWindowEvent
.GetId() == VCLEVENT_TABPAGE_ACTIVATE
);
198 case VCLEVENT_TABPAGE_PAGETEXTCHANGED
:
202 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
203 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
204 UpdatePageText( nPagePos
);
208 case VCLEVENT_TABPAGE_INSERTED
:
212 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
213 sal_uInt16 nPagePos
= m_pTabControl
->GetPagePos( nPageId
);
214 InsertChild( nPagePos
);
218 case VCLEVENT_TABPAGE_REMOVED
:
222 sal_uInt16 nPageId
= (sal_uInt16
)(sal_IntPtr
) rVclWindowEvent
.GetData();
223 for ( sal_Int32 i
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; ++i
)
225 Reference
< XAccessible
> xChild( getAccessibleChild( i
) );
228 VCLXAccessibleTabPage
* pVCLXAccessibleTabPage
= static_cast< VCLXAccessibleTabPage
* >( xChild
.get() );
229 if ( pVCLXAccessibleTabPage
&& pVCLXAccessibleTabPage
->GetPageId() == nPageId
)
239 case VCLEVENT_TABPAGE_REMOVEDALL
:
241 for ( sal_Int32 i
= m_aAccessibleChildren
.size() - 1; i
>= 0; --i
)
245 case VCLEVENT_WINDOW_GETFOCUS
:
246 case VCLEVENT_WINDOW_LOSEFOCUS
:
251 case VCLEVENT_OBJECT_DYING
:
255 m_pTabControl
= NULL
;
257 // dispose all tab pages
258 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
260 Reference
< XComponent
> xComponent( m_aAccessibleChildren
[i
], UNO_QUERY
);
261 if ( xComponent
.is() )
262 xComponent
->dispose();
264 m_aAccessibleChildren
.clear();
267 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
271 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent
);
275 // -----------------------------------------------------------------------------
277 void VCLXAccessibleTabControl::ProcessWindowChildEvent( const VclWindowEvent
& rVclWindowEvent
)
279 switch ( rVclWindowEvent
.GetId() )
281 case VCLEVENT_WINDOW_SHOW
:
282 case VCLEVENT_WINDOW_HIDE
:
286 Window
* pChild
= static_cast< Window
* >( rVclWindowEvent
.GetData() );
287 if ( pChild
&& pChild
->GetType() == WINDOW_TABPAGE
)
289 for ( sal_Int32 i
= 0, nCount
= m_pTabControl
->GetPageCount(); i
< nCount
; ++i
)
291 sal_uInt16 nPageId
= m_pTabControl
->GetPageId( (sal_uInt16
)i
);
292 TabPage
* pTabPage
= m_pTabControl
->GetTabPage( nPageId
);
293 if ( pTabPage
== (TabPage
*) pChild
)
294 UpdateTabPage( i
, rVclWindowEvent
.GetId() == VCLEVENT_WINDOW_SHOW
);
301 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent
);
306 // -----------------------------------------------------------------------------
308 void VCLXAccessibleTabControl::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
310 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet
);
313 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
316 // -----------------------------------------------------------------------------
318 // -----------------------------------------------------------------------------
320 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleTabControl
, VCLXAccessibleComponent
, VCLXAccessibleTabControl_BASE
)
322 // -----------------------------------------------------------------------------
324 // -----------------------------------------------------------------------------
326 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleTabControl
, VCLXAccessibleComponent
, VCLXAccessibleTabControl_BASE
)
328 // -----------------------------------------------------------------------------
330 // -----------------------------------------------------------------------------
332 void VCLXAccessibleTabControl::disposing()
334 VCLXAccessibleComponent::disposing();
338 m_pTabControl
= NULL
;
340 // dispose all tab pages
341 for ( sal_uInt32 i
= 0; i
< m_aAccessibleChildren
.size(); ++i
)
343 Reference
< XComponent
> xComponent( m_aAccessibleChildren
[i
], UNO_QUERY
);
344 if ( xComponent
.is() )
345 xComponent
->dispose();
347 m_aAccessibleChildren
.clear();
351 // -----------------------------------------------------------------------------
353 // -----------------------------------------------------------------------------
355 ::rtl::OUString
VCLXAccessibleTabControl::getImplementationName() throw (RuntimeException
)
357 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleTabControl" );
360 // -----------------------------------------------------------------------------
362 Sequence
< ::rtl::OUString
> VCLXAccessibleTabControl::getSupportedServiceNames() throw (RuntimeException
)
364 Sequence
< ::rtl::OUString
> aNames(1);
365 aNames
[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleTabControl" );
369 // -----------------------------------------------------------------------------
370 // XAccessibleContext
371 // -----------------------------------------------------------------------------
373 sal_Int32
VCLXAccessibleTabControl::getAccessibleChildCount() throw (RuntimeException
)
375 OExternalLockGuard
aGuard( this );
377 return m_aAccessibleChildren
.size();
380 // -----------------------------------------------------------------------------
382 Reference
< XAccessible
> VCLXAccessibleTabControl::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
)
384 OExternalLockGuard
aGuard( this );
386 if ( i
< 0 || i
>= getAccessibleChildCount() )
387 throw IndexOutOfBoundsException();
389 Reference
< XAccessible
> xChild
= m_aAccessibleChildren
[i
];
394 sal_uInt16 nPageId
= m_pTabControl
->GetPageId( (sal_uInt16
)i
);
396 xChild
= new VCLXAccessibleTabPage( m_pTabControl
, nPageId
);
398 // insert into tab page list
399 m_aAccessibleChildren
[i
] = xChild
;
406 // -----------------------------------------------------------------------------
408 sal_Int16
VCLXAccessibleTabControl::getAccessibleRole( ) throw (RuntimeException
)
410 OExternalLockGuard
aGuard( this );
412 return AccessibleRole::PAGE_TAB_LIST
;
415 // -----------------------------------------------------------------------------
417 ::rtl::OUString
VCLXAccessibleTabControl::getAccessibleName( ) throw (RuntimeException
)
419 OExternalLockGuard
aGuard( this );
421 return ::rtl::OUString();
424 // -----------------------------------------------------------------------------
425 // XAccessibleSelection
426 // -----------------------------------------------------------------------------
428 void VCLXAccessibleTabControl::selectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
430 OExternalLockGuard
aGuard( this );
432 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
433 throw IndexOutOfBoundsException();
436 m_pTabControl
->SelectTabPage( m_pTabControl
->GetPageId( (sal_uInt16
)nChildIndex
) );
439 // -----------------------------------------------------------------------------
441 sal_Bool
VCLXAccessibleTabControl::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
443 OExternalLockGuard
aGuard( this );
445 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
446 throw IndexOutOfBoundsException();
448 sal_Bool bSelected
= sal_False
;
449 if ( m_pTabControl
&& m_pTabControl
->GetCurPageId() == m_pTabControl
->GetPageId( (sal_uInt16
)nChildIndex
) )
450 bSelected
= sal_True
;
455 // -----------------------------------------------------------------------------
457 void VCLXAccessibleTabControl::clearAccessibleSelection( ) throw (RuntimeException
)
459 // This method makes no sense in a tab control, and so does nothing.
462 // -----------------------------------------------------------------------------
464 void VCLXAccessibleTabControl::selectAllAccessibleChildren( ) throw (RuntimeException
)
466 OExternalLockGuard
aGuard( this );
468 selectAccessibleChild( 0 );
471 // -----------------------------------------------------------------------------
473 sal_Int32
VCLXAccessibleTabControl::getSelectedAccessibleChildCount( ) throw (RuntimeException
)
475 OExternalLockGuard
aGuard( this );
480 // -----------------------------------------------------------------------------
482 Reference
< XAccessible
> VCLXAccessibleTabControl::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
484 OExternalLockGuard
aGuard( this );
486 if ( nSelectedChildIndex
< 0 || nSelectedChildIndex
>= getSelectedAccessibleChildCount() )
487 throw IndexOutOfBoundsException();
489 Reference
< XAccessible
> xChild
;
491 for ( sal_Int32 i
= 0, j
= 0, nCount
= getAccessibleChildCount(); i
< nCount
; i
++ )
493 if ( isAccessibleChildSelected( i
) && ( j
++ == nSelectedChildIndex
) )
495 xChild
= getAccessibleChild( i
);
503 // -----------------------------------------------------------------------------
505 void VCLXAccessibleTabControl::deselectAccessibleChild( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
507 OExternalLockGuard
aGuard( this );
509 if ( nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount() )
510 throw IndexOutOfBoundsException();
512 // This method makes no sense in a tab control, and so does nothing.
515 // -----------------------------------------------------------------------------