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