[Libreoffice-commits] .: accessibility/inc accessibility/source svtools/inc svtools/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Sep 14 00:16:05 PDT 2012


 accessibility/inc/accessibility/extended/AccessibleGridControl.hxx          |   37 ++
 accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx      |    1 
 accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx     |   10 
 accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx |    8 
 accessibility/source/extended/AccessibleGridControl.cxx                     |   83 +++++
 accessibility/source/extended/AccessibleGridControlBase.cxx                 |    9 
 accessibility/source/extended/AccessibleGridControlHeader.cxx               |   16 -
 accessibility/source/extended/AccessibleGridControlHeaderCell.cxx           |   19 +
 accessibility/source/extended/AccessibleGridControlTable.cxx                |   61 +++-
 accessibility/source/extended/AccessibleGridControlTableCell.cxx            |   18 +
 svtools/inc/svtools/accessibletable.hxx                                     |   29 +
 svtools/inc/svtools/table/tablecontrol.hxx                                  |   13 
 svtools/source/table/tablecontrol.cxx                                       |  150 ++++++++--
 svtools/source/table/tablecontrol_impl.cxx                                  |   58 ++-
 svtools/source/table/tablecontrol_impl.hxx                                  |   10 
 svtools/source/uno/svtxgridcontrol.cxx                                      |   71 ++++
 16 files changed, 531 insertions(+), 62 deletions(-)

New commits:
commit 2095b2e1d44a158418d17836019352ed92f95d21
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Fri Aug 31 00:46:39 2012 -0500

    gridfixes: copied #i112562#'s fix from CWS gridcontrol06 herein
    
    Change-Id: Ifa29a8b3c027970d46844b428a3529e680c0b09c
    Reviewed-on: https://gerrit.libreoffice.org/541
    Reviewed-by: Miklos Vajna <vmiklos at suse.cz>
    Tested-by: Miklos Vajna <vmiklos at suse.cz>

diff --git a/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx b/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx
index 9df2f96..81bdf2a 100644
--- a/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx
+++ b/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx
@@ -35,7 +35,6 @@
 #include <cppuhelper/weakref.hxx>
 #include <svtools/accessibletable.hxx>
 
-
 #include <memory>
 
 using namespace ::svt::table;
@@ -112,6 +111,28 @@ protected:
 
 public:
     // helper functions
+
+     /** commitCellEvent commit the event at all listeners of the table
+         @param nEventId
+             the event id
+         @param rNewValue
+             the new value
+         @param rOldValue
+             the old value
+     */
+     void commitCellEvent(sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue,
+             const ::com::sun::star::uno::Any& rOldValue);
+
+     /** commitTableEvent commit the event at all listeners of the table
+         @param nEventId
+             the event id
+         @param rNewValue
+             the new value
+         @param rOldValue
+             the old value
+     */
+     void commitTableEvent(sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue,
+             const ::com::sun::star::uno::Any& rOldValue);
     /** returns the accessible object for the row or the column header bar
     */
     inline ::com::sun::star::uno::Reference<
@@ -243,6 +264,20 @@ protected:
             xAccessible = pContext->getTable();
         return xAccessible;
     }
