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