1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_svtools.hxx" 29 30 #include "cellvalueconversion.hxx" 31 #include "svtools/table/gridtablerenderer.hxx" 32 #include "svtools/colorcfg.hxx" 33 34 /** === begin UNO includes === **/ 35 #include <com/sun/star/graphic/XGraphic.hpp> 36 /** === end UNO includes === **/ 37 38 #include <comphelper/componentcontext.hxx> 39 #include <comphelper/processfactory.hxx> 40 #include <tools/debug.hxx> 41 #include <tools/diagnose_ex.h> 42 #include <vcl/window.hxx> 43 #include <vcl/image.hxx> 44 #include <vcl/virdev.hxx> 45 #include <vcl/decoview.hxx> 46 47 //...................................................................................................................... 48 namespace svt { namespace table 49 { 50 //...................................................................................................................... 51 52 /** === begin UNO using === **/ 53 using ::com::sun::star::uno::Any; 54 using ::com::sun::star::uno::Reference; 55 using ::com::sun::star::uno::UNO_QUERY; 56 using ::com::sun::star::uno::XInterface; 57 using ::com::sun::star::uno::TypeClass_INTERFACE; 58 using ::com::sun::star::graphic::XGraphic; 59 using ::com::sun::star::style::HorizontalAlignment; 60 using ::com::sun::star::style::HorizontalAlignment_LEFT; 61 using ::com::sun::star::style::HorizontalAlignment_CENTER; 62 using ::com::sun::star::style::HorizontalAlignment_RIGHT; 63 using ::com::sun::star::style::VerticalAlignment; 64 using ::com::sun::star::style::VerticalAlignment_TOP; 65 using ::com::sun::star::style::VerticalAlignment_MIDDLE; 66 using ::com::sun::star::style::VerticalAlignment_BOTTOM; 67 /** === end UNO using === **/ 68 69 //================================================================================================================== 70 //= CachedSortIndicator 71 //================================================================================================================== 72 class CachedSortIndicator 73 { 74 public: 75 CachedSortIndicator() 76 :m_lastHeaderHeight( 0 ) 77 ,m_lastArrowColor( COL_TRANSPARENT ) 78 { 79 } 80 81 BitmapEx const & getBitmapFor( OutputDevice const & i_device, long const i_headerHeight, StyleSettings const & i_style, bool const i_sortAscending ); 82 83 private: 84 long m_lastHeaderHeight; 85 Color m_lastArrowColor; 86 BitmapEx m_sortAscending; 87 BitmapEx m_sortDescending; 88 }; 89 90 //------------------------------------------------------------------------------------------------------------------ 91 BitmapEx const & CachedSortIndicator::getBitmapFor( OutputDevice const & i_device, long const i_headerHeight, 92 StyleSettings const & i_style, bool const i_sortAscending ) 93 { 94 BitmapEx & rBitmap( i_sortAscending ? m_sortAscending : m_sortDescending ); 95 if ( !rBitmap || ( i_headerHeight != m_lastHeaderHeight ) || ( i_style.GetActiveColor() != m_lastArrowColor ) ) 96 { 97 long const nSortIndicatorWidth = 2 * i_headerHeight / 3; 98 long const nSortIndicatorHeight = 2 * nSortIndicatorWidth / 3; 99 100 Point const aBitmapPos( 0, 0 ); 101 Size const aBitmapSize( nSortIndicatorWidth, nSortIndicatorHeight ); 102 VirtualDevice aDevice( i_device, 0, 0 ); 103 aDevice.SetOutputSizePixel( aBitmapSize ); 104 105 DecorationView aDecoView( &aDevice ); 106 aDecoView.DrawSymbol( 107 Rectangle( aBitmapPos, aBitmapSize ), 108 i_sortAscending ? SYMBOL_SPIN_UP : SYMBOL_SPIN_DOWN, 109 i_style.GetActiveColor() 110 ); 111 112 rBitmap = aDevice.GetBitmapEx( aBitmapPos, aBitmapSize ); 113 m_lastHeaderHeight = i_headerHeight; 114 m_lastArrowColor = i_style.GetActiveColor(); 115 } 116 return rBitmap; 117 } 118 119 //================================================================================================================== 120 //= GridTableRenderer_Impl 121 //================================================================================================================== 122 struct GridTableRenderer_Impl 123 { 124 ITableModel& rModel; 125 RowPos nCurrentRow; 126 bool bUseGridLines; 127 CachedSortIndicator aSortIndicator; 128 CellValueConversion aStringConverter; 129 130 GridTableRenderer_Impl( ITableModel& _rModel ) 131 :rModel( _rModel ) 132 ,nCurrentRow( ROW_INVALID ) 133 ,bUseGridLines( true ) 134 ,aSortIndicator( ) 135 ,aStringConverter( ::comphelper::ComponentContext( ::comphelper::getProcessServiceFactory() ) ) 136 { 137 } 138 }; 139 140 //================================================================================================================== 141 //= helper 142 //================================================================================================================== 143 namespace 144 { 145 static Rectangle lcl_getContentArea( GridTableRenderer_Impl const & i_impl, Rectangle const & i_cellArea ) 146 { 147 Rectangle aContentArea( i_cellArea ); 148 if ( i_impl.bUseGridLines ) 149 { 150 --aContentArea.Right(); 151 --aContentArea.Bottom(); 152 } 153 return aContentArea; 154 } 155 static Rectangle lcl_getTextRenderingArea( Rectangle const & i_contentArea ) 156 { 157 Rectangle aTextArea( i_contentArea ); 158 aTextArea.Left() += 2; aTextArea.Right() -= 2; 159 ++aTextArea.Top(); --aTextArea.Bottom(); 160 return aTextArea; 161 } 162 163 static sal_uLong lcl_getAlignmentTextDrawFlags( GridTableRenderer_Impl const & i_impl, ColPos const i_columnPos ) 164 { 165 sal_uLong nVertFlag = TEXT_DRAW_TOP; 166 VerticalAlignment const eVertAlign = i_impl.rModel.getVerticalAlign(); 167 switch ( eVertAlign ) 168 { 169 case VerticalAlignment_MIDDLE: nVertFlag = TEXT_DRAW_VCENTER; break; 170 case VerticalAlignment_BOTTOM: nVertFlag = TEXT_DRAW_BOTTOM; break; 171 default: 172 break; 173 } 174 175 sal_uLong nHorzFlag = TEXT_DRAW_LEFT; 176 HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnCount() > 0 177 ? i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign() 178 : HorizontalAlignment_CENTER; 179 switch ( eHorzAlign ) 180 { 181 case HorizontalAlignment_CENTER: nHorzFlag = TEXT_DRAW_CENTER; break; 182 case HorizontalAlignment_RIGHT: nHorzFlag = TEXT_DRAW_RIGHT; break; 183 default: 184 break; 185 } 186 187 return nVertFlag | nHorzFlag; 188 } 189 190 } 191 192 //================================================================================================================== 193 //= GridTableRenderer 194 //================================================================================================================== 195 //------------------------------------------------------------------------------------------------------------------ 196 GridTableRenderer::GridTableRenderer( ITableModel& _rModel ) 197 :m_pImpl( new GridTableRenderer_Impl( _rModel ) ) 198 { 199 } 200 201 //------------------------------------------------------------------------------------------------------------------ 202 GridTableRenderer::~GridTableRenderer() 203 { 204 } 205 206 //------------------------------------------------------------------------------------------------------------------ 207 RowPos GridTableRenderer::getCurrentRow() const 208 { 209 return m_pImpl->nCurrentRow; 210 } 211 212 //------------------------------------------------------------------------------------------------------------------ 213 bool GridTableRenderer::useGridLines() const 214 { 215 return m_pImpl->bUseGridLines; 216 } 217 218 //------------------------------------------------------------------------------------------------------------------ 219 void GridTableRenderer::useGridLines( bool const i_use ) 220 { 221 m_pImpl->bUseGridLines = i_use; 222 } 223 224 //------------------------------------------------------------------------------------------------------------------ 225 namespace 226 { 227 Color lcl_getEffectiveColor( 228 ::boost::optional< ::Color > const & i_modelColor, 229 StyleSettings const & i_styleSettings, 230 ::Color const & ( StyleSettings::*i_getDefaultColor ) () const 231 ) 232 { 233 if ( !!i_modelColor ) 234 return *i_modelColor; 235 return ( i_styleSettings.*i_getDefaultColor )(); 236 } 237 } 238 239 //------------------------------------------------------------------------------------------------------------------ 240 void GridTableRenderer::PaintHeaderArea( 241 OutputDevice& _rDevice, const Rectangle& _rArea, bool _bIsColHeaderArea, bool _bIsRowHeaderArea, 242 const StyleSettings& _rStyle ) 243 { 244 OSL_PRECOND( _bIsColHeaderArea || _bIsRowHeaderArea, 245 "GridTableRenderer::PaintHeaderArea: invalid area flags!" ); 246 247 _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR ); 248 249 Color const background = lcl_getEffectiveColor( m_pImpl->rModel.getHeaderBackgroundColor(), _rStyle, &StyleSettings::GetDialogColor ); 250 _rDevice.SetFillColor( background ); 251 252 _rDevice.SetLineColor(); 253 _rDevice.DrawRect( _rArea ); 254 255 // delimiter lines at bottom/right 256 ::boost::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() ); 257 ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; 258 _rDevice.SetLineColor( lineColor ); 259 _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); 260 _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); 261 262 _rDevice.Pop(); 263 (void)_bIsColHeaderArea; 264 (void)_bIsRowHeaderArea; 265 } 266 267 //------------------------------------------------------------------------------------------------------------------ 268 void GridTableRenderer::PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected, 269 OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle ) 270 { 271 _rDevice.Push( PUSH_LINECOLOR); 272 273 String sHeaderText; 274 PColumnModel const pColumn = m_pImpl->rModel.getColumnModel( _nCol ); 275 DBG_ASSERT( !!pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" ); 276 if ( !!pColumn ) 277 sHeaderText = pColumn->getName(); 278 279 ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), _rStyle, &StyleSettings::GetFieldTextColor ); 280 _rDevice.SetTextColor( textColor ); 281 282 Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) ); 283 sal_uLong const nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, _nCol ) | TEXT_DRAW_CLIP; 284 _rDevice.DrawText( aTextRect, sHeaderText, nDrawTextFlags ); 285 286 ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() ); 287 ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; 288 _rDevice.SetLineColor( lineColor ); 289 _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight()); 290 _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); 291 292 // draw sort indicator if the model data is sorted by the given column 293 ITableDataSort const * pSortAdapter = m_pImpl->rModel.getSortAdapter(); 294 ColumnSort aCurrentSortOrder; 295 if ( pSortAdapter != NULL ) 296 aCurrentSortOrder = pSortAdapter->getCurrentSortOrder(); 297 if ( aCurrentSortOrder.nColumnPos == _nCol ) 298 { 299 long const nHeaderHeight( _rArea.GetHeight() ); 300 BitmapEx const aIndicatorBitmap = m_pImpl->aSortIndicator.getBitmapFor( _rDevice, nHeaderHeight, _rStyle, 301 aCurrentSortOrder.eSortDirection == ColumnSortAscending ); 302 Size const aBitmapSize( aIndicatorBitmap.GetSizePixel() ); 303 long const nSortIndicatorPaddingX = 2; 304 long const nSortIndicatorPaddingY = ( nHeaderHeight - aBitmapSize.Height() ) / 2; 305 306 if ( ( nDrawTextFlags & TEXT_DRAW_RIGHT ) != 0 ) 307 { 308 // text is right aligned => draw the sort indicator at the left hand side 309 _rDevice.DrawBitmapEx( 310 Point( _rArea.Left() + nSortIndicatorPaddingX, _rArea.Top() + nSortIndicatorPaddingY ), 311 aIndicatorBitmap 312 ); 313 } 314 else 315 { 316 // text is left-aligned or centered => draw the sort indicator at the right hand side 317 _rDevice.DrawBitmapEx( 318 Point( _rArea.Right() - nSortIndicatorPaddingX - aBitmapSize.Width(), nSortIndicatorPaddingY ), 319 aIndicatorBitmap 320 ); 321 } 322 } 323 324 _rDevice.Pop(); 325 326 (void)_bActive; 327 // no special painting for the active column at the moment 328 329 (void)_bSelected; 330 // selection for column header not yet implemented 331 } 332 333 //------------------------------------------------------------------------------------------------------------------ 334 void GridTableRenderer::PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected, 335 OutputDevice& _rDevice, const Rectangle& _rRowArea, const StyleSettings& _rStyle ) 336 { 337 // remember the row for subsequent calls to the other ->ITableRenderer methods 338 m_pImpl->nCurrentRow = _nRow; 339 340 _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR); 341 342 ::Color backgroundColor = _rStyle.GetFieldColor(); 343 344 ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() ); 345 ::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; 346 347 ::Color const activeSelectionBackColor = 348 lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor ); 349 if ( _bSelected ) 350 { 351 // selected rows use the background color from the style 352 backgroundColor = i_hasControlFocus 353 ? activeSelectionBackColor 354 : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor ); 355 if ( !aLineColor ) 356 lineColor = backgroundColor; 357 } 358 else 359 { 360 ::boost::optional< ::std::vector< ::Color > > aRowColors = m_pImpl->rModel.getRowBackgroundColors(); 361 if ( !aRowColors ) 362 { 363 // use alternating default colors 364 Color const fieldColor = _rStyle.GetFieldColor(); 365 if ( _rStyle.GetHighContrastMode() || ( ( m_pImpl->nCurrentRow % 2 ) == 0 ) ) 366 { 367 backgroundColor = fieldColor; 368 } 369 else 370 { 371 Color hilightColor = activeSelectionBackColor; 372 hilightColor.SetRed( 9 * ( fieldColor.GetRed() - hilightColor.GetRed() ) / 10 + hilightColor.GetRed() ); 373 hilightColor.SetGreen( 9 * ( fieldColor.GetGreen() - hilightColor.GetGreen() ) / 10 + hilightColor.GetGreen() ); 374 hilightColor.SetBlue( 9 * ( fieldColor.GetBlue() - hilightColor.GetBlue() ) / 10 + hilightColor.GetBlue() ); 375 backgroundColor = hilightColor; 376 } 377 } 378 else 379 { 380 if ( aRowColors->empty() ) 381 { 382 // all colors have the same background color 383 backgroundColor = _rStyle.GetFieldColor(); 384 } 385 else 386 { 387 backgroundColor = aRowColors->at( m_pImpl->nCurrentRow % aRowColors->size() ); 388 } 389 } 390 } 391 392 //m_pImpl->bUseGridLines ? _rDevice.SetLineColor( lineColor ) : _rDevice.SetLineColor(); 393 _rDevice.SetLineColor(); 394 _rDevice.SetFillColor( backgroundColor ); 395 _rDevice.DrawRect( _rRowArea ); 396 397 _rDevice.Pop(); 398 } 399 400 //------------------------------------------------------------------------------------------------------------------ 401 void GridTableRenderer::PaintRowHeader( bool i_hasControlFocus, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea, 402 const StyleSettings& _rStyle ) 403 { 404 _rDevice.Push( PUSH_LINECOLOR | PUSH_TEXTCOLOR ); 405 406 ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() ); 407 ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; 408 _rDevice.SetLineColor( lineColor ); 409 _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); 410 411 Any const rowHeading( m_pImpl->rModel.getRowHeading( m_pImpl->nCurrentRow ) ); 412 ::rtl::OUString const rowTitle( m_pImpl->aStringConverter.convertToString( rowHeading ) ); 413 if ( rowTitle.getLength() ) 414 { 415 ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getHeaderTextColor(), _rStyle, &StyleSettings::GetFieldTextColor ); 416 _rDevice.SetTextColor( textColor ); 417 418 Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) ); 419 sal_uLong const nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, 0 ) | TEXT_DRAW_CLIP; 420 // TODO: is using the horizontal alignment of the 0'th column a good idea here? This is pretty ... arbitray .. 421 _rDevice.DrawText( aTextRect, rowTitle, nDrawTextFlags ); 422 } 423 424 (void)i_hasControlFocus; 425 (void)_bSelected; 426 _rDevice.Pop(); 427 } 428 429 //------------------------------------------------------------------------------------------------------------------ 430 struct GridTableRenderer::CellRenderContext 431 { 432 OutputDevice& rDevice; 433 Rectangle const aContentArea; 434 StyleSettings const & rStyle; 435 ColPos const nColumn; 436 bool const bSelected; 437 bool const bHasControlFocus; 438 439 CellRenderContext( OutputDevice& i_device, Rectangle const & i_contentArea, 440 StyleSettings const & i_style, ColPos const i_column, bool const i_selected, bool const i_hasControlFocus ) 441 :rDevice( i_device ) 442 ,aContentArea( i_contentArea ) 443 ,rStyle( i_style ) 444 ,nColumn( i_column ) 445 ,bSelected( i_selected ) 446 ,bHasControlFocus( i_hasControlFocus ) 447 { 448 } 449 }; 450 451 //------------------------------------------------------------------------------------------------------------------ 452 void GridTableRenderer::PaintCell( ColPos const i_column, bool _bSelected, bool i_hasControlFocus, 453 OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle ) 454 { 455 _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 456 457 Rectangle const aContentArea( lcl_getContentArea( *m_pImpl, _rArea ) ); 458 CellRenderContext const aRenderContext( _rDevice, aContentArea, _rStyle, i_column, _bSelected, i_hasControlFocus ); 459 impl_paintCellContent( aRenderContext ); 460 461 if ( m_pImpl->bUseGridLines ) 462 { 463 ::boost::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() ); 464 ::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor; 465 466 if ( _bSelected && !aLineColor ) 467 { 468 // if no line color is specified by the model, use the usual selection color for lines in selected cells 469 lineColor = i_hasControlFocus 470 ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor ) 471 : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor ); 472 } 473 474 _rDevice.SetLineColor( lineColor ); 475 _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); 476 _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() ); 477 } 478 479 _rDevice.Pop(); 480 } 481 482 //------------------------------------------------------------------------------------------------------------------ 483 void GridTableRenderer::impl_paintCellImage( CellRenderContext const & i_context, Image const & i_image ) 484 { 485 Point imagePos( Point( i_context.aContentArea.Left(), i_context.aContentArea.Top() ) ); 486 Size imageSize = i_image.GetSizePixel(); 487 if ( i_context.aContentArea.GetWidth() > imageSize.Width() ) 488 { 489 const HorizontalAlignment eHorzAlign = m_pImpl->rModel.getColumnModel( i_context.nColumn )->getHorizontalAlign(); 490 switch ( eHorzAlign ) 491 { 492 case HorizontalAlignment_CENTER: 493 imagePos.X() += ( i_context.aContentArea.GetWidth() - imageSize.Width() ) / 2; 494 break; 495 case HorizontalAlignment_RIGHT: 496 imagePos.X() = i_context.aContentArea.Right() - imageSize.Width(); 497 break; 498 default: 499 break; 500 } 501 502 } 503 else 504 imageSize.Width() = i_context.aContentArea.GetWidth(); 505 506 if ( i_context.aContentArea.GetHeight() > imageSize.Height() ) 507 { 508 const VerticalAlignment eVertAlign = m_pImpl->rModel.getVerticalAlign(); 509 switch ( eVertAlign ) 510 { 511 case VerticalAlignment_MIDDLE: 512 imagePos.Y() += ( i_context.aContentArea.GetHeight() - imageSize.Height() ) / 2; 513 break; 514 case VerticalAlignment_BOTTOM: 515 imagePos.Y() = i_context.aContentArea.Bottom() - imageSize.Height(); 516 break; 517 default: 518 break; 519 } 520 } 521 else 522 imageSize.Height() = i_context.aContentArea.GetHeight() - 1; 523 524 i_context.rDevice.DrawImage( imagePos, imageSize, i_image, 0 ); 525 } 526 527 //------------------------------------------------------------------------------------------------------------------ 528 void GridTableRenderer::impl_paintCellContent( CellRenderContext const & i_context ) 529 { 530 Any aCellContent; 531 m_pImpl->rModel.getCellContent( i_context.nColumn, m_pImpl->nCurrentRow, aCellContent ); 532 533 if ( aCellContent.getValueTypeClass() == TypeClass_INTERFACE ) 534 { 535 Reference< XInterface > const xContentInterface( aCellContent, UNO_QUERY ); 536 if ( !xContentInterface.is() ) 537 // allowed. kind of. 538 return; 539 540 Reference< XGraphic > const xGraphic( aCellContent, UNO_QUERY ); 541 ENSURE_OR_RETURN_VOID( xGraphic.is(), "GridTableRenderer::impl_paintCellContent: only XGraphic interfaces (or NULL) are supported for painting." ); 542 543 const Image aImage( xGraphic ); 544 impl_paintCellImage( i_context, aImage ); 545 return; 546 } 547 548 const ::rtl::OUString sText( m_pImpl->aStringConverter.convertToString( aCellContent ) ); 549 impl_paintCellText( i_context, sText ); 550 } 551 552 //------------------------------------------------------------------------------------------------------------------ 553 void GridTableRenderer::impl_paintCellText( CellRenderContext const & i_context, ::rtl::OUString const & i_text ) 554 { 555 if ( i_context.bSelected ) 556 { 557 ::Color const textColor = i_context.bHasControlFocus 558 ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetHighlightTextColor ) 559 : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetDeactiveTextColor ); 560 i_context.rDevice.SetTextColor( textColor ); 561 } 562 else 563 { 564 ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), i_context.rStyle, &StyleSettings::GetFieldTextColor ); 565 i_context.rDevice.SetTextColor( textColor ); 566 } 567 568 Rectangle const textRect( lcl_getTextRenderingArea( i_context.aContentArea ) ); 569 sal_uLong const nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, i_context.nColumn ) | TEXT_DRAW_CLIP; 570 i_context.rDevice.DrawText( textRect, i_text, nDrawTextFlags ); 571 } 572 573 //------------------------------------------------------------------------------------------------------------------ 574 void GridTableRenderer::ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect) 575 { 576 _rView.ShowFocus( _rCursorRect ); 577 } 578 579 //------------------------------------------------------------------------------------------------------------------ 580 void GridTableRenderer::HideCellCursor( Window& _rView, const Rectangle& _rCursorRect) 581 { 582 (void)_rCursorRect; 583 _rView.HideFocus(); 584 } 585 586 //------------------------------------------------------------------------------------------------------------------ 587 bool GridTableRenderer::FitsIntoCell( Any const & i_cellContent, ColPos const i_colPos, RowPos const i_rowPos, 588 bool const i_active, bool const i_selected, OutputDevice& i_targetDevice, Rectangle const & i_targetArea ) const 589 { 590 if ( !i_cellContent.hasValue() ) 591 return true; 592 593 if ( i_cellContent.getValueTypeClass() == TypeClass_INTERFACE ) 594 { 595 Reference< XInterface > const xContentInterface( i_cellContent, UNO_QUERY ); 596 if ( !xContentInterface.is() ) 597 return true; 598 599 Reference< XGraphic > const xGraphic( i_cellContent, UNO_QUERY ); 600 if ( xGraphic.is() ) 601 // for the moment, assume it fits. We can always scale it down during painting ... 602 return true; 603 604 OSL_ENSURE( false, "GridTableRenderer::FitsIntoCell: only XGraphic interfaces (or NULL) are supported for painting." ); 605 return true; 606 } 607 608 ::rtl::OUString const sText( m_pImpl->aStringConverter.convertToString( i_cellContent ) ); 609 if ( sText.getLength() == 0 ) 610 return true; 611 612 Rectangle const aTargetArea( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, i_targetArea ) ) ); 613 614 long const nTextHeight = i_targetDevice.GetTextHeight(); 615 if ( nTextHeight > aTargetArea.GetHeight() ) 616 return false; 617 618 long const nTextWidth = i_targetDevice.GetTextWidth( sText ); 619 if ( nTextWidth > aTargetArea.GetWidth() ) 620 return false; 621 622 OSL_UNUSED( i_active ); 623 OSL_UNUSED( i_selected ); 624 OSL_UNUSED( i_rowPos ); 625 OSL_UNUSED( i_colPos ); 626 return true; 627 } 628 629 //------------------------------------------------------------------------------------------------------------------ 630 bool GridTableRenderer::GetFormattedCellString( Any const & i_cellValue, ColPos const i_colPos, RowPos const i_rowPos, ::rtl::OUString & o_cellString ) const 631 { 632 o_cellString = m_pImpl->aStringConverter.convertToString( i_cellValue ); 633 634 OSL_UNUSED( i_colPos ); 635 OSL_UNUSED( i_rowPos ); 636 return true; 637 } 638 639 //...................................................................................................................... 640 } } // namespace svt::table 641 //...................................................................................................................... 642 643