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