tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / accessibility / source / extended / AccessibleGridControlTable.cxx
blob930d5c9395cecc76ec0b2a8855cf021a1ca302d2
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 <vcl/accessibletable.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/unohelp.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, AccessibleTableControlObjType::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 m_aCellVector[nChildIndex].set(new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount()));
70 return m_aCellVector[nChildIndex];
73 sal_Int64 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent()
75 SolarMutexGuard aSolarGuard;
77 ensureIsAlive();
78 if(m_aTable.HasRowHeader() && m_aTable.HasColHeader())
79 return 0;
80 else if(m_aTable.HasRowHeader() != m_aTable.HasColHeader())
81 return 1;
82 else
83 return 2;
86 // XAccessibleComponent -------------------------------------------------------
88 Reference< XAccessible > SAL_CALL
89 AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint )
91 SolarMutexGuard aSolarGuard;
93 ensureIsAlive();
95 Reference< XAccessible > xChild;
96 sal_Int32 nRow = 0;
97 sal_Int32 nColumnPos = 0;
98 if (m_aTable.ConvertPointToCellAddress(nRow, nColumnPos,
99 vcl::unohelper::ConvertToVCLPoint(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 u"row description"_ustr;
123 OUString SAL_CALL AccessibleGridControlTable::getAccessibleColumnDescription( sal_Int32 nColumn )
125 SolarMutexGuard aSolarGuard;
127 ensureIsAlive();
128 ensureIsValidColumn( nColumn );
129 return u"col description"_ustr;
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 (nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount())
257 throw lang::IndexOutOfBoundsException(u"Invalid index into selection"_ustr, *this);
259 const sal_Int32 nColCount = getAccessibleColumnCount();
260 assert(nColCount > 0 && "Column count non-positive, but child count > 0");
261 const sal_Int32 nIndexInSelectedRowsSequence = nSelectedChildIndex / nColCount;
262 const Sequence<sal_Int32> aSelectedRows = getSelectedAccessibleRows();
263 const sal_Int32 nRowIndex = aSelectedRows[nIndexInSelectedRowsSequence];
264 const sal_Int32 nColIndex = nSelectedChildIndex % nColCount;
265 return getAccessibleCellAt(nRowIndex, nColIndex);
267 //not implemented yet, because only row selection possible
268 void SAL_CALL AccessibleGridControlTable::deselectAccessibleChild(
269 sal_Int64 )
271 SolarMutexGuard aSolarGuard;
273 ensureIsAlive();
275 // XInterface -----------------------------------------------------------------
277 Any SAL_CALL AccessibleGridControlTable::queryInterface( const uno::Type& rType )
279 Any aAny( AccessibleGridControlTableBase::queryInterface( rType ) );
280 return aAny.hasValue() ?
281 aAny : AccessibleGridControlTableSelectionImplHelper::queryInterface( rType );
284 void SAL_CALL AccessibleGridControlTable::acquire() noexcept
286 AccessibleGridControlTableBase::acquire();
289 void SAL_CALL AccessibleGridControlTable::release() noexcept
291 AccessibleGridControlTableBase::release();
293 // XServiceInfo ---------------------------------------------------------------
295 OUString SAL_CALL AccessibleGridControlTable::getImplementationName()
297 return u"com.sun.star.accessibility.AccessibleGridControlTable"_ustr;
300 void AccessibleGridControlTable::dispose()
302 for (rtl::Reference<AccessibleGridControlTableCell>& rxCell : m_aCellVector)
304 if (rxCell.is())
306 rxCell->dispose();
307 rxCell.clear();
311 AccessibleGridControlTableBase::dispose();
314 void AccessibleGridControlTable::commitEvent(sal_Int16 nEventId, const css::uno::Any& rNewValue,
315 const css::uno::Any& rOldValue)
317 if (nEventId == AccessibleEventId::TABLE_MODEL_CHANGED)
319 AccessibleTableModelChange aChange;
320 if (rNewValue >>= aChange)
322 assert(aChange.Type != AccessibleTableModelChangeType::COLUMNS_REMOVED);
324 if (aChange.Type == AccessibleTableModelChangeType::ROWS_REMOVED)
326 int nColCount = m_aTable.GetColumnCount();
327 // check valid index - entries are inserted lazily
328 size_t const nStart = nColCount * aChange.FirstRow;
329 size_t const nEnd = nColCount * aChange.LastRow;
330 if (nStart < m_aCellVector.size())
332 m_aCellVector.erase(
333 m_aCellVector.begin() + nStart,
334 m_aCellVector.begin() + std::min(m_aCellVector.size(), nEnd));
340 AccessibleGridControlBase::commitEvent(nEventId, rNewValue, rOldValue);
343 // internal virtual methods ---------------------------------------------------
345 tools::Rectangle AccessibleGridControlTable::implGetBoundingBox()
347 vcl::Window* pParent = m_aTable.GetAccessibleParentWindow();
348 assert(pParent && "implGetBoundingBox - missing parent window");
349 tools::Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( *pParent ));
350 tools::Rectangle aTableRect( m_aTable.calcTableRect() );
351 tools::Long nX = aGridRect.Left() + aTableRect.Left();
352 tools::Long nY = aGridRect.Top() + aTableRect.Top();
353 tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
354 tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
355 tools::Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
356 return aTable;
359 AbsoluteScreenPixelRectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen()
361 tools::Rectangle aGridRect( m_aTable.GetWindowExtentsAbsolute());
362 tools::Rectangle aTableRect( m_aTable.calcTableRect() );
363 tools::Long nX = aGridRect.Left() + aTableRect.Left();
364 tools::Long nY = aGridRect.Top() + aTableRect.Top();
365 tools::Long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
366 tools::Long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
367 AbsoluteScreenPixelRectangle aTable( AbsoluteScreenPixelPoint( nX, nY ), AbsoluteScreenPixelSize( nWidth, nHeight ));
368 return aTable;
370 // internal helper methods ----------------------------------------------------
371 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
372 sal_Int32 nChildIndex )
374 Reference< XAccessible > xRet;
376 if (!m_xParent.is())
377 return nullptr;
379 Reference<XAccessibleContext> xContext = m_xParent->getAccessibleContext();
380 if( xContext.is() )
384 xRet = xContext->getAccessibleChild( nChildIndex );
386 catch (const lang::IndexOutOfBoundsException&)
388 OSL_FAIL( "implGetHeaderBar - wrong child index" );
390 // RuntimeException goes to caller
392 return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
396 } // namespace accessibility
399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */