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_svx.hxx"
26 
27 #include <com/sun/star/table/XMergeableCell.hpp>
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
30 
31 #include <comphelper/accessiblewrapper.hxx>
32 #include <vos/mutex.hxx>
33 #include <tools/debug.hxx>
34 #include <vcl/svapp.hxx>
35 
36 #include <svx/AccessibleTableShape.hxx>
37 #include <svx/sdr/table/tablecontroller.hxx>
38 #include "accessiblecell.hxx"
39 
40 #include <algorithm>
41 
42 #include <cppuhelper/implbase1.hxx>
43 #include <svx/svdotable.hxx>
44 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
45 #include <com/sun/star/view/XSelectionSupplier.hpp>
46 
47 using ::rtl::OUString;
48 
49 using namespace ::accessibility;
50 using namespace ::sdr::table;
51 using namespace	::com::sun::star::accessibility;
52 using namespace	::com::sun::star::uno;
53 using namespace	::com::sun::star::beans;
54 using namespace	::com::sun::star::util;
55 using namespace	::com::sun::star::lang;
56 using namespace	::com::sun::star::drawing;
57 using namespace	::com::sun::star::table;
58 using namespace	::com::sun::star::container;
59 
60 #define C2U(x) OUString(RTL_CONSTASCII_USTRINGPARAM(x))
61 
62 namespace accessibility
63 {
64 
65 struct hash
66 {
operator ()accessibility::hash67 	std::size_t operator()( const Reference< XCell >& xCell ) const
68 	{
69 		return std::size_t( xCell.get() );
70 	}
71 };
72 
73 typedef std::hash_map< Reference< XCell >, rtl::Reference< AccessibleCell >, hash > AccessibleCellMap;
74 
75 //-----------------------------------------------------------------------------
76 // AccessibleTableShapeImpl
77 //-----------------------------------------------------------------------------
78 
79 class AccessibleTableShapeImpl : public cppu::WeakImplHelper1< XModifyListener >
80 {
81 public:
82 	AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo );
83 
84 	void init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable );
85 	void dispose();
86 
87 	Reference< XAccessible > getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException);
88 	void getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException );
89 
90     // XModifyListener
91     virtual void SAL_CALL modified( const EventObject& aEvent ) throw (RuntimeException);
92 
93     // XEventListener
94     virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
95 
96 	AccessibleShapeTreeInfo& mrShapeTreeInfo;
97 	Reference< XTable > mxTable;
98 	AccessibleCellMap maChildMap;
99 	Reference< XAccessible> mxAccessible;
100 	sal_Int32 mRowCount, mColCount;
101 	//get the cached AccessibleCell from XCell
102 	Reference< AccessibleCell > getAccessibleCell (Reference< XCell > xCell);
103 };
104 
105 //-----------------------------------------------------------------------------
106 
AccessibleTableShapeImpl(AccessibleShapeTreeInfo & rShapeTreeInfo)107 AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo )
108 : mrShapeTreeInfo( rShapeTreeInfo )
109 , mRowCount(0)
110 , mColCount(0)
111 {
112 }
113 
114 //-----------------------------------------------------------------------------
115 
init(const Reference<XAccessible> & xAccessible,const Reference<XTable> & xTable)116 void AccessibleTableShapeImpl::init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable )
117 {
118 	mxAccessible = xAccessible;
119 	mxTable = xTable;
120 
121 	if( mxTable.is() )
122 	{
123 		Reference< XModifyListener > xListener( this );
124 		mxTable->addModifyListener( xListener );
125 		//register the listener with table model
126 		Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(xTable, UNO_QUERY);
127 		Reference< ::com::sun::star::view::XSelectionChangeListener > xSelListener( xAccessible, UNO_QUERY );
128 		if (xSelSupplier.is())
129 			xSelSupplier->addSelectionChangeListener(xSelListener);
130 		mRowCount = mxTable->getRowCount();
131 		mColCount = mxTable->getColumnCount();
132 	}
133 }
134 
135 //-----------------------------------------------------------------------------
136 
dispose()137 void AccessibleTableShapeImpl::dispose()
138 {
139 	if( mxTable.is() )
140 	{
141 		//IAccessibility2 Implementation 2009-----, remove all the cell's acc object in table's dispose.
142 		for( AccessibleCellMap::iterator iter( maChildMap.begin() ); iter != maChildMap.end(); iter++ )
143 		{
144 			(*iter).second->dispose();
145 		}
146 		Reference< XModifyListener > xListener( this );
147 		mxTable->removeModifyListener( xListener );
148 		mxTable.clear();
149 	}
150 	mxAccessible.clear();
151 }
152 
153 //-----------------------------------------------------------------------------
154 //IAccessibility2 Implementation 2009-----, get the cached AccessibleCell from XCell
getAccessibleCell(Reference<XCell> xCell)155 Reference< AccessibleCell > AccessibleTableShapeImpl::getAccessibleCell (Reference< XCell > xCell)
156 {
157 	AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
158 
159 	if( iter != maChildMap.end() )
160 	{
161 		Reference< AccessibleCell > xChild( (*iter).second.get() );
162 		return xChild;
163 	}
164 	return Reference< AccessibleCell >();
165 }
166 
167 //-----------------------------------------------------------------------------
getAccessibleChild(sal_Int32 nChildIndex)168 Reference< XAccessible > AccessibleTableShapeImpl::getAccessibleChild( sal_Int32 nChildIndex ) throw(IndexOutOfBoundsException)
169 {
170 	sal_Int32 nColumn = 0, nRow = 0;
171 	getColumnAndRow( nChildIndex, nColumn, nRow );
172 
173 	Reference< XCell > xCell( mxTable->getCellByPosition( nColumn, nRow ) );
174 	AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
175 
176 	if( iter != maChildMap.end() )
177 	{
178 		Reference< XAccessible > xChild( (*iter).second.get() );
179 		return xChild;
180 	}
181 	else
182 	{
183 		CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) );
184 
185 		rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) );
186 
187 		xAccessibleCell->Init();
188 		maChildMap[xCell] = xAccessibleCell;
189 
190         xAccessibleCell->Init();
191 
192 		Reference< XAccessible > xChild( xAccessibleCell.get() );
193 		return xChild;
194 	}
195 }
196 
197 //-----------------------------------------------------------------------------
198 
getColumnAndRow(sal_Int32 nChildIndex,sal_Int32 & rnColumn,sal_Int32 & rnRow)199 void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException )
200 {
201 	rnRow = 0;
202 	rnColumn = nChildIndex;
203 
204 	if( mxTable.is() )
205 	{
206 		const sal_Int32 nColumnCount = mxTable->getColumnCount();
207 		while( rnColumn >= nColumnCount )
208 		{
209 			rnRow++;
210 			rnColumn -= nColumnCount;
211 		}
212 
213 		if( rnRow < mxTable->getRowCount() )
214 			return;
215 	}
216 
217 	throw IndexOutOfBoundsException();
218 }
219 
220 // XModifyListener
modified(const EventObject &)221 void SAL_CALL AccessibleTableShapeImpl::modified( const EventObject& /*aEvent*/ ) throw (RuntimeException)
222 {
223 	if( mxTable.is() ) try
224 	{
225 		// structural changes may have happened to the table, validate all accessible cell instances
226 		AccessibleCellMap aTempChildMap;
227 		aTempChildMap.swap( maChildMap );
228 
229 		// first move all still existing cells to maChildMap again and update their index
230 
231 		const sal_Int32 nRowCount = mxTable->getRowCount();
232 		const sal_Int32 nColCount = mxTable->getColumnCount();
233 
234 		sal_Bool bRowOrColumnChanged = sal_False;
235 		if (mRowCount != nRowCount || mColCount != nColCount )
236 		{
237 			bRowOrColumnChanged = sal_True;
238 			mRowCount = nRowCount;
239 			mColCount = nColCount;
240 		}
241 		sal_Int32 nChildIndex = 0;
242 
243 		for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
244 		{
245 			for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
246 			{
247 				Reference< XCell > xCell( mxTable->getCellByPosition( nCol, nRow ) );
248 				AccessibleCellMap::iterator iter( aTempChildMap.find( xCell ) );
249 
250 				if( iter != aTempChildMap.end() )
251 				{
252 					rtl::Reference< AccessibleCell > xAccessibleCell( (*iter).second );
253 					xAccessibleCell->setIndexInParent( nChildIndex );
254 					//IAccessibility2 Implementation 2009-----, the children may need to updated
255 					//xAccessibleCell->CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
256 					xAccessibleCell->UpdateChildren();
257 					// If row or column count is changed, there is split or merge, so all cell's acc name should be updated
258 					if (bRowOrColumnChanged)
259 					{
260 						xAccessibleCell->SetAccessibleName(xAccessibleCell->getAccessibleName(), AccessibleContextBase::ManuallySet);
261 					}
262 					// For merged cell, add invisible & disabled state.
263 					Reference< XMergeableCell > xMergedCell( mxTable->getCellByPosition( nCol, nRow ),  UNO_QUERY );
264 					if (xMergedCell.is() && xMergedCell->isMerged())
265 					{
266 						xAccessibleCell->ResetState(AccessibleStateType::VISIBLE);
267 						xAccessibleCell->ResetState(AccessibleStateType::ENABLED);
268 						// IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
269 						// xAccessibleCell->SetState(AccessibleStateType::OFFSCREEN);
270 						xAccessibleCell->ResetState(AccessibleStateType::SHOWING);
271 					}
272 					else
273 					{
274 						xAccessibleCell->SetState(AccessibleStateType::VISIBLE);
275 						xAccessibleCell->SetState(AccessibleStateType::ENABLED);
276 						// IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
277 						// xAccessibleCell->ResetState(AccessibleStateType::OFFSCREEN);
278 						xAccessibleCell->SetState(AccessibleStateType::SHOWING);
279 					}
280 
281 					// move still existing cell from temporary child map to our child map
282 					maChildMap[xCell] = xAccessibleCell;
283 					aTempChildMap.erase( iter );
284 				}
285 				//IAccessibility2 Implementation 2009-----, need to add the new added cell on demand
286 				else
287 				{
288 					CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) );
289 
290 					rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) );
291 
292 					xAccessibleCell->Init();
293 					maChildMap[xCell] = xAccessibleCell;
294 				}
295 
296 				++nChildIndex;
297 			}
298 		}
299 
300 		// all accessible cell instances still left in aTempChildMap must be disposed
301 		// as they are no longer part of the table
302 
303 		for( AccessibleCellMap::iterator iter( aTempChildMap.begin() ); iter != aTempChildMap.end(); iter++ )
304 		{
305 			(*iter).second->dispose();
306 		}
307 		//IAccessibility2 Implementation 2009-----, notify bridge to update the acc cache.
308 		AccessibleTableShape *pAccTable = dynamic_cast <AccessibleTableShape *> (mxAccessible.get());
309 		pAccTable->CommitChange(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any());
310 	}
311 	catch( Exception& )
312 	{
313 		DBG_ERROR("svx::AccessibleTableShape::modified(), exception caught!");
314 	}
315 }
316 
317 // XEventListener
disposing(const EventObject &)318 void SAL_CALL AccessibleTableShapeImpl::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
319 {
320 }
321 
322 //-----------------------------------------------------------------------------
323 // AccessibleTableShape
324 //-----------------------------------------------------------------------------
325 
326 //-----------------------------------------------------------------------------
327 
AccessibleTableShape(const AccessibleShapeInfo & rShapeInfo,const AccessibleShapeTreeInfo & rShapeTreeInfo)328 AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo& rShapeInfo, const AccessibleShapeTreeInfo& rShapeTreeInfo)
329 : AccessibleTableShape_Base(rShapeInfo, rShapeTreeInfo)
330 , mnPreviousSelectionCount(0)
331 , mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo ) )
332 {
333 }
334 
335 //-----------------------------------------------------------------------------
336 
~AccessibleTableShape(void)337 AccessibleTableShape::~AccessibleTableShape (void)
338 {
339 }
340 
341 //-----------------------------------------------------------------------------
342 
Init()343 void AccessibleTableShape::Init()
344 {
345 	try
346 	{
347 		Reference< XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
348 		Reference< XTable > xTable( xSet->getPropertyValue(C2U("Model")), UNO_QUERY_THROW );
349 
350 		mxImpl->init( this, xTable );
351 	}
352 	catch( Exception& )
353 	{
354 		DBG_ERROR("AccessibleTableShape::init(), exception caught?");
355 	}
356 
357 	AccessibleTableShape_Base::Init();
358 }
359 
360 //-----------------------------------------------------------------------------
361 
getTableController()362 SvxTableController* AccessibleTableShape::getTableController()
363 {
364 	SdrView* pView = maShapeTreeInfo.GetSdrView ();
365 	if( pView )
366 		return dynamic_cast< SvxTableController* >( pView->getSelectionController().get() );
367 	else
368 		return 0;
369 }
370 
371 //-----------------------------------------------------------------------------
372 // XInterface
373 //-----------------------------------------------------------------------------
374 
queryInterface(const Type & aType)375 Any SAL_CALL AccessibleTableShape::queryInterface( const Type& aType ) throw (RuntimeException)
376 {
377 	if ( aType == ::getCppuType((Reference<XAccessibleTableSelection> *)0) )
378     {
379 		Reference<XAccessibleTableSelection> xThis( this );
380 		Any aRet;
381        	aRet <<= xThis;
382 		return aRet;
383 	}
384 	else
385 	return AccessibleTableShape_Base::queryInterface( aType );
386 }
387 
388 //-----------------------------------------------------------------------------
389 
acquire()390 void SAL_CALL AccessibleTableShape::acquire(  ) throw ()
391 {
392 	AccessibleTableShape_Base::acquire();
393 }
394 
395 //-----------------------------------------------------------------------------
396 
release()397 void SAL_CALL AccessibleTableShape::release(  ) throw ()
398 {
399 	AccessibleTableShape_Base::release();
400 }
401 
402 //-----------------------------------------------------------------------------
403 // XAccessible
404 //-----------------------------------------------------------------------------
405 
getAccessibleContext(void)406 Reference< XAccessibleContext > SAL_CALL AccessibleTableShape::getAccessibleContext(void) throw (RuntimeException)
407 {
408 	return AccessibleShape::getAccessibleContext ();
409 }
410 
411 //-----------------------------------------------------------------------------
getImplementationName(void)412 OUString SAL_CALL AccessibleTableShape::getImplementationName(void) throw (RuntimeException)
413 {
414 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.accessibility.AccessibleTableShape" ) );
415 }
416 
417 //-----------------------------------------------------------------------------
418 
CreateAccessibleBaseName(void)419 OUString AccessibleTableShape::CreateAccessibleBaseName(void) throw (RuntimeException)
420 {
421     return OUString (RTL_CONSTASCII_USTRINGPARAM("TableShape"));
422 }
423 
424 //--------------------------------------------------------------------
425 
getAccessibleChildCount()426 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException)
427 {
428     ::vos::OGuard aSolarGuard(::Application::GetSolarMutex());
429 	return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() * mxImpl->mxTable->getColumnCount() : 0;
430 }
431 
432 //--------------------------------------------------------------------
getAccessibleChild(sal_Int32 i)433 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException)
434 {
435     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
436 	ThrowIfDisposed();
437 
438 	return mxImpl->getAccessibleChild( i );
439 }
440 
441 //--------------------------------------------------------------------
getAccessibleRelationSet()442 Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableShape::getAccessibleRelationSet(  ) throw (RuntimeException)
443 {
444 	return AccessibleShape::getAccessibleRelationSet( );
445 }
446 
447 //--------------------------------------------------------------------
448 
getAccessibleRole(void)449 sal_Int16 SAL_CALL AccessibleTableShape::getAccessibleRole (void) throw (RuntimeException)
450 {
451 	return AccessibleRole::TABLE;
452 }
453 
454 //--------------------------------------------------------------------
455 
disposing(void)456 void SAL_CALL AccessibleTableShape::disposing (void)
457 {
458 	mxImpl->dispose();
459 
460 	// let the base do it's stuff
461 	AccessibleShape::disposing();
462 }
463 
464 //--------------------------------------------------------------------
465 // XAccessibleTable
466 //--------------------------------------------------------------------
467 
getAccessibleRowCount()468 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException)
469 {
470     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
471 	return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() : 0;
472 }
473 
474 //--------------------------------------------------------------------
475 
getAccessibleColumnCount()476 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnCount(  ) throw (RuntimeException)
477 {
478     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
479 	return mxImpl->mxTable.is() ? mxImpl->mxTable->getColumnCount() : 0;
480 }
481 
482 //--------------------------------------------------------------------
483 
getAccessibleRowDescription(sal_Int32 nRow)484 OUString SAL_CALL AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
485 {
486 	checkCellPosition( 0, nRow );
487 	return OUString();
488 }
489 
490 //--------------------------------------------------------------------
491 
getAccessibleColumnDescription(sal_Int32 nColumn)492 OUString SAL_CALL AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
493 {
494     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
495 	checkCellPosition( nColumn, 0 );
496 	return OUString();
497 }
498 
499 //--------------------------------------------------------------------
500 
getAccessibleRowExtentAt(sal_Int32 nRow,sal_Int32 nColumn)501 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
502 {
503     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
504 	checkCellPosition( nColumn, nRow );
505 	if( mxImpl->mxTable.is() )
506 	{
507 		Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
508 		if( xCell.is() )
509 			return xCell->getRowSpan();
510 	}
511 	return 1;
512 }
513 
514 //--------------------------------------------------------------------
515 
getAccessibleColumnExtentAt(sal_Int32 nRow,sal_Int32 nColumn)516 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
517 {
518     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
519 	checkCellPosition( nColumn, nRow );
520 	if( mxImpl->mxTable.is() )
521 	{
522 		Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
523 		if( xCell.is() )
524 			return xCell->getColumnSpan();
525 	}
526 	return 1;
527 }
528 
529 //--------------------------------------------------------------------
530 
getAccessibleRowHeaders()531 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleRowHeaders(  ) throw (RuntimeException)
532 {
533 	//Reference< XAccessibleTable > xRet( this ); // todo
534 	Reference< XAccessibleTable > xRet;
535 	SvxTableController* pController = getTableController();
536 	if( pController )
537 	{
538 		if( pController->isRowHeader() )
539 		{
540 			AccessibleTableHeaderShape* pTableHeader = new AccessibleTableHeaderShape( this, sal_True );
541 			xRet.set( pTableHeader );
542 		}
543 	}
544 	return xRet;
545 }
546 
547 //--------------------------------------------------------------------
548 
getAccessibleColumnHeaders()549 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleColumnHeaders(  ) throw (RuntimeException)
550 {
551 	//Reference< XAccessibleTable > xRet( this ); // todo
552 	Reference< XAccessibleTable > xRet;
553 	SvxTableController* pController = getTableController();
554 	if( pController )
555 	{
556 		if( pController->isColumnHeader() )
557 		{
558 			AccessibleTableHeaderShape* pTableHeader = new AccessibleTableHeaderShape( this, sal_False );
559 			xRet.set( pTableHeader );
560 		}
561 	}
562 	return xRet;
563 }
564 
565 //--------------------------------------------------------------------
566 
getSelectedAccessibleRows()567 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleRows(  ) throw (RuntimeException)
568 {
569 	/*Sequence< sal_Int32 > aRet;*/
570 	sal_Int32 nRow = getAccessibleRowCount();
571 	::std::vector< sal_Bool > aSelected( nRow, sal_True );
572 	sal_Int32 nCount = nRow;
573 	for( sal_Int32 i = 0; i < nRow; i++ )
574 	{
575 		try
576 		{
577 			aSelected[i] = isAccessibleRowSelected( i );
578 		}
579 		catch( ... )
580 		{
581 			return Sequence< sal_Int32 >();
582 		}
583 
584 		if( !aSelected[i] )
585 			nCount--;
586 	}
587 	Sequence < sal_Int32 > aRet( nCount );
588 	sal_Int32 *pRet = aRet.getArray();
589 	sal_Int32 nPos = 0;
590 	size_t nSize = aSelected.size();
591 	for( size_t i=0; i < nSize && nPos < nCount; i++ )
592 	{
593 		if( aSelected[i] )
594 		{
595 			*pRet++ = i;
596 			nPos++;
597 		}
598 	}
599 
600 	return aRet;
601 }
602 
603 //--------------------------------------------------------------------
604 
getSelectedAccessibleColumns()605 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleColumns(  ) throw (RuntimeException)
606 {
607 	/*Sequence< sal_Int32 > aRet;*/
608 	sal_Int32 nColumn = getAccessibleColumnCount();
609 	::std::vector< sal_Bool > aSelected( nColumn, sal_True );
610 	sal_Int32 nCount = nColumn;
611 	for( sal_Int32 i = 0; i < nColumn; i++ )
612 	{
613 		try
614 		{
615 			aSelected[i] = isAccessibleColumnSelected( i );
616 		}
617 		catch( ... )
618 		{
619 			return Sequence< sal_Int32 >();
620 		}
621 
622 		if( !aSelected[i] )
623 			nCount--;
624 	}
625 	Sequence < sal_Int32 > aRet( nCount );
626 	sal_Int32 *pRet = aRet.getArray();
627 	sal_Int32 nPos = 0;
628 	size_t nSize = aSelected.size();
629 	for( size_t i=0; i < nSize && nPos < nCount; i++ )
630 	{
631 		if( aSelected[i] )
632 		{
633 			*pRet++ = i;
634 			nPos++;
635 		}
636 	}
637 
638 	return aRet;
639 }
640 
641 //--------------------------------------------------------------------
642 
isAccessibleRowSelected(sal_Int32 nRow)643 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
644 {
645     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
646 	checkCellPosition( 0, nRow );
647 	SvxTableController* pController = getTableController();
648 	if( pController )
649 	{
650 		return pController->isRowSelected( nRow );
651 	}
652 	return sal_False;
653 }
654 
655 //--------------------------------------------------------------------
656 
isAccessibleColumnSelected(sal_Int32 nColumn)657 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
658 {
659     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
660 	checkCellPosition( nColumn, 0 );
661 	SvxTableController* pController = getTableController();
662 	if( pController )
663 	{
664 		return pController->isColumnSelected( nColumn );
665 	}
666 	return sal_False;
667 }
668 
669 //--------------------------------------------------------------------
670 
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)671 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
672 {
673     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
674 	checkCellPosition( nColumn, nRow );
675 
676     sal_Int32 nChildIndex = 0;
677 	if( mxImpl->mxTable.is() )
678 		nChildIndex = mxImpl->mxTable->getColumnCount() * nRow + nColumn;
679 
680     return getAccessibleChild( nChildIndex );
681 }
682 
683 //--------------------------------------------------------------------
684 
getAccessibleCaption()685 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCaption(  ) throw (RuntimeException)
686 {
687 	Reference< XAccessible > xRet;
688 	return xRet;
689 }
690 
691 //--------------------------------------------------------------------
692 
getAccessibleSummary()693 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleSummary(  ) throw (RuntimeException)
694 {
695 	Reference< XAccessible > xRet;
696 	return xRet;
697 }
698 
699 //--------------------------------------------------------------------
700 
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)701 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
702 {
703     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
704 	checkCellPosition( nColumn, nRow );
705 
706 	SvxTableController* pController = getTableController();
707 	if( pController && pController->hasSelectedCells() )
708 	{
709 		CellPos aFirstPos, aLastPos;
710 		pController->getSelectedCells( aFirstPos, aLastPos );
711 		if( (aFirstPos.mnRow <= nRow) && (aFirstPos.mnCol <= nColumn) && (nRow <= aLastPos.mnRow) && (nColumn <= aLastPos.mnCol) )
712 			return sal_True;
713 	}
714 
715 	return sal_False;
716 }
717 
718 //--------------------------------------------------------------------
719 
getAccessibleIndex(sal_Int32 nRow,sal_Int32 nColumn)720 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
721 {
722     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
723 	checkCellPosition( nColumn, nRow );
724 	return  mxImpl->mxTable.is() ? (nRow * mxImpl->mxTable->getColumnCount() + nColumn) : 0;
725 }
726 
727 //--------------------------------------------------------------------
728 
getAccessibleRow(sal_Int32 nChildIndex)729 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
730 {
731     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
732 	sal_Int32 nColumn = 0, nRow = 0;
733 	mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
734 	return nRow;
735 }
736 
737 //--------------------------------------------------------------------
738 
getAccessibleColumn(sal_Int32 nChildIndex)739 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
740 {
741     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
742 	sal_Int32 nColumn = 0, nRow = 0;
743 	mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
744 	//return nChildIndex;
745 	return nColumn;
746 }
747 
748 //--------------------------------------------------------------------
749 // XAccessibleSelection
750 //--------------------------------------------------------------------
751 
selectAccessibleChild(sal_Int32 nChildIndex)752 void SAL_CALL AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
753 {
754     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
755 	CellPos aPos;
756 	mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
757 
758 	// todo, select table shape?!?
759 	SvxTableController* pController = getTableController();
760 	if( pController )
761 	{
762 		CellPos aFirstPos( aPos ), aLastPos( aPos );
763 		if( pController->hasSelectedCells() )
764 		{
765 			pController->getSelectedCells( aFirstPos, aLastPos );
766 
767 			aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow );
768 			aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol );
769 			aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow );
770 			aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol );
771 		}
772 		pController->setSelectedCells( aFirstPos, aLastPos );
773 	}
774 }
775 
776 //--------------------------------------------------------------------
777 
isAccessibleChildSelected(sal_Int32 nChildIndex)778 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
779 {
780     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
781 	CellPos aPos;
782 	mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
783 
784 	// Para order is not correct
785 	//return isAccessibleSelected(aPos.mnCol, aPos.mnRow);
786 	return isAccessibleSelected(aPos.mnRow, aPos.mnCol);
787 }
788 
789 //--------------------------------------------------------------------
790 
clearAccessibleSelection()791 void SAL_CALL AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException )
792 {
793    ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
794 
795 	SvxTableController* pController = getTableController();
796 	if( pController )
797 		pController->clearSelection();
798 }
799 //--------------------------------------------------------------------
800 
selectAllAccessibleChildren()801 void SAL_CALL AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException )
802 {
803    ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
804 
805    // todo: force selection of shape?
806 	SvxTableController* pController = getTableController();
807 	if( pController )
808 		pController->selectAll();
809 }
810 
811 //--------------------------------------------------------------------
812 
getSelectedAccessibleChildCount()813 sal_Int32 SAL_CALL AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException )
814 {
815     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
816 
817 	SvxTableController* pController = getTableController();
818 	if( pController && pController->hasSelectedCells() )
819 	{
820 		CellPos aFirstPos, aLastPos;
821 		pController->getSelectedCells( aFirstPos, aLastPos );
822 
823 		const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
824 		const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
825 		return nSelectedRows * nSelectedColumns;
826 	}
827 
828 	return 0;
829 }
830 
831 //--------------------------------------------------------------------
832 
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)833 Reference< XAccessible > SAL_CALL AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException)
834 {
835     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
836 
837 	/*SvxTableController* pController = getTableController();
838 	if( pController && pController->hasSelectedCells() )
839 	{
840 		CellPos aFirstPos, aLastPos;
841 		pController->getSelectedCells( aFirstPos, aLastPos );
842 
843 		const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
844 		const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
845 
846 		if( nSelectedChildIndex < (nSelectedRows * nSelectedColumns) )
847 		{
848 			while( nSelectedChildIndex >= nSelectedColumns )
849 			{
850 				aFirstPos.mnRow++;
851 				nSelectedChildIndex -= nSelectedColumns;
852 			}
853 			return getAccessibleCellAt( nSelectedColumns, aFirstPos.mnRow );
854 		}
855 	}
856 
857 	throw IndexOutOfBoundsException();
858 	*/
859 	if( nSelectedChildIndex < 0 )
860         throw IndexOutOfBoundsException();
861 
862 	sal_Int32 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex );
863 
864 	if( nChildIndex < 0 )
865         throw IndexOutOfBoundsException();
866 
867 	if ( nChildIndex >= getAccessibleChildCount() )
868     {
869         throw IndexOutOfBoundsException();
870     }
871 
872 	return getAccessibleChild( nChildIndex );
873 }
874 
875 //--------------------------------------------------------------------
876 
deselectAccessibleChild(sal_Int32 nChildIndex)877 void SAL_CALL AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex )  throw ( IndexOutOfBoundsException, RuntimeException )
878 {
879    ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
880 	CellPos aPos;
881 	mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
882 
883 	// todo, select table shape?!?
884 	SvxTableController* pController = getTableController();
885 	if( pController && pController->hasSelectedCells() )
886 	{
887 		CellPos aFirstPos, aLastPos;
888 		pController->getSelectedCells( aFirstPos, aLastPos );
889 
890 		// create a selection where aPos is not part of anymore
891 		aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow+1 );
892 		aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol+1 );
893 		aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow-1 );
894 		aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol-1 );
895 
896 		// new selection may be invalid (child to deselect is not at a border of the selection but in between)
897 		if( (aFirstPos.mnRow > aLastPos.mnRow) || (aFirstPos.mnCol > aLastPos.mnCol) )
898 			pController->clearSelection(); // if selection is invalid, clear all
899 		else
900 			pController->setSelectedCells( aFirstPos, aLastPos );
901 	}
902 }
903 //--------------------------------------------------------------------
904 
905 //=====  XAccessibleTableSelection  ============================================
selectRow(sal_Int32 row)906 sal_Bool SAL_CALL AccessibleTableShape::selectRow( sal_Int32 row )
907 throw (IndexOutOfBoundsException, RuntimeException)
908 {
909 	::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
910 	SvxTableController* pController = getTableController();
911 	if( !pController )
912 		return sal_False;
913 	return pController->selectRow( row );
914 }
selectColumn(sal_Int32 column)915 sal_Bool SAL_CALL AccessibleTableShape::selectColumn( sal_Int32 column )
916 throw (IndexOutOfBoundsException, RuntimeException)
917 {
918 	::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
919 	SvxTableController* pController = getTableController();
920 	if( !pController )
921 		return sal_False;
922 	return pController->selectColumn( column );
923 }
unselectRow(sal_Int32 row)924 sal_Bool SAL_CALL AccessibleTableShape::unselectRow( sal_Int32 row )
925 throw (IndexOutOfBoundsException, RuntimeException)
926 {
927 	::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
928 	SvxTableController* pController = getTableController();
929 	if( !pController )
930 		return sal_False;
931 	return pController->deselectRow( row );
932 }
unselectColumn(sal_Int32 column)933 sal_Bool SAL_CALL AccessibleTableShape::unselectColumn( sal_Int32 column )
934 throw (IndexOutOfBoundsException, RuntimeException)
935 {
936 	::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
937 	SvxTableController* pController = getTableController();
938 	if( !pController )
939 		return sal_False;
940 	return pController->deselectColumn( column );
941 }
GetIndexOfSelectedChild(sal_Int32 nSelectedChildIndex) const942 sal_Int32 AccessibleTableShape::GetIndexOfSelectedChild(
943 				sal_Int32 nSelectedChildIndex ) const
944 {
945     sal_Int32 nChildren = const_cast<AccessibleTableShape*>(this)->getAccessibleChildCount();
946 
947 	if( nSelectedChildIndex >= nChildren )
948 		return -1L;
949 
950     sal_Int32 n = 0;
951     while( n < nChildren )
952     {
953         if( const_cast<AccessibleTableShape*>(this)->isAccessibleChildSelected( n ) )
954 		{
955 			if( 0 == nSelectedChildIndex )
956 				break;
957 			else
958 				--nSelectedChildIndex;
959 		}
960         ++n;
961     }
962 
963 	return n < nChildren ? n : -1L;
964 }
getColumnAndRow(sal_Int32 nChildIndex,sal_Int32 & rnColumn,sal_Int32 & rnRow)965 void AccessibleTableShape::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException )
966 {
967 	mxImpl->getColumnAndRow(nChildIndex, rnColumn, rnRow);
968 }
969 //--------------------------------------------------------------------
970 // XSelectionChangeListener
971 void SAL_CALL
disposing(const EventObject & aEvent)972     AccessibleTableShape::disposing (const EventObject& aEvent)
973     throw (RuntimeException)
974 {
975 	AccessibleShape::disposing(aEvent);
976 }
selectionChanged(const EventObject & rEvent)977 void  SAL_CALL AccessibleTableShape::selectionChanged (const EventObject& rEvent)
978         throw (RuntimeException)
979 {
980 	//::sdr::table::CellRef xCellRef = static_cast< ::sdr::table::CellRef > (rEvent.Source);
981 	Reference< XCell > xCell(rEvent.Source, UNO_QUERY);
982 	if (xCell.is())
983 	{
984 		Reference< AccessibleCell > xAccCell = mxImpl->getAccessibleCell( xCell );
985 		if (xAccCell.is())
986 		{
987 			sal_Int32 nIndex = xAccCell->getAccessibleIndexInParent(),
988 				nCount = getSelectedAccessibleChildCount();
989 			sal_Bool bSelected = isAccessibleChildSelected(nIndex);
990 			if (mnPreviousSelectionCount == 0 && nCount > 0 && bSelected)
991 			{
992 				xAccCell->SetState(AccessibleStateType::SELECTED);
993 				xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED, Any(), Any());
994 			}
995 			else if (bSelected)
996 			{
997 				xAccCell->SetState(AccessibleStateType::SELECTED);
998 				xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_ADD, Any(), Any());
999 			}
1000 			else
1001 			{
1002 				xAccCell->ResetState(AccessibleStateType::SELECTED);
1003 				xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, Any(), Any());
1004 			}
1005 			mnPreviousSelectionCount = nCount;
1006 		}
1007 	}
1008 }
1009 // Get the currently active cell which is text editing
GetActiveAccessibleCell()1010 AccessibleCell* AccessibleTableShape::GetActiveAccessibleCell()
1011 {
1012 	sal_Bool bCellEditing = sal_False;
1013 	Reference< AccessibleCell > xAccCell;
1014 	AccessibleCell* pAccCell = NULL;
1015 	SvxTableController* pController = getTableController();
1016 	if (pController)
1017 	{
1018 		::sdr::table::SdrTableObj* pTableObj = pController->GetTableObj();
1019 		if ( pTableObj )
1020 		{
1021 			::sdr::table::CellRef xCellRef (pTableObj->getActiveCell());
1022 			if ( xCellRef.is() )
1023 			{
1024 				bCellEditing = xCellRef->IsTextEditActive();
1025 				if (bCellEditing)
1026 				{
1027 					//Reference< XCell > xCell(xCellRef.get(), UNO_QUERY);
1028 					xAccCell = mxImpl->getAccessibleCell(Reference< XCell >( xCellRef.get() ));
1029 					if (xAccCell.is())
1030 						pAccCell = xAccCell.get();
1031 				}
1032 			}
1033 		}
1034 	}
1035 	return pAccCell;
1036 }
1037 //--------------------------------------------------------------------
1038 //If current active cell is in editing, the focus state should be set to internal text
SetState(sal_Int16 aState)1039 sal_Bool AccessibleTableShape::SetState (sal_Int16 aState)
1040 {
1041     AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell();
1042     sal_Bool bStateHasChanged = sal_False;
1043     if (aState == AccessibleStateType::FOCUSED && pActiveAccessibleCell != NULL)
1044     {
1045 		return pActiveAccessibleCell->SetState(aState);
1046     }
1047     else
1048         bStateHasChanged = AccessibleShape::SetState (aState);
1049     return bStateHasChanged;
1050 }
1051 //--------------------------------------------------------------------
1052 //If current active cell is in editing, the focus state should be reset to internal text
ResetState(sal_Int16 aState)1053 sal_Bool AccessibleTableShape::ResetState (sal_Int16 aState)
1054 {
1055     AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell();
1056     sal_Bool bStateHasChanged = sal_False;
1057     if (aState == AccessibleStateType::FOCUSED && pActiveAccessibleCell != NULL)
1058     {
1059 		return pActiveAccessibleCell->ResetState(aState);
1060     }
1061     else
1062         bStateHasChanged = AccessibleShape::ResetState (aState);
1063     return bStateHasChanged;
1064 }
1065 //--------------------------------------------------------------------
SetStateDirectly(sal_Int16 aState)1066 sal_Bool AccessibleTableShape::SetStateDirectly (sal_Int16 aState)
1067 {
1068 	return AccessibleContextBase::SetState (aState);
1069 }
1070 //--------------------------------------------------------------------
ResetStateDirectly(sal_Int16 aState)1071 sal_Bool AccessibleTableShape::ResetStateDirectly (sal_Int16 aState)
1072 {
1073 	return AccessibleContextBase::ResetState (aState);
1074 }
checkCellPosition(sal_Int32 nCol,sal_Int32 nRow)1075 void AccessibleTableShape::checkCellPosition( sal_Int32 nCol, sal_Int32 nRow ) throw ( IndexOutOfBoundsException )
1076 {
1077 	if( (nCol >= 0) && (nRow >= 0) && mxImpl->mxTable.is() && (nCol < mxImpl->mxTable->getColumnCount()) && (nRow < mxImpl->mxTable->getRowCount()) )
1078 		return;
1079 
1080 	throw IndexOutOfBoundsException();
1081 }
1082 
AccessibleTableHeaderShape(AccessibleTableShape * pTable,sal_Bool bRow)1083 AccessibleTableHeaderShape::AccessibleTableHeaderShape( AccessibleTableShape* pTable, sal_Bool bRow )
1084 {
1085 	mpTable = pTable;
1086 	mbRow = bRow;
1087 }
1088 
~AccessibleTableHeaderShape(void)1089 AccessibleTableHeaderShape::~AccessibleTableHeaderShape (void)
1090 {
1091 	mpTable = NULL;
1092 }
1093 
1094 // XAccessible
getAccessibleContext(void)1095 Reference< XAccessibleContext > SAL_CALL AccessibleTableHeaderShape::getAccessibleContext(void) throw (RuntimeException)
1096 {
1097 	return this;
1098 }
1099 
1100 // XAccessibleContext
getAccessibleChildCount()1101 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleChildCount( ) throw(RuntimeException)
1102 {
1103 	return getAccessibleRowCount() * getAccessibleColumnCount();
1104 }
1105 
getAccessibleChild(sal_Int32 i)1106 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException)
1107 {
1108 	return mpTable->getAccessibleChild( i );
1109 }
1110 
getAccessibleParent(void)1111 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleParent (void) throw (RuntimeException)
1112 {
1113 	Reference< XAccessible > XParent;
1114     return XParent;
1115 }
1116 
getAccessibleIndexInParent(void)1117 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndexInParent (void) throw (RuntimeException)
1118 {
1119 	return -1;
1120 }
1121 
getAccessibleRole(void)1122 sal_Int16 SAL_CALL AccessibleTableHeaderShape::getAccessibleRole (void) throw (RuntimeException)
1123 {
1124 	return mpTable->getAccessibleRole();
1125 }
1126 
getAccessibleDescription(void)1127 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleDescription (void) throw (RuntimeException)
1128 {
1129     return mpTable->getAccessibleDescription();
1130 }
1131 
getAccessibleName(void)1132 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleName (void) throw (RuntimeException)
1133 {
1134 	return mpTable->getAccessibleName();
1135 }
1136 
getAccessibleStateSet(void)1137 Reference< XAccessibleStateSet > SAL_CALL AccessibleTableHeaderShape::getAccessibleStateSet (void) throw (RuntimeException)
1138 {
1139 	return mpTable->getAccessibleStateSet();
1140 }
1141 
getAccessibleRelationSet(void)1142 Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableHeaderShape::getAccessibleRelationSet (void) throw (RuntimeException)
1143 {
1144 	return mpTable->getAccessibleRelationSet();
1145 }
1146 
getLocale(void)1147 Locale SAL_CALL AccessibleTableHeaderShape::getLocale (void) throw (IllegalAccessibleComponentStateException, RuntimeException)
1148 {
1149 	return mpTable->getLocale();
1150 }
1151 
1152 //XAccessibleComponent
containsPoint(const::com::sun::star::awt::Point & aPoint)1153 sal_Bool SAL_CALL AccessibleTableHeaderShape::containsPoint ( const ::com::sun::star::awt::Point& aPoint ) throw (RuntimeException)
1154 {
1155 	return mpTable->containsPoint( aPoint );
1156 }
1157 
getAccessibleAtPoint(const::com::sun::star::awt::Point & aPoint)1158 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw (RuntimeException)
1159 {
1160 	return mpTable->getAccessibleAtPoint( aPoint );
1161 }
1162 
getBounds(void)1163 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleTableHeaderShape::getBounds (void) throw (RuntimeException)
1164 {
1165 	return mpTable->getBounds();
1166 }
1167 
getLocation(void)1168 ::com::sun::star::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocation (void) throw (RuntimeException)
1169 {
1170 	return mpTable->getLocation();
1171 }
1172 
getLocationOnScreen(void)1173 ::com::sun::star::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocationOnScreen (void) throw (RuntimeException)
1174 {
1175 	return mpTable->getLocationOnScreen();
1176 }
1177 
getSize(void)1178 ::com::sun::star::awt::Size SAL_CALL AccessibleTableHeaderShape::getSize (void) throw (RuntimeException)
1179 {
1180 	return mpTable->getSize();
1181 }
1182 
getForeground(void)1183 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getForeground (void) throw (RuntimeException)
1184 {
1185     return mpTable->getForeground();
1186 }
1187 
getBackground(void)1188 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getBackground (void) throw (RuntimeException)
1189 {
1190     return mpTable->getBackground();
1191 }
1192 
grabFocus(void)1193 void SAL_CALL AccessibleTableHeaderShape::grabFocus (void) throw (RuntimeException)
1194 {
1195 	mpTable->grabFocus();
1196 }
1197 //=====  XAccessibleTable  ============================================
1198 
getAccessibleRowCount()1199 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowCount() throw (RuntimeException)
1200 {
1201 	return mbRow ? 1 : mpTable->getAccessibleRowCount();
1202 }
1203 
getAccessibleColumnCount()1204 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnCount() throw (RuntimeException)
1205 {
1206     return !mbRow ? 1 : mpTable->getAccessibleColumnCount();
1207 }
1208 
getAccessibleRowDescription(sal_Int32 nRow)1209 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
1210 {
1211 	return mpTable->getAccessibleRowDescription( nRow );
1212 }
1213 
getAccessibleColumnDescription(sal_Int32 nColumn)1214 OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1215 {
1216     return mpTable->getAccessibleColumnDescription( nColumn );
1217 }
1218 
getAccessibleRowExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1219 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1220 {
1221 	return mpTable->getAccessibleRowExtentAt( nRow, nColumn );
1222 }
1223 
getAccessibleColumnExtentAt(sal_Int32 nRow,sal_Int32 nColumn)1224 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1225 {
1226 	return mpTable->getAccessibleColumnExtentAt( nRow, nColumn );
1227 }
1228 
getAccessibleRowHeaders()1229 Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleRowHeaders(  ) throw (RuntimeException)
1230 {
1231 	Reference< XAccessibleTable > xRet;
1232 	return xRet;
1233 }
1234 
getAccessibleColumnHeaders()1235 Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnHeaders(  ) throw (RuntimeException)
1236 {
1237 	Reference< XAccessibleTable > xRet;
1238 	return xRet;
1239 }
1240 
getSelectedAccessibleRows()1241 Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleRows(  ) throw (RuntimeException)
1242 {
1243 	sal_Int32 nRow = getAccessibleRowCount();
1244 	::std::vector< sal_Bool > aSelected( nRow, sal_True );
1245 	sal_Int32 nCount = nRow;
1246 	for( sal_Int32 i = 0; i < nRow; i++ )
1247 	{
1248 		try
1249 		{
1250 			aSelected[i] = isAccessibleRowSelected( i );
1251 		}
1252 		catch( ... )
1253 		{
1254 			return Sequence< sal_Int32 >();
1255 		}
1256 
1257 		if( !aSelected[i] )
1258 			nCount--;
1259 	}
1260 	Sequence < sal_Int32 > aRet( nCount );
1261 	sal_Int32 *pRet = aRet.getArray();
1262 	sal_Int32 nPos = 0;
1263 	size_t nSize = aSelected.size();
1264 	for( size_t i=0; i < nSize && nPos < nCount; i++ )
1265 	{
1266 		if( aSelected[i] )
1267 		{
1268 			*pRet++ = i;
1269 			nPos++;
1270 		}
1271 	}
1272 
1273 	return aRet;
1274 }
1275 
getSelectedAccessibleColumns()1276 Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleColumns(  ) throw (RuntimeException)
1277 {
1278 	sal_Int32 nColumn = getAccessibleColumnCount();
1279 	::std::vector< sal_Bool > aSelected( nColumn, sal_True );
1280 	sal_Int32 nCount = nColumn;
1281 	for( sal_Int32 i = 0; i < nColumn; i++ )
1282 	{
1283 		try
1284 		{
1285 			aSelected[i] = isAccessibleColumnSelected( i );
1286 		}
1287 		catch( ... )
1288 		{
1289 			return Sequence< sal_Int32 >();
1290 		}
1291 
1292 		if( !aSelected[i] )
1293 			nCount--;
1294 	}
1295 	Sequence < sal_Int32 > aRet( nCount );
1296 	sal_Int32 *pRet = aRet.getArray();
1297 	sal_Int32 nPos = 0;
1298 	size_t nSize = aSelected.size();
1299 	for( size_t i=0; i < nSize && nPos < nCount; i++ )
1300 	{
1301 		if( aSelected[i] )
1302 		{
1303 			*pRet++ = i;
1304 			nPos++;
1305 		}
1306 	}
1307 
1308 	return aRet;
1309 }
1310 
isAccessibleRowSelected(sal_Int32 nRow)1311 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
1312 {
1313 	return mpTable->isAccessibleRowSelected( nRow );
1314 }
1315 
isAccessibleColumnSelected(sal_Int32 nColumn)1316 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1317 {
1318 	return mpTable->isAccessibleColumnSelected( nColumn );
1319 }
1320 
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)1321 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1322 {
1323 	return mpTable->getAccessibleCellAt( nRow, nColumn );
1324 }
1325 
getAccessibleCaption()1326 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCaption(  ) throw (RuntimeException)
1327 {
1328 	return mpTable->getAccessibleCaption();
1329 }
1330 
getAccessibleSummary()1331 Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleSummary(  ) throw (RuntimeException)
1332 {
1333 	return mpTable->getAccessibleSummary();
1334 }
1335 
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)1336 sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1337 {
1338 	return mpTable->isAccessibleSelected( nRow, nColumn );
1339 }
1340 
getAccessibleIndex(sal_Int32 nRow,sal_Int32 nColumn)1341 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
1342 {
1343 	return mpTable->getAccessibleIndex( nRow, nColumn );
1344 }
1345 
getAccessibleRow(sal_Int32 nChildIndex)1346 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1347 {
1348 	return mpTable->getAccessibleRow( nChildIndex );
1349 }
1350 
getAccessibleColumn(sal_Int32 nChildIndex)1351 sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1352 {
1353 	return mpTable->getAccessibleColumn( nChildIndex );
1354 }
1355 
1356 //=====  XAccessibleTableSelection  ============================================
selectRow(sal_Int32 row)1357 sal_Bool SAL_CALL AccessibleTableHeaderShape::selectRow( sal_Int32 row )
1358 throw (IndexOutOfBoundsException, RuntimeException)
1359 {
1360 	if( mbRow )
1361 		return mpTable->selectRow( row );
1362 	else
1363 	{
1364 		mpTable->clearAccessibleSelection();
1365 		sal_Int32 nIndex = mpTable->getAccessibleIndex( row, 0 );
1366 		mpTable->selectAccessibleChild( nIndex );
1367 		return sal_True;
1368 	}
1369 }
1370 
selectColumn(sal_Int32 column)1371 sal_Bool SAL_CALL AccessibleTableHeaderShape::selectColumn( sal_Int32 column )
1372 throw (IndexOutOfBoundsException, RuntimeException)
1373 {
1374 	if( !mbRow )
1375 		return mpTable->selectColumn( column );
1376 	else
1377 	{
1378 		mpTable->clearAccessibleSelection();
1379 		sal_Int32 nIndex = mpTable->getAccessibleIndex( 0, column );
1380 		mpTable->selectAccessibleChild( nIndex );
1381 		return sal_True;
1382 	}
1383 }
1384 
unselectRow(sal_Int32 row)1385 sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectRow( sal_Int32 row )
1386 throw (IndexOutOfBoundsException, RuntimeException)
1387 {
1388 	if( mbRow )
1389 		return mpTable->unselectRow( row );
1390 	else
1391 	{
1392 		sal_Int32 nIndex = mpTable->getAccessibleIndex( row, 0 );
1393 		mpTable->deselectAccessibleChild( nIndex );
1394 		return sal_True;
1395 	}
1396 }
1397 
unselectColumn(sal_Int32 column)1398 sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectColumn( sal_Int32 column )
1399 throw (IndexOutOfBoundsException, RuntimeException)
1400 {
1401 	if( !mbRow )
1402 		return mpTable->unselectColumn( column );
1403 	else
1404 	{
1405 		sal_Int32 nIndex = mpTable->getAccessibleIndex( 0, column );
1406 		mpTable->deselectAccessibleChild( nIndex );
1407 		return sal_True;
1408 	}
1409 }
1410 }
1411