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/accessibletablistboxtable.hxx>
21 #include <extended/AccessibleBrowseBoxTableCell.hxx>
22 #include <extended/AccessibleBrowseBoxCheckBoxCell.hxx>
23 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <vcl/toolkit/svtabbx.hxx>
28 namespace accessibility
32 // class AccessibleTabListBoxTable ---------------------------------------------
34 using namespace ::com::sun::star::accessibility
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::lang
;
37 using namespace ::com::sun::star
;
42 AccessibleTabListBoxTable::AccessibleTabListBoxTable( const Reference
< XAccessible
>& rxParent
, SvHeaderTabListBox
& rBox
) :
44 AccessibleBrowseBoxTable( rxParent
, rBox
),
46 m_pTabListBox ( &rBox
)
49 m_pTabListBox
->AddEventListener( LINK( this, AccessibleTabListBoxTable
, WindowEventListener
) );
52 AccessibleTabListBoxTable::~AccessibleTabListBoxTable()
56 m_pTabListBox
= nullptr;
58 // increment ref count to prevent double call of Dtor
59 osl_atomic_increment( &m_refCount
);
64 void AccessibleTabListBoxTable::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
69 switch ( VclEventId nEventId
= rVclWindowEvent
.GetId(); nEventId
)
71 case VclEventId::ObjectDying
:
73 m_pTabListBox
->RemoveEventListener( LINK( this, AccessibleTabListBoxTable
, WindowEventListener
) );
74 m_pTabListBox
= nullptr;
78 case VclEventId::ControlGetFocus
:
79 case VclEventId::ControlLoseFocus
:
81 uno::Any aOldValue
, aNewValue
;
82 if ( nEventId
== VclEventId::ControlGetFocus
)
83 aNewValue
<<= AccessibleStateType::FOCUSED
;
85 aOldValue
<<= AccessibleStateType::FOCUSED
;
86 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
90 case VclEventId::ListboxSelect
:
92 // First send an event that tells the listeners of a
93 // modified selection. The active descendant event is
94 // send after that so that the receiving AT has time to
95 // read the text or name of the active child.
96 commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
97 if ( m_pTabListBox
&& m_pTabListBox
->HasFocus() )
99 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
102 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
103 sal_uInt16 nCol
= m_pTabListBox
->GetCurrColumn();
104 Reference
< XAccessible
> xChild
=
105 m_pTabListBox
->CreateAccessibleCell( nRow
, nCol
);
106 uno::Any aOldValue
, aNewValue
;
107 aNewValue
<<= xChild
;
108 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aNewValue
, aOldValue
);
113 case VclEventId::WindowGetFocus
:
115 uno::Any aOldValue
, aNewValue
;
116 aNewValue
<<= AccessibleStateType::FOCUSED
;
117 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
121 case VclEventId::WindowLoseFocus
:
123 uno::Any aOldValue
, aNewValue
;
124 aOldValue
<<= AccessibleStateType::FOCUSED
;
125 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
128 case VclEventId::ListboxTreeSelect
:
130 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
133 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
134 Reference
< XAccessible
> xChild
= m_pTabListBox
->CreateAccessibleCell( nRow
, m_pTabListBox
->GetCurrColumn() );
135 TriState eState
= TRISTATE_INDET
;
136 if ( m_pTabListBox
->IsCellCheckBox( nRow
, m_pTabListBox
->GetCurrColumn(), eState
) )
138 AccessibleCheckBoxCell
* pCell
= static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
139 pCell
->commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
143 AccessibleBrowseBoxTableCell
* pCell
= static_cast< AccessibleBrowseBoxTableCell
* >( xChild
.get() );
144 pCell
->commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
149 case VclEventId::ListboxTreeFocus
:
151 if ( m_pTabListBox
&& m_pTabListBox
->HasFocus() )
153 uno::Any aOldValue
, aNewValue
;
154 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
157 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
158 m_xCurChild
= m_pTabListBox
->CreateAccessibleCell( nRow
, m_pTabListBox
->GetCurrColumn() );
159 aNewValue
<<= m_xCurChild
;
160 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aNewValue
,aOldValue
);
164 aNewValue
<<= AccessibleStateType::FOCUSED
;
165 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
,aOldValue
);
171 case VclEventId::CheckboxToggle
:
173 if ( m_pTabListBox
&& m_pTabListBox
->HasFocus() )
175 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
178 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
179 sal_uInt16 nCol
= m_pTabListBox
->GetCurrColumn();
180 TriState eState
= TRISTATE_INDET
;
181 if ( m_pTabListBox
->IsCellCheckBox( nRow
, nCol
, eState
) )
183 Reference
< XAccessible
> xChild
=
184 m_pTabListBox
->CreateAccessibleCell( nRow
, nCol
);
185 AccessibleCheckBoxCell
* pCell
=
186 static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
187 pCell
->SetChecked( SvHeaderTabListBox::IsItemChecked( pEntry
, nCol
) );
198 IMPL_LINK( AccessibleTabListBoxTable
, WindowEventListener
, VclWindowEvent
&, rEvent
, void )
200 OSL_ENSURE( rEvent
.GetWindow() && m_pTabListBox
, "no event window" );
201 ProcessWindowEvent( rEvent
);
203 // helpers --------------------------------------------------------------------
205 void AccessibleTabListBoxTable::ensureValidIndex( sal_Int32 _nIndex
) const
207 if ( ( _nIndex
< 0 ) || ( _nIndex
>= (implGetRowCount() * implGetColumnCount()) ) )
208 throw IndexOutOfBoundsException();
211 void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow
, bool _bSelect
)
214 m_pTabListBox
->Select( m_pTabListBox
->GetEntry( _nRow
), _bSelect
);
217 sal_Int32
AccessibleTabListBoxTable::implGetRowCount() const
219 return m_pTabListBox
? m_pTabListBox
->GetEntryCount() : 0;
222 sal_Int32
AccessibleTabListBoxTable::implGetColumnCount() const
224 return m_pTabListBox
? m_pTabListBox
->GetColumnCount() : 0;
227 sal_Int32
AccessibleTabListBoxTable::implGetSelRowCount() const
229 return m_pTabListBox
? m_pTabListBox
->GetSelectionCount() : 0;
232 sal_Int32
AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow
) const
237 SvTreeListEntry
* pEntry
= m_pTabListBox
->FirstSelected();
241 if ( nRow
== nSelRow
)
242 return m_pTabListBox
->GetEntryPos( pEntry
);
243 pEntry
= m_pTabListBox
->NextSelected( pEntry
);
250 // XInterface & XTypeProvider
252 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable
, AccessibleBrowseBoxTable
, AccessibleTabListBoxTableImplHelper
)
253 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable
, AccessibleBrowseBoxTable
, AccessibleTabListBoxTableImplHelper
)
257 OUString
AccessibleTabListBoxTable::getImplementationName()
259 return "com.sun.star.comp.svtools.AccessibleTabListBoxTable";
262 // XAccessibleSelection
264 void SAL_CALL
AccessibleTabListBoxTable::selectAccessibleChild( sal_Int32 nChildIndex
)
266 SolarMutexGuard aSolarGuard
;
267 ::osl::MutexGuard
aGuard( getMutex() );
270 ensureValidIndex( nChildIndex
);
272 implSelectRow( implGetRow( nChildIndex
), true );
275 sal_Bool SAL_CALL
AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int32 nChildIndex
)
277 SolarMutexGuard aSolarGuard
;
278 ::osl::MutexGuard
aGuard( getMutex() );
281 ensureValidIndex( nChildIndex
);
283 return m_pTabListBox
&& m_pTabListBox
->IsSelected( m_pTabListBox
->GetEntry( implGetRow( nChildIndex
) ) );
286 void SAL_CALL
AccessibleTabListBoxTable::clearAccessibleSelection( )
288 SolarMutexGuard aSolarGuard
;
289 ::osl::MutexGuard
aGuard( getMutex() );
293 m_pTabListBox
->SetNoSelection();
296 void SAL_CALL
AccessibleTabListBoxTable::selectAllAccessibleChildren( )
298 SolarMutexGuard aSolarGuard
;
299 ::osl::MutexGuard
aGuard( getMutex() );
303 m_pTabListBox
->SelectAll();
306 sal_Int32 SAL_CALL
AccessibleTabListBoxTable::getSelectedAccessibleChildCount( )
308 SolarMutexGuard aSolarGuard
;
309 ::osl::MutexGuard
aGuard( getMutex() );
313 return implGetColumnCount() * implGetSelRowCount();
316 Reference
< XAccessible
> SAL_CALL
AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
)
318 SolarMutexGuard aSolarGuard
;
319 ::osl::MutexGuard
aGuard( getMutex() );
323 sal_Int32 nRows
= implGetSelRowCount();
325 throw IndexOutOfBoundsException();
327 sal_Int32 nRow
= implGetSelRow( nSelectedChildIndex
% nRows
);
328 sal_Int32 nColumn
= nSelectedChildIndex
/ nRows
;
329 return getAccessibleCellAt( nRow
, nColumn
);
332 void SAL_CALL
AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int32 nSelectedChildIndex
)
334 SolarMutexGuard aSolarGuard
;
335 ::osl::MutexGuard
aGuard( getMutex() );
338 ensureValidIndex( nSelectedChildIndex
);
340 implSelectRow( implGetRow( nSelectedChildIndex
), false );
344 }// namespace accessibility
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */