summaryrefslogtreecommitdiff
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
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>
-rw-r--r--accessibility/inc/accessibility/extended/AccessibleGridControl.hxx37
-rw-r--r--accessibility/inc/accessibility/extended/AccessibleGridControlBase.hxx1
-rw-r--r--accessibility/inc/accessibility/extended/AccessibleGridControlTable.hxx10
-rw-r--r--accessibility/inc/accessibility/extended/AccessibleGridControlTableBase.hxx8
-rw-r--r--accessibility/source/extended/AccessibleGridControl.cxx83
-rw-r--r--accessibility/source/extended/AccessibleGridControlBase.cxx9
-rw-r--r--accessibility/source/extended/AccessibleGridControlHeader.cxx16
-rw-r--r--accessibility/source/extended/AccessibleGridControlHeaderCell.cxx19
-rw-r--r--accessibility/source/extended/AccessibleGridControlTable.cxx61
-rw-r--r--accessibility/source/extended/AccessibleGridControlTableCell.cxx18
-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
16 files changed, 531 insertions, 62 deletions
diff --git a/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx b/accessibility/inc/accessibility/extended/AccessibleGridControl.hxx
index 9df2f960cf2b..81bdf2a7cd8b 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 7c4d22ed720a..c032e38d3959 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 65d573a3d128..95acb0d31371 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 daa6fd179ef6..54491c24272e 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 a093318ffd3a..e8058eab628d 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 c092e4872997..ecccf07c0041 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 27dfb6084d18..609000d3d62a 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 e0fb0c10695d..8ad0a949ff6c 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 55b204d05ebc..b0e2e4e6c02b 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 caef437f341f..f32eec0a1f1f 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 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 );
}
//----------------------------------------------------------------------------------------------------------------------