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 "unocontroltablemodel.hxx" 31 #include "unogridcolumnfacade.hxx" 32 33 #include "svtools/table/defaultinputhandler.hxx" 34 #include "svtools/table/gridtablerenderer.hxx" 35 #include "svtools/table/tablecontrol.hxx" 36 37 /** === begin UNO includes === **/ 38 #include <com/sun/star/awt/grid/XGridColumn.hpp> 39 #include <com/sun/star/view/SelectionType.hpp> 40 #include <com/sun/star/awt/grid/XGridColumnListener.hpp> 41 #include <com/sun/star/awt/grid/XSortableGridData.hpp> 42 /** === end UNO includes === **/ 43 44 #include <comphelper/stlunosequence.hxx> 45 #include <cppuhelper/weakref.hxx> 46 #include <tools/debug.hxx> 47 #include <tools/diagnose_ex.h> 48 #include <vcl/svapp.hxx> 49 #include <vos/mutex.hxx> 50 51 // ..................................................................................................................... 52 namespace svt { namespace table 53 { 54 // ..................................................................................................................... 55 56 /** === begin UNO using === **/ 57 using ::com::sun::star::uno::Reference; 58 using ::com::sun::star::uno::RuntimeException; 59 using ::com::sun::star::uno::Sequence; 60 using ::com::sun::star::uno::UNO_QUERY_THROW; 61 using ::com::sun::star::uno::UNO_QUERY; 62 using ::com::sun::star::awt::grid::XGridColumn; 63 using ::com::sun::star::uno::XInterface; 64 using ::com::sun::star::uno::Exception; 65 using ::com::sun::star::awt::grid::XGridColumnListener; 66 using ::com::sun::star::lang::EventObject; 67 using ::com::sun::star::awt::grid::GridColumnEvent; 68 using ::com::sun::star::awt::grid::XGridDataModel; 69 using ::com::sun::star::awt::grid::XGridColumnModel; 70 using ::com::sun::star::uno::Any; 71 using ::com::sun::star::style::HorizontalAlignment_LEFT; 72 using ::com::sun::star::style::HorizontalAlignment; 73 using ::com::sun::star::style::VerticalAlignment_TOP; 74 using ::com::sun::star::style::VerticalAlignment; 75 using ::com::sun::star::uno::WeakReference; 76 using ::com::sun::star::awt::grid::GridDataEvent; 77 using ::com::sun::star::awt::grid::XSortableGridData; 78 using ::com::sun::star::beans::Pair; 79 /** === end UNO using === **/ 80 81 //================================================================================================================== 82 //= UnoControlTableModel_Impl 83 //================================================================================================================== 84 typedef ::std::vector< PTableModelListener > ModellListeners; 85 typedef ::std::vector< PColumnModel > ColumnModels; 86 struct UnoControlTableModel_Impl 87 { 88 ColumnModels aColumns; 89 bool bHasColumnHeaders; 90 bool bHasRowHeaders; 91 ScrollbarVisibility eVScrollMode; 92 ScrollbarVisibility eHScrollMode; 93 PTableRenderer pRenderer; 94 PTableInputHandler pInputHandler; 95 TableMetrics nRowHeight; 96 TableMetrics nColumnHeaderHeight; 97 TableMetrics nRowHeaderWidth; 98 ::boost::optional< ::Color > m_aGridLineColor; 99 ::boost::optional< ::Color > m_aHeaderBackgroundColor; 100 ::boost::optional< ::Color > m_aHeaderTextColor; 101 ::boost::optional< ::Color > m_aActiveSelectionBackColor; 102 ::boost::optional< ::Color > m_aInactiveSelectionBackColor; 103 ::boost::optional< ::Color > m_aActiveSelectionTextColor; 104 ::boost::optional< ::Color > m_aInactiveSelectionTextColor; 105 ::boost::optional< ::Color > m_aTextColor; 106 ::boost::optional< ::Color > m_aTextLineColor; 107 ::boost::optional< ::std::vector< ::Color > > m_aRowColors; 108 VerticalAlignment m_eVerticalAlign; 109 ModellListeners m_aListeners; 110 WeakReference< XGridDataModel > m_aDataModel; 111 WeakReference< XGridColumnModel > m_aColumnModel; 112 113 UnoControlTableModel_Impl() 114 :aColumns ( ) 115 ,bHasColumnHeaders ( true ) 116 ,bHasRowHeaders ( false ) 117 ,eVScrollMode ( ScrollbarShowNever ) 118 ,eHScrollMode ( ScrollbarShowNever ) 119 ,pRenderer ( ) 120 ,pInputHandler ( ) 121 ,nRowHeight ( 10 ) 122 ,nColumnHeaderHeight ( 10 ) 123 ,nRowHeaderWidth ( 10 ) 124 ,m_aGridLineColor ( ) 125 ,m_aHeaderBackgroundColor ( ) 126 ,m_aHeaderTextColor ( ) 127 ,m_aActiveSelectionBackColor ( ) 128 ,m_aInactiveSelectionBackColor ( ) 129 ,m_aActiveSelectionTextColor ( ) 130 ,m_aInactiveSelectionTextColor ( ) 131 ,m_aTextColor ( ) 132 ,m_aTextLineColor ( ) 133 ,m_aRowColors ( ) 134 ,m_eVerticalAlign ( VerticalAlignment_TOP ) 135 { 136 } 137 }; 138 139 //================================================================================================================== 140 //= UnoControlTableModel 141 //================================================================================================================== 142 #ifdef DBG_UTIL 143 const char* UnoControlTableModel_checkInvariants( const void* _pInstance ) 144 { 145 return static_cast< const UnoControlTableModel* >( _pInstance )->checkInvariants(); 146 } 147 148 //------------------------------------------------------------------------------------------------------------------ 149 const char* UnoControlTableModel::checkInvariants() const 150 { 151 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 152 if ( !xDataModel.is() ) 153 return "data model anymore"; 154 155 // TODO: more? 156 157 return NULL; 158 } 159 #endif 160 161 #define DBG_CHECK_ME() \ 162 DBG_TESTSOLARMUTEX(); \ 163 DBG_CHKTHIS( UnoControlTableModel, UnoControlTableModel_checkInvariants ) 164 165 //------------------------------------------------------------------------------------------------------------------ 166 DBG_NAME( UnoControlTableModel ) 167 UnoControlTableModel::UnoControlTableModel() 168 :m_pImpl( new UnoControlTableModel_Impl ) 169 { 170 DBG_CTOR( UnoControlTableModel, UnoControlTableModel_checkInvariants ); 171 m_pImpl->bHasColumnHeaders = true; 172 m_pImpl->bHasRowHeaders = false; 173 m_pImpl->pRenderer.reset( new GridTableRenderer( *this ) ); 174 m_pImpl->pInputHandler.reset( new DefaultInputHandler ); 175 } 176 177 //------------------------------------------------------------------------------------------------------------------ 178 UnoControlTableModel::~UnoControlTableModel() 179 { 180 DBG_DTOR( UnoControlTableModel, UnoControlTableModel_checkInvariants ); 181 DELETEZ( m_pImpl ); 182 } 183 184 //------------------------------------------------------------------------------------------------------------------ 185 TableSize UnoControlTableModel::getColumnCount() const 186 { 187 DBG_CHECK_ME(); 188 return (TableSize)m_pImpl->aColumns.size(); 189 } 190 191 //------------------------------------------------------------------------------------------------------------------ 192 TableSize UnoControlTableModel::getRowCount() const 193 { 194 DBG_CHECK_ME(); 195 196 TableSize nRowCount = 0; 197 try 198 { 199 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 200 ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" ); 201 nRowCount = xDataModel->getRowCount(); 202 } 203 catch( const Exception& ) 204 { 205 DBG_UNHANDLED_EXCEPTION(); 206 } 207 return nRowCount; 208 } 209 210 //------------------------------------------------------------------------------------------------------------------ 211 bool UnoControlTableModel::hasColumnHeaders() const 212 { 213 DBG_CHECK_ME(); 214 return m_pImpl->bHasColumnHeaders; 215 } 216 217 //------------------------------------------------------------------------------------------------------------------ 218 bool UnoControlTableModel::hasRowHeaders() const 219 { 220 DBG_CHECK_ME(); 221 return m_pImpl->bHasRowHeaders; 222 } 223 224 //------------------------------------------------------------------------------------------------------------------ 225 void UnoControlTableModel::setRowHeaders(bool _bRowHeaders) 226 { 227 DBG_CHECK_ME(); 228 if ( m_pImpl->bHasRowHeaders == _bRowHeaders ) 229 return; 230 231 m_pImpl->bHasRowHeaders = _bRowHeaders; 232 impl_notifyTableMetricsChanged(); 233 } 234 235 //------------------------------------------------------------------------------------------------------------------ 236 void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders) 237 { 238 DBG_CHECK_ME(); 239 if ( m_pImpl->bHasColumnHeaders == _bColumnHeaders ) 240 return; 241 242 m_pImpl->bHasColumnHeaders = _bColumnHeaders; 243 impl_notifyTableMetricsChanged(); 244 } 245 246 //------------------------------------------------------------------------------------------------------------------ 247 bool UnoControlTableModel::isCellEditable( ColPos col, RowPos row ) const 248 { 249 DBG_CHECK_ME(); 250 (void)col; 251 (void)row; 252 return false; 253 } 254 255 //------------------------------------------------------------------------------------------------------------------ 256 PColumnModel UnoControlTableModel::getColumnModel( ColPos column ) 257 { 258 DBG_CHECK_ME(); 259 ENSURE_OR_RETURN( ( column >= 0 ) && ( column < getColumnCount() ), 260 "DefaultTableModel::getColumnModel: invalid index!", PColumnModel() ); 261 return m_pImpl->aColumns[ column ]; 262 } 263 264 //------------------------------------------------------------------------------------------------------------------ 265 void UnoControlTableModel::appendColumn( Reference< XGridColumn > const & i_column ) 266 { 267 DBG_CHECK_ME(); 268 insertColumn( m_pImpl->aColumns.size(), i_column ); 269 } 270 271 //------------------------------------------------------------------------------------------------------------------ 272 void UnoControlTableModel::insertColumn( ColPos const i_position, Reference< XGridColumn > const & i_column ) 273 { 274 DBG_CHECK_ME(); 275 ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( size_t( i_position ) <= m_pImpl->aColumns.size() ), 276 "UnoControlTableModel::insertColumn: illegal position!" ); 277 278 const PColumnModel pColumn( new UnoGridColumnFacade( *this, i_column ) ); 279 m_pImpl->aColumns.insert( m_pImpl->aColumns.begin() + i_position, pColumn ); 280 281 // notify listeners 282 ModellListeners aListeners( m_pImpl->m_aListeners ); 283 for ( ModellListeners::const_iterator loop = aListeners.begin(); 284 loop != aListeners.end(); 285 ++loop 286 ) 287 { 288 (*loop)->columnInserted( i_position ); 289 } 290 } 291 292 //------------------------------------------------------------------------------------------------------------------ 293 void UnoControlTableModel::removeColumn( ColPos const i_position ) 294 { 295 DBG_CHECK_ME(); 296 ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( size_t( i_position ) <= m_pImpl->aColumns.size() ), 297 "UnoControlTableModel::removeColumn: illegal position!" ); 298 299 // remove the column 300 ColumnModels::iterator pos = m_pImpl->aColumns.begin() + i_position; 301 const PColumnModel pColumn = *pos; 302 m_pImpl->aColumns.erase( pos ); 303 304 // notify listeners 305 ModellListeners aListeners( m_pImpl->m_aListeners ); 306 for ( ModellListeners::const_iterator loop = aListeners.begin(); 307 loop != aListeners.end(); 308 ++loop 309 ) 310 { 311 (*loop)->columnRemoved( i_position ); 312 } 313 314 // dispose the column 315 UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() ); 316 OSL_ENSURE( pColumnImpl != NULL, "UnoControlTableModel::removeColumn: illegal column implementation!" ); 317 if ( pColumnImpl ) 318 pColumnImpl->dispose(); 319 } 320 321 //------------------------------------------------------------------------------------------------------------------ 322 void UnoControlTableModel::removeAllColumns() 323 { 324 DBG_CHECK_ME(); 325 if ( m_pImpl->aColumns.empty() ) 326 return; 327 328 // dispose the column instances 329 for ( ColumnModels::const_iterator col = m_pImpl->aColumns.begin(); 330 col != m_pImpl->aColumns.end(); 331 ++col 332 ) 333 { 334 UnoGridColumnFacade* pColumn = dynamic_cast< UnoGridColumnFacade* >( col->get() ); 335 ENSURE_OR_CONTINUE( pColumn != NULL, "UnoControlTableModel::removeAllColumns: illegal column implementation!" ); 336 pColumn->dispose(); 337 } 338 m_pImpl->aColumns.clear(); 339 340 // notify listeners 341 ModellListeners aListeners( m_pImpl->m_aListeners ); 342 for ( ModellListeners::const_iterator loop = aListeners.begin(); 343 loop != aListeners.end(); 344 ++loop 345 ) 346 { 347 (*loop)->allColumnsRemoved(); 348 } 349 } 350 351 //------------------------------------------------------------------------------------------------------------------ 352 void UnoControlTableModel::impl_notifyTableMetricsChanged() const 353 { 354 ModellListeners aListeners( m_pImpl->m_aListeners ); 355 for ( ModellListeners::const_iterator loop = aListeners.begin(); 356 loop != aListeners.end(); 357 ++loop 358 ) 359 { 360 (*loop)->tableMetricsChanged(); 361 } 362 } 363 364 //------------------------------------------------------------------------------------------------------------------ 365 PTableRenderer UnoControlTableModel::getRenderer() const 366 { 367 DBG_CHECK_ME(); 368 return m_pImpl->pRenderer; 369 } 370 371 //------------------------------------------------------------------------------------------------------------------ 372 PTableInputHandler UnoControlTableModel::getInputHandler() const 373 { 374 DBG_CHECK_ME(); 375 return m_pImpl->pInputHandler; 376 } 377 378 //------------------------------------------------------------------------------------------------------------------ 379 TableMetrics UnoControlTableModel::getRowHeight() const 380 { 381 DBG_CHECK_ME(); 382 return m_pImpl->nRowHeight; 383 } 384 385 //------------------------------------------------------------------------------------------------------------------ 386 void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight) 387 { 388 DBG_CHECK_ME(); 389 if ( m_pImpl->nRowHeight == _nRowHeight ) 390 return; 391 392 m_pImpl->nRowHeight = _nRowHeight; 393 impl_notifyTableMetricsChanged(); 394 } 395 396 //------------------------------------------------------------------------------------------------------------------ 397 TableMetrics UnoControlTableModel::getColumnHeaderHeight() const 398 { 399 DBG_CHECK_ME(); 400 DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" ); 401 return m_pImpl->nColumnHeaderHeight; 402 } 403 404 //------------------------------------------------------------------------------------------------------------------ 405 TableMetrics UnoControlTableModel::getRowHeaderWidth() const 406 { 407 DBG_CHECK_ME(); 408 DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" ); 409 return m_pImpl->nRowHeaderWidth; 410 } 411 //------------------------------------------------------------------------------------------------------------------ 412 void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight) 413 { 414 DBG_CHECK_ME(); 415 if ( m_pImpl->nColumnHeaderHeight == _nHeight ) 416 return; 417 418 m_pImpl->nColumnHeaderHeight = _nHeight; 419 impl_notifyTableMetricsChanged(); 420 } 421 422 //------------------------------------------------------------------------------------------------------------------ 423 void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth) 424 { 425 DBG_CHECK_ME(); 426 if ( m_pImpl->nRowHeaderWidth == _nWidth ) 427 return; 428 429 m_pImpl->nRowHeaderWidth = _nWidth; 430 impl_notifyTableMetricsChanged(); 431 } 432 433 //------------------------------------------------------------------------------------------------------------------ 434 ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility() const 435 { 436 DBG_CHECK_ME(); 437 return m_pImpl->eVScrollMode; 438 } 439 440 //------------------------------------------------------------------------------------------------------------------ 441 ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility() const 442 { 443 DBG_CHECK_ME(); 444 return m_pImpl->eHScrollMode; 445 } 446 447 //------------------------------------------------------------------------------------------------------------------ 448 void UnoControlTableModel::addTableModelListener( const PTableModelListener& i_listener ) 449 { 450 DBG_CHECK_ME(); 451 ENSURE_OR_RETURN_VOID( !!i_listener, "illegal NULL listener" ); 452 m_pImpl->m_aListeners.push_back( i_listener ); 453 } 454 455 //------------------------------------------------------------------------------------------------------------------ 456 void UnoControlTableModel::removeTableModelListener( const PTableModelListener& i_listener ) 457 { 458 DBG_CHECK_ME(); 459 for ( ModellListeners::iterator lookup = m_pImpl->m_aListeners.begin(); 460 lookup != m_pImpl->m_aListeners.end(); 461 ++lookup 462 ) 463 { 464 if ( *lookup == i_listener ) 465 { 466 m_pImpl->m_aListeners.erase( lookup ); 467 return; 468 } 469 } 470 OSL_ENSURE( false, "UnoControlTableModel::removeTableModelListener: listener is not registered - sure you're doing the right thing here?" ); 471 } 472 473 //------------------------------------------------------------------------------------------------------------------ 474 void UnoControlTableModel::setVerticalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const 475 { 476 DBG_CHECK_ME(); 477 m_pImpl->eVScrollMode = i_visibility; 478 } 479 480 //------------------------------------------------------------------------------------------------------------------ 481 void UnoControlTableModel::setHorizontalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const 482 { 483 DBG_CHECK_ME(); 484 m_pImpl->eHScrollMode = i_visibility; 485 } 486 487 //------------------------------------------------------------------------------------------------------------------ 488 void UnoControlTableModel::setDataModel( Reference< XGridDataModel > const & i_gridDataModel ) 489 { 490 DBG_CHECK_ME(); 491 m_pImpl->m_aDataModel = i_gridDataModel; 492 // TODO: register as listener, so we're notified of row/data changes, and can multiplex them to our 493 // own listeners 494 } 495 496 //------------------------------------------------------------------------------------------------------------------ 497 Reference< XGridDataModel > UnoControlTableModel::getDataModel() const 498 { 499 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 500 return xDataModel; 501 } 502 503 //------------------------------------------------------------------------------------------------------------------ 504 bool UnoControlTableModel::hasDataModel() const 505 { 506 return getDataModel().is(); 507 } 508 509 //------------------------------------------------------------------------------------------------------------------ 510 void UnoControlTableModel::setColumnModel( Reference< XGridColumnModel > const & i_gridColumnModel ) 511 { 512 DBG_CHECK_ME(); 513 m_pImpl->m_aColumnModel = i_gridColumnModel; 514 } 515 516 //------------------------------------------------------------------------------------------------------------------ 517 Reference< XGridColumnModel > UnoControlTableModel::getColumnModel() const 518 { 519 Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel ); 520 return xColumnModel; 521 } 522 523 //------------------------------------------------------------------------------------------------------------------ 524 bool UnoControlTableModel::hasColumnModel() const 525 { 526 return getColumnModel().is(); 527 } 528 529 //------------------------------------------------------------------------------------------------------------------ 530 void UnoControlTableModel::getCellContent( ColPos const i_col, RowPos const i_row, Any& o_cellContent ) 531 { 532 DBG_CHECK_ME(); 533 534 o_cellContent.clear(); 535 try 536 { 537 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 538 ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::getCellContent: no data model anymore!" ); 539 540 PColumnModel const pColumn = getColumnModel( i_col ); 541 UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() ); 542 ENSURE_OR_RETURN_VOID( pColumnImpl != NULL, "UnoControlTableModel::getCellContent: no (valid) column at this position!" ); 543 sal_Int32 const nDataColumnIndex = pColumnImpl->getDataColumnIndex() >= 0 ? pColumnImpl->getDataColumnIndex() : i_col; 544 545 if ( nDataColumnIndex >= xDataModel->getColumnCount() ) 546 { 547 // this is allowed, in case the column model has been dynamically extended, but the data model does 548 // not (yet?) know about it. 549 // So, handle it gracefully. 550 #if OSL_DEBUG_LEVEL > 0 551 { 552 Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel ); 553 OSL_ENSURE( xColumnModel.is() && i_col < xColumnModel->getColumnCount(), 554 "UnoControlTableModel::getCellContent: request a column's value which the ColumnModel doesn't know about!" ); 555 } 556 #endif 557 } 558 else 559 { 560 o_cellContent = xDataModel->getCellData( nDataColumnIndex, i_row ); 561 } 562 } 563 catch( const Exception& ) 564 { 565 DBG_UNHANDLED_EXCEPTION(); 566 } 567 } 568 569 //------------------------------------------------------------------------------------------------------------------ 570 void UnoControlTableModel::getCellToolTip( ColPos const i_col, RowPos const i_row, Any& o_cellToolTip ) 571 { 572 DBG_CHECK_ME(); 573 try 574 { 575 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 576 ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" ); 577 578 o_cellToolTip = xDataModel->getCellToolTip( i_col, i_row ); 579 } 580 catch( const Exception& ) 581 { 582 DBG_UNHANDLED_EXCEPTION(); 583 } 584 } 585 586 //------------------------------------------------------------------------------------------------------------------ 587 Any UnoControlTableModel::getRowHeading( RowPos const i_rowPos ) const 588 { 589 DBG_CHECK_ME(); 590 591 Any aRowHeading; 592 593 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 594 ENSURE_OR_RETURN( xDataModel.is(), "UnoControlTableModel::getRowHeading: no data model anymore!", aRowHeading ); 595 596 try 597 { 598 aRowHeading = xDataModel->getRowHeading( i_rowPos ); 599 } 600 catch( const Exception& ) 601 { 602 DBG_UNHANDLED_EXCEPTION(); 603 } 604 return aRowHeading; 605 } 606 607 //------------------------------------------------------------------------------------------------------------------ 608 namespace 609 { 610 void lcl_setColor( Any const & i_color, ::boost::optional< ::Color > & o_convertedColor ) 611 { 612 if ( !i_color.hasValue() ) 613 o_convertedColor.reset(); 614 else 615 { 616 sal_Int32 nColor = COL_TRANSPARENT; 617 if ( i_color >>= nColor ) 618 { 619 o_convertedColor.reset( ::Color( nColor ) ); 620 } 621 else 622 { 623 OSL_ENSURE( false, "lcl_setColor: could not extract color value!" ); 624 } 625 } 626 } 627 } 628 629 //------------------------------------------------------------------------------------------------------------------ 630 ::boost::optional< ::Color > UnoControlTableModel::getLineColor() const 631 { 632 DBG_CHECK_ME(); 633 return m_pImpl->m_aGridLineColor; 634 } 635 636 //------------------------------------------------------------------------------------------------------------------ 637 void UnoControlTableModel::setLineColor( Any const & i_color ) 638 { 639 DBG_CHECK_ME(); 640 lcl_setColor( i_color, m_pImpl->m_aGridLineColor ); 641 } 642 643 //------------------------------------------------------------------------------------------------------------------ 644 ::boost::optional< ::Color > UnoControlTableModel::getHeaderBackgroundColor() const 645 { 646 DBG_CHECK_ME(); 647 return m_pImpl->m_aHeaderBackgroundColor; 648 } 649 650 //------------------------------------------------------------------------------------------------------------------ 651 void UnoControlTableModel::setHeaderBackgroundColor( Any const & i_color ) 652 { 653 DBG_CHECK_ME(); 654 lcl_setColor( i_color, m_pImpl->m_aHeaderBackgroundColor ); 655 } 656 657 //------------------------------------------------------------------------------------------------------------------ 658 ::boost::optional< ::Color > UnoControlTableModel::getHeaderTextColor() const 659 { 660 DBG_CHECK_ME(); 661 return m_pImpl->m_aHeaderTextColor; 662 } 663 664 //------------------------------------------------------------------------------------------------------------------ 665 ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionBackColor() const 666 { 667 DBG_CHECK_ME(); 668 return m_pImpl->m_aActiveSelectionBackColor; 669 } 670 671 //------------------------------------------------------------------------------------------------------------------ 672 ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionBackColor() const 673 { 674 DBG_CHECK_ME(); 675 return m_pImpl->m_aInactiveSelectionBackColor; 676 } 677 678 //------------------------------------------------------------------------------------------------------------------ 679 ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionTextColor() const 680 { 681 DBG_CHECK_ME(); 682 return m_pImpl->m_aActiveSelectionTextColor; 683 } 684 685 //------------------------------------------------------------------------------------------------------------------ 686 ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionTextColor() const 687 { 688 DBG_CHECK_ME(); 689 return m_pImpl->m_aInactiveSelectionTextColor; 690 } 691 692 //------------------------------------------------------------------------------------------------------------------ 693 void UnoControlTableModel::setHeaderTextColor( Any const & i_color ) 694 { 695 DBG_CHECK_ME(); 696 lcl_setColor( i_color, m_pImpl->m_aHeaderTextColor ); 697 } 698 699 //------------------------------------------------------------------------------------------------------------------ 700 void UnoControlTableModel::setActiveSelectionBackColor( Any const & i_color ) 701 { 702 DBG_CHECK_ME(); 703 lcl_setColor( i_color, m_pImpl->m_aActiveSelectionBackColor ); 704 } 705 706 //------------------------------------------------------------------------------------------------------------------ 707 void UnoControlTableModel::setInactiveSelectionBackColor( Any const & i_color ) 708 { 709 DBG_CHECK_ME(); 710 lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionBackColor ); 711 } 712 713 //------------------------------------------------------------------------------------------------------------------ 714 void UnoControlTableModel::setActiveSelectionTextColor( Any const & i_color ) 715 { 716 DBG_CHECK_ME(); 717 lcl_setColor( i_color, m_pImpl->m_aActiveSelectionTextColor ); 718 } 719 720 //------------------------------------------------------------------------------------------------------------------ 721 void UnoControlTableModel::setInactiveSelectionTextColor( Any const & i_color ) 722 { 723 DBG_CHECK_ME(); 724 lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionTextColor ); 725 } 726 727 //------------------------------------------------------------------------------------------------------------------ 728 ::boost::optional< ::Color > UnoControlTableModel::getTextColor() const 729 { 730 DBG_CHECK_ME(); 731 return m_pImpl->m_aTextColor; 732 } 733 734 //------------------------------------------------------------------------------------------------------------------ 735 void UnoControlTableModel::setTextColor( Any const & i_color ) 736 { 737 DBG_CHECK_ME(); 738 lcl_setColor( i_color, m_pImpl->m_aTextColor ); 739 } 740 741 //------------------------------------------------------------------------------------------------------------------ 742 ::boost::optional< ::Color > UnoControlTableModel::getTextLineColor() const 743 { 744 DBG_CHECK_ME(); 745 return m_pImpl->m_aTextColor; 746 } 747 748 //------------------------------------------------------------------------------------------------------------------ 749 void UnoControlTableModel::setTextLineColor( Any const & i_color ) 750 { 751 DBG_CHECK_ME(); 752 lcl_setColor( i_color, m_pImpl->m_aTextLineColor ); 753 } 754 755 //------------------------------------------------------------------------------------------------------------------ 756 ::boost::optional< ::std::vector< ::Color > > UnoControlTableModel::getRowBackgroundColors() const 757 { 758 DBG_CHECK_ME(); 759 return m_pImpl->m_aRowColors; 760 } 761 762 //------------------------------------------------------------------------------------------------------------------ 763 void UnoControlTableModel::setRowBackgroundColors( ::com::sun::star::uno::Any const & i_APIValue ) 764 { 765 DBG_CHECK_ME(); 766 Sequence< ::com::sun::star::util::Color > aAPIColors; 767 if ( !( i_APIValue >>= aAPIColors ) ) 768 m_pImpl->m_aRowColors.reset(); 769 else 770 { 771 ::std::vector< ::Color > aColors( aAPIColors.getLength() ); 772 for ( sal_Int32 i=0; i<aAPIColors.getLength(); ++i ) 773 { 774 aColors[i] = ::Color( aAPIColors[i] ); 775 } 776 m_pImpl->m_aRowColors.reset( aColors ); 777 } 778 } 779 780 //------------------------------------------------------------------------------------------------------------------ 781 VerticalAlignment UnoControlTableModel::getVerticalAlign() const 782 { 783 DBG_CHECK_ME(); 784 return m_pImpl->m_eVerticalAlign; 785 } 786 787 //------------------------------------------------------------------------------------------------------------------ 788 void UnoControlTableModel::setVerticalAlign( VerticalAlignment _xAlign ) 789 { 790 DBG_CHECK_ME(); 791 m_pImpl->m_eVerticalAlign = _xAlign; 792 } 793 794 //------------------------------------------------------------------------------------------------------------------ 795 ColPos UnoControlTableModel::getColumnPos( UnoGridColumnFacade const & i_column ) const 796 { 797 DBG_CHECK_ME(); 798 for ( ColumnModels::const_iterator col = m_pImpl->aColumns.begin(); 799 col != m_pImpl->aColumns.end(); 800 ++col 801 ) 802 { 803 if ( &i_column == col->get() ) 804 return col - m_pImpl->aColumns.begin(); 805 } 806 OSL_ENSURE( false, "UnoControlTableModel::getColumnPos: column not found!" ); 807 return COL_INVALID; 808 } 809 810 //------------------------------------------------------------------------------------------------------------------ 811 ITableDataSort* UnoControlTableModel::getSortAdapter() 812 { 813 DBG_CHECK_ME(); 814 815 Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY ); 816 if ( xSortAccess.is() ) 817 return this; 818 return NULL; 819 } 820 821 //------------------------------------------------------------------------------------------------------------------ 822 void UnoControlTableModel::sortByColumn( ColPos const i_column, ColumnSortDirection const i_sortDirection ) 823 { 824 DBG_CHECK_ME(); 825 826 try 827 { 828 Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW ); 829 xSortAccess->sortByColumn( i_column, i_sortDirection == ColumnSortAscending ); 830 } 831 catch( const Exception& ) 832 { 833 DBG_UNHANDLED_EXCEPTION(); 834 } 835 } 836 837 //------------------------------------------------------------------------------------------------------------------ 838 ColumnSort UnoControlTableModel::getCurrentSortOrder() const 839 { 840 DBG_CHECK_ME(); 841 842 ColumnSort currentSort; 843 try 844 { 845 Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW ); 846 Pair< ::sal_Int32, ::sal_Bool > const aCurrentSortOrder( xSortAccess->getCurrentSortOrder() ); 847 currentSort.nColumnPos = aCurrentSortOrder.First; 848 currentSort.eSortDirection = aCurrentSortOrder.Second ? ColumnSortAscending : ColumnSortDescending; 849 } 850 catch( const Exception& ) 851 { 852 DBG_UNHANDLED_EXCEPTION(); 853 } 854 return currentSort; 855 } 856 857 //-------------------------------------------------------------------- 858 void UnoControlTableModel::notifyColumnChange( ColPos const i_columnPos, ColumnAttributeGroup const i_attributeGroup ) const 859 { 860 DBG_CHECK_ME(); 861 ENSURE_OR_RETURN_VOID( ( i_columnPos >= 0 ) && ( i_columnPos < getColumnCount() ), 862 "UnoControlTableModel::notifyColumnChange: invalid column index!" ); 863 864 ModellListeners aListeners( m_pImpl->m_aListeners ); 865 for ( ModellListeners::const_iterator loop = aListeners.begin(); 866 loop != aListeners.end(); 867 ++loop 868 ) 869 { 870 (*loop)->columnChanged( i_columnPos, i_attributeGroup ); 871 } 872 } 873 874 //------------------------------------------------------------------------------------------------------------------ 875 void UnoControlTableModel::notifyRowsInserted( GridDataEvent const & i_event ) const 876 { 877 // check sanity of the event 878 ENSURE_OR_RETURN_VOID( i_event.FirstRow >= 0, "UnoControlTableModel::notifyRowsInserted: invalid first row!" ); 879 ENSURE_OR_RETURN_VOID( i_event.LastRow >= i_event.FirstRow, "UnoControlTableModel::notifyRowsInserted: invalid row indexes!" ); 880 881 // check own sanity 882 Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel ); 883 ENSURE_OR_RETURN_VOID( xColumnModel.is(), "UnoControlTableModel::notifyRowsInserted: no column model anymore!" ); 884 885 Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel ); 886 ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::notifyRowsInserted: no data model anymore!" ); 887 888 // implicitly add columns to the column model 889 // TODO: is this really a good idea? 890 sal_Int32 const dataColumnCount = xDataModel->getColumnCount(); 891 OSL_ENSURE( dataColumnCount > 0, "UnoControlTableModel::notifyRowsInserted: no columns at all?" ); 892 893 sal_Int32 const modelColumnCount = xColumnModel->getColumnCount(); 894 if ( ( modelColumnCount == 0 ) && ( dataColumnCount > 0 ) ) 895 { 896 // TODO: shouldn't we clear the mutexes guard for this call? 897 xColumnModel->setDefaultColumns( dataColumnCount ); 898 } 899 900 // multiplex the event to our own listeners 901 ModellListeners aListeners( m_pImpl->m_aListeners ); 902 for ( ModellListeners::const_iterator loop = aListeners.begin(); 903 loop != aListeners.end(); 904 ++loop 905 ) 906 { 907 (*loop)->rowsInserted( i_event.FirstRow, i_event.LastRow ); 908 } 909 } 910 911 //------------------------------------------------------------------------------------------------------------------ 912 void UnoControlTableModel::notifyRowsRemoved( GridDataEvent const & i_event ) const 913 { 914 ModellListeners aListeners( m_pImpl->m_aListeners ); 915 for ( ModellListeners::const_iterator loop = aListeners.begin(); 916 loop != aListeners.end(); 917 ++loop 918 ) 919 { 920 (*loop)->rowsRemoved( i_event.FirstRow, i_event.LastRow ); 921 } 922 } 923 924 //------------------------------------------------------------------------------------------------------------------ 925 void UnoControlTableModel::notifyDataChanged( ::com::sun::star::awt::grid::GridDataEvent const & i_event ) const 926 { 927 ColPos const firstCol = i_event.FirstColumn == -1 ? 0 : i_event.FirstColumn; 928 ColPos const lastCol = i_event.FirstColumn == -1 ? getColumnCount() - 1 : i_event.LastColumn; 929 RowPos const firstRow = i_event.FirstRow == -1 ? 0 : i_event.FirstRow; 930 RowPos const lastRow = i_event.FirstRow == -1 ? getRowCount() - 1 : i_event.LastRow; 931 932 ModellListeners aListeners( m_pImpl->m_aListeners ); 933 for ( ModellListeners::const_iterator loop = aListeners.begin(); 934 loop != aListeners.end(); 935 ++loop 936 ) 937 { 938 (*loop)->cellsUpdated( firstCol, lastCol, firstRow, lastRow ); 939 } 940 } 941 942 //------------------------------------------------------------------------------------------------------------------ 943 void UnoControlTableModel::notifyAllDataChanged() const 944 { 945 ModellListeners aListeners( m_pImpl->m_aListeners ); 946 for ( ModellListeners::const_iterator loop = aListeners.begin(); 947 loop != aListeners.end(); 948 ++loop 949 ) 950 { 951 (*loop)->cellsUpdated( 0, getColumnCount() - 1, 0, getRowCount() - 1 ); 952 } 953 } 954 955 // ..................................................................................................................... 956 } } // svt::table 957 // ..................................................................................................................... 958