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 .
21 #include <extended/accessibletablistboxtable.hxx>
22 #include <extended/AccessibleBrowseBoxTableCell.hxx>
23 #include <extended/AccessibleBrowseBoxCheckBoxCell.hxx>
24 #include <vcl/svtabbx.hxx>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
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
)
68 VclEventId nEventId
= rVclWindowEvent
.GetId();
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
;
108 if ( m_pTabListBox
->IsTransientChildrenDisabled() )
110 aNewValue
<<= AccessibleStateType::FOCUSED
;
111 TriState eState
= TRISTATE_INDET
;
112 if ( m_pTabListBox
->IsCellCheckBox( nRow
, nCol
, eState
) )
114 AccessibleCheckBoxCell
* pCell
=
115 static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
116 pCell
->commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
120 AccessibleBrowseBoxTableCell
* pCell
=
121 static_cast< AccessibleBrowseBoxTableCell
* >( xChild
.get() );
122 pCell
->commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
127 aNewValue
<<= xChild
;
128 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aNewValue
, aOldValue
);
134 case VclEventId::WindowGetFocus
:
136 uno::Any aOldValue
, aNewValue
;
137 aNewValue
<<= AccessibleStateType::FOCUSED
;
138 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
142 case VclEventId::WindowLoseFocus
:
144 uno::Any aOldValue
, aNewValue
;
145 aOldValue
<<= AccessibleStateType::FOCUSED
;
146 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
, aOldValue
);
149 case VclEventId::ListboxTreeSelect
:
151 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
154 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
155 Reference
< XAccessible
> xChild
= m_pTabListBox
->CreateAccessibleCell( nRow
, m_pTabListBox
->GetCurrColumn() );
156 TriState eState
= TRISTATE_INDET
;
157 if ( m_pTabListBox
->IsCellCheckBox( nRow
, m_pTabListBox
->GetCurrColumn(), eState
) )
159 AccessibleCheckBoxCell
* pCell
= static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
160 pCell
->commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
164 AccessibleBrowseBoxTableCell
* pCell
= static_cast< AccessibleBrowseBoxTableCell
* >( xChild
.get() );
165 pCell
->commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
170 case VclEventId::ListboxTreeFocus
:
172 if ( m_pTabListBox
&& m_pTabListBox
->HasFocus() )
174 uno::Any aOldValue
, aNewValue
;
175 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
178 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
179 m_xCurChild
= m_pTabListBox
->CreateAccessibleCell( nRow
, m_pTabListBox
->GetCurrColumn() );
180 aNewValue
<<= m_xCurChild
;
181 commitEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, aNewValue
,aOldValue
);
185 aNewValue
<<= AccessibleStateType::FOCUSED
;
186 commitEvent( AccessibleEventId::STATE_CHANGED
, aNewValue
,aOldValue
);
192 case VclEventId::CheckboxToggle
:
194 if ( m_pTabListBox
&& m_pTabListBox
->HasFocus() )
196 SvTreeListEntry
* pEntry
= static_cast< SvTreeListEntry
* >( rVclWindowEvent
.GetData() );
199 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
200 sal_uInt16 nCol
= m_pTabListBox
->GetCurrColumn();
201 TriState eState
= TRISTATE_INDET
;
202 if ( m_pTabListBox
->IsCellCheckBox( nRow
, nCol
, eState
) )
204 Reference
< XAccessible
> xChild
=
205 m_pTabListBox
->CreateAccessibleCell( nRow
, nCol
);
206 AccessibleCheckBoxCell
* pCell
=
207 static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
208 pCell
->SetChecked( SvHeaderTabListBox::IsItemChecked( pEntry
, nCol
) );
215 case VclEventId::TableCellNameChanged
:
217 if ( m_pTabListBox
->IsTransientChildrenDisabled() )
219 commitEvent( AccessibleEventId::SELECTION_CHANGED
, Any(), Any() );
220 TabListBoxEventData
* pData
= static_cast< TabListBoxEventData
* >( rVclWindowEvent
.GetData() );
221 SvTreeListEntry
* pEntry
= pData
!= nullptr ? pData
->m_pEntry
: nullptr;
224 sal_Int32 nRow
= m_pTabListBox
->GetEntryPos( pEntry
);
225 sal_uInt16 nCol
= pData
->m_nColumn
;
226 Reference
< XAccessible
> xChild
=
227 m_pTabListBox
->CreateAccessibleCell( nRow
, nCol
);
228 uno::Any aOldValue
, aNewValue
;
229 aOldValue
<<= pData
->m_sOldText
;
230 OUString
sNewText( m_pTabListBox
->GetCellText( nRow
, nCol
) );
231 aNewValue
<<= sNewText
;
232 TriState eState
= TRISTATE_INDET
;
234 if ( m_pTabListBox
->IsCellCheckBox( nRow
, nCol
, eState
) )
236 AccessibleCheckBoxCell
* pCell
=
237 static_cast< AccessibleCheckBoxCell
* >( xChild
.get() );
238 pCell
->commitEvent( AccessibleEventId::NAME_CHANGED
, aNewValue
, aOldValue
);
242 AccessibleBrowseBoxTableCell
* pCell
=
243 static_cast< AccessibleBrowseBoxTableCell
* >( xChild
.get() );
244 pCell
->nameChanged( sNewText
, pData
->m_sOldText
);
255 IMPL_LINK( AccessibleTabListBoxTable
, WindowEventListener
, VclWindowEvent
&, rEvent
, void )
257 OSL_ENSURE( rEvent
.GetWindow() && m_pTabListBox
, "no event window" );
258 ProcessWindowEvent( rEvent
);
260 // helpers --------------------------------------------------------------------
262 void AccessibleTabListBoxTable::ensureValidIndex( sal_Int32 _nIndex
) const
264 if ( ( _nIndex
< 0 ) || ( _nIndex
>= (implGetRowCount() * implGetColumnCount()) ) )
265 throw IndexOutOfBoundsException();
268 void AccessibleTabListBoxTable::implSelectRow( sal_Int32 _nRow
, bool _bSelect
)
271 m_pTabListBox
->Select( m_pTabListBox
->GetEntry( _nRow
), _bSelect
);
274 sal_Int32
AccessibleTabListBoxTable::implGetRowCount() const
276 return m_pTabListBox
? m_pTabListBox
->GetEntryCount() : 0;
279 sal_Int32
AccessibleTabListBoxTable::implGetColumnCount() const
281 return m_pTabListBox
? m_pTabListBox
->GetColumnCount() : 0;
284 sal_Int32
AccessibleTabListBoxTable::implGetSelRowCount() const
286 return m_pTabListBox
? m_pTabListBox
->GetSelectionCount() : 0;
289 sal_Int32
AccessibleTabListBoxTable::implGetSelRow( sal_Int32 nSelRow
) const
294 SvTreeListEntry
* pEntry
= m_pTabListBox
->FirstSelected();
298 if ( nRow
== nSelRow
)
299 return m_pTabListBox
->GetEntryPos( pEntry
);
300 pEntry
= m_pTabListBox
->NextSelected( pEntry
);
307 // XInterface & XTypeProvider
309 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleTabListBoxTable
, AccessibleBrowseBoxTable
, AccessibleTabListBoxTableImplHelper
)
310 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleTabListBoxTable
, AccessibleBrowseBoxTable
, AccessibleTabListBoxTableImplHelper
)
314 OUString
AccessibleTabListBoxTable::getImplementationName()
316 return OUString( "com.sun.star.comp.svtools.AccessibleTabListBoxTable" );
319 // XAccessibleSelection
321 void SAL_CALL
AccessibleTabListBoxTable::selectAccessibleChild( sal_Int32 nChildIndex
)
323 SolarMutexGuard aSolarGuard
;
324 ::osl::MutexGuard
aGuard( getMutex() );
327 ensureValidIndex( nChildIndex
);
329 implSelectRow( implGetRow( nChildIndex
), true );
332 sal_Bool SAL_CALL
AccessibleTabListBoxTable::isAccessibleChildSelected( sal_Int32 nChildIndex
)
334 SolarMutexGuard aSolarGuard
;
335 ::osl::MutexGuard
aGuard( getMutex() );
338 ensureValidIndex( nChildIndex
);
340 return m_pTabListBox
&& m_pTabListBox
->IsSelected( m_pTabListBox
->GetEntry( implGetRow( nChildIndex
) ) );
343 void SAL_CALL
AccessibleTabListBoxTable::clearAccessibleSelection( )
345 SolarMutexGuard aSolarGuard
;
346 ::osl::MutexGuard
aGuard( getMutex() );
350 m_pTabListBox
->SetNoSelection();
353 void SAL_CALL
AccessibleTabListBoxTable::selectAllAccessibleChildren( )
355 SolarMutexGuard aSolarGuard
;
356 ::osl::MutexGuard
aGuard( getMutex() );
360 m_pTabListBox
->SelectAll();
363 sal_Int32 SAL_CALL
AccessibleTabListBoxTable::getSelectedAccessibleChildCount( )
365 SolarMutexGuard aSolarGuard
;
366 ::osl::MutexGuard
aGuard( getMutex() );
370 return implGetColumnCount() * implGetSelRowCount();
373 Reference
< XAccessible
> SAL_CALL
AccessibleTabListBoxTable::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
)
375 SolarMutexGuard aSolarGuard
;
376 ::osl::MutexGuard
aGuard( getMutex() );
380 sal_Int32 nRows
= implGetSelRowCount();
382 throw IndexOutOfBoundsException();
384 sal_Int32 nRow
= implGetSelRow( nSelectedChildIndex
% nRows
);
385 sal_Int32 nColumn
= nSelectedChildIndex
/ nRows
;
386 return getAccessibleCellAt( nRow
, nColumn
);
389 void SAL_CALL
AccessibleTabListBoxTable::deselectAccessibleChild( sal_Int32 nSelectedChildIndex
)
391 SolarMutexGuard aSolarGuard
;
392 ::osl::MutexGuard
aGuard( getMutex() );
395 ensureValidIndex( nSelectedChildIndex
);
397 implSelectRow( implGetRow( nSelectedChildIndex
), false );
401 }// namespace accessibility
404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */