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