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 <AccessibleTableShape.hxx>
30 #include <svx/sdr/table/tablecontroller.hxx>
31 #include "accessiblecell.hxx"
35 #include <cppuhelper/implbase1.hxx>
36 #include <svx/svdotable.hxx>
37 #include <com/sun/star/view/XSelectionSupplier.hpp>
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
;
51 namespace accessibility
56 std::size_t operator()( const Reference
< XCell
>& xCell
) const
58 return std::size_t( xCell
.get() );
62 typedef std::unordered_map
< Reference
< XCell
>, rtl::Reference
< AccessibleCell
>, hash
> AccessibleCellMap
;
64 class AccessibleTableShapeImpl
: public cppu::WeakImplHelper1
< XModifyListener
>
67 AccessibleTableShapeImpl( AccessibleShapeTreeInfo
& rShapeTreeInfo
);
69 void init( const Reference
< XAccessible
>& xAccessible
, const Reference
< XTable
>& xTable
);
72 Reference
< XAccessible
> getAccessibleChild(sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
);
73 void getColumnAndRow( sal_Int32 nChildIndex
, sal_Int32
& rnColumn
, sal_Int32
& rnRow
) throw (IndexOutOfBoundsException
);
76 virtual void SAL_CALL
modified( const EventObject
& aEvent
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
79 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
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
);
92 AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo
& rShapeTreeInfo
)
93 : mrShapeTreeInfo( rShapeTreeInfo
)
101 void AccessibleTableShapeImpl::init( const Reference
< XAccessible
>& xAccessible
, const Reference
< XTable
>& xTable
)
103 mxAccessible
= xAccessible
;
108 Reference
< XModifyListener
> xListener( this );
109 mxTable
->addModifyListener( xListener
);
110 //register the listener with table model
111 Reference
< ::com::sun::star::view::XSelectionSupplier
> xSelSupplier(xTable
, UNO_QUERY
);
112 Reference
< ::com::sun::star::view::XSelectionChangeListener
> xSelListener( xAccessible
, UNO_QUERY
);
113 if (xSelSupplier
.is())
114 xSelSupplier
->addSelectionChangeListener(xSelListener
);
115 mRowCount
= mxTable
->getRowCount();
116 mColCount
= mxTable
->getColumnCount();
122 void AccessibleTableShapeImpl::dispose()
126 //remove all the cell's acc object in table's dispose.
127 for( AccessibleCellMap::iterator
iter( maChildMap
.begin() ); iter
!= maChildMap
.end(); ++iter
)
129 (*iter
).second
->dispose();
132 Reference
< XModifyListener
> xListener( this );
133 mxTable
->removeModifyListener( xListener
);
136 mxAccessible
.clear();
140 //get the cached AccessibleCell from XCell
141 Reference
< AccessibleCell
> AccessibleTableShapeImpl::getAccessibleCell (Reference
< XCell
> xCell
)
143 AccessibleCellMap::iterator
iter( maChildMap
.find( xCell
) );
145 if( iter
!= maChildMap
.end() )
147 Reference
< AccessibleCell
> xChild( (*iter
).second
.get() );
150 return Reference
< AccessibleCell
>();
154 Reference
< XAccessible
> AccessibleTableShapeImpl::getAccessibleChild(sal_Int32 nChildIndex
)
155 throw (IndexOutOfBoundsException
, RuntimeException
)
157 sal_Int32 nColumn
= 0, nRow
= 0;
158 getColumnAndRow( nChildIndex
, nColumn
, nRow
);
160 Reference
< XCell
> xCell( mxTable
->getCellByPosition( nColumn
, nRow
) );
161 AccessibleCellMap::iterator
iter( maChildMap
.find( xCell
) );
163 if( iter
!= maChildMap
.end() )
165 Reference
< XAccessible
> xChild( (*iter
).second
.get() );
170 CellRef
xCellRef( dynamic_cast< Cell
* >( xCell
.get() ) );
172 rtl::Reference
< AccessibleCell
> xAccessibleCell( new AccessibleCell( mxAccessible
, xCellRef
, nChildIndex
, mrShapeTreeInfo
) );
174 xAccessibleCell
->Init();
175 maChildMap
[xCell
] = xAccessibleCell
;
177 Reference
< XAccessible
> xChild( xAccessibleCell
.get() );
184 void AccessibleTableShapeImpl::getColumnAndRow( sal_Int32 nChildIndex
, sal_Int32
& rnColumn
, sal_Int32
& rnRow
) throw (IndexOutOfBoundsException
)
187 rnColumn
= nChildIndex
;
191 const sal_Int32 nColumnCount
= mxTable
->getColumnCount();
192 while( rnColumn
>= nColumnCount
)
195 rnColumn
-= nColumnCount
;
198 if( rnRow
< mxTable
->getRowCount() )
202 throw IndexOutOfBoundsException();
206 void SAL_CALL
AccessibleTableShapeImpl::modified( const EventObject
& /*aEvent*/ ) throw (RuntimeException
, std::exception
)
208 if( mxTable
.is() ) try
210 // structural changes may have happened to the table, validate all accessible cell instances
211 AccessibleCellMap aTempChildMap
;
212 aTempChildMap
.swap( maChildMap
);
214 // first move all still existing cells to maChildMap again and update their index
216 const sal_Int32 nRowCount
= mxTable
->getRowCount();
217 const sal_Int32 nColCount
= mxTable
->getColumnCount();
219 bool bRowOrColumnChanged
= false;
220 if (mRowCount
!= nRowCount
|| mColCount
!= nColCount
)
222 bRowOrColumnChanged
= true;
223 mRowCount
= nRowCount
;
224 mColCount
= nColCount
;
226 sal_Int32 nChildIndex
= 0;
228 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; ++nRow
)
230 for( sal_Int32 nCol
= 0; nCol
< nColCount
; ++nCol
)
232 Reference
< XCell
> xCell( mxTable
->getCellByPosition( nCol
, nRow
) );
233 AccessibleCellMap::iterator
iter( aTempChildMap
.find( xCell
) );
235 if( iter
!= aTempChildMap
.end() )
237 rtl::Reference
< AccessibleCell
> xAccessibleCell( (*iter
).second
);
238 xAccessibleCell
->setIndexInParent( nChildIndex
);
239 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 if (bRowOrColumnChanged
)
243 xAccessibleCell
->SetAccessibleName(xAccessibleCell
->getAccessibleName(), AccessibleContextBase::ManuallySet
);
245 // For merged cell, add invisible & disabled state.
246 Reference
< XMergeableCell
> xMergedCell( mxTable
->getCellByPosition( nCol
, nRow
), UNO_QUERY
);
247 if (xMergedCell
.is() && xMergedCell
->isMerged())
249 xAccessibleCell
->ResetState(AccessibleStateType::VISIBLE
);
250 xAccessibleCell
->ResetState(AccessibleStateType::ENABLED
);
251 // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
252 // xAccessibleCell->SetState(AccessibleStateType::OFFSCREEN);
253 xAccessibleCell
->ResetState(AccessibleStateType::SHOWING
);
257 xAccessibleCell
->SetState(AccessibleStateType::VISIBLE
);
258 xAccessibleCell
->SetState(AccessibleStateType::ENABLED
);
259 // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
260 // xAccessibleCell->ResetState(AccessibleStateType::OFFSCREEN);
261 xAccessibleCell
->SetState(AccessibleStateType::SHOWING
);
264 // move still existing cell from temporary child map to our child map
265 maChildMap
[xCell
] = xAccessibleCell
;
266 aTempChildMap
.erase( iter
);
270 CellRef
xCellRef( dynamic_cast< Cell
* >( xCell
.get() ) );
272 rtl::Reference
< AccessibleCell
> xAccessibleCell( new AccessibleCell( mxAccessible
, xCellRef
, nChildIndex
, mrShapeTreeInfo
) );
274 xAccessibleCell
->Init();
275 maChildMap
[xCell
] = xAccessibleCell
;
282 // all accessible cell instances still left in aTempChildMap must be disposed
283 // as they are no longer part of the table
285 for( AccessibleCellMap::iterator
iter( aTempChildMap
.begin() ); iter
!= aTempChildMap
.end(); ++iter
)
287 (*iter
).second
->dispose();
289 //notify bridge to update the acc cache.
290 AccessibleTableShape
*pAccTable
= dynamic_cast <AccessibleTableShape
*> (mxAccessible
.get());
292 pAccTable
->CommitChange(AccessibleEventId::INVALIDATE_ALL_CHILDREN
, Any(), Any());
294 catch( const Exception
& )
296 OSL_FAIL("svx::AccessibleTableShape::modified(), exception caught!");
301 void SAL_CALL
AccessibleTableShapeImpl::disposing( const EventObject
& /*Source*/ ) throw (RuntimeException
, std::exception
)
305 AccessibleTableShape::AccessibleTableShape( const AccessibleShapeInfo
& rShapeInfo
, const AccessibleShapeTreeInfo
& rShapeTreeInfo
)
306 : AccessibleTableShape_Base(rShapeInfo
, rShapeTreeInfo
)
307 , mnPreviousSelectionCount(0)
308 , mxImpl( new AccessibleTableShapeImpl( maShapeTreeInfo
) )
314 AccessibleTableShape::~AccessibleTableShape()
320 void AccessibleTableShape::Init()
324 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY_THROW
);
325 Reference
< XTable
> xTable( xSet
->getPropertyValue("Model"), UNO_QUERY_THROW
);
327 mxImpl
->init( this, xTable
);
331 OSL_FAIL("AccessibleTableShape::init(), exception caught?");
334 AccessibleTableShape_Base::Init();
339 SvxTableController
* AccessibleTableShape::getTableController()
341 SdrView
* pView
= maShapeTreeInfo
.GetSdrView ();
343 return dynamic_cast< SvxTableController
* >( pView
->getSelectionController().get() );
352 Any SAL_CALL
AccessibleTableShape::queryInterface( const Type
& aType
) throw (RuntimeException
, std::exception
)
354 if ( aType
== cppu::UnoType
<XAccessibleTableSelection
>::get())
356 Reference
<XAccessibleTableSelection
> xThis( this );
362 return AccessibleTableShape_Base::queryInterface( aType
);
367 void SAL_CALL
AccessibleTableShape::acquire( ) throw ()
369 AccessibleTableShape_Base::acquire();
374 void SAL_CALL
AccessibleTableShape::release( ) throw ()
376 AccessibleTableShape_Base::release();
383 Reference
< XAccessibleContext
> SAL_CALL
AccessibleTableShape::getAccessibleContext() throw (RuntimeException
, std::exception
)
385 return AccessibleShape::getAccessibleContext ();
389 OUString SAL_CALL
AccessibleTableShape::getImplementationName() throw (RuntimeException
, std::exception
)
391 return OUString( "com.sun.star.comp.accessibility.AccessibleTableShape" );
396 OUString
AccessibleTableShape::CreateAccessibleBaseName() throw (RuntimeException
)
398 return OUString("TableShape");
403 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleChildCount( ) throw(RuntimeException
, std::exception
)
405 SolarMutexGuard aSolarGuard
;
406 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getRowCount() * mxImpl
->mxTable
->getColumnCount() : 0;
410 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleChild( sal_Int32 i
) throw(IndexOutOfBoundsException
, RuntimeException
, std::exception
)
412 SolarMutexGuard aSolarGuard
;
415 return mxImpl
->getAccessibleChild( i
);
419 Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleTableShape::getAccessibleRelationSet( ) throw (RuntimeException
, std::exception
)
421 return AccessibleShape::getAccessibleRelationSet( );
426 sal_Int16 SAL_CALL
AccessibleTableShape::getAccessibleRole() throw (RuntimeException
, std::exception
)
428 return AccessibleRole::TABLE
;
433 void SAL_CALL
AccessibleTableShape::disposing()
437 // let the base do it's stuff
438 AccessibleShape::disposing();
445 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRowCount() throw (RuntimeException
, std::exception
)
447 SolarMutexGuard aSolarGuard
;
448 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getRowCount() : 0;
453 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumnCount( ) throw (RuntimeException
, std::exception
)
455 SolarMutexGuard aSolarGuard
;
456 return mxImpl
->mxTable
.is() ? mxImpl
->mxTable
->getColumnCount() : 0;
461 OUString SAL_CALL
AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
463 checkCellPosition( 0, nRow
);
469 OUString SAL_CALL
AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
471 SolarMutexGuard aSolarGuard
;
472 checkCellPosition( nColumn
, 0 );
478 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
480 SolarMutexGuard aSolarGuard
;
481 checkCellPosition( nColumn
, nRow
);
482 if( mxImpl
->mxTable
.is() )
484 Reference
< XMergeableCell
> xCell( mxImpl
->mxTable
->getCellByPosition( nColumn
, nRow
), UNO_QUERY
);
486 return xCell
->getRowSpan();
493 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
495 SolarMutexGuard aSolarGuard
;
496 checkCellPosition( nColumn
, nRow
);
497 if( mxImpl
->mxTable
.is() )
499 Reference
< XMergeableCell
> xCell( mxImpl
->mxTable
->getCellByPosition( nColumn
, nRow
), UNO_QUERY
);
501 return xCell
->getColumnSpan();
508 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableShape::getAccessibleRowHeaders( ) throw (RuntimeException
, std::exception
)
510 Reference
< XAccessibleTable
> xRet
;
511 SvxTableController
* pController
= getTableController();
514 if( pController
->isRowHeader() )
516 AccessibleTableHeaderShape
* pTableHeader
= new AccessibleTableHeaderShape( this, true );
517 xRet
.set( pTableHeader
);
525 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableShape::getAccessibleColumnHeaders( ) throw (RuntimeException
, std::exception
)
527 Reference
< XAccessibleTable
> xRet
;
528 SvxTableController
* pController
= getTableController();
531 if( pController
->isColumnHeader() )
533 AccessibleTableHeaderShape
* pTableHeader
= new AccessibleTableHeaderShape( this, false );
534 xRet
.set( pTableHeader
);
542 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleRows( ) throw (RuntimeException
, std::exception
)
544 sal_Int32 nRow
= getAccessibleRowCount();
545 ::std::vector
< sal_Bool
> aSelected( nRow
, sal_True
);
546 sal_Int32 nCount
= nRow
;
547 for( sal_Int32 i
= 0; i
< nRow
; i
++ )
551 aSelected
[i
] = isAccessibleRowSelected( i
);
555 return Sequence
< sal_Int32
>();
561 Sequence
< sal_Int32
> aRet( nCount
);
562 sal_Int32
*pRet
= aRet
.getArray();
564 size_t nSize
= aSelected
.size();
565 for( size_t i
=0; i
< nSize
&& nPos
< nCount
; i
++ )
579 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleColumns( ) throw (RuntimeException
, std::exception
)
581 sal_Int32 nColumn
= getAccessibleColumnCount();
582 ::std::vector
< sal_Bool
> aSelected( nColumn
, sal_True
);
583 sal_Int32 nCount
= nColumn
;
584 for( sal_Int32 i
= 0; i
< nColumn
; i
++ )
588 aSelected
[i
] = isAccessibleColumnSelected( i
);
592 return Sequence
< sal_Int32
>();
598 Sequence
< sal_Int32
> aRet( nCount
);
599 sal_Int32
*pRet
= aRet
.getArray();
601 size_t nSize
= aSelected
.size();
602 for( size_t i
=0; i
< nSize
&& nPos
< nCount
; i
++ )
616 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
618 SolarMutexGuard aSolarGuard
;
619 checkCellPosition( 0, nRow
);
620 SvxTableController
* pController
= getTableController();
623 return pController
->isRowSelected( nRow
);
630 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
632 SolarMutexGuard aSolarGuard
;
633 checkCellPosition( nColumn
, 0 );
634 SvxTableController
* pController
= getTableController();
637 return pController
->isColumnSelected( nColumn
);
644 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
646 SolarMutexGuard aSolarGuard
;
647 checkCellPosition( nColumn
, nRow
);
649 sal_Int32 nChildIndex
= 0;
650 if( mxImpl
->mxTable
.is() )
651 nChildIndex
= mxImpl
->mxTable
->getColumnCount() * nRow
+ nColumn
;
653 return getAccessibleChild( nChildIndex
);
658 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleCaption( ) throw (RuntimeException
, std::exception
)
660 Reference
< XAccessible
> xRet
;
666 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getAccessibleSummary( ) throw (RuntimeException
, std::exception
)
668 Reference
< XAccessible
> xRet
;
674 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
676 SolarMutexGuard aSolarGuard
;
677 checkCellPosition( nColumn
, nRow
);
679 SvxTableController
* pController
= getTableController();
680 if( pController
&& pController
->hasSelectedCells() )
682 CellPos aFirstPos
, aLastPos
;
683 pController
->getSelectedCells( aFirstPos
, aLastPos
);
684 if( (aFirstPos
.mnRow
<= nRow
) && (aFirstPos
.mnCol
<= nColumn
) && (nRow
<= aLastPos
.mnRow
) && (nColumn
<= aLastPos
.mnCol
) )
693 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
695 SolarMutexGuard aSolarGuard
;
696 checkCellPosition( nColumn
, nRow
);
697 return mxImpl
->mxTable
.is() ? (nRow
* mxImpl
->mxTable
->getColumnCount() + nColumn
) : 0;
702 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleRow( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
704 SolarMutexGuard aSolarGuard
;
705 sal_Int32 nColumn
= 0, nRow
= 0;
706 mxImpl
->getColumnAndRow( nChildIndex
, nColumn
, nRow
);
712 sal_Int32 SAL_CALL
AccessibleTableShape::getAccessibleColumn( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
714 SolarMutexGuard aSolarGuard
;
715 sal_Int32 nColumn
= 0, nRow
= 0;
716 mxImpl
->getColumnAndRow( nChildIndex
, nColumn
, nRow
);
721 // XAccessibleSelection
724 void SAL_CALL
AccessibleTableShape::selectAccessibleChild( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
, std::exception
)
726 SolarMutexGuard aSolarGuard
;
728 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
730 // todo, select table shape?!?
731 SvxTableController
* pController
= getTableController();
734 CellPos
aFirstPos( aPos
), aLastPos( aPos
);
735 if( pController
->hasSelectedCells() )
737 pController
->getSelectedCells( aFirstPos
, aLastPos
);
739 aFirstPos
.mnRow
= std::min( aFirstPos
.mnRow
, aPos
.mnRow
);
740 aFirstPos
.mnCol
= std::min( aFirstPos
.mnCol
, aPos
.mnCol
);
741 aLastPos
.mnRow
= std::max( aLastPos
.mnRow
, aPos
.mnRow
);
742 aLastPos
.mnCol
= std::max( aLastPos
.mnCol
, aPos
.mnCol
);
744 pController
->setSelectedCells( aFirstPos
, aLastPos
);
750 sal_Bool SAL_CALL
AccessibleTableShape::isAccessibleChildSelected( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
, std::exception
)
752 SolarMutexGuard aSolarGuard
;
754 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
756 return isAccessibleSelected(aPos
.mnRow
, aPos
.mnCol
);
761 void SAL_CALL
AccessibleTableShape::clearAccessibleSelection() throw ( RuntimeException
, std::exception
)
763 SolarMutexGuard aSolarGuard
;
765 SvxTableController
* pController
= getTableController();
767 pController
->clearSelection();
771 void SAL_CALL
AccessibleTableShape::selectAllAccessibleChildren() throw ( RuntimeException
, std::exception
)
773 SolarMutexGuard aSolarGuard
;
775 // todo: force selection of shape?
776 SvxTableController
* pController
= getTableController();
778 pController
->selectAll();
783 sal_Int32 SAL_CALL
AccessibleTableShape::getSelectedAccessibleChildCount() throw ( RuntimeException
, std::exception
)
785 SolarMutexGuard aSolarGuard
;
787 SvxTableController
* pController
= getTableController();
788 if( pController
&& pController
->hasSelectedCells() )
790 CellPos aFirstPos
, aLastPos
;
791 pController
->getSelectedCells( aFirstPos
, aLastPos
);
793 const sal_Int32 nSelectedColumns
= std::max( (sal_Int32
)0, aLastPos
.mnCol
- aFirstPos
.mnCol
) + 1;
794 const sal_Int32 nSelectedRows
= std::max( (sal_Int32
)0, aLastPos
.mnRow
- aFirstPos
.mnRow
) + 1;
795 return nSelectedRows
* nSelectedColumns
;
803 Reference
< XAccessible
> SAL_CALL
AccessibleTableShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
, std::exception
)
805 SolarMutexGuard aSolarGuard
;
807 if( nSelectedChildIndex
< 0 )
808 throw IndexOutOfBoundsException();
810 sal_Int32 nChildIndex
= GetIndexOfSelectedChild( nSelectedChildIndex
);
812 if( nChildIndex
< 0 )
813 throw IndexOutOfBoundsException();
815 if ( nChildIndex
>= getAccessibleChildCount() )
817 throw IndexOutOfBoundsException();
820 return getAccessibleChild( nChildIndex
);
825 void SAL_CALL
AccessibleTableShape::deselectAccessibleChild( sal_Int32 nChildIndex
) throw ( IndexOutOfBoundsException
, RuntimeException
, std::exception
)
827 SolarMutexGuard aSolarGuard
;
829 mxImpl
->getColumnAndRow( nChildIndex
, aPos
.mnCol
, aPos
.mnRow
);
831 // todo, select table shape?!?
832 SvxTableController
* pController
= getTableController();
833 if( pController
&& pController
->hasSelectedCells() )
835 CellPos aFirstPos
, aLastPos
;
836 pController
->getSelectedCells( aFirstPos
, aLastPos
);
838 // create a selection where aPos is not part of anymore
839 aFirstPos
.mnRow
= std::min( aFirstPos
.mnRow
, aPos
.mnRow
+1 );
840 aFirstPos
.mnCol
= std::min( aFirstPos
.mnCol
, aPos
.mnCol
+1 );
841 aLastPos
.mnRow
= std::max( aLastPos
.mnRow
, aPos
.mnRow
-1 );
842 aLastPos
.mnCol
= std::max( aLastPos
.mnCol
, aPos
.mnCol
-1 );
844 // new selection may be invalid (child to deselect is not at a border of the selection but in between)
845 if( (aFirstPos
.mnRow
> aLastPos
.mnRow
) || (aFirstPos
.mnCol
> aLastPos
.mnCol
) )
846 pController
->clearSelection(); // if selection is invalid, clear all
848 pController
->setSelectedCells( aFirstPos
, aLastPos
);
852 // XAccessibleTableSelection
853 sal_Bool SAL_CALL
AccessibleTableShape::selectRow( sal_Int32 row
)
854 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
856 SolarMutexGuard aSolarGuard
;
857 SvxTableController
* pController
= getTableController();
860 return pController
->selectRow( row
);
863 sal_Bool SAL_CALL
AccessibleTableShape::selectColumn( sal_Int32 column
)
864 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
866 SolarMutexGuard aSolarGuard
;
867 SvxTableController
* pController
= getTableController();
870 return pController
->selectColumn( column
);
873 sal_Bool SAL_CALL
AccessibleTableShape::unselectRow( sal_Int32 row
)
874 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
876 SolarMutexGuard aSolarGuard
;
877 SvxTableController
* pController
= getTableController();
880 return pController
->deselectRow( row
);
883 sal_Bool SAL_CALL
AccessibleTableShape::unselectColumn( sal_Int32 column
)
884 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
886 SolarMutexGuard aSolarGuard
;
887 SvxTableController
* pController
= getTableController();
890 return pController
->deselectColumn( column
);
893 sal_Int32
AccessibleTableShape::GetIndexOfSelectedChild(
894 sal_Int32 nSelectedChildIndex
) const
896 sal_Int32 nChildren
= const_cast<AccessibleTableShape
*>(this)->getAccessibleChildCount();
898 if( nSelectedChildIndex
>= nChildren
)
902 while( n
< nChildren
)
904 if( const_cast<AccessibleTableShape
*>(this)->isAccessibleChildSelected( n
) )
906 if( 0 == nSelectedChildIndex
)
909 --nSelectedChildIndex
;
914 return n
< nChildren
? n
: -1L;
916 void AccessibleTableShape::getColumnAndRow( sal_Int32 nChildIndex
, sal_Int32
& rnColumn
, sal_Int32
& rnRow
) throw (IndexOutOfBoundsException
)
918 mxImpl
->getColumnAndRow(nChildIndex
, rnColumn
, rnRow
);
921 // XSelectionChangeListener
923 AccessibleTableShape::disposing (const EventObject
& aEvent
)
924 throw (RuntimeException
, std::exception
)
926 AccessibleShape::disposing(aEvent
);
928 void SAL_CALL
AccessibleTableShape::selectionChanged (const EventObject
& rEvent
)
929 throw (RuntimeException
, std::exception
)
931 //sdr::table::CellRef xCellRef = static_cast< sdr::table::CellRef > (rEvent.Source);
932 Reference
< XCell
> xCell(rEvent
.Source
, UNO_QUERY
);
935 Reference
< AccessibleCell
> xAccCell
= mxImpl
->getAccessibleCell( xCell
);
938 sal_Int32 nIndex
= xAccCell
->getAccessibleIndexInParent(),
939 nCount
= getSelectedAccessibleChildCount();
940 bool bSelected
= isAccessibleChildSelected(nIndex
);
941 if (mnPreviousSelectionCount
== 0 && nCount
> 0 && bSelected
)
943 xAccCell
->SetState(AccessibleStateType::SELECTED
);
944 xAccCell
->CommitChange(AccessibleEventId::SELECTION_CHANGED
, Any(), Any());
948 xAccCell
->SetState(AccessibleStateType::SELECTED
);
949 xAccCell
->CommitChange(AccessibleEventId::SELECTION_CHANGED_ADD
, Any(), Any());
953 xAccCell
->ResetState(AccessibleStateType::SELECTED
);
954 xAccCell
->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE
, Any(), Any());
956 mnPreviousSelectionCount
= nCount
;
960 // Get the currently active cell which is text editing
961 AccessibleCell
* AccessibleTableShape::GetActiveAccessibleCell()
963 Reference
< AccessibleCell
> xAccCell
;
964 AccessibleCell
* pAccCell
= NULL
;
965 SvxTableController
* pController
= getTableController();
968 sdr::table::SdrTableObj
* pTableObj
= pController
->GetTableObj();
971 sdr::table::CellRef
xCellRef (pTableObj
->getActiveCell());
974 const bool bCellEditing
= xCellRef
->IsTextEditActive();
977 //Reference< XCell > xCell(xCellRef.get(), UNO_QUERY);
978 xAccCell
= mxImpl
->getAccessibleCell(Reference
< XCell
>( xCellRef
.get() ));
980 pAccCell
= xAccCell
.get();
988 //If current active cell is in editing, the focus state should be set to internal text
989 bool AccessibleTableShape::SetState (sal_Int16 aState
)
991 AccessibleCell
* pActiveAccessibleCell
= GetActiveAccessibleCell();
992 bool bStateHasChanged
= false;
993 if (aState
== AccessibleStateType::FOCUSED
&& pActiveAccessibleCell
!= NULL
)
995 return pActiveAccessibleCell
->SetState(aState
);
998 bStateHasChanged
= AccessibleShape::SetState (aState
);
999 return bStateHasChanged
;
1002 //If current active cell is in editing, the focus state should be reset to internal text
1003 bool AccessibleTableShape::ResetState (sal_Int16 aState
)
1005 AccessibleCell
* pActiveAccessibleCell
= GetActiveAccessibleCell();
1006 bool bStateHasChanged
= false;
1007 if (aState
== AccessibleStateType::FOCUSED
&& pActiveAccessibleCell
!= NULL
)
1009 return pActiveAccessibleCell
->ResetState(aState
);
1012 bStateHasChanged
= AccessibleShape::ResetState (aState
);
1013 return bStateHasChanged
;
1016 bool AccessibleTableShape::SetStateDirectly (sal_Int16 aState
)
1018 return AccessibleContextBase::SetState (aState
);
1021 bool AccessibleTableShape::ResetStateDirectly (sal_Int16 aState
)
1023 return AccessibleContextBase::ResetState (aState
);
1026 void AccessibleTableShape::checkCellPosition( sal_Int32 nCol
, sal_Int32 nRow
) throw ( IndexOutOfBoundsException
)
1028 if( (nCol
>= 0) && (nRow
>= 0) && mxImpl
->mxTable
.is() && (nCol
< mxImpl
->mxTable
->getColumnCount()) && (nRow
< mxImpl
->mxTable
->getRowCount()) )
1031 throw IndexOutOfBoundsException();
1034 AccessibleTableHeaderShape::AccessibleTableHeaderShape( AccessibleTableShape
* pTable
, bool bRow
)
1040 AccessibleTableHeaderShape::~AccessibleTableHeaderShape()
1046 Reference
< XAccessibleContext
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleContext() throw (RuntimeException
, std::exception
)
1051 // XAccessibleContext
1052 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleChildCount( ) throw(RuntimeException
, std::exception
)
1054 return getAccessibleRowCount() * getAccessibleColumnCount();
1057 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleChild( sal_Int32 i
) throw(IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1059 return mpTable
->getAccessibleChild( i
);
1062 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleParent() throw (RuntimeException
, std::exception
)
1064 Reference
< XAccessible
> XParent
;
1068 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleIndexInParent() throw (RuntimeException
, std::exception
)
1073 sal_Int16 SAL_CALL
AccessibleTableHeaderShape::getAccessibleRole() throw (RuntimeException
, std::exception
)
1075 return mpTable
->getAccessibleRole();
1078 OUString SAL_CALL
AccessibleTableHeaderShape::getAccessibleDescription() throw (RuntimeException
, std::exception
)
1080 return mpTable
->getAccessibleDescription();
1083 OUString SAL_CALL
AccessibleTableHeaderShape::getAccessibleName() throw (RuntimeException
, std::exception
)
1085 return mpTable
->getAccessibleName();
1088 Reference
< XAccessibleStateSet
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleStateSet() throw (RuntimeException
, std::exception
)
1090 return mpTable
->getAccessibleStateSet();
1093 Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleRelationSet() throw (RuntimeException
, std::exception
)
1095 return mpTable
->getAccessibleRelationSet();
1098 Locale SAL_CALL
AccessibleTableHeaderShape::getLocale() throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
1100 return mpTable
->getLocale();
1103 //XAccessibleComponent
1104 sal_Bool SAL_CALL
AccessibleTableHeaderShape::containsPoint ( const ::com::sun::star::awt::Point
& aPoint
) throw (RuntimeException
, std::exception
)
1106 return mpTable
->containsPoint( aPoint
);
1109 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleAtPoint ( const ::com::sun::star::awt::Point
& aPoint
) throw (RuntimeException
, std::exception
)
1111 return mpTable
->getAccessibleAtPoint( aPoint
);
1114 ::com::sun::star::awt::Rectangle SAL_CALL
AccessibleTableHeaderShape::getBounds() throw (RuntimeException
, std::exception
)
1116 return mpTable
->getBounds();
1119 ::com::sun::star::awt::Point SAL_CALL
AccessibleTableHeaderShape::getLocation() throw (RuntimeException
, std::exception
)
1121 return mpTable
->getLocation();
1124 ::com::sun::star::awt::Point SAL_CALL
AccessibleTableHeaderShape::getLocationOnScreen() throw (RuntimeException
, std::exception
)
1126 return mpTable
->getLocationOnScreen();
1129 ::com::sun::star::awt::Size SAL_CALL
AccessibleTableHeaderShape::getSize() throw (RuntimeException
, std::exception
)
1131 return mpTable
->getSize();
1134 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getForeground() throw (RuntimeException
, std::exception
)
1136 return mpTable
->getForeground();
1139 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getBackground() throw (RuntimeException
, std::exception
)
1141 return mpTable
->getBackground();
1144 void SAL_CALL
AccessibleTableHeaderShape::grabFocus() throw (RuntimeException
, std::exception
)
1146 mpTable
->grabFocus();
1149 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleRowCount() throw (RuntimeException
, std::exception
)
1151 return mbRow
? 1 : mpTable
->getAccessibleRowCount();
1154 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleColumnCount() throw (RuntimeException
, std::exception
)
1156 return !mbRow
? 1 : mpTable
->getAccessibleColumnCount();
1159 OUString SAL_CALL
AccessibleTableHeaderShape::getAccessibleRowDescription( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1161 return mpTable
->getAccessibleRowDescription( nRow
);
1164 OUString SAL_CALL
AccessibleTableHeaderShape::getAccessibleColumnDescription( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1166 return mpTable
->getAccessibleColumnDescription( nColumn
);
1169 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1171 return mpTable
->getAccessibleRowExtentAt( nRow
, nColumn
);
1174 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1176 return mpTable
->getAccessibleColumnExtentAt( nRow
, nColumn
);
1179 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleRowHeaders( ) throw (RuntimeException
, std::exception
)
1181 Reference
< XAccessibleTable
> xRet
;
1185 Reference
< XAccessibleTable
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleColumnHeaders( ) throw (RuntimeException
, std::exception
)
1187 Reference
< XAccessibleTable
> xRet
;
1191 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableHeaderShape::getSelectedAccessibleRows( ) throw (RuntimeException
, std::exception
)
1193 sal_Int32 nRow
= getAccessibleRowCount();
1194 ::std::vector
< sal_Bool
> aSelected( nRow
, sal_True
);
1195 sal_Int32 nCount
= nRow
;
1196 for( sal_Int32 i
= 0; i
< nRow
; i
++ )
1200 aSelected
[i
] = isAccessibleRowSelected( i
);
1204 return Sequence
< sal_Int32
>();
1210 Sequence
< sal_Int32
> aRet( nCount
);
1211 sal_Int32
*pRet
= aRet
.getArray();
1213 size_t nSize
= aSelected
.size();
1214 for( size_t i
=0; i
< nSize
&& nPos
< nCount
; i
++ )
1226 Sequence
< sal_Int32
> SAL_CALL
AccessibleTableHeaderShape::getSelectedAccessibleColumns( ) throw (RuntimeException
, std::exception
)
1228 sal_Int32 nColumn
= getAccessibleColumnCount();
1229 ::std::vector
< sal_Bool
> aSelected( nColumn
, sal_True
);
1230 sal_Int32 nCount
= nColumn
;
1231 for( sal_Int32 i
= 0; i
< nColumn
; i
++ )
1235 aSelected
[i
] = isAccessibleColumnSelected( i
);
1239 return Sequence
< sal_Int32
>();
1245 Sequence
< sal_Int32
> aRet( nCount
);
1246 sal_Int32
*pRet
= aRet
.getArray();
1248 size_t nSize
= aSelected
.size();
1249 for( size_t i
=0; i
< nSize
&& nPos
< nCount
; i
++ )
1261 sal_Bool SAL_CALL
AccessibleTableHeaderShape::isAccessibleRowSelected( sal_Int32 nRow
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1263 return mpTable
->isAccessibleRowSelected( nRow
);
1266 sal_Bool SAL_CALL
AccessibleTableHeaderShape::isAccessibleColumnSelected( sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1268 return mpTable
->isAccessibleColumnSelected( nColumn
);
1271 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleCellAt( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1273 return mpTable
->getAccessibleCellAt( nRow
, nColumn
);
1276 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleCaption( ) throw (RuntimeException
, std::exception
)
1278 return mpTable
->getAccessibleCaption();
1281 Reference
< XAccessible
> SAL_CALL
AccessibleTableHeaderShape::getAccessibleSummary( ) throw (RuntimeException
, std::exception
)
1283 return mpTable
->getAccessibleSummary();
1286 sal_Bool SAL_CALL
AccessibleTableHeaderShape::isAccessibleSelected( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1288 return mpTable
->isAccessibleSelected( nRow
, nColumn
);
1291 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1293 return mpTable
->getAccessibleIndex( nRow
, nColumn
);
1296 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleRow( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1298 return mpTable
->getAccessibleRow( nChildIndex
);
1301 sal_Int32 SAL_CALL
AccessibleTableHeaderShape::getAccessibleColumn( sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1303 return mpTable
->getAccessibleColumn( nChildIndex
);
1306 // XAccessibleTableSelection
1307 sal_Bool SAL_CALL
AccessibleTableHeaderShape::selectRow( sal_Int32 row
)
1308 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1311 return mpTable
->selectRow( row
);
1314 mpTable
->clearAccessibleSelection();
1315 sal_Int32 nIndex
= mpTable
->getAccessibleIndex( row
, 0 );
1316 mpTable
->selectAccessibleChild( nIndex
);
1321 sal_Bool SAL_CALL
AccessibleTableHeaderShape::selectColumn( sal_Int32 column
)
1322 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1325 return mpTable
->selectColumn( column
);
1328 mpTable
->clearAccessibleSelection();
1329 sal_Int32 nIndex
= mpTable
->getAccessibleIndex( 0, column
);
1330 mpTable
->selectAccessibleChild( nIndex
);
1335 sal_Bool SAL_CALL
AccessibleTableHeaderShape::unselectRow( sal_Int32 row
)
1336 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1339 return mpTable
->unselectRow( row
);
1342 sal_Int32 nIndex
= mpTable
->getAccessibleIndex( row
, 0 );
1343 mpTable
->deselectAccessibleChild( nIndex
);
1348 sal_Bool SAL_CALL
AccessibleTableHeaderShape::unselectColumn( sal_Int32 column
)
1349 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
1352 return mpTable
->unselectColumn( column
);
1355 sal_Int32 nIndex
= mpTable
->getAccessibleIndex( 0, column
);
1356 mpTable
->deselectAccessibleChild( nIndex
);
1362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */