/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include "svtools/table/tablecontrol.hxx"

#include "tablegeometry.hxx"
#include "tablecontrol_impl.hxx"
#include "tabledatawindow.hxx"

#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>

using namespace ::com::sun::star::uno;
using ::com::sun::star::accessibility::XAccessible;
using namespace ::com::sun::star::accessibility;
using namespace ::com::sun::star::lang;
using namespace utl;

//......................................................................................................................
namespace svt { namespace table
{
//......................................................................................................................

    namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;

    //==================================================================================================================
	//= TableControl
    //==================================================================================================================
    // -----------------------------------------------------------------------------------------------------------------
    TableControl::TableControl( Window* _pParent, WinBits _nStyle )
        :Control( _pParent, _nStyle )
        ,m_pImpl( new TableControl_Impl( *this ) )
    {
		TableDataWindow& rDataWindow = m_pImpl->getDataWindow();
		rDataWindow.SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) );

        // by default, use the background as determined by the style settings
        const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() );
		SetBackground( Wallpaper( aWindowColor ) );
		SetFillColor( aWindowColor );

        SetCompoundControl( true );
    }

    // -----------------------------------------------------------------------------------------------------------------
    TableControl::~TableControl()
    {
		ImplCallEventListeners( VCLEVENT_OBJECT_DYING );

        m_pImpl->setModel( PTableModel() );
        m_pImpl->disposeAccessible();
        m_pImpl.reset();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::GetFocus()
    {
        if ( !m_pImpl->getInputHandler()->GetFocus( *m_pImpl ) )
            Control::GetFocus();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::LoseFocus()
    {
        if ( !m_pImpl->getInputHandler()->LoseFocus( *m_pImpl ) )
            Control::LoseFocus();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::KeyInput( const KeyEvent& rKEvt )
    {
        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?
            }
        }
    }


    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::StateChanged( StateChangedType i_nStateChange )
    {
        Control::StateChanged( i_nStateChange );

        // forward certain settings to the data window
        switch ( i_nStateChange )
        {
        case STATE_CHANGE_CONTROL_FOCUS:
            m_pImpl->invalidateSelectedRows();
            break;

        case STATE_CHANGE_CONTROLBACKGROUND:
            if ( IsControlBackground() )
                getDataWindow().SetControlBackground( GetControlBackground() );
            else
                getDataWindow().SetControlBackground();
            break;

        case STATE_CHANGE_CONTROLFOREGROUND:
            if ( IsControlForeground() )
                getDataWindow().SetControlForeground( GetControlForeground() );
            else
                getDataWindow().SetControlForeground();
            break;

        case STATE_CHANGE_CONTROLFONT:
            if ( IsControlFont() )
                getDataWindow().SetControlFont( GetControlFont() );
            else
                getDataWindow().SetControlFont();
            break;
        }
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::Resize()
    {
        Control::Resize();
        m_pImpl->onResize();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::SetModel( PTableModel _pModel )
    {
        m_pImpl->setModel( _pModel );
    }

    // -----------------------------------------------------------------------------------------------------------------
    PTableModel TableControl::GetModel() const
    {
        return m_pImpl->getModel();
    }

    // -----------------------------------------------------------------------------------------------------------------
    RowPos TableControl::GetTopRow() const
    {
        return m_pImpl->getTopRow();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::SetTopRow( RowPos _nRow )
    {
        OSL_ENSURE( false, "TableControl::SetTopRow: not implemented!" );
        OSL_UNUSED( _nRow );
    }

    // -----------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetCurrentRow() const
    {
        return m_pImpl->getCurrentRow();
    }

    // -----------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetCurrentColumn() const
    {
        return m_pImpl->getCurrentColumn();
    }

    // -----------------------------------------------------------------------------------------------------------------
    bool TableControl::GoTo( ColPos _nColumn, RowPos _nRow )
    {
        return m_pImpl->goTo( _nColumn, _nRow );
    }

	// -----------------------------------------------------------------------------------------------------------------
	sal_Bool TableControl::GoToCell(sal_Int32 _nColPos, sal_Int32 _nRowPos)
	{
		return m_pImpl->goTo( _nColPos, _nRowPos );
	}

    //------------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetSelectedRowCount() const
    {
	    return sal_Int32( m_pImpl->getSelectedRowCount() );
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetSelectedRowIndex( sal_Int32 const i_selectionIndex ) const
    {
	    return sal_Int32( m_pImpl->getSelectedRowIndex( i_selectionIndex ) );
    }

    //------------------------------------------------------------------------------------------------------------------
    bool TableControl::IsRowSelected( sal_Int32 const i_rowIndex ) const
    {
	    return m_pImpl->isRowSelected( i_rowIndex );
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::SelectRow( RowPos const i_rowIndex, bool const i_select )
    {
        ENSURE_OR_RETURN_VOID( ( i_rowIndex >= 0 ) && ( i_rowIndex < m_pImpl->getModel()->getRowCount() ),
            "TableControl::SelectRow: invalid row index!" );

        if ( i_select )
        {
            if ( !m_pImpl->markRowAsSelected( i_rowIndex ) )
                // nothing to do
                return;
        }
        else
        {
            m_pImpl->markRowAsDeselected( i_rowIndex );
        }

		m_pImpl->invalidateRowRange( i_rowIndex, i_rowIndex );
	    Select();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TableControl::SelectAllRows( bool const i_select )
    {
        if ( i_select )
        {
            if ( !m_pImpl->markAllRowsAsSelected() )
                // nothing to do
                return;
        }
        else
        {
            if ( !m_pImpl->markAllRowsAsDeselected() )
                // nothing to do
                return;
        }


        Invalidate();
            // TODO: can't we do better than this, and invalidate only the rows which changed?
        Select();
    }

    // -----------------------------------------------------------------------------------------------------------------
    ITableControl& TableControl::getTableControlInterface()
    {
        return *m_pImpl;
    }

    // -----------------------------------------------------------------------------------------------------------------
	SelectionEngine* TableControl::getSelEngine()
	{
		return m_pImpl->getSelEngine();
	}

    // -----------------------------------------------------------------------------------------------------------------
	Window& TableControl::getDataWindow()
	{
		return m_pImpl->getDataWindow();
	}

    // -----------------------------------------------------------------------------------------------------------------
	Reference< XAccessible > TableControl::CreateAccessible()
	{
		Window* pParent = GetAccessibleParentWindow();
		ENSURE_OR_RETURN( pParent, "TableControl::CreateAccessible - parent not found", NULL );

        return m_pImpl->getAccessible( *pParent );
	}

    // -----------------------------------------------------------------------------------------------------------------
	Reference<XAccessible> TableControl::CreateAccessibleControl( sal_Int32 _nIndex )
	{
		(void)_nIndex;
		DBG_ASSERT( sal_False, "TableControl::CreateAccessibleControl: to be overwritten!" );
		return NULL;
	}

    // -----------------------------------------------------------------------------------------------------------------
	::rtl::OUString TableControl::GetAccessibleObjectName( AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const
	{
		::rtl::OUString aRetText;
		//Window* pWin;
		switch( eObjType )
		{
			case TCTYPE_GRIDCONTROL:
				aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control" ) );
				break;
			case TCTYPE_TABLE:
				aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid conrol" ) );
				break;
			case TCTYPE_ROWHEADERBAR:
				aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) );
				break;
			case TCTYPE_COLUMNHEADERBAR:
				aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) );
				break;
			case TCTYPE_TABLECELL:
				//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);
				break;
			case TCTYPE_COLUMNHEADERCELL:
				aRetText = GetColumnName(_nCol);
				break;
			default:
				OSL_ENSURE(0,"GridControl::GetAccessibleName: invalid enum!");
		}
		return aRetText;
	}

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetAccessibleObjectDescription( AccessibleTableControlObjType eObjType, sal_Int32 ) const
    {
        ::rtl::OUString aRetText;
        switch( eObjType )
        {
            case TCTYPE_GRIDCONTROL:
			    aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control description" ) );
			    break;
            case TCTYPE_TABLE:
				    aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) );
			    break;
            case TCTYPE_ROWHEADERBAR:
				    aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERBAR description" ) );
			    break;
            case TCTYPE_COLUMNHEADERBAR:
				    aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) );
			    break;
            case TCTYPE_TABLECELL:
                // 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" ) );
			    break;
            case TCTYPE_COLUMNHEADERCELL:
				    aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERCELL description" ) );
			    break;
        }
        return aRetText;
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetRowDescription( sal_Int32 _nRow) const
    {
	    (void)_nRow;
	    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "row description" ) );
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetRowName( sal_Int32 _nIndex) const
    {
        ::rtl::OUString sRowName;
        GetModel()->getRowHeading( _nIndex ) >>= sRowName;
        return sRowName;
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetColumnDescription( sal_uInt16 _nColumn) const
    {
	    (void)_nColumn;
	    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "col description" ) );
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetColumnName( sal_Int32 _nIndex) const
    {
	    return GetModel()->getColumnModel(_nIndex)->getName();
    }

    //------------------------------------------------------------------------------------------------------------------
    ::com::sun::star::uno::Any TableControl::GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos ) const
    {
        Any aCellContent;
        GetModel()->getCellContent( _nColPos, _nRowPos, aCellContent );
        return aCellContent;
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString TableControl::GetAccessibleCellText( sal_Int32 _nRowPos, sal_Int32 _nColPos) const
    {
	    return m_pImpl->getCellContentAsString( _nRowPos, _nColPos );
    }

    //------------------------------------------------------------------------------------------------------------------
    void TableControl::FillAccessibleStateSet(
            ::utl::AccessibleStateSetHelper& rStateSet,
            AccessibleTableControlObjType eObjType ) const
    {
	    switch( eObjType )
        {
            case TCTYPE_GRIDCONTROL:
		    case TCTYPE_TABLE:

			    rStateSet.AddState( AccessibleStateType::FOCUSABLE );

                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 ( m_pImpl->getDataWindow().IsEnabled() )
                {
                    rStateSet.AddState( AccessibleStateType::ENABLED );
                    rStateSet.AddState( AccessibleStateType::SENSITIVE );
                }

                if ( IsReallyVisible() )
				    rStateSet.AddState( AccessibleStateType::VISIBLE );

                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);
                    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;
	    }
    }

    //------------------------------------------------------------------------------------------------------------------
    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 );
    }

    //------------------------------------------------------------------------------------------------------------------
    void TableControl::GrabFocus()
    {
	    Control::GrabFocus();
    }

    //------------------------------------------------------------------------------------------------------------------
    Reference< XAccessible > TableControl::GetAccessible( sal_Bool bCreate )
    {
	    return Control::GetAccessible( bCreate );
    }

    //------------------------------------------------------------------------------------------------------------------
    Window* TableControl::GetAccessibleParentWindow() const
    {
	    return Control::GetAccessibleParentWindow();
    }

    //------------------------------------------------------------------------------------------------------------------
    Window* TableControl::GetWindowInstance()
    {
	    return this;
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Bool TableControl::HasRowHeader()
    {
	    return GetModel()->hasRowHeaders();
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Bool TableControl::HasColHeader()
    {
	    return GetModel()->hasColumnHeaders();
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetAccessibleControlCount() const
    {
        // 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;
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Bool TableControl::ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint )
    {
	    sal_Int32 nRow = m_pImpl->getRowAtPoint( _rPoint );
	    sal_Int32 nCol = m_pImpl->getColAtPoint( _rPoint );
	    _rnIndex = nRow * GetColumnCount() + nCol;
        return nRow >= 0 ? sal_True : sal_False;
    }

    //------------------------------------------------------------------------------------------------------------------
    long TableControl::GetRowCount() const
    {
	    return GetModel()->getRowCount();
    }

    //------------------------------------------------------------------------------------------------------------------
    long TableControl::GetColumnCount() const
    {
	    return GetModel()->getColumnCount();
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Bool TableControl::HasRowHeader() const
    {
	    return GetModel()->hasRowHeaders();
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Bool TableControl::ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint )
    {
	    _rnRow = m_pImpl->getRowAtPoint( _rPoint );
	    _rnColPos = m_pImpl->getColAtPoint( _rPoint );
	    return _rnRow >= 0 ? sal_True : sal_False;
    }

    //------------------------------------------------------------------------------------------------------------------
    void TableControl::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
    {
        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;
    }

    //------------------------------------------------------------------------------------------------------------------
    Rectangle TableControl::GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex)
    {
	    (void)_nRow;
	    (void)_nColumnPos;
	    return GetCharacterBounds(nIndex);
    }

    //------------------------------------------------------------------------------------------------------------------
    sal_Int32 TableControl::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
    {
	    (void)_nRow;
	    (void)_nColumnPos;
	    return GetIndexForPoint(_rPoint);
    }

    //------------------------------------------------------------------------------------------------------------------
    Rectangle TableControl::calcHeaderRect(sal_Bool _bIsColumnBar,sal_Bool _bOnScreen)
    {
	    (void)_bOnScreen;
        return m_pImpl->calcHeaderRect( _bIsColumnBar ? false : true );
    }

    //------------------------------------------------------------------------------------------------------------------
    Rectangle TableControl::calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos )
    {
        return m_pImpl->calcHeaderCellRect( _bIsColumnBar, nPos );
    }

    //------------------------------------------------------------------------------------------------------------------
    Rectangle TableControl::calcTableRect(sal_Bool _bOnScreen)
    {
	    (void)_bOnScreen;
	    return m_pImpl->calcTableRect();
    }

    //------------------------------------------------------------------------------------------------------------------
    Rectangle TableControl::calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos )
    {
        return m_pImpl->calcCellRect( _nRowPos, _nColPos );
    }
    //------------------------------------------------------------------------------------------------------------------
    IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG )
    {
	    Select();
	    return 1;
    }

    //------------------------------------------------------------------------------------------------------------------
    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?
        }
    }

    //------------------------------------------------------------------------------------------------------------------
    void TableControl::SetSelectHdl( const Link& i_selectHandler )
    {
        m_pImpl->setSelectHandler( i_selectHandler );
    }

    //------------------------------------------------------------------------------------------------------------------
    const Link& TableControl::GetSelectHdl() const
    {
        return m_pImpl->getSelectHandler();
    }

//......................................................................................................................
}} // namespace svt::table
//......................................................................................................................