+    virtual void commitCellEvent( sal_Int16 nEventId,
+         const ::com::sun::star::uno::Any& rNewValue, const ::com::sun::star::uno::Any& rOldValue )
+    {
+         AccessibleGridControl* pContext( getContext() );
+         if ( pContext )
+            pContext->commitCellEvent( nEventId, rNewValue, rOldValue );
+    }
+    virtual void commitTableEvent( sal_Int16 nEventId,
+         const ::com::sun::star::uno::Any& rNewValue, const ::com::sun::star::uno::Any& rOldValue )
+    {
+         AccessibleGridControl* pContext( getContext() );
+         if ( pContext )
+            pContext->commitTableEvent( nEventId, rNewValue, rOldValue );
+    }
     virtual void commitEvent( sal_Int16 nEventId,
         const ::com::sun::star::uno::Any& rNewValue, const ::com::sun::star::uno::Any& rOldValue )
     {
diff --git a/accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx b/accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx
index 7c4d22e..c032e38 100644
--- a/accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx
+++ b/accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx
@@ -47,7 +47,6 @@
 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
 #include <com/sun/star/accessibility/AccessibleRole.hpp>
 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
-#include <com/sun/star/awt/XFocusListener.hpp>
 #include <comphelper/accessibleeventnotifier.hxx>
 #include <comphelper/uno3.hxx>
 
diff --git a/accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx b/accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx
index 65d573a..95acb0d 100644
--- a/accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx
+++ b/accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx
@@ -33,6 +33,7 @@
 #include "accessibility/extended/AccessibleGridControlTableBase.hxx"
 #include <cppuhelper/implbase1.hxx>
 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <accessibility/extended/AccessibleGridControlTableCell.hxx>
 
 // ============================================================================
 
@@ -56,7 +57,9 @@ public:
 
 protected:
     virtual ~AccessibleGridControlTable();
-
+private:
+    std::vector< AccessibleGridControlTableCell* > m_pCellVector;
+    std::vector< com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible> > m_pAccessCellVector;
 public:
     // XAccessibleContext -----------------------------------------------------
 
@@ -197,6 +200,11 @@ public:
     virtual OUString SAL_CALL getImplementationName()
         throw ( ::com::sun::star::uno::RuntimeException );
 
+    /**@return m_pCellVector*/
+    std::vector< AccessibleGridControlTableCell* >& getCellVector();
+    /**@return m_xAccessCellVector*/
+    std::vector< com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible > >& getAccessibleCellVector();
+
 protected:
     // internal virtual methods -----------------------------------------------
 
diff --git a/accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx b/accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx
index daa6fd1..54491c2 100644
--- a/accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx
+++ b/accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx
@@ -174,6 +174,14 @@ public:
 protected:
     // internal helper methods ------------------------------------------------
 
+//    /** @attention  This method requires locked mutex's and a living object.
+//        @param nColumn
+//            the position of the column in the Accessible world
+//        @return
+//            the position of the column in VCL the Accessible world
+//    */
+//    sal_uInt16 implToVCLColumnPos( sal_Int32 nColumn ) const;
+
     /** @attention  This method requires locked mutex's and a living object.
         @return  The number of cells of the table. */
     sal_Int32 implGetChildCount() const;
diff --git a/accessibility/source/extended/AccessibleGridControl.cxx b/accessibility/source/extended/AccessibleGridControl.cxx
index a093318..e8058ea 100644
--- a/accessibility/source/extended/AccessibleGridControl.cxx
+++ b/accessibility/source/extended/AccessibleGridControl.cxx
@@ -29,6 +29,9 @@
 #include "accessibility/extended/AccessibleGridControl.hxx"
 #include "accessibility/extended/AccessibleGridControlTable.hxx"
 #include "accessibility/extended/AccessibleGridControlHeader.hxx"
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
+#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
 #include <svtools/accessibletable.hxx>
 #include <comphelper/types.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
@@ -68,6 +71,12 @@ public:
     Reference<
         ::com::sun::star::accessibility::XAccessible >          m_xColumnHeaderBar;
     AccessibleGridControlHeader*                m_pColumnHeaderBar;
+
+    /** The table cell child. */
+    Reference<
+        ::com::sun::star::accessibility::XAccessible >          m_xCell;
+    AccessibleGridControlTableCell*             m_pCell;
+
 };
 
 AccessibleGridControl::AccessibleGridControl(
@@ -92,6 +101,7 @@ void SAL_CALL AccessibleGridControl::disposing()
     m_pImpl->m_pTable       = NULL;
     m_pImpl->m_pColumnHeaderBar = NULL;
     m_pImpl->m_pRowHeaderBar    = NULL;
+    m_pImpl->m_pCell            = NULL;
     m_pImpl->m_aCreator         = Reference< XAccessible >();
 
     Reference< XAccessible >  xTable = m_pImpl->m_xTable;
@@ -101,7 +111,16 @@ void SAL_CALL AccessibleGridControl::disposing()
     {
         xComp->dispose();
     }
+    Reference< XAccessible >  xCell = m_pImpl->m_xCell;
+
+    Reference< XComponent > xCellComp( m_pImpl->m_xCell, UNO_QUERY );
+    if ( xCellComp.is() )
+    {
+        xCellComp->dispose();
+    }
 
+    ::comphelper::disposeComponent(m_pImpl->m_xRowHeaderBar);
+    ::comphelper::disposeComponent(m_pImpl->m_xColumnHeaderBar);
     AccessibleGridControlBase::disposing();
 }
 // -----------------------------------------------------------------------------
