xref: /trunk/main/sc/source/ui/Accessibility/AccessibleTableBase.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 #include "AccessibleTableBase.hxx"
33 #include "miscuno.hxx"
34 #include "document.hxx"
35 #include "unoguard.hxx"
36 #include "scresid.hxx"
37 #ifndef SC_SC_HRC
38 #include "sc.hrc"
39 #endif
40 
41 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
42 #include <com/sun/star/accessibility/AccessibleRole.hpp>
43 #endif
44 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
45 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
46 #include <rtl/uuid.h>
47 #include <tools/debug.hxx>
48 #include <comphelper/sequence.hxx>
49 
50 
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::accessibility;
53 
54 //=====  internal  ============================================================
55 
56 ScAccessibleTableBase::ScAccessibleTableBase(
57         const uno::Reference<XAccessible>& rxParent,
58         ScDocument* pDoc,
59         const ScRange& rRange)
60     :
61     ScAccessibleContextBase (rxParent, AccessibleRole::TABLE),
62     maRange(rRange),
63     mpDoc(pDoc)
64 {
65 }
66 
67 ScAccessibleTableBase::~ScAccessibleTableBase()
68 {
69 }
70 
71 void SAL_CALL ScAccessibleTableBase::disposing()
72 {
73     ScUnoGuard aGuard;
74     mpDoc = NULL;
75 
76     ScAccessibleContextBase::disposing();
77 }
78 
79     //=====  XInterface  =====================================================
80 
81 uno::Any SAL_CALL ScAccessibleTableBase::queryInterface( uno::Type const & rType )
82     throw (uno::RuntimeException)
83 {
84     uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
85     return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
86 }
87 
88 void SAL_CALL ScAccessibleTableBase::acquire()
89     throw ()
90 {
91     ScAccessibleContextBase::acquire();
92 }
93 
94 void SAL_CALL ScAccessibleTableBase::release()
95     throw ()
96 {
97     ScAccessibleContextBase::release();
98 }
99 
100     //=====  XAccessibleTable  ================================================
101 
102 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount(  )
103                     throw (uno::RuntimeException)
104 {
105     ScUnoGuard aGuard;
106     IsObjectValid();
107     return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
108 }
109 
110 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount(  )
111                     throw (uno::RuntimeException)
112 {
113     ScUnoGuard aGuard;
114     IsObjectValid();
115     return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
116 }
117 
118 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
119     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
120 {
121     DBG_ERROR("Here should be a implementation to fill the description");
122 
123     if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
124         throw lang::IndexOutOfBoundsException();
125 
126     //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
127     return rtl::OUString();
128 }
129 
130 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
131     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
132 {
133     DBG_ERROR("Here should be a implementation to fill the description");
134 
135     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
136         throw lang::IndexOutOfBoundsException();
137 
138     //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
139     return rtl::OUString();
140 }
141 
142 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
143     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
144 {
145     ScUnoGuard aGuard;
146     IsObjectValid();
147 
148     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
149         (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
150         throw lang::IndexOutOfBoundsException();
151 
152     sal_Int32 nCount(1); // the same cell
153     nRow += maRange.aStart.Row();
154     nColumn += maRange.aStart.Col();
155 
156     if (mpDoc)
157     {
158         SCROW nEndRow(0);
159         SCCOL nEndCol(0);
160         if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
161             nEndCol, nEndRow, maRange.aStart.Tab()))
162         {
163             if (nEndRow > nRow)
164                 nCount = nEndRow - nRow + 1;
165         }
166     }
167 
168     return nCount;
169 }
170 
171 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
172     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
173 {
174     ScUnoGuard aGuard;
175     IsObjectValid();
176 
177     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
178         (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
179         throw lang::IndexOutOfBoundsException();
180 
181     sal_Int32 nCount(1); // the same cell
182     nRow += maRange.aStart.Row();
183     nColumn += maRange.aStart.Col();
184 
185     if (mpDoc)
186     {
187         SCROW nEndRow(0);
188         SCCOL nEndCol(0);
189         if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
190             nEndCol, nEndRow, maRange.aStart.Tab()))
191         {
192             if (nEndCol > nColumn)
193                 nCount = nEndCol - nColumn + 1;
194         }
195     }
196 
197     return nCount;
198 }
199 
200 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders(  )
201                     throw (uno::RuntimeException)
202 {
203     uno::Reference< XAccessibleTable > xAccessibleTable;
204     DBG_ERROR("Here should be a implementation to fill the row headers");
205 
206     //CommitChange
207     return xAccessibleTable;
208 }
209 
210 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders(  )
211                     throw (uno::RuntimeException)
212 {
213     uno::Reference< XAccessibleTable > xAccessibleTable;
214     DBG_ERROR("Here should be a implementation to fill the column headers");
215 
216     //CommitChange
217     return xAccessibleTable;
218 }
219 
220 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows(  )
221                     throw (uno::RuntimeException)
222 {
223     DBG_ERROR("not implemented yet");
224     uno::Sequence< sal_Int32 > aSequence;
225     return aSequence;
226 }
227 
228 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns(  )
229                     throw (uno::RuntimeException)
230 {
231     DBG_ERROR("not implemented yet");
232     uno::Sequence< sal_Int32 > aSequence;
233     return aSequence;
234 }
235 
236 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
237     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
238 {
239     DBG_ERROR("not implemented yet");
240     return sal_False;
241 }
242 
243 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
244     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
245 {
246     DBG_ERROR("not implemented yet");
247     return sal_False;
248 }
249 
250 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
251                     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
252 {
253     DBG_ERROR("not implemented yet");
254     uno::Reference< XAccessible > xAccessible;
255     return xAccessible;
256 }
257 
258 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption(  )
259                     throw (uno::RuntimeException)
260 {
261     DBG_ERROR("not implemented yet");
262     uno::Reference< XAccessible > xAccessible;
263     return xAccessible;
264 }
265 
266 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary(  )
267                     throw (uno::RuntimeException)
268 {
269     DBG_ERROR("not implemented yet");
270     uno::Reference< XAccessible > xAccessible;
271     return xAccessible;
272 }
273 
274 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
275     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
276 {
277     DBG_ERROR("not implemented yet");
278     return sal_False;
279 }
280 
281     //=====  XAccessibleExtendedTable  ========================================
282 
283 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
284     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
285 {
286     ScUnoGuard aGuard;
287     IsObjectValid();
288 
289     if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
290         nRow < 0 ||
291         nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
292         nColumn < 0)
293         throw lang::IndexOutOfBoundsException();
294 
295     nRow -= maRange.aStart.Row();
296     nColumn -= maRange.aStart.Col();
297     return (nRow * (maRange.aEnd.Col() + 1)) + nColumn;
298 }
299 
300 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex )
301     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
302 {
303     ScUnoGuard aGuard;
304     IsObjectValid();
305 
306     if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
307         throw lang::IndexOutOfBoundsException();
308 
309     return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
310 }
311 
312 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex )
313     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
314 {
315     ScUnoGuard aGuard;
316     IsObjectValid();
317 
318     if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
319         throw lang::IndexOutOfBoundsException();
320 
321     return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
322 }
323 
324     //=====  XAccessibleContext  ==============================================
325 
326 sal_Int32 SAL_CALL
327     ScAccessibleTableBase::getAccessibleChildCount(void)
328                     throw (uno::RuntimeException)
329 {
330     ScUnoGuard aGuard;
331     IsObjectValid();
332     return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
333             (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
334 //  return 1;
335 }
336 
337 uno::Reference< XAccessible > SAL_CALL
338     ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex)
339         throw (uno::RuntimeException,
340         lang::IndexOutOfBoundsException)
341 {
342     ScUnoGuard aGuard;
343     IsObjectValid();
344 
345     if (nIndex >= getAccessibleChildCount() || nIndex < 0)
346         throw lang::IndexOutOfBoundsException();
347 
348     sal_Int32 nRow(0);
349     sal_Int32 nColumn(0);
350     sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
351     nRow = nIndex / nTemp;
352     nColumn = nIndex % nTemp;
353     return getAccessibleCellAt(nRow, nColumn);
354 }
355 
356 ::rtl::OUString SAL_CALL
357     ScAccessibleTableBase::createAccessibleDescription(void)
358     throw (uno::RuntimeException)
359 {
360     String sDesc(ScResId(STR_ACC_TABLE_DESCR));
361 /*  String sCoreName;
362     if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
363         sDesc.SearchAndReplaceAscii("%1", sCoreName);
364     sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
365     return rtl::OUString(sDesc);
366 }
367 
368 ::rtl::OUString SAL_CALL
369     ScAccessibleTableBase::createAccessibleName(void)
370     throw (uno::RuntimeException)
371 {
372     String sName(ScResId(STR_ACC_TABLE_NAME));
373     String sCoreName;
374     if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
375         sName.SearchAndReplaceAscii("%1", sCoreName);
376     return rtl::OUString(sName);
377 }
378 
379 uno::Reference<XAccessibleRelationSet> SAL_CALL
380     ScAccessibleTableBase::getAccessibleRelationSet(void)
381     throw (uno::RuntimeException)
382 {
383     DBG_ERROR("should be implemented in the abrevated class");
384     return uno::Reference<XAccessibleRelationSet>();
385 }
386 
387 uno::Reference<XAccessibleStateSet> SAL_CALL
388     ScAccessibleTableBase::getAccessibleStateSet(void)
389     throw (uno::RuntimeException)
390 {
391     DBG_ERROR("should be implemented in the abrevated class");
392     uno::Reference< XAccessibleStateSet > xAccessibleStateSet;
393     return xAccessibleStateSet;
394 }
395 
396     ///=====  XAccessibleSelection  ===========================================
397 
398 void SAL_CALL
399         ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
400         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
401 {
402 }
403 
404 sal_Bool SAL_CALL
405         ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex )
406         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
407 {
408     // I don't need to guard, because the called funtions have a guard
409 //    ScUnoGuard aGuard;
410     if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
411         throw lang::IndexOutOfBoundsException();
412     return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
413 }
414 
415 void SAL_CALL
416         ScAccessibleTableBase::clearAccessibleSelection(  )
417         throw (uno::RuntimeException)
418 {
419 }
420 
421 void SAL_CALL
422         ScAccessibleTableBase::selectAllAccessibleChildren(  )
423         throw (uno::RuntimeException)
424 {
425 }
426 
427 sal_Int32 SAL_CALL
428         ScAccessibleTableBase::getSelectedAccessibleChildCount(  )
429         throw (uno::RuntimeException)
430 {
431     sal_Int32 nResult(0);
432     return nResult;
433 }
434 
435 uno::Reference<XAccessible > SAL_CALL
436         ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
437         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
438 {
439     uno::Reference < XAccessible > xAccessible;
440     return xAccessible;
441 }
442 
443 void SAL_CALL
444         ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
445         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
446 {
447 }
448 
449     //=====  XServiceInfo  ====================================================
450 
451 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void)
452         throw (uno::RuntimeException)
453 {
454     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleTableBase"));
455 }
456 
457     //=====  XTypeProvider  ===================================================
458 
459 uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes()
460         throw (uno::RuntimeException)
461 {
462     return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
463 }
464 
465 uno::Sequence<sal_Int8> SAL_CALL
466     ScAccessibleTableBase::getImplementationId(void)
467     throw (uno::RuntimeException)
468 {
469     ScUnoGuard aGuard;
470     IsObjectValid();
471     static uno::Sequence<sal_Int8> aId;
472     if (aId.getLength() == 0)
473     {
474         aId.realloc (16);
475         rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
476     }
477     return aId;
478 }
479 
480 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
481 {
482     AccessibleTableModelChange aModelChange;
483     aModelChange.FirstRow = nStartRow;
484     aModelChange.FirstColumn = nStartCol;
485     aModelChange.LastRow = nEndRow;
486     aModelChange.LastColumn = nEndCol;
487     aModelChange.Type = nId;
488 
489     AccessibleEventObject aEvent;
490     aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
491     aEvent.Source = uno::Reference< XAccessibleContext >(this);
492     aEvent.NewValue <<= aModelChange;
493 
494     CommitChange(aEvent);
495 }
496