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