1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_svtools.hxx" 29 30 #include "svtxgridcontrol.hxx" 31 #include <com/sun/star/view/SelectionType.hpp> 32 #include "svtools/table/tablecontrolinterface.hxx" 33 #include "svtools/table/gridtablerenderer.hxx" 34 #include "svtools/table/tablecontrol.hxx" 35 #include "unocontroltablemodel.hxx" 36 #include <comphelper/sequence.hxx> 37 #include <rtl/ref.hxx> 38 #include <tools/diagnose_ex.h> 39 #include <toolkit/helper/property.hxx> 40 #include <toolkit/helper/vclunohelper.hxx> 41 #include <comphelper/processfactory.hxx> 42 #include <com/sun/star/awt/grid/XGridColumn.hpp> 43 #include <com/sun/star/awt/XControl.hpp> 44 #include <com/sun/star/awt/grid/GridInvalidDataException.hpp> 45 #include <com/sun/star/awt/grid/GridInvalidModelException.hpp> 46 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 47 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 48 #include <com/sun/star/util/Color.hpp> 49 #include <com/sun/star/awt/FontDescriptor.hpp> 50 51 /** === begin UNO using === **/ 52 using ::com::sun::star::uno::RuntimeException; 53 using ::com::sun::star::uno::Reference; 54 using ::com::sun::star::uno::Exception; 55 using ::com::sun::star::uno::UNO_QUERY; 56 using ::com::sun::star::uno::UNO_QUERY_THROW; 57 using ::com::sun::star::uno::Any; 58 using ::com::sun::star::uno::makeAny; 59 using ::com::sun::star::uno::Sequence; 60 using ::com::sun::star::awt::grid::XGridSelectionListener; 61 using ::com::sun::star::style::VerticalAlignment; 62 using ::com::sun::star::style::VerticalAlignment_TOP; 63 using ::com::sun::star::view::SelectionType; 64 using ::com::sun::star::view::SelectionType_NONE; 65 using ::com::sun::star::view::SelectionType_RANGE; 66 using ::com::sun::star::view::SelectionType_SINGLE; 67 using ::com::sun::star::view::SelectionType_MULTI; 68 using ::com::sun::star::awt::grid::XGridDataModel; 69 using ::com::sun::star::awt::grid::GridInvalidDataException; 70 using ::com::sun::star::lang::EventObject; 71 using ::com::sun::star::lang::IndexOutOfBoundsException; 72 using ::com::sun::star::awt::grid::XGridColumnModel; 73 using ::com::sun::star::awt::grid::GridSelectionEvent; 74 using ::com::sun::star::awt::grid::XGridColumn; 75 using ::com::sun::star::container::ContainerEvent; 76 using ::com::sun::star::awt::grid::GridDataEvent; 77 using ::com::sun::star::awt::grid::GridInvalidModelException; 78 using ::com::sun::star::util::VetoException; 79 /** === end UNO using === **/ 80 81 namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; 82 namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; 83 84 using namespace ::svt::table; 85 86 typedef ::com::sun::star::util::Color UnoColor; 87 88 // --------------------------------------------------------------------------------------------------------------------- 89 SVTXGridControl::SVTXGridControl() 90 :m_pTableModel( new UnoControlTableModel() ) 91 ,m_bTableModelInitCompleted( false ) 92 ,m_aSelectionListeners( *this ) 93 { 94 } 95 96 // --------------------------------------------------------------------------------------------------------------------- 97 SVTXGridControl::~SVTXGridControl() 98 { 99 } 100 101 // --------------------------------------------------------------------------------------------------------------------- 102 void SVTXGridControl::SetWindow( Window* pWindow ) 103 { 104 SVTXGridControl_Base::SetWindow( pWindow ); 105 impl_checkTableModelInit(); 106 } 107 108 // --------------------------------------------------------------------------------------------------------------------- 109 void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const 110 { 111 if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) ) 112 throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) ); 113 } 114 115 // --------------------------------------------------------------------------------------------------------------------- 116 void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const 117 { 118 if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) ) 119 throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) ); 120 } 121 122 // --------------------------------------------------------------------------------------------------------------------- 123 sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException) 124 { 125 ::vos::OGuard aGuard( GetMutex() ); 126 127 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 128 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 ); 129 130 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); 131 return ( tableCell.nRow >= 0 ) ? tableCell.nRow : -1; 132 } 133 134 // --------------------------------------------------------------------------------------------------------------------- 135 sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException) 136 { 137 ::vos::OGuard aGuard( GetMutex() ); 138 139 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 140 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 ); 141 142 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); 143 return ( tableCell.nColumn >= 0 ) ? tableCell.nColumn : -1; 144 } 145 146 // --------------------------------------------------------------------------------------------------------------------- 147 sal_Int32 SAL_CALL SVTXGridControl::getCurrentColumn( ) throw (RuntimeException) 148 { 149 ::vos::OGuard aGuard( GetMutex() ); 150 151 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 152 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 ); 153 154 sal_Int32 const nColumn = pTable->GetCurrentColumn(); 155 return ( nColumn >= 0 ) ? nColumn : -1; 156 } 157 158 // --------------------------------------------------------------------------------------------------------------------- 159 sal_Int32 SAL_CALL SVTXGridControl::getCurrentRow( ) throw (RuntimeException) 160 { 161 ::vos::OGuard aGuard( GetMutex() ); 162 163 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 164 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 ); 165 166 sal_Int32 const nRow = pTable->GetCurrentRow(); 167 return ( nRow >= 0 ) ? nRow : -1; 168 } 169 170 //---------------------------------------------------------------------------------------------------------------------- 171 void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException) 172 { 173 ::vos::OGuard aGuard( GetMutex() ); 174 175 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 176 ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!" ); 177 178 impl_checkColumnIndex_throw( *pTable, i_columnIndex ); 179 impl_checkRowIndex_throw( *pTable, i_rowIndex ); 180 181 pTable->GoTo( i_columnIndex, i_rowIndex ); 182 } 183 184 // --------------------------------------------------------------------------------------------------------------------- 185 void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException) 186 { 187 m_aSelectionListeners.addInterface(listener); 188 } 189 190 // --------------------------------------------------------------------------------------------------------------------- 191 void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException) 192 { 193 m_aSelectionListeners.removeInterface(listener); 194 } 195 196 // --------------------------------------------------------------------------------------------------------------------- 197 void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) 198 { 199 ::vos::OGuard aGuard( GetMutex() ); 200 201 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 202 ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::setProperty: no control (anymore)!" ); 203 204 switch( GetPropertyId( PropertyName ) ) 205 { 206 case BASEPROPERTY_ROW_HEADER_WIDTH: 207 { 208 sal_Int32 rowHeaderWidth( -1 ); 209 aValue >>= rowHeaderWidth; 210 ENSURE_OR_BREAK( rowHeaderWidth > 0, "SVTXGridControl::setProperty: illegal row header width!" ); 211 m_pTableModel->setRowHeaderWidth( rowHeaderWidth ); 212 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed 213 pTable->Invalidate(); 214 } 215 break; 216 217 case BASEPROPERTY_COLUMN_HEADER_HEIGHT: 218 { 219 sal_Int32 columnHeaderHeight = 0; 220 if ( !aValue.hasValue() ) 221 { 222 columnHeaderHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height(); 223 } 224 else 225 { 226 aValue >>= columnHeaderHeight; 227 } 228 ENSURE_OR_BREAK( columnHeaderHeight > 0, "SVTXGridControl::setProperty: illegal column header height!" ); 229 m_pTableModel->setColumnHeaderHeight( columnHeaderHeight ); 230 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed 231 pTable->Invalidate(); 232 } 233 break; 234 235 case BASEPROPERTY_USE_GRID_LINES: 236 { 237 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( 238 m_pTableModel->getRenderer().get() ); 239 ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" ); 240 sal_Bool bUseGridLines = sal_False; 241 OSL_VERIFY( aValue >>= bUseGridLines ); 242 pGridRenderer->useGridLines( bUseGridLines ); 243 pTable->Invalidate(); 244 } 245 break; 246 247 case BASEPROPERTY_ROW_HEIGHT: 248 { 249 sal_Int32 rowHeight = 0; 250 if ( !aValue.hasValue() ) 251 { 252 rowHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height(); 253 } 254 else 255 { 256 aValue >>= rowHeight; 257 } 258 m_pTableModel->setRowHeight( rowHeight ); 259 ENSURE_OR_BREAK( rowHeight > 0, "SVTXGridControl::setProperty: illegal row height!" ); 260 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed 261 pTable->Invalidate(); 262 } 263 break; 264 265 case BASEPROPERTY_BACKGROUNDCOLOR: 266 { 267 // let the base class handle this for the TableControl 268 VCLXWindow::setProperty( PropertyName, aValue ); 269 // and forward to the grid control's data window 270 if ( pTable->IsBackground() ) 271 pTable->getDataWindow().SetBackground( pTable->GetBackground() ); 272 else 273 pTable->getDataWindow().SetBackground(); 274 } 275 break; 276 277 case BASEPROPERTY_GRID_SELECTIONMODE: 278 { 279 SelectionType eSelectionType; 280 if( aValue >>= eSelectionType ) 281 { 282 SelectionMode eSelMode; 283 switch( eSelectionType ) 284 { 285 case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; 286 case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; 287 case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; 288 default: eSelMode = NO_SELECTION; break; 289 } 290 if( pTable->getSelEngine()->GetSelectionMode() != eSelMode ) 291 pTable->getSelEngine()->SetSelectionMode( eSelMode ); 292 } 293 break; 294 } 295 case BASEPROPERTY_HSCROLL: 296 { 297 sal_Bool bHScroll = true; 298 if( aValue >>= bHScroll ) 299 m_pTableModel->setHorizontalScrollbarVisibility( bHScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); 300 break; 301 } 302 303 case BASEPROPERTY_VSCROLL: 304 { 305 sal_Bool bVScroll = true; 306 if( aValue >>= bVScroll ) 307 { 308 m_pTableModel->setVerticalScrollbarVisibility( bVScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); 309 } 310 break; 311 } 312 313 case BASEPROPERTY_GRID_SHOWROWHEADER: 314 { 315 sal_Bool rowHeader = true; 316 if( aValue >>= rowHeader ) 317 { 318 m_pTableModel->setRowHeaders(rowHeader); 319 } 320 break; 321 } 322 323 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: 324 m_pTableModel->setRowBackgroundColors( aValue ); 325 pTable->Invalidate(); 326 break; 327 328 case BASEPROPERTY_GRID_LINE_COLOR: 329 m_pTableModel->setLineColor( aValue ); 330 pTable->Invalidate(); 331 break; 332 333 case BASEPROPERTY_GRID_HEADER_BACKGROUND: 334 m_pTableModel->setHeaderBackgroundColor( aValue ); 335 pTable->Invalidate(); 336 break; 337 338 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: 339 m_pTableModel->setHeaderTextColor( aValue ); 340 pTable->Invalidate(); 341 break; 342 343 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: 344 m_pTableModel->setActiveSelectionBackColor( aValue ); 345 pTable->Invalidate(); 346 break; 347 348 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: 349 m_pTableModel->setInactiveSelectionBackColor( aValue ); 350 pTable->Invalidate(); 351 break; 352 353 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: 354 m_pTableModel->setActiveSelectionTextColor( aValue ); 355 pTable->Invalidate(); 356 break; 357 358 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: 359 m_pTableModel->setInactiveSelectionTextColor( aValue ); 360 pTable->Invalidate(); 361 break; 362 363 364 case BASEPROPERTY_TEXTCOLOR: 365 m_pTableModel->setTextColor( aValue ); 366 pTable->Invalidate(); 367 break; 368 369 case BASEPROPERTY_TEXTLINECOLOR: 370 m_pTableModel->setTextLineColor( aValue ); 371 pTable->Invalidate(); 372 break; 373 374 case BASEPROPERTY_VERTICALALIGN: 375 { 376 VerticalAlignment eAlign( VerticalAlignment_TOP ); 377 if ( aValue >>= eAlign ) 378 m_pTableModel->setVerticalAlign( eAlign ); 379 break; 380 } 381 382 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: 383 { 384 sal_Bool colHeader = true; 385 if( aValue >>= colHeader ) 386 { 387 m_pTableModel->setColumnHeaders(colHeader); 388 } 389 break; 390 } 391 case BASEPROPERTY_GRID_DATAMODEL: 392 { 393 Reference< XGridDataModel > const xDataModel( aValue, UNO_QUERY ); 394 if ( !xDataModel.is() ) 395 throw GridInvalidDataException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid data model." ) ), *this ); 396 397 m_pTableModel->setDataModel( xDataModel ); 398 impl_checkTableModelInit(); 399 } 400 break; 401 402 case BASEPROPERTY_GRID_COLUMNMODEL: 403 { 404 // obtain new col model 405 Reference< XGridColumnModel > const xColumnModel( aValue, UNO_QUERY ); 406 if ( !xColumnModel.is() ) 407 throw GridInvalidModelException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid column model." ) ), *this ); 408 409 // remove all old columns 410 m_pTableModel->removeAllColumns(); 411 412 // announce to the TableModel 413 m_pTableModel->setColumnModel( xColumnModel ); 414 impl_checkTableModelInit(); 415 416 // add new columns 417 impl_updateColumnsFromModel_nothrow(); 418 break; 419 } 420 default: 421 VCLXWindow::setProperty( PropertyName, aValue ); 422 break; 423 } 424 } 425 426 427 void SVTXGridControl::impl_checkTableModelInit() 428 { 429 if ( !m_bTableModelInitCompleted && m_pTableModel->hasColumnModel() && m_pTableModel->hasDataModel() ) 430 { 431 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 432 if ( pTable ) 433 { 434 pTable->SetModel( PTableModel( m_pTableModel ) ); 435 436 m_bTableModelInitCompleted = true; 437 438 // ensure default columns exist, if they have not previously been added 439 Reference< XGridDataModel > const xDataModel( m_pTableModel->getDataModel(), UNO_QUERY_THROW ); 440 Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel(), UNO_QUERY_THROW ); 441 442 sal_Int32 const nDataColumnCount = xDataModel->getColumnCount(); 443 if ( ( nDataColumnCount > 0 ) && ( xColumnModel->getColumnCount() == 0 ) ) 444 xColumnModel->setDefaultColumns( nDataColumnCount ); 445 // this will trigger notifications, which in turn will let us update our m_pTableModel 446 } 447 } 448 } 449 450 namespace 451 { 452 void lcl_convertColor( ::boost::optional< ::Color > const & i_color, Any & o_colorValue ) 453 { 454 if ( !i_color ) 455 o_colorValue.clear(); 456 else 457 o_colorValue <<= i_color->GetColor(); 458 } 459 } 460 461 Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) 462 { 463 ::vos::OGuard aGuard( GetMutex() ); 464 465 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 466 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getProperty: no control (anymore)!", Any() ); 467 468 Any aPropertyValue; 469 470 const sal_uInt16 nPropId = GetPropertyId( PropertyName ); 471 switch(nPropId) 472 { 473 case BASEPROPERTY_GRID_SELECTIONMODE: 474 { 475 SelectionType eSelectionType; 476 477 SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); 478 switch( eSelMode ) 479 { 480 case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; 481 case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; 482 case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; 483 default: eSelectionType = SelectionType_NONE; break; 484 } 485 aPropertyValue <<= eSelectionType; 486 break; 487 } 488 489 case BASEPROPERTY_GRID_SHOWROWHEADER: 490 aPropertyValue <<= sal_Bool( m_pTableModel->hasRowHeaders() ); 491 break; 492 493 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: 494 aPropertyValue <<= sal_Bool( m_pTableModel->hasColumnHeaders() ); 495 break; 496 497 case BASEPROPERTY_GRID_DATAMODEL: 498 aPropertyValue <<= m_pTableModel->getDataModel(); 499 break; 500 501 case BASEPROPERTY_GRID_COLUMNMODEL: 502 aPropertyValue <<= m_pTableModel->getColumnModel(); 503 break; 504 505 case BASEPROPERTY_HSCROLL: 506 { 507 sal_Bool const bHasScrollbar = ( m_pTableModel->getHorizontalScrollbarVisibility() != ScrollbarShowNever ); 508 aPropertyValue <<= bHasScrollbar; 509 break; 510 } 511 512 case BASEPROPERTY_VSCROLL: 513 { 514 sal_Bool const bHasScrollbar = ( m_pTableModel->getVerticalScrollbarVisibility() != ScrollbarShowNever ); 515 aPropertyValue <<= bHasScrollbar; 516 break; 517 } 518 519 case BASEPROPERTY_USE_GRID_LINES: 520 { 521 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( 522 m_pTableModel->getRenderer().get() ); 523 ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" ); 524 aPropertyValue <<= pGridRenderer->useGridLines(); 525 } 526 break; 527 528 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: 529 { 530 ::boost::optional< ::std::vector< ::Color > > aColors( m_pTableModel->getRowBackgroundColors() ); 531 if ( !aColors ) 532 aPropertyValue.clear(); 533 else 534 { 535 Sequence< UnoColor > aAPIColors( aColors->size() ); 536 for ( size_t i=0; i<aColors->size(); ++i ) 537 { 538 aAPIColors[i] = aColors->at(i).GetColor(); 539 } 540 aPropertyValue <<= aAPIColors; 541 } 542 } 543 break; 544 545 case BASEPROPERTY_GRID_LINE_COLOR: 546 lcl_convertColor( m_pTableModel->getLineColor(), aPropertyValue ); 547 break; 548 549 case BASEPROPERTY_GRID_HEADER_BACKGROUND: 550 lcl_convertColor( m_pTableModel->getHeaderBackgroundColor(), aPropertyValue ); 551 break; 552 553 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: 554 lcl_convertColor( m_pTableModel->getHeaderTextColor(), aPropertyValue ); 555 break; 556 557 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: 558 lcl_convertColor( m_pTableModel->getActiveSelectionBackColor(), aPropertyValue ); 559 break; 560 561 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: 562 lcl_convertColor( m_pTableModel->getInactiveSelectionBackColor(), aPropertyValue ); 563 break; 564 565 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: 566 lcl_convertColor( m_pTableModel->getActiveSelectionTextColor(), aPropertyValue ); 567 break; 568 569 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: 570 lcl_convertColor( m_pTableModel->getInactiveSelectionTextColor(), aPropertyValue ); 571 break; 572 573 case BASEPROPERTY_TEXTCOLOR: 574 lcl_convertColor( m_pTableModel->getTextColor(), aPropertyValue ); 575 break; 576 577 case BASEPROPERTY_TEXTLINECOLOR: 578 lcl_convertColor( m_pTableModel->getTextLineColor(), aPropertyValue ); 579 break; 580 581 default: 582 aPropertyValue = VCLXWindow::getProperty( PropertyName ); 583 break; 584 } 585 586 return aPropertyValue; 587 } 588 589 void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) 590 { 591 PushPropertyIds( rIds, 592 BASEPROPERTY_GRID_SHOWROWHEADER, 593 BASEPROPERTY_GRID_SHOWCOLUMNHEADER, 594 BASEPROPERTY_GRID_DATAMODEL, 595 BASEPROPERTY_GRID_COLUMNMODEL, 596 BASEPROPERTY_GRID_SELECTIONMODE, 597 BASEPROPERTY_GRID_HEADER_BACKGROUND, 598 BASEPROPERTY_GRID_HEADER_TEXT_COLOR, 599 BASEPROPERTY_GRID_LINE_COLOR, 600 BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS, 601 BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR, 602 BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR, 603 BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR, 604 BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR, 605 0 606 ); 607 VCLXWindow::ImplGetPropertyIds( rIds, true ); 608 } 609 610 //---------------------------------------------------------------------------------------------------------------------- 611 void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException) 612 { 613 ::vos::OGuard aGuard( GetMutex() ); 614 m_pTableModel->notifyRowsInserted( i_event ); 615 } 616 617 //---------------------------------------------------------------------------------------------------------------------- 618 void SAL_CALL//---------------------------------------------------------------------------------------------------------------------- 619 SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException) 620 { 621 ::vos::OGuard aGuard( GetMutex() ); 622 m_pTableModel->notifyRowsRemoved( i_event ); 623 } 624 625 //---------------------------------------------------------------------------------------------------------------------- 626 void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException) 627 { 628 ::vos::OGuard aGuard( GetMutex() ); 629 630 m_pTableModel->notifyDataChanged( i_event ); 631 632 // if the data model is sortable, a dataChanged event is also fired in case the sort order changed. 633 // So, just in case, invalidate the column header area, too. 634 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 635 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::dataChanged: no control (anymore)!" ); 636 pTable->getTableControlInterface().invalidate( TableAreaColumnHeaders ); 637 } 638 639 //---------------------------------------------------------------------------------------------------------------------- 640 void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException) 641 { 642 ::vos::OGuard aGuard( GetMutex() ); 643 OSL_UNUSED( i_event ); 644 645 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 646 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" ); 647 648 // TODO: we could do better than this - invalidate the header area only 649 pTable->getTableControlInterface().invalidate( TableAreaRowHeaders ); 650 } 651 652 //---------------------------------------------------------------------------------------------------------------------- 653 void SAL_CALL SVTXGridControl::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException) 654 { 655 ::vos::OGuard aGuard( GetMutex() ); 656 657 Reference< XGridColumn > const xGridColumn( i_event.Element, UNO_QUERY_THROW ); 658 659 sal_Int32 nIndex( m_pTableModel->getColumnCount() ); 660 OSL_VERIFY( i_event.Accessor >>= nIndex ); 661 m_pTableModel->insertColumn( nIndex, xGridColumn ); 662 } 663 664 //---------------------------------------------------------------------------------------------------------------------- 665 void SAL_CALL SVTXGridControl::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException) 666 { 667 ::vos::OGuard aGuard( GetMutex() ); 668 669 sal_Int32 nIndex( -1 ); 670 OSL_VERIFY( i_event.Accessor >>= nIndex ); 671 m_pTableModel->removeColumn( nIndex ); 672 } 673 674 //---------------------------------------------------------------------------------------------------------------------- 675 void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException) 676 { 677 OSL_ENSURE( false, "SVTXGridControl::elementReplaced: not implemented!" ); 678 // at the moment, the XGridColumnModel API does not allow replacing columns 679 OSL_UNUSED( i_event ); 680 // TODO: replace the respective column in our table model 681 } 682 683 684 //---------------------------------------------------------------------------------------------------------------------- 685 void SAL_CALL SVTXGridControl::disposing( const EventObject& Source ) throw(RuntimeException) 686 { 687 VCLXWindow::disposing( Source ); 688 } 689 690 //---------------------------------------------------------------------------------------------------------------------- 691 void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) 692 { 693 ::vos::OGuard aGuard( GetMutex() ); 694 695 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 696 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" ); 697 698 impl_checkRowIndex_throw( *pTable, i_rowIndex ); 699 700 pTable->SelectRow( i_rowIndex, true ); 701 } 702 703 //---------------------------------------------------------------------------------------------------------------------- 704 void SAL_CALL SVTXGridControl::selectAllRows() throw (RuntimeException) 705 { 706 ::vos::OGuard aGuard( GetMutex() ); 707 708 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 709 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectAllRows: no control (anymore)!" ); 710 711 pTable->SelectAllRows( true ); 712 } 713 714 //---------------------------------------------------------------------------------------------------------------------- 715 void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) 716 { 717 ::vos::OGuard aGuard( GetMutex() ); 718 719 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 720 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" ); 721 722 impl_checkRowIndex_throw( *pTable, i_rowIndex ); 723 724 pTable->SelectRow( i_rowIndex, false ); 725 } 726 727 //---------------------------------------------------------------------------------------------------------------------- 728 void SAL_CALL SVTXGridControl::deselectAllRows() throw (RuntimeException) 729 { 730 ::vos::OGuard aGuard( GetMutex() ); 731 732 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 733 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectAllRows: no control (anymore)!" ); 734 735 pTable->SelectAllRows( false ); 736 } 737 738 //---------------------------------------------------------------------------------------------------------------------- 739 Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows() throw (RuntimeException) 740 { 741 ::vos::OGuard aGuard( GetMutex() ); 742 743 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 744 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() ); 745 746 sal_Int32 selectionCount = pTable->GetSelectedRowCount(); 747 Sequence< sal_Int32 > selectedRows( selectionCount ); 748 for ( sal_Int32 i=0; i<selectionCount; ++i ) 749 selectedRows[i] = pTable->GetSelectedRowIndex(i); 750 return selectedRows; 751 } 752 753 //---------------------------------------------------------------------------------------------------------------------- 754 ::sal_Bool SAL_CALL SVTXGridControl::hasSelectedRows() throw (RuntimeException) 755 { 756 ::vos::OGuard aGuard( GetMutex() ); 757 758 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 759 ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", sal_True ); 760 761 return pTable->GetSelectedRowCount() > 0; 762 } 763 764 //---------------------------------------------------------------------------------------------------------------------- 765 ::sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index ) throw (RuntimeException) 766 { 767 ::vos::OGuard aGuard( GetMutex() ); 768 769 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 770 ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", sal_False ); 771 772 return pTable->IsRowSelected( index ); 773 } 774 775 //---------------------------------------------------------------------------------------------------------------------- 776 void SVTXGridControl::dispose() throw(RuntimeException) 777 { 778 EventObject aObj; 779 aObj.Source = (::cppu::OWeakObject*)this; 780 m_aSelectionListeners.disposeAndClear( aObj ); 781 VCLXWindow::dispose(); 782 } 783 784 //---------------------------------------------------------------------------------------------------------------------- 785 void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 786 { 787 ::vos::OGuard aGuard( GetMutex() ); 788 789 Reference< XWindow > xKeepAlive( this ); 790 791 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 792 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" ); 793 794 bool handled = false; 795 switch ( rVclWindowEvent.GetId() ) 796 { 797 case VCLEVENT_TABLEROW_SELECT: 798 { 799 if ( m_aSelectionListeners.getLength() ) 800 ImplCallItemListeners(); 801 handled = true; 802 } 803 break; 804 805 case VCLEVENT_CONTROL_GETFOCUS: 806 { 807 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also 808 // works when the control is used outside the UNO context 809 if ( pTable->GetRowCount()>0 ) 810 { 811 pTable->commitCellEventIfAccessibleAlive( 812 AccessibleEventId::STATE_CHANGED, 813 makeAny( AccessibleStateType::FOCUSED ), 814 Any() 815 ); 816 pTable->commitTableEventIfAccessibleAlive( 817 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, 818 Any(), 819 Any() 820 ); 821 } 822 else 823 { 824 pTable->commitTableEventIfAccessibleAlive( 825 AccessibleEventId::STATE_CHANGED, 826 makeAny( AccessibleStateType::FOCUSED ), 827 Any() 828 ); 829 } 830 } 831 break; 832 833 case VCLEVENT_CONTROL_LOSEFOCUS: 834 { 835 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also 836 // works when the control is used outside the UNO context 837 if ( pTable->GetRowCount()>0 ) 838 { 839 pTable->commitCellEventIfAccessibleAlive( 840 AccessibleEventId::STATE_CHANGED, 841 Any(), 842 makeAny( AccessibleStateType::FOCUSED ) 843 ); 844 } 845 else 846 { 847 pTable->commitTableEventIfAccessibleAlive( 848 AccessibleEventId::STATE_CHANGED, 849 Any(), 850 makeAny( AccessibleStateType::FOCUSED ) 851 ); 852 } 853 } 854 break; 855 } 856 857 if ( !handled ) 858 VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); 859 } 860 861 //---------------------------------------------------------------------------------------------------------------------- 862 void SVTXGridControl::ImplCallItemListeners() 863 { 864 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 865 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" ); 866 867 if ( m_aSelectionListeners.getLength() ) 868 { 869 GridSelectionEvent aEvent; 870 aEvent.Source = (::cppu::OWeakObject*)this; 871 872 sal_Int32 const nSelectedRowCount( pTable->GetSelectedRowCount() ); 873 aEvent.SelectedRowIndexes.realloc( nSelectedRowCount ); 874 for ( sal_Int32 i=0; i<nSelectedRowCount; ++i ) 875 aEvent.SelectedRowIndexes[i] = pTable->GetSelectedRowIndex( i ); 876 m_aSelectionListeners.selectionChanged( aEvent ); 877 } 878 } 879 880 //---------------------------------------------------------------------------------------------------------------------- 881 void SVTXGridControl::impl_updateColumnsFromModel_nothrow() 882 { 883 Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel() ); 884 ENSURE_OR_RETURN_VOID( xColumnModel.is(), "no model!" ); 885 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); 886 ENSURE_OR_RETURN_VOID( pTable != NULL, "no table!" ); 887 888 try 889 { 890 const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns(); 891 for ( const Reference< XGridColumn >* colRef = columns.getConstArray(); 892 colRef != columns.getConstArray() + columns.getLength(); 893 ++colRef 894 ) 895 { 896 ENSURE_OR_CONTINUE( colRef->is(), "illegal column!" ); 897 898 m_pTableModel->appendColumn( *colRef ); 899 } 900 } 901 catch( const Exception& ) 902 { 903 DBG_UNHANDLED_EXCEPTION(); 904 } 905 } 906