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