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