xref: /trunk/main/sc/source/ui/Accessibility/AccessibleTableBase.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
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 aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
81     //return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
82     uno::Any aRet;
83     if ( rType == ::getCppuType((uno::Reference<XAccessibleTableSelection> *)0) )
84     {
85         uno::Reference<XAccessibleTableSelection> xThis( this );
86         aRet <<= xThis;
87         return aRet;
88     }
89     else
90     {
91         uno::Any aAny (ScAccessibleTableBaseImpl::queryInterface(rType));
92         return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
93     }
94     return aRet;
95 }
96 
97 void SAL_CALL ScAccessibleTableBase::acquire()
98     throw ()
99 {
100     ScAccessibleContextBase::acquire();
101 }
102 
103 void SAL_CALL ScAccessibleTableBase::release()
104     throw ()
105 {
106     ScAccessibleContextBase::release();
107 }
108 
109     //=====  XAccessibleTable  ================================================
110 
111 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount(  )
112                     throw (uno::RuntimeException)
113 {
114     ScUnoGuard aGuard;
115     IsObjectValid();
116     return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
117 }
118 
119 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount(  )
120                     throw (uno::RuntimeException)
121 {
122     ScUnoGuard aGuard;
123     IsObjectValid();
124     return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
125 }
126 
127 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
128     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
129 {
130     DBG_ERROR("Here should be a implementation to fill the description");
131 
132     if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
133         throw lang::IndexOutOfBoundsException();
134 
135     //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
136     return rtl::OUString();
137 }
138 
139 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
140     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
141 {
142     DBG_ERROR("Here should be a implementation to fill the description");
143 
144     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
145         throw lang::IndexOutOfBoundsException();
146 
147     //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
148     return rtl::OUString();
149 }
150 
151 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
152     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
153 {
154     ScUnoGuard aGuard;
155     IsObjectValid();
156 
157     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
158         (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
159         throw lang::IndexOutOfBoundsException();
160 
161     sal_Int32 nCount(1); // the same cell
162     nRow += maRange.aStart.Row();
163     nColumn += maRange.aStart.Col();
164 
165     if (mpDoc)
166     {
167         SCROW nEndRow(0);
168         SCCOL nEndCol(0);
169         mpDoc->GetTableByIndex(maRange.aStart.Tab())->GetColumnByIndex(nColumn)->
170             ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False, sal_False );
171         if (nEndRow > nRow)
172                nCount = nEndRow - nRow + 1;
173     //  if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
174     //      nEndCol, nEndRow, maRange.aStart.Tab()))
175         //{
176     //      if (nEndRow > nRow)
177     //          nCount = nEndRow - nRow + 1;
178         //}
179     }
180 
181     return nCount;
182 }
183 
184 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
185     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
186 {
187     ScUnoGuard aGuard;
188     IsObjectValid();
189 
190     if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
191         (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
192         throw lang::IndexOutOfBoundsException();
193 
194     sal_Int32 nCount(1); // the same cell
195     nRow += maRange.aStart.Row();
196     nColumn += maRange.aStart.Col();
197 
198     if (mpDoc)
199     {
200         SCROW nEndRow(0);
201         SCCOL nEndCol(0);
202         mpDoc->GetTableByIndex(maRange.aStart.Tab())->GetColumnByIndex(nColumn)->
203             ExtendMerge( static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow), nRow, nEndCol, nEndRow, sal_False, sal_False );
204         if (nEndCol > nColumn)
205                 nCount = nEndCol - nColumn + 1;
206     //  if (mpDoc->ExtendMerge(static_cast<SCCOL>(nColumn), static_cast<SCROW>(nRow),
207     //      nEndCol, nEndRow, maRange.aStart.Tab()))
208         //{
209     //      if (nEndCol > nColumn)
210     //          nCount = nEndCol - nColumn + 1;
211         //}
212     }
213 
214     return nCount;
215 }
216 
217 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders(  )
218                     throw (uno::RuntimeException)
219 {
220     uno::Reference< XAccessibleTable > xAccessibleTable;
221     DBG_ERROR("Here should be a implementation to fill the row headers");
222 
223     //CommitChange
224     return xAccessibleTable;
225 }
226 
227 uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders(  )
228                     throw (uno::RuntimeException)
229 {
230     uno::Reference< XAccessibleTable > xAccessibleTable;
231     DBG_ERROR("Here should be a implementation to fill the column headers");
232 
233     //CommitChange
234     return xAccessibleTable;
235 }
236 
237 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows(  )
238                     throw (uno::RuntimeException)
239 {
240     DBG_ERROR("not implemented yet");
241     uno::Sequence< sal_Int32 > aSequence;
242     return aSequence;
243 }
244 
245 uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns(  )
246                     throw (uno::RuntimeException)
247 {
248     DBG_ERROR("not implemented yet");
249     uno::Sequence< sal_Int32 > aSequence;
250     return aSequence;
251 }
252 
253 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
254     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
255 {
256     DBG_ERROR("not implemented yet");
257     return sal_False;
258 }
259 
260 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
261     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
262 {
263     DBG_ERROR("not implemented yet");
264     return sal_False;
265 }
266 
267 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
268                     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
269 {
270     DBG_ERROR("not implemented yet");
271     uno::Reference< XAccessible > xAccessible;
272     return xAccessible;
273 }
274 
275 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption(  )
276                     throw (uno::RuntimeException)
277 {
278     DBG_ERROR("not implemented yet");
279     uno::Reference< XAccessible > xAccessible;
280     return xAccessible;
281 }
282 
283 uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary(  )
284                     throw (uno::RuntimeException)
285 {
286     DBG_ERROR("not implemented yet");
287     uno::Reference< XAccessible > xAccessible;
288     return xAccessible;
289 }
290 
291 sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
292     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
293 {
294     DBG_ERROR("not implemented yet");
295     return sal_False;
296 }
297 
298     //=====  XAccessibleExtendedTable  ========================================
299 
300 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
301     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
302 {
303     ScUnoGuard aGuard;
304     IsObjectValid();
305 
306     if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
307         nRow < 0 ||
308         nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
309         nColumn < 0)
310         throw lang::IndexOutOfBoundsException();
311 
312     nRow -= maRange.aStart.Row();
313     nColumn -= maRange.aStart.Col();
314     return (nRow * (maRange.aEnd.Col() + 1)) + nColumn;
315 }
316 
317 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex )
318     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
319 {
320     ScUnoGuard aGuard;
321     IsObjectValid();
322 
323     if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
324         throw lang::IndexOutOfBoundsException();
325 
326     return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
327 }
328 
329 sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex )
330     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
331 {
332     ScUnoGuard aGuard;
333     IsObjectValid();
334 
335     if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
336         throw lang::IndexOutOfBoundsException();
337 
338     return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
339 }
340 
341     //=====  XAccessibleContext  ==============================================
342 
343 sal_Int32 SAL_CALL
344     ScAccessibleTableBase::getAccessibleChildCount(void)
345                     throw (uno::RuntimeException)
346 {
347     ScUnoGuard aGuard;
348     IsObjectValid();
349     return static_cast<sal_Int32>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
350             (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
351 //  return 1;
352 }
353 
354 uno::Reference< XAccessible > SAL_CALL
355     ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex)
356         throw (uno::RuntimeException,
357         lang::IndexOutOfBoundsException)
358 {
359     ScUnoGuard aGuard;
360     IsObjectValid();
361 
362     if (nIndex >= getAccessibleChildCount() || nIndex < 0)
363         throw lang::IndexOutOfBoundsException();
364 
365     sal_Int32 nRow(0);
366     sal_Int32 nColumn(0);
367     sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
368     nRow = nIndex / nTemp;
369     nColumn = nIndex % nTemp;
370     return getAccessibleCellAt(nRow, nColumn);
371 }
372 
373 ::rtl::OUString SAL_CALL
374     ScAccessibleTableBase::createAccessibleDescription(void)
375     throw (uno::RuntimeException)
376 {
377     String sDesc(ScResId(STR_ACC_TABLE_DESCR));
378 /*  String sCoreName;
379     if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
380         sDesc.SearchAndReplaceAscii("%1", sCoreName);
381     sDesc.SearchAndReplaceAscii("%2", String(ScResId(SCSTR_UNKNOWN)));*/
382     return rtl::OUString(sDesc);
383 }
384 
385 ::rtl::OUString SAL_CALL
386     ScAccessibleTableBase::createAccessibleName(void)
387     throw (uno::RuntimeException)
388 {
389     String sName(ScResId(STR_ACC_TABLE_NAME));
390     String sCoreName;
391     if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
392         sName.SearchAndReplaceAscii("%1", sCoreName);
393     return rtl::OUString(sName);
394 }
395 
396 uno::Reference<XAccessibleRelationSet> SAL_CALL
397     ScAccessibleTableBase::getAccessibleRelationSet(void)
398     throw (uno::RuntimeException)
399 {
400     DBG_ERROR("should be implemented in the abrevated class");
401     return uno::Reference<XAccessibleRelationSet>();
402 }
403 
404 uno::Reference<XAccessibleStateSet> SAL_CALL
405     ScAccessibleTableBase::getAccessibleStateSet(void)
406     throw (uno::RuntimeException)
407 {
408     DBG_ERROR("should be implemented in the abrevated class");
409     uno::Reference< XAccessibleStateSet > xAccessibleStateSet;
410     return xAccessibleStateSet;
411 }
412 
413     ///=====  XAccessibleSelection  ===========================================
414 
415 void SAL_CALL
416         ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
417         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
418 {
419 }
420 
421 sal_Bool SAL_CALL
422         ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex )
423         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
424 {
425     // I don't need to guard, because the called funtions have a guard
426 //    ScUnoGuard aGuard;
427     if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
428         throw lang::IndexOutOfBoundsException();
429     return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
430 }
431 
432 void SAL_CALL
433         ScAccessibleTableBase::clearAccessibleSelection(  )
434         throw (uno::RuntimeException)
435 {
436 }
437 
438 void SAL_CALL
439         ScAccessibleTableBase::selectAllAccessibleChildren(  )
440         throw (uno::RuntimeException)
441 {
442 }
443 
444 sal_Int32 SAL_CALL
445         ScAccessibleTableBase::getSelectedAccessibleChildCount(  )
446         throw (uno::RuntimeException)
447 {
448     sal_Int32 nResult(0);
449     return nResult;
450 }
451 
452 uno::Reference<XAccessible > SAL_CALL
453         ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
454         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
455 {
456     uno::Reference < XAccessible > xAccessible;
457     return xAccessible;
458 }
459 
460 void SAL_CALL
461         ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
462         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
463 {
464 }
465 
466     //=====  XServiceInfo  ====================================================
467 
468 ::rtl::OUString SAL_CALL ScAccessibleTableBase::getImplementationName(void)
469         throw (uno::RuntimeException)
470 {
471     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleTableBase"));
472 }
473 
474     //=====  XTypeProvider  ===================================================
475 
476 uno::Sequence< uno::Type > SAL_CALL ScAccessibleTableBase::getTypes()
477         throw (uno::RuntimeException)
478 {
479     return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
480 }
481 
482 uno::Sequence<sal_Int8> SAL_CALL
483     ScAccessibleTableBase::getImplementationId(void)
484     throw (uno::RuntimeException)
485 {
486     ScUnoGuard aGuard;
487     IsObjectValid();
488     static uno::Sequence<sal_Int8> aId;
489     if (aId.getLength() == 0)
490     {
491         aId.realloc (16);
492         rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
493     }
494     return aId;
495 }
496 
497 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
498 {
499     AccessibleTableModelChange aModelChange;
500     aModelChange.FirstRow = nStartRow;
501     aModelChange.FirstColumn = nStartCol;
502     aModelChange.LastRow = nEndRow;
503     aModelChange.LastColumn = nEndCol;
504     aModelChange.Type = nId;
505 
506     AccessibleEventObject aEvent;
507     aEvent.EventId = AccessibleEventId::TABLE_MODEL_CHANGED;
508     aEvent.Source = uno::Reference< XAccessibleContext >(this);
509     aEvent.NewValue <<= aModelChange;
510 
511     CommitChange(aEvent);
512 }
513 sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 )
514 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
515 {
516     return sal_True;
517 }
518 sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 )
519         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
520 {
521     return sal_True;
522 }
523 sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 )
524         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
525 {
526         return sal_True;
527 }
528 sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 )
529         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
530 {
531     return sal_True;
532 }
533 
534 
535