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