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