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