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