Line data Source code
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 "miscuno.hxx"
22 : #include "document.hxx"
23 : #include "scresid.hxx"
24 : #include "sc.hrc"
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 <comphelper/sequence.hxx>
31 : #include <comphelper/servicehelper.hxx>
32 : #include <vcl/svapp.hxx>
33 :
34 :
35 : using namespace ::com::sun::star;
36 : using namespace ::com::sun::star::accessibility;
37 :
38 : //===== internal ============================================================
39 :
40 0 : ScAccessibleTableBase::ScAccessibleTableBase(
41 : const uno::Reference<XAccessible>& rxParent,
42 : ScDocument* pDoc,
43 : const ScRange& rRange)
44 : :
45 : ScAccessibleContextBase (rxParent, AccessibleRole::TABLE),
46 : maRange(rRange),
47 0 : mpDoc(pDoc)
48 : {
49 0 : }
50 :
51 0 : ScAccessibleTableBase::~ScAccessibleTableBase()
52 : {
53 0 : }
54 :
55 0 : void SAL_CALL ScAccessibleTableBase::disposing()
56 : {
57 0 : SolarMutexGuard aGuard;
58 0 : mpDoc = NULL;
59 :
60 0 : ScAccessibleContextBase::disposing();
61 0 : }
62 :
63 : //===== XInterface =====================================================
64 :
65 0 : uno::Any SAL_CALL ScAccessibleTableBase::queryInterface( uno::Type const & rType )
66 : throw (uno::RuntimeException, std::exception)
67 : {
68 0 : if ( rType == ::getCppuType((uno::Reference<XAccessibleTableSelection> *)0) )
69 : {
70 0 : return uno::Any(uno::Reference<XAccessibleTableSelection>(this));
71 : }
72 : else
73 : {
74 0 : uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
75 0 : return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
76 : }
77 : }
78 :
79 0 : void SAL_CALL ScAccessibleTableBase::acquire()
80 : throw ()
81 : {
82 0 : ScAccessibleContextBase::acquire();
83 0 : }
84 :
85 0 : void SAL_CALL ScAccessibleTableBase::release()
86 : throw ()
87 : {
88 0 : ScAccessibleContextBase::release();
89 0 : }
90 :
91 : //===== XAccessibleTable ================================================
92 :
93 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount( )
94 : throw (uno::RuntimeException, std::exception)
95 : {
96 0 : SolarMutexGuard aGuard;
97 0 : IsObjectValid();
98 0 : return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
99 : }
100 :
101 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount( )
102 : throw (uno::RuntimeException, std::exception)
103 : {
104 0 : SolarMutexGuard aGuard;
105 0 : IsObjectValid();
106 0 : return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
107 : }
108 :
109 0 : OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
110 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
111 : {
112 : OSL_FAIL("Here should be a implementation to fill the description");
113 :
114 0 : if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
115 0 : throw lang::IndexOutOfBoundsException();
116 :
117 : //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
118 0 : return OUString();
119 : }
120 :
121 0 : OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
122 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
123 : {
124 : OSL_FAIL("Here should be a implementation to fill the description");
125 :
126 0 : if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
127 0 : throw lang::IndexOutOfBoundsException();
128 :
129 : //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
130 0 : return OUString();
131 : }
132 :
133 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
134 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
135 : {
136 0 : SolarMutexGuard aGuard;
137 0 : IsObjectValid();
138 :
139 0 : if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
140 0 : (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
141 0 : throw lang::IndexOutOfBoundsException();
142 :
143 0 : sal_Int32 nCount(1); // the same cell
144 0 : nRow += maRange.aStart.Row();
145 0 : nColumn += maRange.aStart.Col();
146 :
147 0 : if (mpDoc)
148 : {
149 0 : ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab());
150 0 : if (pTab)
151 : {
152 0 : SCROW nStartRow = static_cast<SCROW>(nRow);
153 0 : SCROW nEndRow = nStartRow;
154 0 : SCCOL nStartCol = static_cast<SCCOL>(nColumn);
155 0 : SCCOL nEndCol = nStartCol;
156 0 : if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false))
157 : {
158 0 : if (nEndRow > nStartRow)
159 0 : nCount = nEndRow - nStartRow + 1;
160 : }
161 : }
162 : }
163 :
164 0 : return nCount;
165 : }
166 :
167 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
168 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
169 : {
170 0 : SolarMutexGuard aGuard;
171 0 : IsObjectValid();
172 :
173 0 : if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
174 0 : (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
175 0 : throw lang::IndexOutOfBoundsException();
176 :
177 0 : sal_Int32 nCount(1); // the same cell
178 0 : nRow += maRange.aStart.Row();
179 0 : nColumn += maRange.aStart.Col();
180 :
181 0 : if (mpDoc)
182 : {
183 0 : ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab());
184 0 : if (pTab)
185 : {
186 0 : SCROW nStartRow = static_cast<SCROW>(nRow);
187 0 : SCROW nEndRow = nStartRow;
188 0 : SCCOL nStartCol = static_cast<SCCOL>(nColumn);
189 0 : SCCOL nEndCol = nStartCol;
190 0 : if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false))
191 : {
192 0 : if (nEndCol > nStartCol)
193 0 : nCount = nEndCol - nStartCol + 1;
194 : }
195 : }
196 : }
197 :
198 0 : return nCount;
199 : }
200 :
201 0 : uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders( )
202 : throw (uno::RuntimeException, std::exception)
203 : {
204 0 : uno::Reference< XAccessibleTable > xAccessibleTable;
205 : OSL_FAIL("Here should be a implementation to fill the row headers");
206 :
207 : //CommitChange
208 0 : return xAccessibleTable;
209 : }
210 :
211 0 : uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders( )
212 : throw (uno::RuntimeException, std::exception)
213 : {
214 0 : uno::Reference< XAccessibleTable > xAccessibleTable;
215 : OSL_FAIL("Here should be a implementation to fill the column headers");
216 :
217 : //CommitChange
218 0 : return xAccessibleTable;
219 : }
220 :
221 0 : uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows( )
222 : throw (uno::RuntimeException, std::exception)
223 : {
224 : OSL_FAIL("not implemented yet");
225 0 : uno::Sequence< sal_Int32 > aSequence;
226 0 : return aSequence;
227 : }
228 :
229 0 : uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns( )
230 : throw (uno::RuntimeException, std::exception)
231 : {
232 : OSL_FAIL("not implemented yet");
233 0 : uno::Sequence< sal_Int32 > aSequence;
234 0 : return aSequence;
235 : }
236 :
237 0 : sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
238 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
239 : {
240 : OSL_FAIL("not implemented yet");
241 0 : return false;
242 : }
243 :
244 0 : sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
245 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
246 : {
247 : OSL_FAIL("not implemented yet");
248 0 : return false;
249 : }
250 :
251 0 : uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
252 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
253 : {
254 : OSL_FAIL("not implemented yet");
255 0 : uno::Reference< XAccessible > xAccessible;
256 0 : return xAccessible;
257 : }
258 :
259 0 : uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption( )
260 : throw (uno::RuntimeException, std::exception)
261 : {
262 : OSL_FAIL("not implemented yet");
263 0 : uno::Reference< XAccessible > xAccessible;
264 0 : return xAccessible;
265 : }
266 :
267 0 : uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary( )
268 : throw (uno::RuntimeException, std::exception)
269 : {
270 : OSL_FAIL("not implemented yet");
271 0 : uno::Reference< XAccessible > xAccessible;
272 0 : return xAccessible;
273 : }
274 :
275 0 : sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
276 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
277 : {
278 : OSL_FAIL("not implemented yet");
279 0 : return false;
280 : }
281 :
282 : // ===== XAccessibleExtendedTable ========================================
283 :
284 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
285 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
286 : {
287 0 : SolarMutexGuard aGuard;
288 0 : IsObjectValid();
289 :
290 0 : if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
291 0 : nRow < 0 ||
292 0 : nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
293 : nColumn < 0)
294 0 : throw lang::IndexOutOfBoundsException();
295 :
296 0 : nRow -= maRange.aStart.Row();
297 0 : nColumn -= maRange.aStart.Col();
298 0 : return (nRow * (maRange.aEnd.Col() + 1)) + nColumn;
299 : }
300 :
301 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex )
302 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
303 : {
304 0 : SolarMutexGuard aGuard;
305 0 : IsObjectValid();
306 :
307 0 : if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
308 0 : throw lang::IndexOutOfBoundsException();
309 :
310 0 : return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
311 : }
312 :
313 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex )
314 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
315 : {
316 0 : SolarMutexGuard aGuard;
317 0 : IsObjectValid();
318 :
319 0 : if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
320 0 : throw lang::IndexOutOfBoundsException();
321 :
322 0 : return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
323 : }
324 :
325 : // ===== XAccessibleContext ==============================================
326 :
327 0 : sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleChildCount()
328 : throw (uno::RuntimeException, std::exception)
329 : {
330 0 : SolarMutexGuard aGuard;
331 0 : IsObjectValid();
332 :
333 : // FIXME: representing rows & columns this way is a plain and simple madness.
334 : // this needs a radical re-think.
335 0 : sal_Int64 nMax = ((sal_Int64)(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
336 0 : (sal_Int64)(maRange.aEnd.Col() - maRange.aStart.Col() + 1));
337 0 : if (nMax > SAL_MAX_INT32)
338 0 : nMax = SAL_MAX_INT32;
339 0 : if (nMax < 0)
340 0 : return 0;
341 0 : return static_cast<sal_Int32>(nMax);
342 : }
343 :
344 : uno::Reference< XAccessible > SAL_CALL
345 0 : ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex)
346 : throw (uno::RuntimeException,
347 : lang::IndexOutOfBoundsException,
348 : std::exception)
349 : {
350 0 : SolarMutexGuard aGuard;
351 0 : IsObjectValid();
352 :
353 0 : if (nIndex >= getAccessibleChildCount() || nIndex < 0)
354 0 : throw lang::IndexOutOfBoundsException();
355 :
356 : // FIXME: representing rows & columns this way is a plain and simple madness.
357 : // this needs a radical re-think.
358 :
359 0 : sal_Int32 nRow(0);
360 0 : sal_Int32 nColumn(0);
361 0 : sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
362 0 : nRow = nIndex / nTemp;
363 0 : nColumn = nIndex % nTemp;
364 0 : return getAccessibleCellAt(nRow, nColumn);
365 : }
366 :
367 : OUString SAL_CALL
368 0 : ScAccessibleTableBase::createAccessibleDescription(void)
369 : throw (uno::RuntimeException)
370 : {
371 0 : OUString sDesc(ScResId(STR_ACC_TABLE_DESCR));
372 0 : return sDesc;
373 : }
374 :
375 0 : OUString SAL_CALL ScAccessibleTableBase::createAccessibleName()
376 : throw (uno::RuntimeException, std::exception)
377 : {
378 0 : OUString sName(SC_RESSTR(STR_ACC_TABLE_NAME));
379 0 : OUString sCoreName;
380 0 : if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
381 0 : sName = sName.replaceFirst("%1", sCoreName);
382 0 : return sName;
383 : }
384 :
385 : uno::Reference<XAccessibleRelationSet> SAL_CALL
386 0 : ScAccessibleTableBase::getAccessibleRelationSet(void)
387 : throw (uno::RuntimeException, std::exception)
388 : {
389 : OSL_FAIL("should be implemented in the abrevated class");
390 0 : return uno::Reference<XAccessibleRelationSet>();
391 : }
392 :
393 : uno::Reference<XAccessibleStateSet> SAL_CALL
394 0 : ScAccessibleTableBase::getAccessibleStateSet(void)
395 : throw (uno::RuntimeException, std::exception)
396 : {
397 : OSL_FAIL("should be implemented in the abrevated class");
398 0 : uno::Reference< XAccessibleStateSet > xAccessibleStateSet;
399 0 : return xAccessibleStateSet;
400 : }
401 :
402 : ///===== XAccessibleSelection ===========================================
403 :
404 0 : void SAL_CALL ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
405 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
406 : {
407 0 : }
408 :
409 : sal_Bool SAL_CALL
410 0 : ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex )
411 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
412 : {
413 : // I don't need to guard, because the called functions have a guard
414 0 : if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
415 0 : throw lang::IndexOutOfBoundsException();
416 0 : return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
417 : }
418 :
419 : void SAL_CALL
420 0 : ScAccessibleTableBase::clearAccessibleSelection( )
421 : throw (uno::RuntimeException, std::exception)
422 : {
423 0 : }
424 :
425 0 : void SAL_CALL ScAccessibleTableBase::selectAllAccessibleChildren()
426 : throw (uno::RuntimeException, std::exception)
427 : {
428 0 : }
429 :
430 : sal_Int32 SAL_CALL
431 0 : ScAccessibleTableBase::getSelectedAccessibleChildCount( )
432 : throw (uno::RuntimeException, std::exception)
433 : {
434 0 : sal_Int32 nResult(0);
435 0 : return nResult;
436 : }
437 :
438 : uno::Reference<XAccessible > SAL_CALL
439 0 : ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
440 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
441 : {
442 0 : uno::Reference < XAccessible > xAccessible;
443 0 : return xAccessible;
444 : }
445 :
446 0 : void SAL_CALL ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
447 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
448 : {
449 0 : }
450 :
451 : //===== XServiceInfo ====================================================
452 :
453 0 : OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void)
454 : throw (uno::RuntimeException, std::exception)
455 : {
456 0 : return OUString("ScAccessibleTableBase");
457 : }
458 :
459 : //===== XTypeProvider ===================================================
460 :
461 0 : uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes()
462 : throw (uno::RuntimeException, std::exception)
463 : {
464 0 : return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
465 : }
466 :
467 : uno::Sequence<sal_Int8> SAL_CALL
468 0 : ScAccessibleTableBase::getImplementationId(void)
469 : throw (uno::RuntimeException, std::exception)
470 : {
471 0 : return css::uno::Sequence<sal_Int8>();
472 : }
473 :
474 0 : void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
475 : {
476 0 : AccessibleTableModelChange aModelChange;
477 0 : aModelChange.FirstRow = nStartRow;
478 0 : aModelChange.FirstColumn = nStartCol;
479 0 : aModelChange.LastRow = nEndRow;
480 0 : aModelChange.LastColumn = nEndCol;
481 0 : aModelChange.Type = nId;
482 :
483 0 : AccessibleEventObject aEvent;
484 0 : aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
485 0 : aEvent.Source = uno::Reference< XAccessibleContext >(this);
486 0 : aEvent.NewValue <<= aModelChange;
487 :
488 0 : CommitChange(aEvent);
489 0 : }
490 :
491 0 : sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 )
492 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException,
493 : std::exception)
494 : {
495 0 : return sal_True;
496 : }
497 :
498 0 : sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 )
499 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException,
500 : std::exception)
501 : {
502 0 : return sal_True;
503 : }
504 :
505 0 : sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 )
506 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException,
507 : std::exception)
508 : {
509 0 : return sal_True;
510 : }
511 :
512 0 : sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 )
513 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException,
514 : std::exception)
515 : {
516 0 : return sal_True;
517 0 : }
518 :
519 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|