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