1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/table/XMergeableCell.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <comphelper/accessiblewrapper.hxx>
26 #include <osl/mutex.hxx>
27 #include <vcl/svapp.hxx>
29 #include <svx/AccessibleTableShape.hxx>
30 #include <svx/sdr/table/tablecontroller.hxx>
31 #include "accessiblecell.hxx"
35 #include <cppuhelper/implbase1.hxx>
38 using namespace ::accessibility
;
39 using namespace ::sdr::table
;
40 using namespace ::com::sun::star::accessibility
;
41 using namespace ::com::sun::star::uno
;
42 using namespace ::com::sun::star::beans
;
43 using namespace ::com::sun::star::util
;
44 using namespace ::com::sun::star::lang
;
45 using namespace ::com::sun::star::drawing
;
46 using namespace ::com::sun::star::table
;
47 using namespace ::com::sun::star::container
;
49 namespace accessibility
54 std::size_t operator()( const Reference
< XCell
>& xCell
) const
56 return std::size_t( xCell
.get() );
60 typedef boost::unordered_map
< Reference
< XCell
>, rtl::Reference
< AccessibleCell
>, hash
> AccessibleCellMap
;
62 //-----------------------------------------------------------------------------
63 // AccessibleTableShapeImpl
64 //-----------------------------------------------------------------------------
66 class AccessibleTableShapeImpl
: public cppu::WeakImplHelper1
< XModifyListener
>
69 AccessibleTableShapeImpl( AccessibleShapeTreeInfo
& rShapeTreeInfo
);
71 void init( const Reference
< XAccessible
>& xAccessible
, const Reference
< XTable
>& xTable
);
74 Reference
< XAccessible
> getAccessibleChild( sal_Int32 i
) throw(IndexOutOfBoundsException
);
75 void getColumnAndRow( sal_Int32 nChildIndex
, sal_Int32
& rnColumn
, sal_Int32
& rnRow
) throw (IndexOutOfBoundsException
);
78 virtual void SAL_CALL
modified( const EventObject
& aEvent
) throw (RuntimeException
);
81 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
83 AccessibleShapeTreeInfo
& mrShapeTreeInfo
;
84 Reference
< XTable
> mxTable
;
85 AccessibleCellMap maChildMap
;
86 Reference
< XAccessible
> mxAccessible
;
89 //-----------------------------------------------------------------------------
91 AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo
& rShapeTreeInfo
)
92 : mrShapeTreeInfo( rShapeTreeInfo
)
96 //-----------------------------------------------------------------------------
98 void AccessibleTableShapeImpl::init( const Reference
< XAccessible
>& xAccessible
, const Reference
< XTable
>& xTable
)
100 mxAccessible
= xAccessible
;
105 Reference
< XModifyListener
> xListener( this );
106 mxTable
->addModifyListener( xListener
);
110 //-----------------------------------------------------------------------------
112 void AccessibleTableShapeImpl::dispose()
116 //remove all the cell's acc object in table's dispose.
117 for( AccessibleCellMap::iterator
iter( maChildMap
.begin() ); iter
!= maChildMap
.end(); iter
++ )
119 (*iter
).second
->dispose();
122 Reference
< XModifyListener
> xListener( this );
123 mxTable
->removeModifyListener( xListener
);
126 mxAccessible
.clear();
129 //-----------------------------------------------------------------------------
131 Reference
< XAccessible
> AccessibleTableShapeImpl::getAccessibleChild( sal_Int32 nChildIndex
) throw(IndexOutOfBoundsException
)
133 sal_Int32 nColumn
= 0, nRow
= 0;
134 getColumnAndRow( nChildIndex
, nColumn
, nRow
);
136 Reference
< XCell
> xCell( mxTable
->getCellByPosition( nColumn
, nRow
) );
137 AccessibleCellMap::iterator
iter( maChildMap
.find( xCell
) );
139 if( iter
!= maChildMap
.end() )
141 Reference
< XAccessible
> xChild( (*iter
).second
.get() );
146 CellRef
xCellRef( dynamic_cast< Cell
* >( xCell
.get() ) );
148 rtl::Reference
< AccessibleCell
> xAccessibleCell( new AccessibleCell( mxAccessible
, xCellRef
, nChildIndex
, mrShapeTreeInfo
) );
150 maChildMap
[xCell
] = xAccessibleCell
;
152 xAccessibleCell
->Init();
154 Reference
< XAccessible
> xChild( xAccessibleCell
.get() );
159 //-----------------------------------------------------------------------------
161 void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex
, sal_Int32
& rnColumn
, sal_Int32
& rnRow
) throw (IndexOutOfBoundsException
)
164 rnColumn
= nChildIndex
;
168 const sal_Int32 nColumnCount
= mxTable
->getColumnCount();
169 while( rnColumn
>= nColumnCount
)
172 rnColumn
-= nColumnCount
;
175 if( rnRow
< mxTable
->getRowCount() )
179 throw IndexOutOfBoundsException();
183 void SAL_CALL
AccessibleTableShapeImpl::modified( const EventObject
& /*aEvent*/ ) throw (RuntimeException
)
185 if( mxTable
.is() ) try
187 // structural changes may have happened to the table, validate all accessible cell instances
188 AccessibleCellMap aTempChildMap
;
189 aTempChildMap
.swap( maChildMap
);
191 // first move all still existing cells to maChildMap again and update their index
193 const sal_Int32 nRowCount
= mxTable
->getRowCount();
194 const sal_Int32 nColCount
= mxTable
->getColumnCount();
196 sal_Int32 nChildIndex
= 0;
198 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; ++nRow
)
200 for( sal_Int32 nCol
= 0; nCol
< nColCount
; ++nCol
)
202 Reference
< XCell
> xCell( mxTable
->getCellByPosition( nCol
, nRow
) );
203 AccessibleCellMap::iterator
iter( aTempChildMap
.find( xCell
) );
205 if( iter
!= aTempChildMap
.end() )
207 rtl::Reference
< AccessibleCell
> xAccessibleCell( (*iter
).second
);
208 xAccessibleCell
->setIndexInParent( nChildIndex
);
209 xAccessibleCell
->CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED
, Any(), Any());
211 // move still existing cell from temporary child map to our child map
212 maChildMap
[xCell
] = xAccessibleCell
;
213 aTempChildMap
.erase( iter
);
220 // all accessible cell instances still left in aTempChildMap must be disposed
221 // as they are no longer part of the table
223 for( AccessibleCellMap::iterator
iter( aTempChildMap
.begin() ); iter
!= aTempChildMap
.end(); ++iter
)
225 (*iter
).second
->dispose();
230 OSL_FAIL("svx::AccessibleTableShape::modified(), exception caught!");
235 void SAL_CALL
AccessibleTableShapeImpl::disposing( const EventObject
& /*Source*/ ) throw (RuntimeException
)
239 //-----------------------------------------------------------------------------
240 // AccessibleTableShape
241 //-----------------------------------------------------------------------------
243 //-----------------------------------------------------------------------------
245 AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo
& rShapeInfo
, const AccessibleShapeTreeInfo
& rShapeTreeInfo
)
246 : AccessibleTableShape_Base(rShapeInfo
, rShapeTreeInfo
)
247 , mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo
) )
251 //-----------------------------------------------------------------------------
253 AccessibleTableShape::~AccessibleTableShape (void)
257 //-----------------------------------------------------------------------------
259 void AccessibleTableShape::Init()
264 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY_THROW
);
265 Reference
< XTable
> xTable( xSet
->getPropertyValue("Model"), UNO_QUERY_THROW
);
267 mxImpl
->init( this, xTable
);
271 OSL_FAIL("AccessibleTableShape::init(), exception caught?");
274 AccessibleTableShape_Base::Init();
277 //-----------------------------------------------------------------------------
279 SvxTableController
* AccessibleTableShape::getTableController()
281 SdrView
* pView
= maShapeTreeInfo
.GetSdrView ();
283 return dynamic_cast< SvxTableController
* >( pView
->getSelectionController().get() );
288 //-----------------------------------------------------------------------------
290 //-----------------------------------------------------------------------------
292 Any SAL_CALL
AccessibleTableShape::queryInterface( const Type
& aType
) throw (RuntimeException
)
294 return AccessibleTableShape_Base::queryInterface( aType
);
297 //-----------------------------------------------------------------------------
299 void SAL_CALL
AccessibleTableShape::acquire( ) throw ()
301 AccessibleTableShape_Base::acquire();
304 //-----------------------------------------------------------------------------
306 void SAL_CALL
AccessibleTableShape::release( ) throw ()
308 AccessibleTableShape_Base::release();
311 //-----------------------------------------------------------------------------
313 //-----------------------------------------------------------------------------
315 Reference
< XAccessibleContext
> SAL_CALL
AccessibleTableShape::getAccessibleContext(void) throw (RuntimeException
)
317 return AccessibleShape::getAccessibleContext ();
320 //-----------------------------------------------------------------------------
321 OUString SAL_CALL
AccessibleTableShape::getImplementationName(void) throw (RuntimeException
)
323 return OUString( "com.sun.star.comp.accessibility.AccessibleTableShape" );
326 //-----------------------------------------------------------------------------
328 OUString
AccessibleTableShape::CreateAccessibleBaseName(void) throw (RuntimeException
)
330 return OUString("TableShape");
333 //--------------------------------------------------------------------
335 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException
)
337 SolarMutexGuard aSolarGuard
;
338 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getRowCount() * mxImpl
->mxTable
->getColumnCount() : 0;
341 //--------------------------------------------------------------------
342 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleChild( sal_Int32 i
) throw(IndexOutOfBoundsException
, RuntimeException
)
344 SolarMutexGuard aSolarGuard
;
347 return mxImpl
->getAccessibleChild( i
);
350 //--------------------------------------------------------------------
351 Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleTableShape::getAccessibleRelationSet( ) throw (RuntimeException
)
353 return AccessibleShape::getAccessibleRelationSet( );
356 //--------------------------------------------------------------------
358 sal_Int16 SAL_CALL
AccessibleTableShape::getAccessibleRole (void) throw (RuntimeException
)
360 return AccessibleRole::TABLE
;
363 //--------------------------------------------------------------------
365 void SAL_CALL
AccessibleTableShape::disposing (void)
369 // let the base do it's stuff
370 AccessibleShape::disposing();
373 //--------------------------------------------------------------------
375 //--------------------------------------------------------------------
377 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException
)
379 SolarMutexGuard aSolarGuard
;
380 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getRowCount() : 0;
383 //--------------------------------------------------------------------
385 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumnCount( ) throw (RuntimeException
)
387 SolarMutexGuard aSolarGuard
;
388 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getColumnCount() : 0;
391 //--------------------------------------------------------------------
393 OUString SAL_CALL
AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
)
395 checkCellPosition( 0, nRow
);
399 //--------------------------------------------------------------------
401 OUString SAL_CALL
AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
403 SolarMutexGuard aSolarGuard
;
404 checkCellPosition( nColumn
, 0 );
408 //--------------------------------------------------------------------
410 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
412 SolarMutexGuard aSolarGuard
;
413 checkCellPosition( nColumn
, nRow
);
414 if( mxImpl
->mxTable
.is() )
416 Reference
< XMergeableCell
> xCell( mxImpl
->mxTable
->getCellByPosition( nColumn
, nRow
), UNO_QUERY
);
418 return xCell
->getRowSpan();
423 //--------------------------------------------------------------------
425 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
427 SolarMutexGuard aSolarGuard
;
428 checkCellPosition( nColumn
, nRow
);
429 if( mxImpl
->mxTable
.is() )
431 Reference
< XMergeableCell
> xCell( mxImpl
->mxTable
->getCellByPosition( nColumn
, nRow
), UNO_QUERY
);
433 return xCell
->getColumnSpan();
438 //--------------------------------------------------------------------
440 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableShape::getAccessibleRowHeaders( ) throw (RuntimeException
)
442 Reference
< XAccessibleTable
> xRet( this ); // todo
446 //--------------------------------------------------------------------
448 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableShape::getAccessibleColumnHeaders( ) throw (RuntimeException
)
450 Reference
< XAccessibleTable
> xRet( this ); // todo
454 //--------------------------------------------------------------------
456 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleRows( ) throw (RuntimeException
)
458 Sequence
< sal_Int32
> aRet
;
462 //--------------------------------------------------------------------
464 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleColumns( ) throw (RuntimeException
)
466 Sequence
< sal_Int32
> aRet
;
470 //--------------------------------------------------------------------
472 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
)
474 SolarMutexGuard aSolarGuard
;
475 checkCellPosition( 0, nRow
);
479 //--------------------------------------------------------------------
481 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
483 SolarMutexGuard aSolarGuard
;
484 checkCellPosition( nColumn
, 0 );
488 //--------------------------------------------------------------------
490 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
492 SolarMutexGuard aSolarGuard
;
493 checkCellPosition( nColumn
, nRow
);
495 sal_Int32 nChildIndex
= 0;
496 if( mxImpl
->mxTable
.is() )
497 nChildIndex
= mxImpl
->mxTable
->getColumnCount() * nRow
+ nColumn
;
499 return getAccessibleChild( nChildIndex
);
502 //--------------------------------------------------------------------
504 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleCaption( ) throw (RuntimeException
)
506 Reference
< XAccessible
> xRet
;
510 //--------------------------------------------------------------------
512 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleSummary( ) throw (RuntimeException
)
514 Reference
< XAccessible
> xRet
;
518 //--------------------------------------------------------------------
520 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
522 SolarMutexGuard aSolarGuard
;
523 checkCellPosition( nColumn
, nRow
);
525 SvxTableController
* pController
= getTableController();
526 if( pController
&& pController
->hasSelectedCells() )
528 CellPos aFirstPos
, aLastPos
;
529 pController
->getSelectedCells( aFirstPos
, aLastPos
);
530 if( (aFirstPos
.mnRow
<= nRow
) && (aFirstPos
.mnCol
<= nColumn
) && (nRow
<= aLastPos
.mnRow
) && (nColumn
<= aLastPos
.mnCol
) )
537 //--------------------------------------------------------------------
539 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
)
541 SolarMutexGuard aSolarGuard
;
542 checkCellPosition( nColumn
, nRow
);
543 return mxImpl
->mxTable
.is() ? (nRow
* mxImpl
->mxTable
->getColumnCount() + nColumn
) : 0;
546 //--------------------------------------------------------------------
548 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
550 SolarMutexGuard aSolarGuard
;
551 sal_Int32 nColumn
= 0, nRow
= 0;
552 mxImpl
->getColumnAndRow( nChildIndex
, nColumn
, nRow
);
556 //--------------------------------------------------------------------
558 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
560 SolarMutexGuard aSolarGuard
;
561 sal_Int32 nColumn
= 0, nRow
= 0;
562 mxImpl
->getColumnAndRow( nChildIndex
, nColumn
, nRow
);
566 //--------------------------------------------------------------------
567 // XAccessibleSelection
568 //--------------------------------------------------------------------
570 void SAL_CALL
AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
)
572 SolarMutexGuard aSolarGuard
;
574 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
576 // todo, select table shape?!?
577 SvxTableController
* pController
= getTableController();
580 CellPos
aFirstPos( aPos
), aLastPos( aPos
);
581 if( pController
->hasSelectedCells() )
583 pController
->getSelectedCells( aFirstPos
, aLastPos
);
585 aFirstPos
.mnRow
= std::min( aFirstPos
.mnRow
, aPos
.mnRow
);
586 aFirstPos
.mnCol
= std::min( aFirstPos
.mnCol
, aPos
.mnCol
);
587 aLastPos
.mnRow
= std::max( aLastPos
.mnRow
, aPos
.mnRow
);
588 aLastPos
.mnCol
= std::max( aLastPos
.mnCol
, aPos
.mnCol
);
590 pController
->setSelectedCells( aFirstPos
, aLastPos
);
594 //--------------------------------------------------------------------
596 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
)
598 SolarMutexGuard aSolarGuard
;
600 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
602 return isAccessibleSelected(aPos
.mnCol
, aPos
.mnRow
);
605 //--------------------------------------------------------------------
607 void SAL_CALL
AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException
)
609 SolarMutexGuard aSolarGuard
;
611 SvxTableController
* pController
= getTableController();
613 pController
->clearSelection();
615 //--------------------------------------------------------------------
617 void SAL_CALL
AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException
)
619 SolarMutexGuard aSolarGuard
;
621 // todo: force selection of shape?
622 SvxTableController
* pController
= getTableController();
624 pController
->selectAll();
627 //--------------------------------------------------------------------
629 sal_Int32 SAL_CALL
AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException
)
631 SolarMutexGuard aSolarGuard
;
633 SvxTableController
* pController
= getTableController();
634 if( pController
&& pController
->hasSelectedCells() )
636 CellPos aFirstPos
, aLastPos
;
637 pController
->getSelectedCells( aFirstPos
, aLastPos
);
639 const sal_Int32 nSelectedColumns
= std::max( (sal_Int32
)0, aLastPos
.mnCol
- aFirstPos
.mnCol
) + 1;
640 const sal_Int32 nSelectedRows
= std::max( (sal_Int32
)0, aLastPos
.mnRow
- aFirstPos
.mnRow
) + 1;
641 return nSelectedRows
* nSelectedColumns
;
647 //--------------------------------------------------------------------
649 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
)
651 SolarMutexGuard aSolarGuard
;
653 SvxTableController
* pController
= getTableController();
654 if( pController
&& pController
->hasSelectedCells() )
656 CellPos aFirstPos
, aLastPos
;
657 pController
->getSelectedCells( aFirstPos
, aLastPos
);
659 const sal_Int32 nSelectedColumns
= std::max( (sal_Int32
)0, aLastPos
.mnCol
- aFirstPos
.mnCol
) + 1;
660 const sal_Int32 nSelectedRows
= std::max( (sal_Int32
)0, aLastPos
.mnRow
- aFirstPos
.mnRow
) + 1;
662 if( nSelectedChildIndex
< (nSelectedRows
* nSelectedColumns
) )
664 while( nSelectedChildIndex
>= nSelectedColumns
)
667 nSelectedChildIndex
-= nSelectedColumns
;
669 return getAccessibleCellAt( nSelectedColumns
, aFirstPos
.mnRow
);
673 throw IndexOutOfBoundsException();
676 //--------------------------------------------------------------------
678 void SAL_CALL
AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
)
680 SolarMutexGuard aSolarGuard
;
682 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
684 // todo, select table shape?!?
685 SvxTableController
* pController
= getTableController();
686 if( pController
&& pController
->hasSelectedCells() )
688 CellPos aFirstPos
, aLastPos
;
689 pController
->getSelectedCells( aFirstPos
, aLastPos
);
691 // create a selection where aPos is not part of anymore
692 aFirstPos
.mnRow
= std::min( aFirstPos
.mnRow
, aPos
.mnRow
+1 );
693 aFirstPos
.mnCol
= std::min( aFirstPos
.mnCol
, aPos
.mnCol
+1 );
694 aLastPos
.mnRow
= std::max( aLastPos
.mnRow
, aPos
.mnRow
-1 );
695 aLastPos
.mnCol
= std::max( aLastPos
.mnCol
, aPos
.mnCol
-1 );
697 // new selection may be invalid (child to deselect is not at a border of the selection but in between)
698 if( (aFirstPos
.mnRow
> aLastPos
.mnRow
) || (aFirstPos
.mnCol
> aLastPos
.mnCol
) )
699 pController
->clearSelection(); // if selection is invalid, clear all
701 pController
->setSelectedCells( aFirstPos
, aLastPos
);
705 //--------------------------------------------------------------------
707 void AccessibleTableShape::checkCellPosition( sal_Int32 nCol
, sal_Int32 nRow
) throw ( IndexOutOfBoundsException
)
709 if( (nCol
>= 0) && (nRow
>= 0) && mxImpl
->mxTable
.is() && (nCol
< mxImpl
->mxTable
->getColumnCount()) && (nRow
< mxImpl
->mxTable
->getRowCount()) )
712 throw IndexOutOfBoundsException();
717 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */