xref: /trunk/main/svx/source/table/accessibletableshape.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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 //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