xref: /trunk/main/svtools/source/table/tablecontrol.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25 ************************************************************************/
26 
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_svtools.hxx"
29 
30 #include "svtools/table/tablecontrol.hxx"
31 
32 #include "tablegeometry.hxx"
33 #include "tablecontrol_impl.hxx"
34 #include "tabledatawindow.hxx"
35 
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
39 
40 #include <tools/diagnose_ex.h>
41 
42 using namespace ::com::sun::star::uno;
43 using ::com::sun::star::accessibility::XAccessible;
44 using namespace ::com::sun::star::accessibility;
45 using namespace ::com::sun::star::lang;
46 using namespace utl;
47 
48 //......................................................................................................................
49 namespace svt { namespace table
50 {
51 //......................................................................................................................
52 
53     namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
54 
55     //==================================================================================================================
56     //= TableControl
57     //==================================================================================================================
58     // -----------------------------------------------------------------------------------------------------------------
59     TableControl::TableControl( Window* _pParent, WinBits _nStyle )
60         :Control( _pParent, _nStyle )
61         ,m_pImpl( new TableControl_Impl( *this ) )
62     {
63         TableDataWindow& rDataWindow = m_pImpl->getDataWindow();
64         rDataWindow.SetSelectHdl( LINK( this, TableControl, ImplSelectHdl ) );
65 
66         // by default, use the background as determined by the style settings
67         const Color aWindowColor( GetSettings().GetStyleSettings().GetFieldColor() );
68         SetBackground( Wallpaper( aWindowColor ) );
69         SetFillColor( aWindowColor );
70 
71         SetCompoundControl( true );
72     }
73 
74     // -----------------------------------------------------------------------------------------------------------------
75     TableControl::~TableControl()
76     {
77         ImplCallEventListeners( VCLEVENT_OBJECT_DYING );
78 
79         m_pImpl->setModel( PTableModel() );
80         m_pImpl->disposeAccessible();
81         m_pImpl.reset();
82     }
83 
84     // -----------------------------------------------------------------------------------------------------------------
85     void TableControl::GetFocus()
86     {
87         if ( !m_pImpl->getInputHandler()->GetFocus( *m_pImpl ) )
88             Control::GetFocus();
89     }
90 
91     // -----------------------------------------------------------------------------------------------------------------
92     void TableControl::LoseFocus()
93     {
94         if ( !m_pImpl->getInputHandler()->LoseFocus( *m_pImpl ) )
95             Control::LoseFocus();
96     }
97 
98     // -----------------------------------------------------------------------------------------------------------------
99     void TableControl::KeyInput( const KeyEvent& rKEvt )
100     {
101         if ( !m_pImpl->getInputHandler()->KeyInput( *m_pImpl, rKEvt ) )
102             Control::KeyInput( rKEvt );
103         else
104         {
105             if ( m_pImpl->isAccessibleAlive() )
106             {
107                 m_pImpl->commitCellEvent( AccessibleEventId::STATE_CHANGED,
108                                           makeAny( AccessibleStateType::FOCUSED ),
109                                           Any()
110                                         );
111                     // Huh? What the heck? Why do we unconditionally notify a STATE_CHANGE/FOCUSED after each and every
112                     // (handled) key stroke?
113 
114                 m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
115                                            Any(),
116                                            Any()
117                                          );
118                     // ditto: Why do we notify this unconditionally? We should find the right place to notify the
119                     // ACTIVE_DESCENDANT_CHANGED event.
120                     // Also, we should check if STATE_CHANGED/FOCUSED is really necessary: finally, the children are
121                     // transient, aren't they?
122             }
123         }
124     }
125 
126 
127     // -----------------------------------------------------------------------------------------------------------------
128     void TableControl::StateChanged( StateChangedType i_nStateChange )
129     {
130         Control::StateChanged( i_nStateChange );
131 
132         // forward certain settings to the data window
133         switch ( i_nStateChange )
134         {
135         case STATE_CHANGE_CONTROL_FOCUS:
136             m_pImpl->invalidateSelectedRows();
137             break;
138 
139         case STATE_CHANGE_CONTROLBACKGROUND:
140             if ( IsControlBackground() )
141                 getDataWindow().SetControlBackground( GetControlBackground() );
142             else
143                 getDataWindow().SetControlBackground();
144             break;
145 
146         case STATE_CHANGE_CONTROLFOREGROUND:
147             if ( IsControlForeground() )
148                 getDataWindow().SetControlForeground( GetControlForeground() );
149             else
150                 getDataWindow().SetControlForeground();
151             break;
152 
153         case STATE_CHANGE_CONTROLFONT:
154             if ( IsControlFont() )
155                 getDataWindow().SetControlFont( GetControlFont() );
156             else
157                 getDataWindow().SetControlFont();
158             break;
159         }
160     }
161 
162     // -----------------------------------------------------------------------------------------------------------------
163     void TableControl::Resize()
164     {
165         Control::Resize();
166         m_pImpl->onResize();
167     }
168 
169     // -----------------------------------------------------------------------------------------------------------------
170     void TableControl::SetModel( PTableModel _pModel )
171     {
172         m_pImpl->setModel( _pModel );
173     }
174 
175     // -----------------------------------------------------------------------------------------------------------------
176     PTableModel TableControl::GetModel() const
177     {
178         return m_pImpl->getModel();
179     }
180 
181     // -----------------------------------------------------------------------------------------------------------------
182     RowPos TableControl::GetTopRow() const
183     {
184         return m_pImpl->getTopRow();
185     }
186 
187     // -----------------------------------------------------------------------------------------------------------------
188     void TableControl::SetTopRow( RowPos _nRow )
189     {
190         OSL_ENSURE( false, "TableControl::SetTopRow: not implemented!" );
191         OSL_UNUSED( _nRow );
192     }
193 
194     // -----------------------------------------------------------------------------------------------------------------
195     sal_Int32 TableControl::GetCurrentRow() const
196     {
197         return m_pImpl->getCurrentRow();
198     }
199 
200     // -----------------------------------------------------------------------------------------------------------------
201     sal_Int32 TableControl::GetCurrentColumn() const
202     {
203         return m_pImpl->getCurrentColumn();
204     }
205 
206     // -----------------------------------------------------------------------------------------------------------------
207     bool TableControl::GoTo( ColPos _nColumn, RowPos _nRow )
208     {
209         return m_pImpl->goTo( _nColumn, _nRow );
210     }
211 
212     // -----------------------------------------------------------------------------------------------------------------
213     sal_Bool TableControl::GoToCell(sal_Int32 _nColPos, sal_Int32 _nRowPos)
214     {
215         return m_pImpl->goTo( _nColPos, _nRowPos );
216     }
217 
218     //------------------------------------------------------------------------------------------------------------------
219     sal_Int32 TableControl::GetSelectedRowCount() const
220     {
221         return sal_Int32( m_pImpl->getSelectedRowCount() );
222     }
223 
224     //------------------------------------------------------------------------------------------------------------------
225     sal_Int32 TableControl::GetSelectedRowIndex( sal_Int32 const i_selectionIndex ) const
226     {
227         return sal_Int32( m_pImpl->getSelectedRowIndex( i_selectionIndex ) );
228     }
229 
230     //------------------------------------------------------------------------------------------------------------------
231     bool TableControl::IsRowSelected( sal_Int32 const i_rowIndex ) const
232     {
233         return m_pImpl->isRowSelected( i_rowIndex );
234     }
235 
236     // -----------------------------------------------------------------------------------------------------------------
237     void TableControl::SelectRow( RowPos const i_rowIndex, bool const i_select )
238     {
239         ENSURE_OR_RETURN_VOID( ( i_rowIndex >= 0 ) && ( i_rowIndex < m_pImpl->getModel()->getRowCount() ),
240             "TableControl::SelectRow: invalid row index!" );
241 
242         if ( i_select )
243         {
244             if ( !m_pImpl->markRowAsSelected( i_rowIndex ) )
245                 // nothing to do
246                 return;
247         }
248         else
249         {
250             m_pImpl->markRowAsDeselected( i_rowIndex );
251         }
252 
253         m_pImpl->invalidateRowRange( i_rowIndex, i_rowIndex );
254         Select();
255     }
256 
257     // -----------------------------------------------------------------------------------------------------------------
258     void TableControl::SelectAllRows( bool const i_select )
259     {
260         if ( i_select )
261         {
262             if ( !m_pImpl->markAllRowsAsSelected() )
263                 // nothing to do
264                 return;
265         }
266         else
267         {
268             if ( !m_pImpl->markAllRowsAsDeselected() )
269                 // nothing to do
270                 return;
271         }
272 
273 
274         Invalidate();
275             // TODO: can't we do better than this, and invalidate only the rows which changed?
276         Select();
277     }
278 
279     // -----------------------------------------------------------------------------------------------------------------
280     ITableControl& TableControl::getTableControlInterface()
281     {
282         return *m_pImpl;
283     }
284 
285     // -----------------------------------------------------------------------------------------------------------------
286     SelectionEngine* TableControl::getSelEngine()
287     {
288         return m_pImpl->getSelEngine();
289     }
290 
291     // -----------------------------------------------------------------------------------------------------------------
292     Window& TableControl::getDataWindow()
293     {
294         return m_pImpl->getDataWindow();
295     }
296 
297     // -----------------------------------------------------------------------------------------------------------------
298     Reference< XAccessible > TableControl::CreateAccessible()
299     {
300         Window* pParent = GetAccessibleParentWindow();
301         ENSURE_OR_RETURN( pParent, "TableControl::CreateAccessible - parent not found", NULL );
302 
303         return m_pImpl->getAccessible( *pParent );
304     }
305 
306     // -----------------------------------------------------------------------------------------------------------------
307     Reference<XAccessible> TableControl::CreateAccessibleControl( sal_Int32 _nIndex )
308     {
309         (void)_nIndex;
310         DBG_ASSERT( sal_False, "TableControl::CreateAccessibleControl: to be overwritten!" );
311         return NULL;
312     }
313 
314     // -----------------------------------------------------------------------------------------------------------------
315     ::rtl::OUString TableControl::GetAccessibleObjectName( AccessibleTableControlObjType eObjType, sal_Int32 _nRow, sal_Int32 _nCol) const
316     {
317         ::rtl::OUString aRetText;
318         //Window* pWin;
319         switch( eObjType )
320         {
321             case TCTYPE_GRIDCONTROL:
322                 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control" ) );
323                 break;
324             case TCTYPE_TABLE:
325                 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid conrol" ) );
326                 break;
327             case TCTYPE_ROWHEADERBAR:
328                 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowHeaderBar" ) );
329                 break;
330             case TCTYPE_COLUMNHEADERBAR:
331                 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnHeaderBar" ) );
332                 break;
333             case TCTYPE_TABLECELL:
334                 //the name of the cell constists of column name and row name if defined
335                 //if the name is equal to cell content, it'll be read twice
336                 if(GetModel()->hasColumnHeaders())
337                 {
338                     aRetText = GetColumnName(_nCol);
339                     aRetText += rtl::OUString::createFromAscii(" , ");
340                 }
341                 if(GetModel()->hasRowHeaders())
342                 {
343                     aRetText += GetRowName(_nRow);
344                     aRetText += rtl::OUString::createFromAscii(" , ");
345                 }
346                 //aRetText = GetAccessibleCellText(_nRow, _nCol);
347                 break;
348             case TCTYPE_ROWHEADERCELL:
349                 aRetText = GetRowName(_nRow);
350                 break;
351             case TCTYPE_COLUMNHEADERCELL:
352                 aRetText = GetColumnName(_nCol);
353                 break;
354             default:
355                 OSL_ENSURE(0,"GridControl::GetAccessibleName: invalid enum!");
356         }
357         return aRetText;
358     }
359 
360     //------------------------------------------------------------------------------------------------------------------
361     ::rtl::OUString TableControl::GetAccessibleObjectDescription( AccessibleTableControlObjType eObjType, sal_Int32 ) const
362     {
363         ::rtl::OUString aRetText;
364         switch( eObjType )
365         {
366             case TCTYPE_GRIDCONTROL:
367                 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid control description" ) );
368                 break;
369             case TCTYPE_TABLE:
370                     aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TABLE description" ) );
371                 break;
372             case TCTYPE_ROWHEADERBAR:
373                     aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERBAR description" ) );
374                 break;
375             case TCTYPE_COLUMNHEADERBAR:
376                     aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERBAR description" ) );
377                 break;
378             case TCTYPE_TABLECELL:
379                 // the description of the cell consists of column name and row name if defined
380                 // if the name is equal to cell content, it'll be read twice
381                 if ( GetModel()->hasColumnHeaders() )
382                 {
383                     aRetText = GetColumnName( GetCurrentColumn() );
384                     aRetText += rtl::OUString::createFromAscii( " , " );
385                 }
386                 if ( GetModel()->hasRowHeaders() )
387                 {
388                     aRetText += GetRowName( GetCurrentRow() );
389                 }
390                 break;
391             case TCTYPE_ROWHEADERCELL:
392                     aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ROWHEADERCELL description" ) );
393                 break;
394             case TCTYPE_COLUMNHEADERCELL:
395                     aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "COLUMNHEADERCELL description" ) );
396                 break;
397         }
398         return aRetText;
399     }
400 
401     //------------------------------------------------------------------------------------------------------------------
402     ::rtl::OUString TableControl::GetRowDescription( sal_Int32 _nRow) const
403     {
404         (void)_nRow;
405         return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "row description" ) );
406     }
407 
408     //------------------------------------------------------------------------------------------------------------------
409     ::rtl::OUString TableControl::GetRowName( sal_Int32 _nIndex) const
410     {
411         ::rtl::OUString sRowName;
412         GetModel()->getRowHeading( _nIndex ) >>= sRowName;
413         return sRowName;
414     }
415 
416     //------------------------------------------------------------------------------------------------------------------
417     ::rtl::OUString TableControl::GetColumnDescription( sal_uInt16 _nColumn) const
418     {
419         (void)_nColumn;
420         return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "col description" ) );
421     }
422 
423     //------------------------------------------------------------------------------------------------------------------
424     ::rtl::OUString TableControl::GetColumnName( sal_Int32 _nIndex) const
425     {
426         return GetModel()->getColumnModel(_nIndex)->getName();
427     }
428 
429     //------------------------------------------------------------------------------------------------------------------
430     ::com::sun::star::uno::Any TableControl::GetCellContent( sal_Int32 _nRowPos, sal_Int32 _nColPos ) const
431     {
432         Any aCellContent;
433         GetModel()->getCellContent( _nColPos, _nRowPos, aCellContent );
434         return aCellContent;
435     }
436 
437     //------------------------------------------------------------------------------------------------------------------
438     ::rtl::OUString TableControl::GetAccessibleCellText( sal_Int32 _nRowPos, sal_Int32 _nColPos) const
439     {
440         return m_pImpl->getCellContentAsString( _nRowPos, _nColPos );
441     }
442 
443     //------------------------------------------------------------------------------------------------------------------
444     void TableControl::FillAccessibleStateSet(
445             ::utl::AccessibleStateSetHelper& rStateSet,
446             AccessibleTableControlObjType eObjType ) const
447     {
448         switch( eObjType )
449         {
450             case TCTYPE_GRIDCONTROL:
451             case TCTYPE_TABLE:
452 
453                 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
454 
455                 if ( m_pImpl->getSelEngine()->GetSelectionMode() == MULTIPLE_SELECTION )
456                     rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
457 
458                 if ( HasChildPathFocus() )
459                     rStateSet.AddState( AccessibleStateType::FOCUSED );
460 
461                 if ( IsActive() )
462                     rStateSet.AddState( AccessibleStateType::ACTIVE );
463 
464                 if ( m_pImpl->getDataWindow().IsEnabled() )
465                 {
466                     rStateSet.AddState( AccessibleStateType::ENABLED );
467                     rStateSet.AddState( AccessibleStateType::SENSITIVE );
468                 }
469 
470                 if ( IsReallyVisible() )
471                     rStateSet.AddState( AccessibleStateType::VISIBLE );
472 
473                 if ( eObjType == TCTYPE_TABLE )
474                     rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
475                 break;
476 
477             case TCTYPE_ROWHEADERBAR:
478                 rStateSet.AddState( AccessibleStateType::VISIBLE );
479                 rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
480                 break;
481 
482             case TCTYPE_COLUMNHEADERBAR:
483                 rStateSet.AddState( AccessibleStateType::VISIBLE );
484                 rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
485                 break;
486 
487             case TCTYPE_TABLECELL:
488                 {
489                     rStateSet.AddState( AccessibleStateType::FOCUSABLE );
490                     if ( HasChildPathFocus() )
491                         rStateSet.AddState( AccessibleStateType::FOCUSED );
492                     rStateSet.AddState( AccessibleStateType::ACTIVE );
493                     rStateSet.AddState( AccessibleStateType::TRANSIENT );
494                     rStateSet.AddState( AccessibleStateType::SELECTABLE);
495                     rStateSet.AddState( AccessibleStateType::VISIBLE );
496                     rStateSet.AddState( AccessibleStateType::SHOWING );
497                     if ( IsRowSelected( GetCurrentRow() ) )
498                         // Hmm? Wouldn't we expect the affected row to be a parameter to this function?
499                         rStateSet.AddState( AccessibleStateType::SELECTED );
500                 }
501                 break;
502 
503             case TCTYPE_ROWHEADERCELL:
504                 rStateSet.AddState( AccessibleStateType::VISIBLE );
505                 rStateSet.AddState( AccessibleStateType::TRANSIENT );
506                 break;
507 
508             case TCTYPE_COLUMNHEADERCELL:
509                 rStateSet.AddState( AccessibleStateType::VISIBLE );
510                 break;
511         }
512     }
513 
514     //------------------------------------------------------------------------------------------------------------------
515     void TableControl::commitCellEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
516     {
517         if ( m_pImpl->isAccessibleAlive() )
518             m_pImpl->commitCellEvent( i_eventID, i_newValue, i_oldValue );
519     }
520 
521     //------------------------------------------------------------------------------------------------------------------
522     void TableControl::commitTableEventIfAccessibleAlive( sal_Int16 const i_eventID, const Any& i_newValue, const Any& i_oldValue )
523     {
524         if ( m_pImpl->isAccessibleAlive() )
525             m_pImpl->commitTableEvent( i_eventID, i_newValue, i_oldValue );
526     }
527 
528     //------------------------------------------------------------------------------------------------------------------
529     Rectangle TableControl::GetWindowExtentsRelative( Window *pRelativeWindow ) const
530     {
531         return Control::GetWindowExtentsRelative( pRelativeWindow );
532     }
533 
534     //------------------------------------------------------------------------------------------------------------------
535     void TableControl::GrabFocus()
536     {
537         Control::GrabFocus();
538     }
539 
540     //------------------------------------------------------------------------------------------------------------------
541     Reference< XAccessible > TableControl::GetAccessible( sal_Bool bCreate )
542     {
543         return Control::GetAccessible( bCreate );
544     }
545 
546     //------------------------------------------------------------------------------------------------------------------
547     Window* TableControl::GetAccessibleParentWindow() const
548     {
549         return Control::GetAccessibleParentWindow();
550     }
551 
552     //------------------------------------------------------------------------------------------------------------------
553     Window* TableControl::GetWindowInstance()
554     {
555         return this;
556     }
557 
558     //------------------------------------------------------------------------------------------------------------------
559     sal_Bool TableControl::HasRowHeader()
560     {
561         return GetModel()->hasRowHeaders();
562     }
563 
564     //------------------------------------------------------------------------------------------------------------------
565     sal_Bool TableControl::HasColHeader()
566     {
567         return GetModel()->hasColumnHeaders();
568     }
569 
570     //------------------------------------------------------------------------------------------------------------------
571     sal_Int32 TableControl::GetAccessibleControlCount() const
572     {
573         // TC_TABLE is always defined, no matter whether empty or not
574         sal_Int32 count = 1;
575         if ( GetModel()->hasRowHeaders() )
576             ++count;
577         if ( GetModel()->hasColumnHeaders() )
578             ++count;
579         return count;
580     }
581 
582     //------------------------------------------------------------------------------------------------------------------
583     sal_Bool TableControl::ConvertPointToControlIndex( sal_Int32& _rnIndex, const Point& _rPoint )
584     {
585         sal_Int32 nRow = m_pImpl->getRowAtPoint( _rPoint );
586         sal_Int32 nCol = m_pImpl->getColAtPoint( _rPoint );
587         _rnIndex = nRow * GetColumnCount() + nCol;
588         return nRow >= 0 ? sal_True : sal_False;
589     }
590 
591     //------------------------------------------------------------------------------------------------------------------
592     long TableControl::GetRowCount() const
593     {
594         return GetModel()->getRowCount();
595     }
596 
597     //------------------------------------------------------------------------------------------------------------------
598     long TableControl::GetColumnCount() const
599     {
600         return GetModel()->getColumnCount();
601     }
602 
603     //------------------------------------------------------------------------------------------------------------------
604     sal_Bool TableControl::HasRowHeader() const
605     {
606         return GetModel()->hasRowHeaders();
607     }
608 
609     //------------------------------------------------------------------------------------------------------------------
610     sal_Bool TableControl::ConvertPointToCellAddress( sal_Int32& _rnRow, sal_Int32& _rnColPos, const Point& _rPoint )
611     {
612         _rnRow = m_pImpl->getRowAtPoint( _rPoint );
613         _rnColPos = m_pImpl->getColAtPoint( _rPoint );
614         return _rnRow >= 0 ? sal_True : sal_False;
615     }
616 
617     //------------------------------------------------------------------------------------------------------------------
618     void TableControl::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumnPos ) const
619     {
620         if ( IsRowSelected( _nRow ) )
621             _rStateSet.AddState( AccessibleStateType::SELECTED );
622         if ( HasChildPathFocus() )
623             _rStateSet.AddState( AccessibleStateType::FOCUSED );
624         else // only transient when column is not focused
625             _rStateSet.AddState( AccessibleStateType::TRANSIENT );
626 
627         _rStateSet.AddState( AccessibleStateType::VISIBLE );
628         _rStateSet.AddState( AccessibleStateType::SHOWING );
629         _rStateSet.AddState( AccessibleStateType::ENABLED );
630         _rStateSet.AddState( AccessibleStateType::SENSITIVE );
631         _rStateSet.AddState( AccessibleStateType::ACTIVE );
632 
633         (void)_nColumnPos;
634     }
635 
636     //------------------------------------------------------------------------------------------------------------------
637     Rectangle TableControl::GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex)
638     {
639         (void)_nRow;
640         (void)_nColumnPos;
641         return GetCharacterBounds(nIndex);
642     }
643 
644     //------------------------------------------------------------------------------------------------------------------
645     sal_Int32 TableControl::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
646     {
647         (void)_nRow;
648         (void)_nColumnPos;
649         return GetIndexForPoint(_rPoint);
650     }
651 
652     //------------------------------------------------------------------------------------------------------------------
653     Rectangle TableControl::calcHeaderRect(sal_Bool _bIsColumnBar,sal_Bool _bOnScreen)
654     {
655         (void)_bOnScreen;
656         return m_pImpl->calcHeaderRect( _bIsColumnBar ? false : true );
657     }
658 
659     //------------------------------------------------------------------------------------------------------------------
660     Rectangle TableControl::calcHeaderCellRect( sal_Bool _bIsColumnBar, sal_Int32 nPos )
661     {
662         return m_pImpl->calcHeaderCellRect( _bIsColumnBar, nPos );
663     }
664 
665     //------------------------------------------------------------------------------------------------------------------
666     Rectangle TableControl::calcTableRect(sal_Bool _bOnScreen)
667     {
668         (void)_bOnScreen;
669         return m_pImpl->calcTableRect();
670     }
671 
672     //------------------------------------------------------------------------------------------------------------------
673     Rectangle TableControl::calcCellRect( sal_Int32 _nRowPos, sal_Int32 _nColPos )
674     {
675         return m_pImpl->calcCellRect( _nRowPos, _nColPos );
676     }
677     //------------------------------------------------------------------------------------------------------------------
678     IMPL_LINK( TableControl, ImplSelectHdl, void*, EMPTYARG )
679     {
680         Select();
681         return 1;
682     }
683 
684     //------------------------------------------------------------------------------------------------------------------
685     void TableControl::Select()
686     {
687         ImplCallEventListenersAndHandler( VCLEVENT_TABLEROW_SELECT, m_pImpl->getSelectHandler(), this );
688 
689         if ( m_pImpl->isAccessibleAlive() )
690         {
691             m_pImpl->commitAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
692 
693             m_pImpl->commitTableEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), Any() );
694                 // TODO: why do we notify this when the *selection* changed? Shouldn't we find a better place for this,
695                 // actually, when the active descendant, i.e. the current cell, *really* changed?
696         }
697     }
698 
699     //------------------------------------------------------------------------------------------------------------------
700     void TableControl::SetSelectHdl( const Link& i_selectHandler )
701     {
702         m_pImpl->setSelectHandler( i_selectHandler );
703     }
704 
705     //------------------------------------------------------------------------------------------------------------------
706     const Link& TableControl::GetSelectHdl() const
707     {
708         return m_pImpl->getSelectHandler();
709     }
710 
711 //......................................................................................................................
712 }} // namespace svt::table
713 //......................................................................................................................
714