@@ -151,8 +170,12 @@ AccessibleGridControl::getAccessibleChild( sal_Int32 nChildIndex )
         }
         else
         {
+            if(!m_pImpl->m_xTable.is())
+            {
             AccessibleGridControlTable* pTable = new AccessibleGridControlTable(m_pImpl->m_aCreator, m_aTable, svt::table::TCTYPE_TABLE);
             m_pImpl->m_xTable = pTable;
+                m_pImpl->m_pTable = pTable;
+            }
             xChild = m_pImpl->m_xTable;
         }
     }
@@ -311,6 +334,66 @@ AccessibleGridControlTable* AccessibleGridControl::createAccessibleTable()
         OSL_ENSURE( xCreator.is(), "accessibility/extended/AccessibleGirdControl::createAccessibleTable: my creator died - how this?" );
     return new AccessibleGridControlTable( xCreator, m_aTable, TCTYPE_TABLE );
 }
+// -----------------------------------------------------------------------------
+void AccessibleGridControl::commitCellEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
+{
+    sal_Int32 nChildCount = getAccessibleChildCount();
+    if(nChildCount != 0)
+    {
+        for(sal_Int32 i=0;i<nChildCount;i++)
+        {
+            Reference< XAccessible > xAccessible = getAccessibleChild(i);
+            com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessibleContext > xAccessibleChild = xAccessible->getAccessibleContext();
+            if(m_pImpl->m_xTable == xAccessible)
+            {
+                std::vector< AccessibleGridControlTableCell* > xCellCont = m_pImpl->m_pTable->getCellVector();
+                int nIndex = m_aTable.GetCurrentRow()*m_aTable.GetColumnCount()+m_aTable.GetCurrentColumn();
+                if(!xCellCont.empty() && xCellCont[nIndex])
+                {
+                    m_pImpl->m_pCell = xCellCont[nIndex];
+                    m_pImpl->m_pCell->commitEvent( _nEventId, _rNewValue, _rOldValue );
+                }
+            }
+        }
+    }
+    else
+    {
+        if ( m_pImpl->m_xTable.is() )
+            m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
+    }
+}
+
+void AccessibleGridControl::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
+{
+    if ( m_pImpl->m_xTable.is() )
+    {
+        if(_nEventId == AccessibleEventId::ACTIVE_DESCENDANT_CHANGED)
+        {
+            Reference< XAccessible > xChild = m_pImpl->m_pTable->getAccessibleChild(m_aTable.GetCurrentRow()*m_aTable.GetColumnCount()+m_aTable.GetCurrentColumn());
+            m_pImpl->m_pTable->commitEvent(_nEventId, makeAny(xChild),_rOldValue);
+        }
+        else if(_nEventId == AccessibleEventId::TABLE_MODEL_CHANGED)
+        {
+            AccessibleTableModelChange aChange;
+            if(_rNewValue >>= aChange)
+            {
+                if(aChange.Type == AccessibleTableModelChangeType::DELETE)
+                {
+                    std::vector< AccessibleGridControlTableCell* >::iterator m_pCell = m_pImpl->m_pTable->getCellVector().begin();
+                    std::vector< Reference< XAccessible > >::iterator m_xAccessibleVector = m_pImpl->m_pTable->getAccessibleCellVector().begin();
+                    int nColCount = m_aTable.GetColumnCount();
+                    m_pImpl->m_pTable->getCellVector().erase(m_pCell+nColCount*aChange.FirstRow, m_pCell+nColCount*aChange.LastRow );
+                    m_pImpl->m_pTable->getAccessibleCellVector().erase(m_xAccessibleVector+nColCount*aChange.FirstRow, m_xAccessibleVector+nColCount*aChange.LastRow);
+                    m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
+                }
+                else
+                    m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
+            }
+        }
+        else
+            m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
+    }
+}
 // ============================================================================
 // = AccessibleGridControlAccess
 // ============================================================================
