summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorNorbert Thiebaud <nthiebaud@gmail.com>2012-08-31 00:46:39 -0500
committerMiklos Vajna <vmiklos@suse.cz>2012-09-14 07:15:44 +0000
commit2095b2e1d44a158418d17836019352ed92f95d21 (patch)
tree1201a5ba0c1c7e664194b40493e2a56803a6588c /svtools
parent3d934d48606acf8c5c96d0d8b96e2f202db1f37d (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.hxx29
-rw-r--r--svtools/inc/svtools/table/tablecontrol.hxx13
-rw-r--r--svtools/source/table/tablecontrol.cxx150
-rw-r--r--svtools/source/table/tablecontrol_impl.cxx58
-rw-r--r--svtools/source/table/tablecontrol_impl.hxx10
-rw-r--r--svtools/source/uno/svtxgridcontrol.cxx71
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 );
}
//----------------------------------------------------------------------------------------------------------------------