Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / accessibility / source / extended / AccessibleGridControlTable.cxx
blob2c50501cba568431a764171f3523915052e163a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <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>
24 #include <extended/AccessibleGridControlTable.hxx>
25 #include <extended/AccessibleGridControlTableCell.hxx>
26 #include <toolkit/helper/convert.hxx>
27 #include <vcl/accessibletable.hxx>
28 #include <vcl/svapp.hxx>
29 #include <tools/debug.hxx>
31 using ::com::sun::star::uno::Reference;
32 using ::com::sun::star::uno::Sequence;
33 using ::com::sun::star::uno::Any;
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::accessibility;
37 using namespace ::vcl;
38 using namespace ::vcl::table;
41 namespace accessibility {
44 AccessibleGridControlTable::AccessibleGridControlTable(
45 const Reference< XAccessible >& rxParent,
46 IAccessibleTable& rTable) :
47 AccessibleGridControlTableBase( rxParent, rTable, TCTYPE_TABLE )
51 // XAccessibleContext ---------------------------------------------------------
53 Reference< XAccessible > SAL_CALL
54 AccessibleGridControlTable::getAccessibleChild( sal_Int64 nChildIndex )
56 SolarMutexGuard aSolarGuard;
58 ensureIsAlive();
59 ensureIsValidIndex( nChildIndex );
60 sal_Int64 nCount = getAccessibleChildCount();
61 if(m_aCellVector.empty() || m_aCellVector.size() != static_cast<unsigned>(nCount))
63 assert(o3tl::make_unsigned(nCount) < m_aCellVector.max_size());
64 m_aCellVector.resize(nCount);
66 if(!m_aCellVector[nChildIndex].is())
68 rtl::Reference<AccessibleGridControlTableCell> pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount());
69 m_aCellVector[nChildIndex] = pCell;
71 return m_aCellVector[nChildIndex];
74 sal_Int64 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent()
76 SolarMutexGuard aSolarGuard;
78 ensureIsAlive();
79 if(m_aTable.HasRowHeader() && m_aTable.HasColHeader())
80 return 0;
81 else if((!m_aTable.HasRowHeader() && m_aTable.HasColHeader()) || (m_aTable.HasRowHeader() && !m_aTable.HasColHeader()) )
82 return 1;
83 else
84 return 2;
87 // XAccessibleComponent -------------------------------------------------------
89 Reference< XAccessible > SAL_CALL
90 AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint )
92 SolarMutexGuard aSolarGuard;
94 ensureIsAlive();
96 Reference< XAccessible > xChild;
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;
104 void SAL_CALL AccessibleGridControlTable::grabFocus()
106 SolarMutexGuard aSolarGuard;
108 ensureIsAlive();
109 m_aTable.GrabFocus();
112 // XAccessibleTable -----------------------------------------------------------
114 OUString SAL_CALL AccessibleGridControlTable::getAccessibleRowDescription( sal_Int32 nRow )
116 SolarMutexGuard aSolarGuard;
118 ensureIsAlive();
119 ensureIsValidRow( nRow );
120 return "row description";
123 OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn )
125 SolarMutexGuard aSolarGuard;
127 ensureIsAlive();
128 ensureIsValidColumn( nColumn );
129 return "col description";
132 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleRowHeaders()
134 SolarMutexGuard g;
136 ensureIsAlive();
137 if(m_aTable.HasColHeader())
138 return implGetHeaderBar( 1 );
139 else
140 return implGetHeaderBar( 0 );
143 Reference< XAccessibleTable > SAL_CALL AccessibleGridControlTable::getAccessibleColumnHeaders()
145 SolarMutexGuard g;
147 ensureIsAlive();
148 return implGetHeaderBar( 0 );
151 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleRows()
153 SolarMutexGuard aSolarGuard;
155 ensureIsAlive();
156 Sequence< sal_Int32 > aSelSeq;
157 implGetSelectedRows( aSelSeq );
158 return aSelSeq;
161 //columns aren't selectable
162 Sequence< sal_Int32 > SAL_CALL AccessibleGridControlTable::getSelectedAccessibleColumns()
164 return {};
167 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleRowSelected( sal_Int32 nRow )
169 SolarMutexGuard aSolarGuard;
171 ensureIsAlive();
172 ensureIsValidRow( nRow );
173 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
174 return comphelper::findValue(selectedRows, nRow) != -1;
177 //columns aren't selectable
178 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleColumnSelected( sal_Int32 )
180 return false;
183 Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellAt(
184 sal_Int32 nRow, sal_Int32 nColumn )
186 SolarMutexGuard aSolarGuard;
188 ensureIsAlive();
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);
194 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected(
195 sal_Int32 nRow, sal_Int32 nColumn )
197 SolarMutexGuard aSolarGuard;
199 ensureIsAlive();
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);
204 void SAL_CALL AccessibleGridControlTable::selectAccessibleChild( sal_Int64 nChildIndex )
206 SolarMutexGuard aSolarGuard;
208 ensureIsAlive();
209 ensureIsValidIndex( nChildIndex );
210 sal_Int32 nColumns = m_aTable.GetColumnCount();
211 sal_Int32 nRow = nChildIndex / nColumns;
212 m_aTable.SelectRow( nRow, true );
214 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleChildSelected( sal_Int64 nChildIndex )
216 SolarMutexGuard aSolarGuard;
218 ensureIsAlive();
219 ensureIsValidIndex( nChildIndex );
220 sal_Int32 nColumns = m_aTable.GetColumnCount();
221 sal_Int32 nRow = nChildIndex / nColumns;
222 return isAccessibleRowSelected(nRow);
224 void SAL_CALL AccessibleGridControlTable::clearAccessibleSelection()
226 SolarMutexGuard aSolarGuard;
228 ensureIsAlive();
229 m_aTable.SelectAllRows( false );
231 void SAL_CALL AccessibleGridControlTable::selectAllAccessibleChildren()
233 SolarMutexGuard aSolarGuard;
235 ensureIsAlive();
236 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
237 auto selectedRowsRange = asNonConstRange(selectedRows);
238 for(tools::Long i=0; i<m_aTable.GetRowCount(); i++)
239 selectedRowsRange[i]=i;
241 sal_Int64 SAL_CALL AccessibleGridControlTable::getSelectedAccessibleChildCount()
243 SolarMutexGuard aSolarGuard;
245 ensureIsAlive();
246 Sequence< sal_Int32 > selectedRows = getSelectedAccessibleRows();
247 sal_Int32 nColumns = m_aTable.GetColumnCount();
248 return static_cast<sal_Int64>(selectedRows.getLength()) * static_cast<sal_Int64>(nColumns);
250 Reference< XAccessible > SAL_CALL
251 AccessibleGridControlTable::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
253 SolarMutexGuard aSolarGuard;
255 ensureIsAlive();
256 if(isAccessibleChildSelected(nSelectedChildIndex))
257 return getAccessibleChild(nSelectedChildIndex);
258 else
259 return nullptr;
261 //not implemented yet, because only row selection possible
262 void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild(
263 sal_Int64 )
265 SolarMutexGuard aSolarGuard;
267 ensureIsAlive();
269 // XInterface -----------------------------------------------------------------
271 Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType )
273 Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) );
274 return aAny.hasValue() ?
275 aAny : AccessibleGridControlTableSelectionImplHelper::queryInterface( rType );
278 void SAL_CALL AccessibleGridControlTable::acquire() noexcept
280 AccessibleGridControlTableBase::acquire();
283 void SAL_CALL AccessibleGridControlTable::release() noexcept
285 AccessibleGridControlTableBase::release();
287 // XServiceInfo ---------------------------------------------------------------
289 OUString SAL_CALL AccessibleGridControlTable::getImplementationName()
291 return "com.sun.star.accessibility.AccessibleGridControlTable";
294 void AccessibleGridControlTable::dispose()
296 for (rtl::Reference<AccessibleGridControlTableCell>& rxCell : m_aCellVector)
298 if (rxCell.is())
300 rxCell->dispose();
301 rxCell.clear();
305 AccessibleGridControlTableBase::dispose();
308 void AccessibleGridControlTable::commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue,
309 const css::uno::Any& rOldValue)
311 if (nEventId == AccessibleEventId::TABLE_MODEL_CHANGED)
313 AccessibleTableModelChange aChange;
314 if (rNewValue >>= aChange)
316 assert(aChange.Type != AccessibleTableModelChangeType::COLUMNS_REMOVED);
318 if (aChange.Type == AccessibleTableModelChangeType::ROWS_REMOVED)
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())
326 m_aCellVector.erase(
327 m_aCellVector.begin() + nStart,
328 m_aCellVector.begin() + std::min(m_aCellVector.size(), nEnd));
334 AccessibleGridControlBase::commitEvent(nEventId, rNewValue, rOldValue);
337 // internal virtual methods ---------------------------------------------------
339 tools::Rectangle AccessibleGridControlTable::implGetBoundingBox()
341 vcl::Window* pParent = m_aTable.GetAccessibleParentWindow();
342 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
343 tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ));
344 tools::Rectangle aTableRect( m_aTable.calcTableRect() );
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;
353 tools::Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen()
355 tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( nullptr ));
356 tools::Rectangle aTableRect( m_aTable.calcTableRect() );
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;
364 // internal helper methods ----------------------------------------------------
365 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
366 sal_Int32 nChildIndex )
368 Reference< XAccessible > xRet;
369 Reference< XAccessibleContext > xContext( m_xParent, uno::UNO_QUERY );
370 if( xContext.is() )
374 xRet = xContext->getAccessibleChild( nChildIndex );
376 catch (const lang::IndexOutOfBoundsException&)
378 OSL_FAIL( "implGetHeaderBar - wrong child index" );
380 // RuntimeException goes to caller
382 return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
386 } // namespace accessibility
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */