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