Update ooo320-m1
[ooovba.git] / svx / source / table / accessibletableshape.cxx
blob0c6beba8227097ddee6a0bcfed0af2b8de57a3da
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accessibletableshape.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <com/sun/star/table/XMergeableCell.hpp>
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <comphelper/accessiblewrapper.hxx>
39 #include <vos/mutex.hxx>
40 #include <tools/debug.hxx>
41 #include <vcl/svapp.hxx>
43 #include <svx/AccessibleTableShape.hxx>
44 #include "tablecontroller.hxx"
45 #include "accessiblecell.hxx"
47 #include <algorithm>
49 #include <cppuhelper/implbase1.hxx>
51 using ::rtl::OUString;
53 using namespace ::accessibility;
54 using namespace ::sdr::table;
55 using namespace ::com::sun::star::accessibility;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::util;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::drawing;
61 using namespace ::com::sun::star::table;
62 using namespace ::com::sun::star::container;
64 #define C2U(x) OUString(RTL_CONSTASCII_USTRINGPARAM(x))
66 namespace accessibility
69 struct hash
71 std::size_t operator()( const Reference< XCell >& xCell ) const
73 return std::size_t( xCell.get() );
77 typedef std::hash_map< Reference< XCell >, rtl::Reference< AccessibleCell >, hash > AccessibleCellMap;
79 //-----------------------------------------------------------------------------
80 // AccessibleTableShapeImpl
81 //-----------------------------------------------------------------------------
83 class AccessibleTableShapeImpl : public cppu::WeakImplHelper1< XModifyListener >
85 public:
86 AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo );
88 void init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable );
89 void dispose();
91 Reference< XAccessible > getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException);
92 void getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException );
94 // XModifyListener
95 virtual void SAL_CALL modified( const EventObject& aEvent ) throw (RuntimeException);
97 // XEventListener
98 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
100 AccessibleShapeTreeInfo& mrShapeTreeInfo;
101 Reference< XTable > mxTable;
102 AccessibleCellMap maChildMap;
103 Reference< XAccessible> mxAccessible;
106 //-----------------------------------------------------------------------------
108 AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo )
109 : mrShapeTreeInfo( rShapeTreeInfo )
113 //-----------------------------------------------------------------------------
115 void AccessibleTableShapeImpl::init( const Reference< XAccessible>& xAccessible, const Reference< XTable >& xTable )
117 mxAccessible = xAccessible;
118 mxTable = xTable;
120 if( mxTable.is() )
122 Reference< XModifyListener > xListener( this );
123 mxTable->addModifyListener( xListener );
127 //-----------------------------------------------------------------------------
129 void AccessibleTableShapeImpl::dispose()
131 if( mxTable.is() )
133 Reference< XModifyListener > xListener( this );
134 mxTable->removeModifyListener( xListener );
135 mxTable.clear();
137 mxAccessible.clear();
140 //-----------------------------------------------------------------------------
142 Reference< XAccessible > AccessibleTableShapeImpl::getAccessibleChild( sal_Int32 nChildIndex ) throw(IndexOutOfBoundsException)
144 sal_Int32 nColumn = 0, nRow = 0;
145 getColumnAndRow( nChildIndex, nColumn, nRow );
147 Reference< XCell > xCell( mxTable->getCellByPosition( nColumn, nRow ) );
148 AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
150 if( iter != maChildMap.end() )
152 Reference< XAccessible > xChild( (*iter).second.get() );
153 return xChild;
155 else
157 CellRef xCellRef( dynamic_cast< Cell* >( xCell.get() ) );
159 rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCellRef, nChildIndex, mrShapeTreeInfo ) );
161 maChildMap[xCell] = xAccessibleCell;
163 xAccessibleCell->Init();
165 Reference< XAccessible > xChild( xAccessibleCell.get() );
166 return xChild;
170 //-----------------------------------------------------------------------------
172 void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow ) throw (IndexOutOfBoundsException )
174 rnRow = 0;
175 rnColumn = nChildIndex;
177 if( mxTable.is() )
179 const sal_Int32 nColumnCount = mxTable->getColumnCount();
180 while( rnColumn >= nColumnCount )
182 rnRow++;
183 rnColumn -= nColumnCount;
186 if( rnRow < mxTable->getRowCount() )
187 return;
190 throw IndexOutOfBoundsException();
193 // XModifyListener
194 void SAL_CALL AccessibleTableShapeImpl::modified( const EventObject& /*aEvent*/ ) throw (RuntimeException)
196 if( mxTable.is() ) try
198 // structural changes may have happened to the table, validate all accessible cell instances
199 AccessibleCellMap aTempChildMap;
200 aTempChildMap.swap( maChildMap );
202 // first move all still existing cells to maChildMap again and update their index
204 const sal_Int32 nRowCount = mxTable->getRowCount();
205 const sal_Int32 nColCount = mxTable->getColumnCount();
207 sal_Int32 nChildIndex = 0;
209 for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
211 for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
213 Reference< XCell > xCell( mxTable->getCellByPosition( nCol, nRow ) );
214 AccessibleCellMap::iterator iter( aTempChildMap.find( xCell ) );
216 if( iter != aTempChildMap.end() )
218 rtl::Reference< AccessibleCell > xAccessibleCell( (*iter).second );
219 xAccessibleCell->setIndexInParent( nChildIndex );
220 xAccessibleCell->CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
222 // move still existing cell from temporary child map to our child map
223 maChildMap[xCell] = xAccessibleCell;
224 aTempChildMap.erase( iter );
227 ++nChildIndex;
231 // all accessible cell instances still left in aTempChildMap must be disposed
232 // as they are no longer part of the table
234 for( AccessibleCellMap::iterator iter( aTempChildMap.begin() ); iter != aTempChildMap.end(); iter++ )
236 (*iter).second->dispose();
239 catch( Exception& )
241 DBG_ERROR("svx::AccessibleTableShape::modified(), exception caught!");
245 // XEventListener
246 void SAL_CALL AccessibleTableShapeImpl::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
250 //-----------------------------------------------------------------------------
251 // AccessibleTableShape
252 //-----------------------------------------------------------------------------
254 //-----------------------------------------------------------------------------
256 AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo& rShapeInfo, const AccessibleShapeTreeInfo& rShapeTreeInfo)
257 : AccessibleTableShape_Base(rShapeInfo, rShapeTreeInfo)
258 , mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo ) )
262 //-----------------------------------------------------------------------------
264 AccessibleTableShape::~AccessibleTableShape (void)
268 //-----------------------------------------------------------------------------
270 void AccessibleTableShape::Init()
275 Reference< XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
276 Reference< XTable > xTable( xSet->getPropertyValue(C2U("Model")), UNO_QUERY_THROW );
278 mxImpl->init( this, xTable );
280 catch( Exception& )
282 DBG_ERROR("AccessibleTableShape::init(), exception caught?");
285 AccessibleTableShape_Base::Init();
288 //-----------------------------------------------------------------------------
290 SvxTableController* AccessibleTableShape::getTableController()
292 SdrView* pView = maShapeTreeInfo.GetSdrView ();
293 if( pView )
294 return dynamic_cast< SvxTableController* >( pView->getSelectionController().get() );
295 else
296 return 0;
299 //-----------------------------------------------------------------------------
300 // XInterface
301 //-----------------------------------------------------------------------------
303 Any SAL_CALL AccessibleTableShape::queryInterface( const Type& aType ) throw (RuntimeException)
305 return AccessibleTableShape_Base::queryInterface( aType );
308 //-----------------------------------------------------------------------------
310 void SAL_CALL AccessibleTableShape::acquire( ) throw ()
312 AccessibleTableShape_Base::acquire();
315 //-----------------------------------------------------------------------------
317 void SAL_CALL AccessibleTableShape::release( ) throw ()
319 AccessibleTableShape_Base::release();
322 //-----------------------------------------------------------------------------
323 // XAccessible
324 //-----------------------------------------------------------------------------
326 Reference< XAccessibleContext > SAL_CALL AccessibleTableShape::getAccessibleContext(void) throw (RuntimeException)
328 return AccessibleShape::getAccessibleContext ();
331 //-----------------------------------------------------------------------------
332 OUString SAL_CALL AccessibleTableShape::getImplementationName(void) throw (RuntimeException)
334 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.accessibility.AccessibleTableShape" ) );
337 //-----------------------------------------------------------------------------
339 OUString AccessibleTableShape::CreateAccessibleBaseName(void) throw (RuntimeException)
341 return OUString (RTL_CONSTASCII_USTRINGPARAM("TableShape"));;
344 //--------------------------------------------------------------------
346 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException)
348 ::vos::OGuard aSolarGuard(::Application::GetSolarMutex());
349 return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() * mxImpl->mxTable->getColumnCount() : 0;
352 //--------------------------------------------------------------------
353 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException)
355 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
356 ThrowIfDisposed();
358 return mxImpl->getAccessibleChild( i );
361 //--------------------------------------------------------------------
362 Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableShape::getAccessibleRelationSet( ) throw (RuntimeException)
364 return AccessibleShape::getAccessibleRelationSet( );
367 //--------------------------------------------------------------------
369 sal_Int16 SAL_CALL AccessibleTableShape::getAccessibleRole (void) throw (RuntimeException)
371 return AccessibleRole::TABLE;
374 //--------------------------------------------------------------------
376 void SAL_CALL AccessibleTableShape::disposing (void)
378 mxImpl->dispose();
380 // let the base do it's stuff
381 AccessibleShape::disposing();
384 //--------------------------------------------------------------------
385 // XAccessibleTable
386 //--------------------------------------------------------------------
388 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException)
390 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
391 return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() : 0;
394 //--------------------------------------------------------------------
396 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnCount( ) throw (RuntimeException)
398 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
399 return mxImpl->mxTable.is() ? mxImpl->mxTable->getColumnCount() : 0;
402 //--------------------------------------------------------------------
404 OUString SAL_CALL AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
406 checkCellPosition( 0, nRow );
407 return OUString();
410 //--------------------------------------------------------------------
412 OUString SAL_CALL AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
414 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
415 checkCellPosition( nColumn, 0 );
416 return OUString();
419 //--------------------------------------------------------------------
421 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
423 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
424 checkCellPosition( nColumn, nRow );
425 if( mxImpl->mxTable.is() )
427 Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
428 if( xCell.is() )
429 return xCell->getRowSpan();
431 return 1;
434 //--------------------------------------------------------------------
436 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
438 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
439 checkCellPosition( nColumn, nRow );
440 if( mxImpl->mxTable.is() )
442 Reference< XMergeableCell > xCell( mxImpl->mxTable->getCellByPosition( nColumn, nRow ), UNO_QUERY );
443 if( xCell.is() )
444 return xCell->getColumnSpan();
446 return 1;
449 //--------------------------------------------------------------------
451 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleRowHeaders( ) throw (RuntimeException)
453 Reference< XAccessibleTable > xRet( this ); // todo
454 return xRet;
457 //--------------------------------------------------------------------
459 Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleColumnHeaders( ) throw (RuntimeException)
461 Reference< XAccessibleTable > xRet( this ); // todo
462 return xRet;
465 //--------------------------------------------------------------------
467 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleRows( ) throw (RuntimeException)
469 Sequence< sal_Int32 > aRet;
470 return aRet;
473 //--------------------------------------------------------------------
475 Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleColumns( ) throw (RuntimeException)
477 Sequence< sal_Int32 > aRet;
478 return aRet;
481 //--------------------------------------------------------------------
483 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow ) throw (IndexOutOfBoundsException, RuntimeException)
485 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
486 checkCellPosition( 0, nRow );
487 return sal_False;
490 //--------------------------------------------------------------------
492 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
494 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
495 checkCellPosition( nColumn, 0 );
496 return sal_False;
499 //--------------------------------------------------------------------
501 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
503 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
504 checkCellPosition( nColumn, nRow );
506 sal_Int32 nChildIndex = 0;
507 if( mxImpl->mxTable.is() )
508 nChildIndex = mxImpl->mxTable->getColumnCount() * nRow + nColumn;
510 return getAccessibleChild( nChildIndex );
513 //--------------------------------------------------------------------
515 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCaption( ) throw (RuntimeException)
517 Reference< XAccessible > xRet;
518 return xRet;
521 //--------------------------------------------------------------------
523 Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleSummary( ) throw (RuntimeException)
525 Reference< XAccessible > xRet;
526 return xRet;
529 //--------------------------------------------------------------------
531 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
533 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
534 checkCellPosition( nColumn, nRow );
536 SvxTableController* pController = getTableController();
537 if( pController && pController->hasSelectedCells() )
539 CellPos aFirstPos, aLastPos;
540 pController->getSelectedCells( aFirstPos, aLastPos );
541 if( (aFirstPos.mnRow <= nRow) && (aFirstPos.mnCol <= nColumn) && (nRow <= aLastPos.mnRow) && (nColumn <= aLastPos.mnCol) )
542 return sal_True;
545 return sal_False;
548 //--------------------------------------------------------------------
550 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn ) throw (IndexOutOfBoundsException, RuntimeException)
552 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
553 checkCellPosition( nColumn, nRow );
554 return mxImpl->mxTable.is() ? (nRow * mxImpl->mxTable->getColumnCount() + nColumn) : 0;
557 //--------------------------------------------------------------------
559 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
561 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
562 sal_Int32 nColumn = 0, nRow = 0;
563 mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
564 return nRow;
567 //--------------------------------------------------------------------
569 sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
571 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
572 sal_Int32 nColumn = 0, nRow = 0;
573 mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
574 return nChildIndex;
577 //--------------------------------------------------------------------
578 // XAccessibleSelection
579 //--------------------------------------------------------------------
581 void SAL_CALL AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
583 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
584 CellPos aPos;
585 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
587 // todo, select table shape?!?
588 SvxTableController* pController = getTableController();
589 if( pController )
591 CellPos aFirstPos( aPos ), aLastPos( aPos );
592 if( pController->hasSelectedCells() )
594 pController->getSelectedCells( aFirstPos, aLastPos );
596 aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow );
597 aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol );
598 aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow );
599 aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol );
601 pController->setSelectedCells( aFirstPos, aLastPos );
605 //--------------------------------------------------------------------
607 sal_Bool SAL_CALL AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
609 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
610 CellPos aPos;
611 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
613 return isAccessibleSelected(aPos.mnCol, aPos.mnRow);
616 //--------------------------------------------------------------------
618 void SAL_CALL AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException )
620 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
622 SvxTableController* pController = getTableController();
623 if( pController )
624 pController->clearSelection();
626 //--------------------------------------------------------------------
628 void SAL_CALL AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException )
630 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
632 // todo: force selection of shape?
633 SvxTableController* pController = getTableController();
634 if( pController )
635 pController->selectAll();
638 //--------------------------------------------------------------------
640 sal_Int32 SAL_CALL AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException )
642 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
644 SvxTableController* pController = getTableController();
645 if( pController && pController->hasSelectedCells() )
647 CellPos aFirstPos, aLastPos;
648 pController->getSelectedCells( aFirstPos, aLastPos );
650 const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
651 const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
652 return nSelectedRows * nSelectedColumns;
655 return 0;
658 //--------------------------------------------------------------------
660 Reference< XAccessible > SAL_CALL AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException)
662 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
664 SvxTableController* pController = getTableController();
665 if( pController && pController->hasSelectedCells() )
667 CellPos aFirstPos, aLastPos;
668 pController->getSelectedCells( aFirstPos, aLastPos );
670 const sal_Int32 nSelectedColumns = std::max( (sal_Int32)0, aLastPos.mnCol - aFirstPos.mnCol ) + 1;
671 const sal_Int32 nSelectedRows = std::max( (sal_Int32)0, aLastPos.mnRow - aFirstPos.mnRow ) + 1;
673 if( nSelectedChildIndex < (nSelectedRows * nSelectedColumns) )
675 while( nSelectedChildIndex >= nSelectedColumns )
677 aFirstPos.mnRow++;
678 nSelectedChildIndex -= nSelectedColumns;
680 return getAccessibleCellAt( nSelectedColumns, aFirstPos.mnRow );
684 throw IndexOutOfBoundsException();
687 //--------------------------------------------------------------------
689 void SAL_CALL AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex ) throw ( IndexOutOfBoundsException, RuntimeException )
691 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
692 CellPos aPos;
693 mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
695 // todo, select table shape?!?
696 SvxTableController* pController = getTableController();
697 if( pController && pController->hasSelectedCells() )
699 CellPos aFirstPos, aLastPos;
700 pController->getSelectedCells( aFirstPos, aLastPos );
702 // create a selection where aPos is not part of anymore
703 aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow+1 );
704 aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol+1 );
705 aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow-1 );
706 aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol-1 );
708 // new selection may be invalid (child to deselect is not at a border of the selection but in between)
709 if( (aFirstPos.mnRow > aLastPos.mnRow) || (aFirstPos.mnCol > aLastPos.mnCol) )
710 pController->clearSelection(); // if selection is invalid, clear all
711 else
712 pController->setSelectedCells( aFirstPos, aLastPos );
716 //--------------------------------------------------------------------
718 void AccessibleTableShape::checkCellPosition( sal_Int32 nCol, sal_Int32 nRow ) throw ( IndexOutOfBoundsException )
720 if( (nCol >= 0) && (nRow >= 0) && mxImpl->mxTable.is() && (nCol < mxImpl->mxTable->getColumnCount()) && (nRow < mxImpl->mxTable->getRowCount()) )
721 return;
723 throw IndexOutOfBoundsException();