diff --git a/accessibility/source/extended/AccessibleGridControlBase.cxx b/accessibility/source/extended/AccessibleGridControlBase.cxx
index c092e48..ecccf07 100644
--- a/accessibility/source/extended/AccessibleGridControlBase.cxx
+++ b/accessibility/source/extended/AccessibleGridControlBase.cxx
@@ -81,7 +81,16 @@ AccessibleGridControlBase::~AccessibleGridControlBase()
 void SAL_CALL AccessibleGridControlBase::disposing()
 {
     ::osl::MutexGuard aGuard( getOslMutex() );
+
+    if ( getClientId( ) )
+    {
+        AccessibleEventNotifier::TClientId nId( getClientId( ) );
+        setClientId( 0 );
+        AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
+    }
+
     m_xParent = NULL;
+    //m_aTable = NULL;
 }
 
 // XAccessibleContext ---------------------------------------------------------
diff --git a/accessibility/source/extended/AccessibleGridControlHeader.cxx b/accessibility/source/extended/AccessibleGridControlHeader.cxx
index 27dfb60..609000d 100644
--- a/accessibility/source/extended/AccessibleGridControlHeader.cxx
+++ b/accessibility/source/extended/AccessibleGridControlHeader.cxx
@@ -235,12 +235,24 @@ Sequence< sal_Int8 > SAL_CALL AccessibleGridControlHeader::getImplementationId()
 
 Rectangle AccessibleGridControlHeader::implGetBoundingBox()
 {
-    return m_aTable.calcHeaderRect(isColumnBar());
+    Window* pParent = m_aTable.GetAccessibleParentWindow();
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ) );
+    Rectangle aHeaderRect (m_aTable.calcHeaderRect(isColumnBar()));
+    if(isColumnBar())
+        return Rectangle(aGridRect.TopLeft(), Size(aGridRect.getWidth(),aHeaderRect.getHeight()));
+    else
+        return Rectangle(aGridRect.TopLeft(), Size(aHeaderRect.getWidth(),aGridRect.getHeight()));
+
 }
 
 Rectangle AccessibleGridControlHeader::implGetBoundingBoxOnScreen()
 {
-    return m_aTable.calcHeaderRect(isColumnBar());
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL ) );
+    Rectangle aHeaderRect (m_aTable.calcHeaderRect(isColumnBar()));
+    if(isColumnBar())
+        return Rectangle(aGridRect.TopLeft(), Size(aGridRect.getWidth(),aHeaderRect.getHeight()));
+    else
+        return Rectangle(aGridRect.TopLeft(), Size(aHeaderRect.getWidth(),aGridRect.getHeight()));
 }
 
 sal_Int32 AccessibleGridControlHeader::implGetRowCount() const
