LibreOffice Module accessibility (master) 1
AccessibleGridControlTable.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <com/sun/star/accessibility/AccessibleEventId.hpp>
21#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
22#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
23#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28#include <vcl/svapp.hxx>
29#include <tools/debug.hxx>
30
31using ::com::sun::star::uno::Reference;
32using ::com::sun::star::uno::Sequence;
33using ::com::sun::star::uno::Any;
34
35using namespace ::com::sun::star;
36using namespace ::com::sun::star::accessibility;
37using namespace ::vcl;
38using namespace ::vcl::table;
39
40
41namespace accessibility {
42
43
45 const Reference< XAccessible >& rxParent,
46 IAccessibleTable& rTable) :
48{
49}
50
51// XAccessibleContext ---------------------------------------------------------
52
55{
56 SolarMutexGuard aSolarGuard;
57
59 ensureIsValidIndex( nChildIndex );
60 sal_Int64 nCount = getAccessibleChildCount();
61 if(m_aCellVector.empty() || m_aCellVector.size() != static_cast<unsigned>(nCount))
62 {
63 assert(o3tl::make_unsigned(nCount) < m_aCellVector.max_size());
64 m_aCellVector.resize(nCount);
65 }
66 if(!m_aCellVector[nChildIndex].is())
67 {
69 m_aCellVector[nChildIndex] = pCell;
70 }
71 return m_aCellVector[nChildIndex];
72}
73
75{
76 SolarMutexGuard aSolarGuard;
77
80 return 0;
82 return 1;
83 else
84 return 2;
85}
86
87// XAccessibleComponent -------------------------------------------------------
88
91{
92 SolarMutexGuard aSolarGuard;
93
95
97 sal_Int32 nRow = 0;
98 sal_Int32 nColumnPos = 0;
99 if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) )
100 xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos);
101 return xChild;
102}
103
105{
106 SolarMutexGuard aSolarGuard;
107
110}
111
112// XAccessibleTable -----------------------------------------------------------
113
115{
116 SolarMutexGuard aSolarGuard;
117
119 ensureIsValidRow( nRow );
120 return "row description";
121}
122
124{
125 SolarMutexGuard aSolarGuard;
126
128 ensureIsValidColumn( nColumn );
129 return "col description";
130}
131
133{
135
138 return implGetHeaderBar( 1 );
139 else
140 return implGetHeaderBar( 0 );
141}
142
144{
146
148 return implGetHeaderBar( 0 );
149}
150
152{
153 SolarMutexGuard aSolarGuard;
154
156 Sequence< sal_Int32 > aSelSeq;
157 implGetSelectedRows( aSelSeq );
158 return aSelSeq;
159}
160
161//columns aren't selectable
163{
164 return {};
165}
166
168{
169 SolarMutexGuard aSolarGuard;
170
172 ensureIsValidRow( nRow );
174 return comphelper::findValue(selectedRows, nRow) != -1;
175}
176
177//columns aren't selectable
179{
180 return false;
181}
182
184 sal_Int32 nRow, sal_Int32 nColumn )
185{
186 SolarMutexGuard aSolarGuard;
187
189 ensureIsValidAddress( nRow, nColumn );
190 sal_Int64 nChildIndex = static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(m_aTable.GetColumnCount()) + nColumn;
191 return getAccessibleChild(nChildIndex);
192}
193
195 sal_Int32 nRow, sal_Int32 nColumn )
196{
197 SolarMutexGuard aSolarGuard;
198
200 ensureIsValidAddress( nRow, nColumn );
201 //selection of single cells not possible, so if row is selected, the cell will be selected too
202 return isAccessibleRowSelected(nRow);
203}
204void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int64 nChildIndex )
205{
206 SolarMutexGuard aSolarGuard;
207
209 ensureIsValidIndex( nChildIndex );
210 sal_Int32 nColumns = m_aTable.GetColumnCount();
211 sal_Int32 nRow = nChildIndex / nColumns;
212 m_aTable.SelectRow( nRow, true );
213}
215{
216 SolarMutexGuard aSolarGuard;
217
219 ensureIsValidIndex( nChildIndex );
220 sal_Int32 nColumns = m_aTable.GetColumnCount();
221 sal_Int32 nRow = nChildIndex / nColumns;
222 return isAccessibleRowSelected(nRow);
223}
225{
226 SolarMutexGuard aSolarGuard;
227
229 m_aTable.SelectAllRows( false );
230}
232{
233 SolarMutexGuard aSolarGuard;
234
237 auto selectedRowsRange = asNonConstRange(selectedRows);
238 for(tools::Long i=0; i<m_aTable.GetRowCount(); i++)
239 selectedRowsRange[i]=i;
240}
242{
243 SolarMutexGuard aSolarGuard;
244
247 sal_Int32 nColumns = m_aTable.GetColumnCount();
248 return static_cast<sal_Int64>(selectedRows.getLength()) * static_cast<sal_Int64>(nColumns);
249}
252{
253 SolarMutexGuard aSolarGuard;
254
256 if(isAccessibleChildSelected(nSelectedChildIndex))
257 return getAccessibleChild(nSelectedChildIndex);
258 else
259 return nullptr;
260}
261//not implemented yet, because only row selection possible
263 sal_Int64 )
264{
265 SolarMutexGuard aSolarGuard;
266
268}
269// XInterface -----------------------------------------------------------------
270
272{
274 return aAny.hasValue() ?
276}
277
279{
281}
282
284{
286}
287// XServiceInfo ---------------------------------------------------------------
288
290{
291 return "com.sun.star.accessibility.AccessibleGridControlTable";
292}
293
295{
297 {
298 if (rxCell.is())
299 {
300 rxCell->dispose();
301 rxCell.clear();
302 }
303 }
304
305 AccessibleGridControlTableBase::dispose();
306}
307
308void AccessibleGridControlTable::commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue,
309 const css::uno::Any& rOldValue)
310{
311 if (nEventId == AccessibleEventId::TABLE_MODEL_CHANGED)
312 {
313 AccessibleTableModelChange aChange;
314 if (rNewValue >>= aChange)
315 {
316 assert(aChange.Type != AccessibleTableModelChangeType::COLUMNS_REMOVED);
317
318 if (aChange.Type == AccessibleTableModelChangeType::ROWS_REMOVED)
319 {
320 int nColCount = m_aTable.GetColumnCount();
321 // check valid index - entries are inserted lazily
322 size_t const nStart = nColCount * aChange.FirstRow;
323 size_t const nEnd = nColCount * aChange.LastRow;
324 if (nStart < m_aCellVector.size())
325 {
326 m_aCellVector.erase(
327 m_aCellVector.begin() + nStart,
328 m_aCellVector.begin() + std::min(m_aCellVector.size(), nEnd));
329 }
330 }
331 }
332 }
333
334 AccessibleGridControlBase::commitEvent(nEventId, rNewValue, rOldValue);
335}
336
337// internal virtual methods ---------------------------------------------------
338
340{
342 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
343 tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( *pParent ));
345 tools::Long nX = aGridRect.Left() + aTableRect.Left();
346 tools::Long nY = aGridRect.Top() + aTableRect.Top();
347 tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
348 tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
349 tools::Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
350 return aTable;
351}
352
354{
357 tools::Long nX = aGridRect.Left() + aTableRect.Left();
358 tools::Long nY = aGridRect.Top() + aTableRect.Top();
359 tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
360 tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
361 tools::Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
362 return aTable;
363}
364// internal helper methods ----------------------------------------------------
366 sal_Int32 nChildIndex )
367{
369 Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY );
370 if( xContext.is() )
371 {
372 try
373 {
374 xRet = xContext->getAccessibleChild( nChildIndex );
375 }
376 catch (const lang::IndexOutOfBoundsException&)
377 {
378 OSL_FAIL( "implGetHeaderBar - wrong child index" );
379 }
380 // RuntimeException goes to caller
381 }
382 return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
383}
384
385
386} // namespace accessibility
387
388
389/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr tools::Long Height() const
constexpr tools::Long Width() const
css::uno::Reference< css::accessibility::XAccessible > m_xParent
The parent accessible object.
::vcl::table::IAccessibleTable & m_aTable
The SVT Table control.
virtual void commitEvent(sal_Int16 nEventId, const css::uno::Any &rNewValue, const css::uno::Any &rOldValue)
Commits an event to all listeners.
The Grid Control accessible table objects inherit from this base class.
void implGetSelectedRows(css::uno::Sequence< sal_Int32 > &rSeq)
Fills a sequence with sorted indexes of completely selected rows.
virtual sal_Int64 SAL_CALL getAccessibleChildCount() override
virtual void SAL_CALL release() noexcept override
Releases the object (calls release() on base class).
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Queries for a new interface.
virtual void SAL_CALL acquire() noexcept override
Acquires the object (calls acquire() on base class).
void ensureIsValidAddress(sal_Int32 nRow, sal_Int32 nColumn)
virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL getAccessibleRowHeaders() override
virtual OUString SAL_CALL getImplementationName() override
virtual sal_Int64 SAL_CALL getSelectedAccessibleChildCount() override
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int64 nChildIndex) override
virtual css::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleColumns() override
virtual void SAL_CALL selectAccessibleChild(sal_Int64 nChildIndex) override
Selects the specified child (row or column of the table).
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint(const css::awt::Point &rPoint) override
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild(sal_Int64 nChildIndex) override
AccessibleGridControlTable(const css::uno::Reference< css::accessibility::XAccessible > &rxParent, ::vcl::table::IAccessibleTable &rTable)
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int64 nSelectedChildIndex) override
virtual void SAL_CALL selectAllAccessibleChildren() override
Selects all children or first, if multiselection is not supported.
virtual sal_Bool SAL_CALL isAccessibleColumnSelected(sal_Int32 nColumn) override
virtual OUString SAL_CALL getAccessibleRowDescription(sal_Int32 nRow) override
virtual void commitEvent(sal_Int16 nEventId, const css::uno::Any &rNewValue, const css::uno::Any &rOldValue) override
Commits an event to all listeners.
virtual void SAL_CALL deselectAccessibleChild(sal_Int64 nSelectedChildIndex) override
Removes the specified row/column from the selection.
virtual sal_Bool SAL_CALL isAccessibleSelected(sal_Int32 nRow, sal_Int32 nColumn) override
virtual void SAL_CALL clearAccessibleSelection() override
Clears the complete selection.
virtual css::uno::Reference< css::accessibility::XAccessibleTable > SAL_CALL getAccessibleColumnHeaders() override
virtual css::uno::Sequence< sal_Int32 > SAL_CALL getSelectedAccessibleRows() override
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Queries for a new interface.
virtual OUString SAL_CALL getAccessibleColumnDescription(sal_Int32 nColumn) override
virtual tools::Rectangle implGetBoundingBox() override
virtual tools::Rectangle implGetBoundingBoxOnScreen() override
‍**
virtual void SAL_CALL grabFocus() override
Grabs the focus to (the current cell of) the data table.
virtual sal_Bool SAL_CALL isAccessibleRowSelected(sal_Int32 nRow) override
virtual void SAL_CALL acquire() noexcept override
Acquires the object (calls acquire() on base class).
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
virtual void SAL_CALL release() noexcept override
Releases the object (calls release() on base class).
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleCellAt(sal_Int32 nRow, sal_Int32 nColumn) override
std::vector< rtl::Reference< AccessibleGridControlTableCell > > m_aCellVector
css::uno::Reference< css::accessibility::XAccessibleTable > implGetHeaderBar(sal_Int32 nChildIndex)
internal helper methods **
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
constexpr tools::Long Top() const
constexpr Size GetSize() const
constexpr tools::Long Left() const
virtual sal_Int32 GetRowCount() const=0
virtual bool ConvertPointToCellAddress(sal_Int32 &_rnRow, sal_Int32 &_rnColPos, const Point &_rPoint)=0
virtual vcl::Window * GetAccessibleParentWindow() const=0
virtual bool HasColHeader()=0
virtual void SelectRow(sal_Int32 const i_rowIndex, bool const i_select)=0
virtual void GrabFocus()=0
virtual tools::Rectangle GetWindowExtentsRelative(const vcl::Window &rRelativeWindow) const=0
virtual tools::Rectangle calcTableRect()=0
virtual void SelectAllRows(bool const i_select)=0
virtual tools::Rectangle GetWindowExtentsAbsolute() const=0
virtual sal_Int32 GetColumnCount() const=0
virtual bool HasRowHeader()=0
inline ::Point VCLPoint(const css::awt::Point &rAWTPoint)
int nCount
#define DBG_ASSERT(sCon, aError)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
long Long
TCTYPE_TABLE
unsigned char sal_Bool