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