diff --git a/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx
index e0fb0c1..8ad0a94 100644
--- a/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx
+++ b/accessibility/source/extended/AccessibleGridControlHeaderCell.cxx
@@ -145,13 +145,28 @@ OUString SAL_CALL AccessibleGridControlHeaderCell::getImplementationName()
 // -----------------------------------------------------------------------------
 Rectangle AccessibleGridControlHeaderCell::implGetBoundingBox()
 {
-    return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle
+    Window* pParent = m_aTable.GetAccessibleParentWindow();
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ) );
+    sal_Int32 nIndex = getAccessibleIndexInParent();
+    Rectangle aCellRect;
+    if(m_eObjType == TCTYPE_COLUMNHEADERCELL)
+        aCellRect = m_aTable.calcHeaderCellRect(true, nIndex);
+    else
+        aCellRect = m_aTable.calcHeaderCellRect(false, nIndex);
+    return Rectangle(Point(aGridRect.Left()+aCellRect.Left(),aGridRect.Top()+aCellRect.Top()), aCellRect.GetSize());
 }
 // -----------------------------------------------------------------------------
 
 Rectangle AccessibleGridControlHeaderCell::implGetBoundingBoxOnScreen()
 {
-    return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL ) );
+    sal_Int32 nIndex = getAccessibleIndexInParent();
+    Rectangle aCellRect;
+    if(m_eObjType == TCTYPE_COLUMNHEADERCELL)
+        aCellRect = m_aTable.calcHeaderCellRect(true, nIndex);
+    else
+        aCellRect = m_aTable.calcHeaderCellRect(false, nIndex);
+    return Rectangle(Point(aGridRect.Left()+aCellRect.Left(),aGridRect.Top()+aCellRect.Top()), aCellRect.GetSize());
 }
 // -----------------------------------------------------------------------------
 sal_Int32 SAL_CALL AccessibleGridControlHeaderCell::getAccessibleIndexInParent()
diff --git a/accessibility/source/extended/AccessibleGridControlTable.cxx b/accessibility/source/extended/AccessibleGridControlTable.cxx
index 55b204d..b0e2e4e 100644
--- a/accessibility/source/extended/AccessibleGridControlTable.cxx
+++ b/accessibility/source/extended/AccessibleGridControlTable.cxx
@@ -51,6 +51,8 @@ AccessibleGridControlTable::AccessibleGridControlTable(
         IAccessibleTable& rTable,
         AccessibleTableControlObjType _eType) :
     AccessibleGridControlTableBase( rxParent, rTable, _eType )
+        ,m_pCellVector( )
+        ,m_pAccessCellVector( )
 {
 }
 
@@ -68,7 +70,19 @@ AccessibleGridControlTable::getAccessibleChild( sal_Int32 nChildIndex )
     ::osl::MutexGuard aGuard( getOslMutex() );
     ensureIsAlive();
     ensureIsValidIndex( nChildIndex );
-    return new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL);
+    sal_Int32 nCount = getAccessibleChildCount();
+    if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
+    {
+        m_pAccessCellVector.resize(nCount);
+        m_pCellVector.resize(nCount);
+    }
+    if(!m_pAccessCellVector[nChildIndex].is())
+    {
+        AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nChildIndex/m_aTable.GetColumnCount(), nChildIndex%m_aTable.GetColumnCount(), TCTYPE_TABLECELL);
+        m_pCellVector[nChildIndex] = pCell;
+        m_pAccessCellVector[nChildIndex] = pCell;
+    }
+    return m_pAccessCellVector[nChildIndex];
 }
 
 sal_Int32 SAL_CALL AccessibleGridControlTable::getAccessibleIndexInParent()
@@ -98,7 +112,6 @@ AccessibleGridControlTable::getAccessibleAtPoint( const awt::Point& rPoint )
     sal_Int32 nColumnPos = 0;
     if( m_aTable.ConvertPointToCellAddress( nRow, nColumnPos, VCLPoint( rPoint ) ) )
         xChild = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumnPos, TCTYPE_TABLECELL);
-
     return xChild;
 }
 
@@ -214,7 +227,20 @@ Reference< XAccessible > SAL_CALL AccessibleGridControlTable::getAccessibleCellA
     ::osl::MutexGuard aGuard( getOslMutex() );
     ensureIsAlive();
     ensureIsValidAddress( nRow, nColumn );
