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/source/table | |
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/source/table')
-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 |
3 files changed, 183 insertions, 35 deletions
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 ); |