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