-    return new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL);
+    sal_Int32 nCount = getAccessibleChildCount();
+    sal_Int32 nChildIndex = nRow*m_aTable.GetColumnCount() + nColumn;
+    if(m_pAccessCellVector.size() == 0 || m_pAccessCellVector.size() != (unsigned)nCount)
+    {
+        m_pAccessCellVector.resize(nCount);
+        m_pCellVector.resize(nCount);
+    }
+    if(!m_pAccessCellVector[nChildIndex].is())
+    {
+        AccessibleGridControlTableCell* pCell = new AccessibleGridControlTableCell(this, m_aTable, nRow, nColumn, TCTYPE_TABLECELL);
+        m_pCellVector[nChildIndex] = pCell;
+        m_pAccessCellVector[nChildIndex] = pCell;
+    }
+    return m_pAccessCellVector[nChildIndex];
 }
 
 sal_Bool SAL_CALL AccessibleGridControlTable::isAccessibleSelected(
@@ -332,12 +358,28 @@ OUString SAL_CALL AccessibleGridControlTable::getImplementationName()
 
 Rectangle AccessibleGridControlTable::implGetBoundingBox()
 {
-    return m_aTable.calcTableRect();
+    Window* pParent = m_aTable.GetAccessibleParentWindow();
+    DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( pParent ));
+    Rectangle aTableRect( m_aTable.calcTableRect() );
+    long nX = aGridRect.Left() + aTableRect.Left();
+    long nY = aGridRect.Top() + aTableRect.Top();
+    long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
+    long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
+    Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
+    return aTable;
 }
 
 Rectangle AccessibleGridControlTable::implGetBoundingBoxOnScreen()
 {
-    return m_aTable.calcTableRect();
+    Rectangle aGridRect( m_aTable.GetWindowExtentsRelative( NULL ));
+    Rectangle aTableRect( m_aTable.calcTableRect() );
+    long nX = aGridRect.Left() + aTableRect.Left();
+    long nY = aGridRect.Top() + aTableRect.Top();
+    long nWidth = aGridRect.GetSize().Width()-aTableRect.Left();
+    long nHeight = aGridRect.GetSize().Height()-aTableRect.Top();
+    Rectangle aTable( Point( nX, nY ), Size( nWidth, nHeight ));
+    return aTable;
 }
 // internal helper methods ----------------------------------------------------
 Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
@@ -361,6 +403,15 @@ Reference< XAccessibleTable > AccessibleGridControlTable::implGetHeaderBar(
     return Reference< XAccessibleTable >( xRet, uno::UNO_QUERY );
 }
 
+std::vector< AccessibleGridControlTableCell* >& AccessibleGridControlTable::getCellVector()
+{
+    return m_pCellVector;
+}
+
+std::vector< Reference< XAccessible > >& AccessibleGridControlTable::getAccessibleCellVector()
+{
+    return m_pAccessCellVector;
+}
 // ============================================================================
 
 } // namespace accessibility
diff --git a/accessibility/source/extended/AccessibleGridControlTableCell.cxx b/accessibility/source/extended/AccessibleGridControlTableCell.cxx
index caef437..f32eec0 100644
--- a/accessibility/source/extended/AccessibleGridControlTableCell.cxx
+++ b/accessibility/source/extended/AccessibleGridControlTableCell.cxx
@@ -355,12 +355,26 @@ namespace accessibility
 
     Rectangle AccessibleGridControlTableCell::implGetBoundingBox()
     {
-        return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle
+        Window* pParent = m_aTable.GetAccessibleParentWindow();
+        DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
+        Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( pParent );
+        sal_Int32 nIndex = getAccessibleIndexInParent();
+        Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
+        long nX = aGridRect.Left() + aCellRect.Left();
+        long nY = aGridRect.Top() + aCellRect.Top();
+        Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
+        return aCell;
     }
     // -----------------------------------------------------------------------------
     Rectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen()
     {
-        return Rectangle(Point(0,0),Point(0,0));//To Do - return headercell rectangle
+        Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( NULL );
+        sal_Int32 nIndex = getAccessibleIndexInParent();
+        Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
+        long nX = aGridRect.Left() + aCellRect.Left();
+        long nY = aGridRect.Top() + aCellRect.Top();
+        Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
+        return aCell;
     }
 }
 
diff --git a/svtools/inc/svtools/accessibletable.hxx b/svtools/inc/svtools/accessibletable.hxx
index 5d8c932..edeaf25 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 cb2ddaf..c3078d8 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 5f81d6b..99053fe 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 07028ae..a9539cb 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 77b76b3..6fb6b94 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 41b6c12..0a4ffaa 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 );
 }
 
 //----------------------------------------------------------------------------------------------------------------------


More information about the Libreoffice-commits mailing list