diff options
author | Norbert Thiebaud <nthiebaud@gmail.com> | 2012-08-31 00:46:39 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-09-14 07:15:44 +0000 |
commit | 2095b2e1d44a158418d17836019352ed92f95d21 (patch) | |
tree | 1201a5ba0c1c7e664194b40493e2a56803a6588c /svtools | |
parent | 3d934d48606acf8c5c96d0d8b96e2f202db1f37d (diff) |
gridfixes: copied #i112562#'s fix from CWS gridcontrol06 herein
Change-Id: Ifa29a8b3c027970d46844b428a3529e680c0b09c
Reviewed-on: https://gerrit.libreoffice.org/541
Reviewed-by: Miklos Vajna <vmiklos@suse.cz>
Tested-by: Miklos Vajna <vmiklos@suse.cz>
Diffstat (limited to 'svtools')
-rw-r--r-- | svtools/inc/svtools/accessibletable.hxx | 29 | ||||
-rw-r--r-- | svtools/inc/svtools/table/tablecontrol.hxx | 13 | ||||
-rw-r--r-- | svtools/source/table/tablecontrol.cxx | 150 | ||||
-rw-r--r-- | svtools/source/table/tablecontrol_impl.cxx | 58 | ||||
-rw-r--r-- | svtools/source/table/tablecontrol_impl.hxx | 10 | ||||
-rw-r--r-- | svtools/source/uno/svtxgridcontrol.cxx | 71 |
6 files changed, 283 insertions, 48 deletions
diff --git a/svtools/inc/svtools/accessibletable.hxx b/svtools/inc/svtools/accessibletable.hxx index 5d8c932f8b48..edeaf25c3631 100644 --- a/svtools/inc/svtools/accessibletable.hxx +++ b/svtools/inc/svtools/accessibletable.hxx @@ -112,7 +112,9 @@ public: virtual sal_Bool HasRowHeader() const= 0; virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint )= 0; virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, sal_Bool _bOnScreen = sal_True ) = 0; + virtual Rectangle calcHeaderCellRect( sal_Bool _bColHeader, sal_Int32 _nPos ) = 0; virtual Rectangle calcTableRect( sal_Bool _bOnScreen = sal_True ) = 0; + virtual Rectangle calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ) = 0; virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex)= 0; virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)= 0; virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const= 0; @@ -169,6 +171,33 @@ public: virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getTable() = 0; + /** commits the event at all listeners of the cell + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + */ + virtual void commitCellEvent( + sal_Int16 nEventId, + const ::com::sun::star::uno::Any& rNewValue, + const ::com::sun::star::uno::Any& rOldValue + ) = 0; + /** commits the event at all listeners of the table + @param nEventId + the event id + @param rNewValue + the new value + @param rOldValue + the old value + */ + virtual void commitTableEvent( + sal_Int16 nEventId, + const ::com::sun::star::uno::Any& rNewValue, + const ::com::sun::star::uno::Any& rOldValue + ) = 0; + ///** Commits an event to all listeners. */ virtual void commitEvent( sal_Int16 nEventId, diff --git a/svtools/inc/svtools/table/tablecontrol.hxx b/svtools/inc/svtools/table/tablecontrol.hxx index cb2ddaf8d44b..c3078d8a5e7b 100644 --- a/svtools/inc/svtools/table/tablecontrol.hxx +++ b/svtools/inc/svtools/table/tablecontrol.hxx @@ -127,9 +127,14 @@ namespace svt { namespace table SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectName(AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const; SVT_DLLPRIVATE virtual sal_Bool GoToCell( sal_Int32 _nColumnPos, sal_Int32 _nRow ); SVT_DLLPRIVATE virtual ::rtl::OUString GetAccessibleObjectDescription(AccessibleTableControlObjType eObjType, sal_Int32 _nPosition = -1) const; - virtual void FillAccessibleStateSet( - ::utl::AccessibleStateSetHelper& rStateSet, - AccessibleTableControlObjType eObjType ) const; + SVT_DLLPRIVATE virtual void FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet, AccessibleTableControlObjType eObjType ) const; + + // temporary methods + // Those do not really belong into the public API - they're intended for firing A11Y-related events. However, + // firing those events should be an implementation internal to the TableControl resp. TableControl_Impl, + // instead of something triggered externally. + void commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const ::com::sun::star::uno::Any& i_newValue, const ::com::sun::star::uno::Any& i_oldValue ); + void commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const ::com::sun::star::uno::Any& i_newValue, const ::com::sun::star::uno::Any& i_oldValue ); // ............................................................................................................. // IAccessibleTable @@ -145,7 +150,9 @@ namespace svt { namespace table virtual sal_Bool HasRowHeader() const; virtual sal_Bool ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint ); virtual Rectangle calcHeaderRect( sal_Bool _bIsColumnBar, sal_Bool _bOnScreen = sal_True ); + virtual Rectangle calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos); virtual Rectangle calcTableRect( sal_Bool _bOnScreen = sal_True ); + virtual Rectangle calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ); virtual Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex); virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint); virtual void FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const; diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx index 5f81d6b5c7ab..99053fead039 100644 --- a/svtools/source/table/tablecontrol.cxx +++ b/svtools/source/table/tablecontrol.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> #include <tools/diagnose_ex.h> @@ -47,6 +48,8 @@ namespace svt { namespace table { //...................................................................................................................... + namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; + //================================================================================================================== //= TableControl //================================================================================================================== @@ -95,6 +98,27 @@ namespace svt { namespace table { if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) ) Control::KeyInput( rKEvt ); + else + { + if ( m_pImpl->isAccessibleAlive() ) + { + m_pImpl->commitCellEvent( AccessibleEventId::STATE_CHANGED, + makeAny( AccessibleStateType::FOCUSED ), + Any() + ); + // Huh? What the heck? Why do we unconditionally notify a STATE_CHANGE/FOCUSED after each and every + // (handled) key stroke? + + m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + Any(), + Any() + ); + // ditto: Why do we notify this unconditionally? We should find the right place to notify the + // ACTIVE_DESCENDANT_CHANGED event. + // Also, we should check if STATE_CHANGED/FOCUSED is really necessary: finally, the children are + // transient, aren't they? + } + } } @@ -274,10 +298,10 @@ namespace svt { namespace table switch( eObjType ) { case TCTYPE_GRIDCONTROL: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl" ) ); + aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control" ) ); break; case TCTYPE_TABLE: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Table" ) ); + aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid conrol" ) ); break; case TCTYPE_ROWHEADERBAR: aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) ); @@ -286,7 +310,19 @@ namespace svt { namespace table aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) ); break; case TCTYPE_TABLECELL: - aRetText = GetAccessibleCellText(_nRow, _nCol); + //the name of the cell constists of column name and row name if defined + //if the name is equal to cell content, it'll be read twice + if(GetModel()->hasColumnHeaders()) + { + aRetText = GetColumnName(_nCol); + aRetText += rtl::OUString::createFromAscii(" , "); + } + if(GetModel()->hasRowHeaders()) + { + aRetText += GetRowName(_nRow); + aRetText += rtl::OUString::createFromAscii(" , "); + } + //aRetText = GetAccessibleCellText(_nRow, _nCol); break; case TCTYPE_ROWHEADERCELL: aRetText = GetRowName(_nRow); @@ -307,7 +343,7 @@ namespace svt { namespace table switch( eObjType ) { case TCTYPE_GRIDCONTROL: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridControl description" ) ); + aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control description" ) ); break; case TCTYPE_TABLE: aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) ); @@ -319,7 +355,17 @@ namespace svt { namespace table aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) ); break; case TCTYPE_TABLECELL: - aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLECELL description" ) ); + // the description of the cell consists of column name and row name if defined + // if the name is equal to cell content, it'll be read twice + if ( GetModel()->hasColumnHeaders() ) + { + aRetText = GetColumnName( GetCurrentColumn() ); + aRetText += rtl::OUString::createFromAscii( " , " ); + } + if ( GetModel()->hasRowHeaders() ) + { + aRetText += GetRowName( GetCurrentRow() ); + } break; case TCTYPE_ROWHEADERCELL: aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERCELL description" ) ); @@ -384,38 +430,60 @@ namespace svt { namespace table case TCTYPE_TABLE: rStateSet.AddState( AccessibleStateType::FOCUSABLE ); - rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE); - if ( HasFocus() ) + + if ( m_pImpl->getSelEngine()->GetSelectionMode() == MULTIPLE_SELECTION ) + rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE); + + if ( HasChildPathFocus() ) rStateSet.AddState( AccessibleStateType::FOCUSED ); + if ( IsActive() ) rStateSet.AddState( AccessibleStateType::ACTIVE ); - if ( IsEnabled() ) + + if ( m_pImpl->getDataWindow().IsEnabled() ) + { rStateSet.AddState( AccessibleStateType::ENABLED ); + rStateSet.AddState( AccessibleStateType::SENSITIVE ); + } + if ( IsReallyVisible() ) rStateSet.AddState( AccessibleStateType::VISIBLE ); - rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); + if ( eObjType == TCTYPE_TABLE ) + rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); break; + case TCTYPE_ROWHEADERBAR: rStateSet.AddState( AccessibleStateType::VISIBLE ); rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); break; + case TCTYPE_COLUMNHEADERBAR: rStateSet.AddState( AccessibleStateType::VISIBLE ); rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); break; + case TCTYPE_TABLECELL: { + rStateSet.AddState( AccessibleStateType::FOCUSABLE ); + if ( HasChildPathFocus() ) + rStateSet.AddState( AccessibleStateType::FOCUSED ); + rStateSet.AddState( AccessibleStateType::ACTIVE ); rStateSet.AddState( AccessibleStateType::TRANSIENT ); rStateSet.AddState( AccessibleStateType::SELECTABLE); - if( GetSelectedRowCount()>0) - rStateSet.AddState( AccessibleStateType::SELECTED); + rStateSet.AddState( AccessibleStateType::VISIBLE ); + rStateSet.AddState( AccessibleStateType::SHOWING ); + if ( IsRowSelected( GetCurrentRow() ) ) + // Hmm? Wouldn't we expect the affected row to be a parameter to this function? + rStateSet.AddState( AccessibleStateType::SELECTED ); } break; + case TCTYPE_ROWHEADERCELL: rStateSet.AddState( AccessibleStateType::VISIBLE ); rStateSet.AddState( AccessibleStateType::TRANSIENT ); break; + case TCTYPE_COLUMNHEADERCELL: rStateSet.AddState( AccessibleStateType::VISIBLE ); break; @@ -423,6 +491,20 @@ namespace svt { namespace table } //------------------------------------------------------------------------------------------------------------------ + void TableControl::commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) + { + if ( m_pImpl->isAccessibleAlive() ) + m_pImpl->commitCellEvent( i_eventID, i_newValue, i_oldValue ); + } + + //------------------------------------------------------------------------------------------------------------------ + void TableControl::commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) + { + if ( m_pImpl->isAccessibleAlive() ) + m_pImpl->commitTableEvent( i_eventID, i_newValue, i_oldValue ); + } + + //------------------------------------------------------------------------------------------------------------------ Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) const { return Control::GetWindowExtentsRelative( pRelativeWindow ); @@ -467,13 +549,12 @@ namespace svt { namespace table //------------------------------------------------------------------------------------------------------------------ sal_Int32 TableControl::GetAccessibleControlCount() const { - sal_Int32 count = 0; - if(GetRowCount()>0) - count+=1; - if(GetModel()->hasRowHeaders()) - count+=1; - if(GetModel()->hasColumnHeaders()) - count+=1; + // TC_TABLE is always defined, no matter whether empty or not + sal_Int32 count = 1; + if ( GetModel()->hasRowHeaders() ) + ++count; + if ( GetModel()->hasColumnHeaders() ) + ++count; return count; } @@ -515,10 +596,20 @@ namespace svt { namespace table //------------------------------------------------------------------------------------------------------------------ void TableControl::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const { - if ( GetCurrentRow() == _nRow && GetCurrentColumn() == _nColumnPos ) + if ( IsRowSelected( _nRow ) ) + _rStateSet.AddState( AccessibleStateType::SELECTED ); + if ( HasChildPathFocus() ) _rStateSet.AddState( AccessibleStateType::FOCUSED ); else // only transient when column is not focused _rStateSet.AddState( AccessibleStateType::TRANSIENT ); + + _rStateSet.AddState( AccessibleStateType::VISIBLE ); + _rStateSet.AddState( AccessibleStateType::SHOWING ); + _rStateSet.AddState( AccessibleStateType::ENABLED ); + _rStateSet.AddState( AccessibleStateType::SENSITIVE ); + _rStateSet.AddState( AccessibleStateType::ACTIVE ); + + (void)_nColumnPos; } //------------------------------------------------------------------------------------------------------------------ @@ -545,6 +636,12 @@ namespace svt { namespace table } //------------------------------------------------------------------------------------------------------------------ + Rectangle TableControl::calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos ) + { + return m_pImpl->calcHeaderCellRect( _bIsColumnBar, nPos ); + } + + //------------------------------------------------------------------------------------------------------------------ Rectangle TableControl::calcTableRect(sal_Bool _bOnScreen) { (void)_bOnScreen; @@ -552,6 +649,12 @@ namespace svt { namespace table } //------------------------------------------------------------------------------------------------------------------ + Rectangle TableControl::calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos ) + { + return m_pImpl->calcCellRect( _nRowPos, _nColPos ); + } + + //------------------------------------------------------------------------------------------------------------------ IMPL_LINK_NOARG(TableControl, ImplSelectHdl) { Select(); @@ -576,6 +679,15 @@ namespace svt { namespace table void TableControl::Select() { ImplCallEventListenersAndHandler( VCLEVENT_TABLEROW_SELECT, m_pImpl->getSelectHandler(), this ); + + if ( m_pImpl->isAccessibleAlive() ) + { + m_pImpl->commitAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); + + m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), Any() ); + // TODO: why do we notify this when the *selection* changed? Shouldn't we find a better place for this, + // actually, when the active descendant, i.e. the current cell, *really* changed? + } } }} // namespace svt::table diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx index 07028ae4bc9a..a9539cbd7aca 100644 --- a/svtools/source/table/tablecontrol_impl.cxx +++ b/svtools/source/table/tablecontrol_impl.cxx @@ -541,20 +541,6 @@ namespace svt { namespace table makeAny( AccessibleTableModelChange( AccessibleTableModelChangeType::INSERT, i_first, i_last, 0, m_pModel->getColumnCount() ) ), Any() ); - impl_commitAccessibleEvent( AccessibleEventId::CHILD, - makeAny( m_pAccessibleTable->getTableHeader( TCTYPE_ROWHEADERBAR ) ), - Any() - ); - -// for ( sal_Int32 i = 0 ; i <= m_pModel->getColumnCount(); ++i ) -// { -// impl_commitAccessibleEvent( -// CHILD, -// makeAny( m_pAccessibleTable->getTable() ), -// Any()); -// } - // Huh? What's that? We're notifying |columnCount| CHILD events here, claiming the *table* itself - // has been inserted. Doesn't make much sense, does it? } // schedule repaint @@ -612,7 +598,7 @@ namespace svt { namespace table // notify A11Y events if ( impl_isAccessibleAlive() ) { - impl_commitAccessibleEvent( + commitTableEvent( AccessibleEventId::TABLE_MODEL_CHANGED, makeAny( AccessibleTableModelChange( AccessibleTableModelChangeType::DELETE, @@ -2500,6 +2486,28 @@ namespace svt { namespace table } //-------------------------------------------------------------------- + void TableControl_Impl::commitAccessibleEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) + { + impl_commitAccessibleEvent( i_eventID, i_newValue, i_oldValue ); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::commitCellEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) + { + DBG_CHECK_ME(); + if ( impl_isAccessibleAlive() ) + m_pAccessibleTable->commitCellEvent( i_eventID, i_newValue, i_oldValue ); + } + + //-------------------------------------------------------------------- + void TableControl_Impl::commitTableEvent( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue ) + { + DBG_CHECK_ME(); + if ( impl_isAccessibleAlive() ) + m_pAccessibleTable->commitTableEvent( i_eventID, i_newValue, i_oldValue ); + } + + //-------------------------------------------------------------------- Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader) { Rectangle const aRectTableWithHeaders( impl_getAllVisibleCellsArea() ); @@ -2511,12 +2519,32 @@ namespace svt { namespace table } //-------------------------------------------------------------------- + Rectangle TableControl_Impl::calcHeaderCellRect( bool bColHeader, sal_Int32 nPos ) + { + Rectangle const aHeaderRect = calcHeaderRect( bColHeader ); + TableCellGeometry const aGeometry( + *this, aHeaderRect, + bColHeader ? nPos : COL_ROW_HEADERS, + bColHeader ? ROW_COL_HEADERS : nPos + ); + return aGeometry.getRect(); + } + + //-------------------------------------------------------------------- Rectangle TableControl_Impl::calcTableRect() { return impl_getAllVisibleDataCellArea(); } //-------------------------------------------------------------------- + Rectangle TableControl_Impl::calcCellRect( sal_Int32 nRow, sal_Int32 nCol ) + { + Rectangle aCellRect; + impl_getCellRect( nRow, nCol, aCellRect ); + return aCellRect; + } + + //-------------------------------------------------------------------- IMPL_LINK( TableControl_Impl, OnUpdateScrollbars, void*, /**/ ) { DBG_CHECK_ME(); diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx index 77b76b3e3fc6..6fb6b94ee930 100644 --- a/svtools/source/table/tablecontrol_impl.hxx +++ b/svtools/source/table/tablecontrol_impl.hxx @@ -277,6 +277,10 @@ namespace svt { namespace table void setSelectHandler( Link const & i_selectHandler ) { m_aSelectHdl = i_selectHandler; } Link const& getSelectHandler() const { return m_aSelectHdl; } + void commitAccessibleEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue ); + void commitCellEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue ); + void commitTableEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue ); + // ITableControl virtual void hideCursor(); virtual void showCursor(); @@ -306,14 +310,18 @@ namespace svt { namespace table ScrollBar* getHorzScrollbar(); ScrollBar* getVertScrollbar(); - Rectangle calcHeaderRect(bool bColHeader); + Rectangle calcHeaderRect( bool bColHeader ); + Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos ); Rectangle calcTableRect(); + Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol ); // A11Y ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessible( Window& i_parentWindow ); void disposeAccessible(); + inline bool isAccessibleAlive() const { return impl_isAccessibleAlive(); } + // ITableModelListener virtual void rowsInserted( RowPos first, RowPos last ); virtual void rowsRemoved( RowPos first, RowPos last ); diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx index 41b6c12bdfc7..0a4ffaa8ace1 100644 --- a/svtools/source/uno/svtxgridcontrol.cxx +++ b/svtools/source/uno/svtxgridcontrol.cxx @@ -42,6 +42,8 @@ #include <com/sun/star/awt/XControl.hpp> #include <com/sun/star/awt/grid/GridInvalidDataException.hpp> #include <com/sun/star/awt/grid/GridInvalidModelException.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/util/Color.hpp> #include <com/sun/star/awt/FontDescriptor.hpp> @@ -693,26 +695,75 @@ void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent SolarMutexGuard aGuard; ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" ); + + bool handled = false; switch ( rVclWindowEvent.GetId() ) { case VCLEVENT_TABLEROW_SELECT: { - TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); - if ( !pTable ) - { - SAL_WARN( "svtools.uno", "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" ); - break; - } - if ( m_aSelectionListeners.getLength() ) ImplCallItemListeners(); + handled = true; } break; - default: - VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); - break; + case VCLEVENT_CONTROL_GETFOCUS: + { + // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also + // works when the control is used outside the UNO context + if ( pTable->GetRowCount()>0 ) + { + pTable->commitCellEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + makeAny( AccessibleStateType::FOCUSED ), + Any() + ); + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + Any(), + Any() + ); + } + else + { + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + makeAny( AccessibleStateType::FOCUSED ), + Any() + ); + } + } + break; + + case VCLEVENT_CONTROL_LOSEFOCUS: + { + // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also + // works when the control is used outside the UNO context + if ( pTable->GetRowCount()>0 ) + { + pTable->commitCellEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + Any(), + makeAny( AccessibleStateType::FOCUSED ) + ); + } + else + { + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + Any(), + makeAny( AccessibleStateType::FOCUSED ) + ); + } + } + break; } + + if ( !handled ) + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); } //---------------------------------------------------------------------------------------------------------------------- |