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 	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 
acquire()94 void SAL_CALL ScAccessibleTableBase::acquire()
95 	throw ()
96 {
97 	ScAccessibleContextBase::acquire();
98 }
99 
release()100 void SAL_CALL ScAccessibleTableBase::release()
101 	throw ()
102 {
103 	ScAccessibleContextBase::release();
104 }
105 
106 	//=====  XAccessibleTable  ================================================
107 
getAccessibleRowCount()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 
getAccessibleColumnCount()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 
getAccessibleRowDescription(sal_Int32 nRow)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 
getAccessibleColumnDescription(sal_Int32 nColumn)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 
getAccessibleRowExtentAt(sal_Int32 nRow,sal_Int32 nColumn)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 
getAccessibleColumnExtentAt(sal_Int32 nRow,sal_Int32 nColumn)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 
getAccessibleRowHeaders()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 
getAccessibleColumnHeaders()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 
getSelectedAccessibleRows()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 
getSelectedAccessibleColumns()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 
isAccessibleRowSelected(sal_Int32)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 
isAccessibleColumnSelected(sal_Int32)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 
getAccessibleCellAt(sal_Int32,sal_Int32)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 
getAccessibleCaption()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 
getAccessibleSummary()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 
isAccessibleSelected(sal_Int32,sal_Int32)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 
getAccessibleIndex(sal_Int32 nRow,sal_Int32 nColumn)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 
getAccessibleRow(sal_Int32 nChildIndex)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 
getAccessibleColumn(sal_Int32 nChildIndex)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
getAccessibleChildCount(void)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
getAccessibleChild(sal_Int32 nIndex)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
createAccessibleDescription(void)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
createAccessibleName(void)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
getAccessibleRelationSet(void)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
getAccessibleStateSet(void)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
selectAccessibleChild(sal_Int32)401         ScAccessibleTableBase::selectAccessibleChild( sal_Int32 /* nChildIndex */ )
402 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
403 {
404 }
405 
406 sal_Bool SAL_CALL
isAccessibleChildSelected(sal_Int32 nChildIndex)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
clearAccessibleSelection()418 		ScAccessibleTableBase::clearAccessibleSelection(  )
419 		throw (uno::RuntimeException)
420 {
421 }
422 
423 void SAL_CALL
selectAllAccessibleChildren()424 		ScAccessibleTableBase::selectAllAccessibleChildren(  )
425 		throw (uno::RuntimeException)
426 {
427 }
428 
429 sal_Int32 SAL_CALL
getSelectedAccessibleChildCount()430 		ScAccessibleTableBase::getSelectedAccessibleChildCount(  )
431 		throw (uno::RuntimeException)
432 {
433 	sal_Int32 nResult(0);
434 	return nResult;
435 }
436 
437 uno::Reference<XAccessible > SAL_CALL
getSelectedAccessibleChild(sal_Int32)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
deselectAccessibleChild(sal_Int32)446         ScAccessibleTableBase::deselectAccessibleChild( sal_Int32 /* nSelectedChildIndex */ )
447 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
448 {
449 }
450 
451 	//=====  XServiceInfo  ====================================================
452 
getImplementationName(void)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 
getTypes()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
getImplementationId(void)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 
CommitTableModelChange(sal_Int32 nStartRow,sal_Int32 nStartCol,sal_Int32 nEndRow,sal_Int32 nEndCol,sal_uInt16 nId)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 }
selectRow(sal_Int32)498 sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 )
499 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
500 {
501 	return sal_True;
502 }
selectColumn(sal_Int32)503 sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 )
504 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
505 {
506 	return sal_True;
507 }
unselectRow(sal_Int32)508 sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 )
509 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
510 {
511 		return sal_True;
512 }
unselectColumn(sal_Int32)513 sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 )
514 		throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
515 {
516 	return sal_True;
517 }
518 
519 
520