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