/src/libreoffice/sc/source/ui/Accessibility/AccessibleTableBase.cxx
Line | Count | Source |
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 <AccessibleTableBase.hxx> |
21 | | #include <document.hxx> |
22 | | #include <scresid.hxx> |
23 | | #include <strings.hrc> |
24 | | #include <strings.hxx> |
25 | | #include <table.hxx> |
26 | | |
27 | | #include <com/sun/star/accessibility/AccessibleRole.hpp> |
28 | | #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> |
29 | | #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
30 | | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
31 | | #include <comphelper/sequence.hxx> |
32 | | #include <vcl/svapp.hxx> |
33 | | |
34 | | using namespace ::com::sun::star; |
35 | | using namespace ::com::sun::star::accessibility; |
36 | | |
37 | | ScAccessibleTableBase::ScAccessibleTableBase(const uno::Reference<XAccessible>& rxParent, |
38 | | ScDocument* pDoc, const ScRange& rRange) |
39 | 0 | : ImplInheritanceHelper(rxParent, AccessibleRole::TABLE) |
40 | 0 | , maRange(rRange) |
41 | 0 | , mpDoc(pDoc) |
42 | 0 | { |
43 | 0 | } |
44 | | |
45 | | ScAccessibleTableBase::~ScAccessibleTableBase() |
46 | 0 | { |
47 | 0 | } |
48 | | |
49 | | void SAL_CALL ScAccessibleTableBase::disposing() |
50 | 0 | { |
51 | 0 | SolarMutexGuard aGuard; |
52 | 0 | mpDoc = nullptr; |
53 | |
|
54 | 0 | ScAccessibleContextBase::disposing(); |
55 | 0 | } |
56 | | |
57 | | //===== XAccessibleTable ================================================ |
58 | | |
59 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount( ) |
60 | 0 | { |
61 | 0 | SolarMutexGuard aGuard; |
62 | 0 | ensureAlive(); |
63 | 0 | return maRange.aEnd.Row() - maRange.aStart.Row() + 1; |
64 | 0 | } |
65 | | |
66 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount( ) |
67 | 0 | { |
68 | 0 | SolarMutexGuard aGuard; |
69 | 0 | ensureAlive(); |
70 | 0 | return maRange.aEnd.Col() - maRange.aStart.Col() + 1; |
71 | 0 | } |
72 | | |
73 | | OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow ) |
74 | 0 | { |
75 | 0 | OSL_FAIL("Here should be an implementation to fill the description"); |
76 | |
|
77 | 0 | if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) |
78 | 0 | throw lang::IndexOutOfBoundsException(); |
79 | | |
80 | | //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description |
81 | 0 | return OUString(); |
82 | 0 | } |
83 | | |
84 | | OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn ) |
85 | 0 | { |
86 | 0 | OSL_FAIL("Here should be an implementation to fill the description"); |
87 | |
|
88 | 0 | if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0)) |
89 | 0 | throw lang::IndexOutOfBoundsException(); |
90 | | |
91 | | //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description |
92 | 0 | return OUString(); |
93 | 0 | } |
94 | | |
95 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) |
96 | 0 | { |
97 | 0 | SolarMutexGuard aGuard; |
98 | 0 | ensureAlive(); |
99 | |
|
100 | 0 | if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || |
101 | 0 | (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) |
102 | 0 | throw lang::IndexOutOfBoundsException(); |
103 | | |
104 | 0 | sal_Int32 nCount(1); // the same cell |
105 | 0 | nRow += maRange.aStart.Row(); |
106 | 0 | nColumn += maRange.aStart.Col(); |
107 | |
|
108 | 0 | if (mpDoc) |
109 | 0 | { |
110 | 0 | ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab()); |
111 | 0 | if (pTab) |
112 | 0 | { |
113 | 0 | SCROW nStartRow = static_cast<SCROW>(nRow); |
114 | 0 | SCROW nEndRow = nStartRow; |
115 | 0 | SCCOL nStartCol = static_cast<SCCOL>(nColumn); |
116 | 0 | SCCOL nEndCol = nStartCol; |
117 | 0 | if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false)) |
118 | 0 | { |
119 | 0 | if (nEndRow > nStartRow) |
120 | 0 | nCount = nEndRow - nStartRow + 1; |
121 | 0 | } |
122 | 0 | } |
123 | 0 | } |
124 | |
|
125 | 0 | return nCount; |
126 | 0 | } |
127 | | |
128 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) |
129 | 0 | { |
130 | 0 | SolarMutexGuard aGuard; |
131 | 0 | ensureAlive(); |
132 | |
|
133 | 0 | if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) || |
134 | 0 | (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0)) |
135 | 0 | throw lang::IndexOutOfBoundsException(); |
136 | | |
137 | 0 | sal_Int32 nCount(1); // the same cell |
138 | 0 | nRow += maRange.aStart.Row(); |
139 | 0 | nColumn += maRange.aStart.Col(); |
140 | |
|
141 | 0 | if (mpDoc) |
142 | 0 | { |
143 | 0 | ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab()); |
144 | 0 | if (pTab) |
145 | 0 | { |
146 | 0 | SCROW nStartRow = static_cast<SCROW>(nRow); |
147 | 0 | SCROW nEndRow = nStartRow; |
148 | 0 | SCCOL nStartCol = static_cast<SCCOL>(nColumn); |
149 | 0 | SCCOL nEndCol = nStartCol; |
150 | 0 | if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false)) |
151 | 0 | { |
152 | 0 | if (nEndCol > nStartCol) |
153 | 0 | nCount = nEndCol - nStartCol + 1; |
154 | 0 | } |
155 | 0 | } |
156 | 0 | } |
157 | |
|
158 | 0 | return nCount; |
159 | 0 | } |
160 | | |
161 | | uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders( ) |
162 | 0 | { |
163 | 0 | uno::Reference< XAccessibleTable > xAccessibleTable; |
164 | 0 | OSL_FAIL("Here should be an implementation to fill the row headers"); |
165 | | |
166 | | //CommitChange |
167 | 0 | return xAccessibleTable; |
168 | 0 | } |
169 | | |
170 | | uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders( ) |
171 | 0 | { |
172 | 0 | uno::Reference< XAccessibleTable > xAccessibleTable; |
173 | 0 | OSL_FAIL("Here should be an implementation to fill the column headers"); |
174 | | |
175 | | //CommitChange |
176 | 0 | return xAccessibleTable; |
177 | 0 | } |
178 | | |
179 | | uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows( ) |
180 | 0 | { |
181 | 0 | OSL_FAIL("not implemented yet"); |
182 | 0 | uno::Sequence< sal_Int32 > aSequence; |
183 | 0 | return aSequence; |
184 | 0 | } |
185 | | |
186 | | uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns( ) |
187 | 0 | { |
188 | 0 | OSL_FAIL("not implemented yet"); |
189 | 0 | uno::Sequence< sal_Int32 > aSequence; |
190 | 0 | return aSequence; |
191 | 0 | } |
192 | | |
193 | | sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ ) |
194 | 0 | { |
195 | 0 | OSL_FAIL("not implemented yet"); |
196 | 0 | return false; |
197 | 0 | } |
198 | | |
199 | | sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ ) |
200 | 0 | { |
201 | 0 | OSL_FAIL("not implemented yet"); |
202 | 0 | return false; |
203 | 0 | } |
204 | | |
205 | | uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ ) |
206 | 0 | { |
207 | 0 | OSL_FAIL("not implemented yet"); |
208 | 0 | uno::Reference< XAccessible > xAccessible; |
209 | 0 | return xAccessible; |
210 | 0 | } |
211 | | |
212 | | uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption( ) |
213 | 0 | { |
214 | 0 | OSL_FAIL("not implemented yet"); |
215 | 0 | uno::Reference< XAccessible > xAccessible; |
216 | 0 | return xAccessible; |
217 | 0 | } |
218 | | |
219 | | uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary( ) |
220 | 0 | { |
221 | 0 | OSL_FAIL("not implemented yet"); |
222 | 0 | uno::Reference< XAccessible > xAccessible; |
223 | 0 | return xAccessible; |
224 | 0 | } |
225 | | |
226 | | sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ ) |
227 | 0 | { |
228 | 0 | OSL_FAIL("not implemented yet"); |
229 | 0 | return false; |
230 | 0 | } |
231 | | |
232 | | // ===== XAccessibleExtendedTable ======================================== |
233 | | |
234 | | sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) |
235 | 0 | { |
236 | 0 | SolarMutexGuard aGuard; |
237 | 0 | ensureAlive(); |
238 | |
|
239 | 0 | if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) || |
240 | 0 | nRow < 0 || |
241 | 0 | nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) || |
242 | 0 | nColumn < 0) |
243 | 0 | throw lang::IndexOutOfBoundsException(); |
244 | | |
245 | 0 | nRow -= maRange.aStart.Row(); |
246 | 0 | nColumn -= maRange.aStart.Col(); |
247 | 0 | return (static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(maRange.aEnd.Col() + 1)) + nColumn; |
248 | 0 | } |
249 | | |
250 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int64 nChildIndex ) |
251 | 0 | { |
252 | 0 | SolarMutexGuard aGuard; |
253 | 0 | ensureAlive(); |
254 | |
|
255 | 0 | if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0) |
256 | 0 | throw lang::IndexOutOfBoundsException(); |
257 | | |
258 | 0 | return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1); |
259 | 0 | } |
260 | | |
261 | | sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int64 nChildIndex ) |
262 | 0 | { |
263 | 0 | SolarMutexGuard aGuard; |
264 | 0 | ensureAlive(); |
265 | |
|
266 | 0 | if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0) |
267 | 0 | throw lang::IndexOutOfBoundsException(); |
268 | | |
269 | 0 | return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1); |
270 | 0 | } |
271 | | |
272 | | // ===== XAccessibleContext ============================================== |
273 | | |
274 | | sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleChildCount() |
275 | 0 | { |
276 | 0 | SolarMutexGuard aGuard; |
277 | 0 | ensureAlive(); |
278 | | |
279 | | // FIXME: representing rows & columns this way is a plain and simple madness. |
280 | | // this needs a radical re-think. |
281 | 0 | sal_Int64 nMax = static_cast<sal_Int64>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) * |
282 | 0 | static_cast<sal_Int64>(maRange.aEnd.Col() - maRange.aStart.Col() + 1); |
283 | 0 | if (nMax < 0) |
284 | 0 | return 0; |
285 | 0 | return nMax; |
286 | 0 | } |
287 | | |
288 | | uno::Reference< XAccessible > SAL_CALL |
289 | | ScAccessibleTableBase::getAccessibleChild(sal_Int64 nIndex) |
290 | 0 | { |
291 | 0 | SolarMutexGuard aGuard; |
292 | 0 | ensureAlive(); |
293 | |
|
294 | 0 | if (nIndex >= getAccessibleChildCount() || nIndex < 0) |
295 | 0 | throw lang::IndexOutOfBoundsException(); |
296 | | |
297 | | // FIXME: representing rows & columns this way is a plain and simple madness. |
298 | | // this needs a radical re-think. |
299 | | |
300 | 0 | sal_Int32 nRow(0); |
301 | 0 | sal_Int32 nColumn(0); |
302 | 0 | sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1); |
303 | 0 | nRow = nIndex / nTemp; |
304 | 0 | nColumn = nIndex % nTemp; |
305 | 0 | return getAccessibleCellAt(nRow, nColumn); |
306 | 0 | } |
307 | | |
308 | | OUString |
309 | | ScAccessibleTableBase::createAccessibleDescription() |
310 | 0 | { |
311 | 0 | return STR_ACC_TABLE_DESCR; |
312 | 0 | } |
313 | | |
314 | | OUString ScAccessibleTableBase::createAccessibleName() |
315 | 0 | { |
316 | 0 | OUString sName(ScResId(STR_ACC_TABLE_NAME)); |
317 | 0 | OUString sCoreName; |
318 | 0 | if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName )) |
319 | 0 | sName = sName.replaceFirst("%1", sCoreName); |
320 | 0 | return sName; |
321 | 0 | } |
322 | | |
323 | | uno::Reference<XAccessibleRelationSet> SAL_CALL |
324 | | ScAccessibleTableBase::getAccessibleRelationSet() |
325 | 0 | { |
326 | 0 | OSL_FAIL("should be implemented in the abbreviated class"); |
327 | 0 | return uno::Reference<XAccessibleRelationSet>(); |
328 | 0 | } |
329 | | |
330 | | sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleStateSet() |
331 | 0 | { |
332 | 0 | OSL_FAIL("should be implemented in the abbreviated class"); |
333 | 0 | return 0; |
334 | 0 | } |
335 | | |
336 | | ///===== XAccessibleSelection =========================================== |
337 | | |
338 | | void SAL_CALL ScAccessibleTableBase::selectAccessibleChild( sal_Int64 /* nChildIndex */ ) |
339 | 0 | { |
340 | 0 | } |
341 | | |
342 | | sal_Bool SAL_CALL |
343 | | ScAccessibleTableBase::isAccessibleChildSelected( sal_Int64 nChildIndex ) |
344 | 0 | { |
345 | | // I don't need to guard, because the called functions have a guard |
346 | 0 | if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount()) |
347 | 0 | throw lang::IndexOutOfBoundsException(); |
348 | 0 | return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex)); |
349 | 0 | } |
350 | | |
351 | | void SAL_CALL |
352 | | ScAccessibleTableBase::clearAccessibleSelection( ) |
353 | 0 | { |
354 | 0 | } |
355 | | |
356 | | void SAL_CALL ScAccessibleTableBase::selectAllAccessibleChildren() |
357 | 0 | { |
358 | 0 | } |
359 | | |
360 | | sal_Int64 SAL_CALL |
361 | | ScAccessibleTableBase::getSelectedAccessibleChildCount( ) |
362 | 0 | { |
363 | 0 | return 0; |
364 | 0 | } |
365 | | |
366 | | uno::Reference<XAccessible > SAL_CALL |
367 | | ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int64 /* nSelectedChildIndex */ ) |
368 | 0 | { |
369 | 0 | uno::Reference < XAccessible > xAccessible; |
370 | 0 | return xAccessible; |
371 | 0 | } |
372 | | |
373 | | void SAL_CALL ScAccessibleTableBase::deselectAccessibleChild( sal_Int64 /* nSelectedChildIndex */ ) |
374 | 0 | { |
375 | 0 | } |
376 | | |
377 | | void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId) |
378 | 0 | { |
379 | 0 | AccessibleTableModelChange aModelChange; |
380 | 0 | aModelChange.FirstRow = nStartRow; |
381 | 0 | aModelChange.FirstColumn = nStartCol; |
382 | 0 | aModelChange.LastRow = nEndRow; |
383 | 0 | aModelChange.LastColumn = nEndCol; |
384 | 0 | aModelChange.Type = nId; |
385 | |
|
386 | 0 | CommitChange(AccessibleEventId::TABLE_MODEL_CHANGED, uno::Any(), uno::Any(aModelChange)); |
387 | 0 | } |
388 | | |
389 | | sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 ) |
390 | 0 | { |
391 | 0 | return true; |
392 | 0 | } |
393 | | |
394 | | sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 ) |
395 | 0 | { |
396 | 0 | return true; |
397 | 0 | } |
398 | | |
399 | | sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 ) |
400 | 0 | { |
401 | 0 | return true; |
402 | 0 | } |
403 | | |
404 | | sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 ) |
405 | 0 | { |
406 | 0 | return true; |
407 | 0 | } |
408 | | |
409 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |