summaryrefslogtreecommitdiffstats
path: root/svtools/source/table/gridtablerenderer.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /svtools/source/table/gridtablerenderer.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--svtools/source/table/gridtablerenderer.cxx598
1 files changed, 598 insertions, 0 deletions
diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx
new file mode 100644
index 000000000..f814fc64d
--- /dev/null
+++ b/svtools/source/table/gridtablerenderer.cxx
@@ -0,0 +1,598 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include "cellvalueconversion.hxx"
+#include <table/gridtablerenderer.hxx>
+#include <table/tablesort.hxx>
+
+#include <com/sun/star/graphic/XGraphic.hpp>
+
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/window.hxx>
+#include <vcl/image.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/settings.hxx>
+
+
+namespace svt::table
+{
+ using ::css::uno::Any;
+ using ::css::uno::Reference;
+ using ::css::uno::UNO_QUERY;
+ using ::css::uno::XInterface;
+ using ::css::uno::TypeClass_INTERFACE;
+ using ::css::graphic::XGraphic;
+ using ::css::style::HorizontalAlignment;
+ using ::css::style::HorizontalAlignment_CENTER;
+ using ::css::style::HorizontalAlignment_RIGHT;
+ using ::css::style::VerticalAlignment;
+ using ::css::style::VerticalAlignment_MIDDLE;
+ using ::css::style::VerticalAlignment_BOTTOM;
+
+
+ //= CachedSortIndicator
+
+ namespace {
+
+ class CachedSortIndicator
+ {
+ public:
+ CachedSortIndicator()
+ : m_lastHeaderHeight( 0 )
+ , m_lastArrowColor( COL_TRANSPARENT )
+ {
+ }
+
+ BitmapEx const & getBitmapFor(vcl::RenderContext const & i_device, tools::Long const i_headerHeight,
+ StyleSettings const & i_style, bool const i_sortAscending);
+
+ private:
+ tools::Long m_lastHeaderHeight;
+ Color m_lastArrowColor;
+ BitmapEx m_sortAscending;
+ BitmapEx m_sortDescending;
+ };
+
+ }
+
+ BitmapEx const & CachedSortIndicator::getBitmapFor(vcl::RenderContext const& i_device, tools::Long const i_headerHeight,
+ StyleSettings const & i_style, bool const i_sortAscending )
+ {
+ BitmapEx& rBitmap(i_sortAscending ? m_sortAscending : m_sortDescending);
+ if (rBitmap.IsEmpty() || (i_headerHeight != m_lastHeaderHeight) || (i_style.GetActiveColor() != m_lastArrowColor))
+ {
+ tools::Long const nSortIndicatorWidth = 2 * i_headerHeight / 3;
+ tools::Long const nSortIndicatorHeight = 2 * nSortIndicatorWidth / 3;
+
+ Point const aBitmapPos( 0, 0 );
+ Size const aBitmapSize( nSortIndicatorWidth, nSortIndicatorHeight );
+ ScopedVclPtrInstance< VirtualDevice > aDevice(i_device, DeviceFormat::DEFAULT,
+ DeviceFormat::DEFAULT);
+ aDevice->SetOutputSizePixel( aBitmapSize );
+
+ DecorationView aDecoView(aDevice.get());
+ aDecoView.DrawSymbol(tools::Rectangle(aBitmapPos, aBitmapSize),
+ i_sortAscending ? SymbolType::SPIN_UP : SymbolType::SPIN_DOWN,
+ i_style.GetActiveColor());
+
+ rBitmap = aDevice->GetBitmapEx(aBitmapPos, aBitmapSize);
+ m_lastHeaderHeight = i_headerHeight;
+ m_lastArrowColor = i_style.GetActiveColor();
+ }
+ return rBitmap;
+ }
+
+
+ //= GridTableRenderer_Impl
+
+ struct GridTableRenderer_Impl
+ {
+ ITableModel& rModel;
+ RowPos nCurrentRow;
+ bool bUseGridLines;
+ CachedSortIndicator aSortIndicator;
+ CellValueConversion aStringConverter;
+
+ explicit GridTableRenderer_Impl( ITableModel& _rModel )
+ : rModel( _rModel )
+ , nCurrentRow( ROW_INVALID )
+ , bUseGridLines( true )
+ , aSortIndicator( )
+ , aStringConverter()
+ {
+ }
+ };
+
+
+ //= helper
+
+ namespace
+ {
+ tools::Rectangle lcl_getContentArea( GridTableRenderer_Impl const & i_impl, tools::Rectangle const & i_cellArea )
+ {
+ tools::Rectangle aContentArea( i_cellArea );
+ if ( i_impl.bUseGridLines )
+ {
+ aContentArea.AdjustRight( -1 );
+ aContentArea.AdjustBottom( -1 );
+ }
+ return aContentArea;
+ }
+ tools::Rectangle lcl_getTextRenderingArea( tools::Rectangle const & i_contentArea )
+ {
+ tools::Rectangle aTextArea( i_contentArea );
+ aTextArea.AdjustLeft(2 ); aTextArea.AdjustRight( -2 );
+ aTextArea.AdjustTop( 1 ); aTextArea.AdjustBottom( -1 );
+ return aTextArea;
+ }
+
+ DrawTextFlags lcl_getAlignmentTextDrawFlags( GridTableRenderer_Impl const & i_impl, ColPos const i_columnPos )
+ {
+ DrawTextFlags nVertFlag = DrawTextFlags::Top;
+ VerticalAlignment const eVertAlign = i_impl.rModel.getVerticalAlign();
+ switch ( eVertAlign )
+ {
+ case VerticalAlignment_MIDDLE: nVertFlag = DrawTextFlags::VCenter; break;
+ case VerticalAlignment_BOTTOM: nVertFlag = DrawTextFlags::Bottom; break;
+ default:
+ break;
+ }
+
+ DrawTextFlags nHorzFlag = DrawTextFlags::Left;
+ HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnCount() > 0
+ ? i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign()
+ : HorizontalAlignment_CENTER;
+ switch ( eHorzAlign )
+ {
+ case HorizontalAlignment_CENTER: nHorzFlag = DrawTextFlags::Center; break;
+ case HorizontalAlignment_RIGHT: nHorzFlag = DrawTextFlags::Right; break;
+ default:
+ break;
+ }
+
+ return nVertFlag | nHorzFlag;
+ }
+
+ }
+
+
+ //= GridTableRenderer
+
+
+ GridTableRenderer::GridTableRenderer( ITableModel& _rModel )
+ :m_pImpl( new GridTableRenderer_Impl( _rModel ) )
+ {
+ }
+
+
+ GridTableRenderer::~GridTableRenderer()
+ {
+ }
+
+
+ bool GridTableRenderer::useGridLines() const
+ {
+ return m_pImpl->bUseGridLines;
+ }
+
+
+ void GridTableRenderer::useGridLines( bool const i_use )
+ {
+ m_pImpl->bUseGridLines = i_use;
+ }
+
+
+ namespace
+ {
+ Color lcl_getEffectiveColor(std::optional<Color> const& i_modelColor,
+ StyleSettings const& i_styleSettings,
+ Color const& (StyleSettings::*i_getDefaultColor) () const)
+ {
+ if (!!i_modelColor)
+ return *i_modelColor;
+ return (i_styleSettings.*i_getDefaultColor)();
+ }
+ }
+
+
+ void GridTableRenderer::PaintHeaderArea(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rArea,
+ bool _bIsColHeaderArea, bool _bIsRowHeaderArea, const StyleSettings& _rStyle)
+ {
+ OSL_PRECOND(_bIsColHeaderArea || _bIsRowHeaderArea, "GridTableRenderer::PaintHeaderArea: invalid area flags!");
+
+ rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR);
+
+ Color const background = lcl_getEffectiveColor(m_pImpl->rModel.getHeaderBackgroundColor(),
+ _rStyle, &StyleSettings::GetDialogColor);
+ rRenderContext.SetFillColor(background);
+
+ rRenderContext.SetLineColor();
+ rRenderContext.DrawRect(_rArea);
+
+ // delimiter lines at bottom/right
+ std::optional<Color> aLineColor(m_pImpl->rModel.getLineColor());
+ Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
+ rRenderContext.SetLineColor(lineColor);
+ rRenderContext.DrawLine(_rArea.BottomLeft(), _rArea.BottomRight());
+ rRenderContext.DrawLine(_rArea.BottomRight(), _rArea.TopRight());
+
+ rRenderContext.Pop();
+ }
+
+
+ void GridTableRenderer::PaintColumnHeader(
+ ColPos _nCol,
+ vcl::RenderContext& rRenderContext,
+ const tools::Rectangle& _rArea, const StyleSettings& _rStyle)
+ {
+ rRenderContext.Push(vcl::PushFlags::LINECOLOR);
+
+ OUString sHeaderText;
+ PColumnModel const pColumn = m_pImpl->rModel.getColumnModel( _nCol );
+ DBG_ASSERT( pColumn, "GridTableRenderer::PaintColumnHeader: invalid column model object!" );
+ if ( pColumn )
+ sHeaderText = pColumn->getName();
+
+ Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), _rStyle, &StyleSettings::GetFieldTextColor );
+ rRenderContext.SetTextColor(textColor);
+
+ tools::Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) );
+ DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, _nCol ) | DrawTextFlags::Clip;
+ if (!m_pImpl->rModel.isEnabled())
+ nDrawTextFlags |= DrawTextFlags::Disable;
+ rRenderContext.DrawText( aTextRect, sHeaderText, nDrawTextFlags );
+
+ std::optional<Color> const aLineColor( m_pImpl->rModel.getLineColor() );
+ Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
+ rRenderContext.SetLineColor( lineColor );
+ rRenderContext.DrawLine( _rArea.BottomRight(), _rArea.TopRight());
+ rRenderContext.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
+
+ // draw sort indicator if the model data is sorted by the given column
+ ITableDataSort const * pSortAdapter = m_pImpl->rModel.getSortAdapter();
+ ColumnSort aCurrentSortOrder;
+ if ( pSortAdapter != nullptr )
+ aCurrentSortOrder = pSortAdapter->getCurrentSortOrder();
+ if ( aCurrentSortOrder.nColumnPos == _nCol )
+ {
+ tools::Long const nHeaderHeight( _rArea.GetHeight() );
+ BitmapEx const aIndicatorBitmap = m_pImpl->aSortIndicator.getBitmapFor(rRenderContext, nHeaderHeight, _rStyle,
+ aCurrentSortOrder.eSortDirection == ColumnSortAscending);
+ Size const aBitmapSize( aIndicatorBitmap.GetSizePixel() );
+ tools::Long const nSortIndicatorPaddingX = 2;
+ tools::Long const nSortIndicatorPaddingY = ( nHeaderHeight - aBitmapSize.Height() ) / 2;
+
+ if ( nDrawTextFlags & DrawTextFlags::Right )
+ {
+ // text is right aligned => draw the sort indicator at the left hand side
+ rRenderContext.DrawBitmapEx(Point(_rArea.Left() + nSortIndicatorPaddingX, _rArea.Top() + nSortIndicatorPaddingY),
+ aIndicatorBitmap);
+ }
+ else
+ {
+ // text is left-aligned or centered => draw the sort indicator at the right hand side
+ rRenderContext.DrawBitmapEx(Point(_rArea.Right() - nSortIndicatorPaddingX - aBitmapSize.Width(), nSortIndicatorPaddingY),
+ aIndicatorBitmap);
+ }
+ }
+
+ rRenderContext.Pop();
+ }
+
+
+ void GridTableRenderer::PrepareRow(RowPos _nRow, bool i_hasControlFocus, bool _bSelected, vcl::RenderContext& rRenderContext,
+ const tools::Rectangle& _rRowArea, const StyleSettings& _rStyle)
+ {
+ // remember the row for subsequent calls to the other ->ITableRenderer methods
+ m_pImpl->nCurrentRow = _nRow;
+
+ rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR);
+
+ Color backgroundColor = _rStyle.GetFieldColor();
+
+ Color const activeSelectionBackColor = lcl_getEffectiveColor(m_pImpl->rModel.getActiveSelectionBackColor(),
+ _rStyle, &StyleSettings::GetHighlightColor);
+ if (_bSelected)
+ {
+ // selected rows use the background color from the style
+ backgroundColor = i_hasControlFocus
+ ? activeSelectionBackColor
+ : lcl_getEffectiveColor(m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor);
+ }
+ else
+ {
+ std::optional< std::vector<Color> > aRowColors = m_pImpl->rModel.getRowBackgroundColors();
+ if (!aRowColors)
+ {
+ // use alternating default colors
+ Color const fieldColor = _rStyle.GetFieldColor();
+ if (_rStyle.GetHighContrastMode() || ((m_pImpl->nCurrentRow % 2) == 0))
+ {
+ backgroundColor = fieldColor;
+ }
+ else
+ {
+ Color hilightColor = activeSelectionBackColor;
+ hilightColor.SetRed( 9 * ( fieldColor.GetRed() - hilightColor.GetRed() ) / 10 + hilightColor.GetRed() );
+ hilightColor.SetGreen( 9 * ( fieldColor.GetGreen() - hilightColor.GetGreen() ) / 10 + hilightColor.GetGreen() );
+ hilightColor.SetBlue( 9 * ( fieldColor.GetBlue() - hilightColor.GetBlue() ) / 10 + hilightColor.GetBlue() );
+ backgroundColor = hilightColor;
+ }
+ }
+ else
+ {
+ if (aRowColors->empty())
+ {
+ // all colors have the same background color
+ backgroundColor = _rStyle.GetFieldColor();
+ }
+ else
+ {
+ backgroundColor = aRowColors->at(m_pImpl->nCurrentRow % aRowColors->size());
+ }
+ }
+ }
+
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(backgroundColor);
+ rRenderContext.DrawRect(_rRowArea);
+
+ rRenderContext.Pop();
+ }
+
+
+ void GridTableRenderer::PaintRowHeader(vcl::RenderContext& rRenderContext,
+ const tools::Rectangle& _rArea, const StyleSettings& _rStyle)
+ {
+ rRenderContext.Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::TEXTCOLOR );
+
+ std::optional<Color> const aLineColor( m_pImpl->rModel.getLineColor() );
+ Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
+ rRenderContext.SetLineColor(lineColor);
+ rRenderContext.DrawLine(_rArea.BottomLeft(), _rArea.BottomRight());
+
+ Any const rowHeading( m_pImpl->rModel.getRowHeading( m_pImpl->nCurrentRow ) );
+ OUString const rowTitle( m_pImpl->aStringConverter.convertToString( rowHeading ) );
+ if (!rowTitle.isEmpty())
+ {
+ Color const textColor = lcl_getEffectiveColor(m_pImpl->rModel.getHeaderTextColor(),
+ _rStyle, &StyleSettings::GetFieldTextColor);
+ rRenderContext.SetTextColor(textColor);
+
+ tools::Rectangle const aTextRect(lcl_getTextRenderingArea(lcl_getContentArea(*m_pImpl, _rArea)));
+ DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags(*m_pImpl, 0) | DrawTextFlags::Clip;
+ if (!m_pImpl->rModel.isEnabled())
+ nDrawTextFlags |= DrawTextFlags::Disable;
+ // TODO: is using the horizontal alignment of the 0'th column a good idea here? This is pretty ... arbitrary ..
+ rRenderContext.DrawText(aTextRect, rowTitle, nDrawTextFlags);
+ }
+
+ rRenderContext.Pop();
+ }
+
+
+ struct GridTableRenderer::CellRenderContext
+ {
+ OutputDevice& rDevice;
+ tools::Rectangle const aContentArea;
+ StyleSettings const & rStyle;
+ ColPos const nColumn;
+ bool const bSelected;
+ bool const bHasControlFocus;
+
+ CellRenderContext( OutputDevice& i_device, tools::Rectangle const & i_contentArea,
+ StyleSettings const & i_style, ColPos const i_column, bool const i_selected, bool const i_hasControlFocus )
+ :rDevice( i_device )
+ ,aContentArea( i_contentArea )
+ ,rStyle( i_style )
+ ,nColumn( i_column )
+ ,bSelected( i_selected )
+ ,bHasControlFocus( i_hasControlFocus )
+ {
+ }
+ };
+
+
+ void GridTableRenderer::PaintCell(ColPos const i_column, bool _bSelected, bool i_hasControlFocus,
+ vcl::RenderContext& rRenderContext, const tools::Rectangle& _rArea, const StyleSettings& _rStyle)
+ {
+ rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
+
+ tools::Rectangle const aContentArea(lcl_getContentArea(*m_pImpl, _rArea));
+ CellRenderContext const aCellRenderContext(rRenderContext, aContentArea, _rStyle, i_column, _bSelected, i_hasControlFocus);
+ impl_paintCellContent(aCellRenderContext);
+
+ if ( m_pImpl->bUseGridLines )
+ {
+ ::std::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() );
+ ::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
+
+ if ( _bSelected && !aLineColor )
+ {
+ // if no line color is specified by the model, use the usual selection color for lines in selected cells
+ lineColor = i_hasControlFocus
+ ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionBackColor(), _rStyle, &StyleSettings::GetHighlightColor )
+ : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionBackColor(), _rStyle, &StyleSettings::GetDeactiveColor );
+ }
+
+ rRenderContext.SetLineColor( lineColor );
+ rRenderContext.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
+ rRenderContext.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );
+ }
+
+ rRenderContext.Pop();
+ }
+
+
+ void GridTableRenderer::impl_paintCellImage( CellRenderContext const & i_context, Image const & i_image )
+ {
+ Point imagePos( Point( i_context.aContentArea.Left(), i_context.aContentArea.Top() ) );
+ Size imageSize = i_image.GetSizePixel();
+ if ( i_context.aContentArea.GetWidth() > imageSize.Width() )
+ {
+ const HorizontalAlignment eHorzAlign = m_pImpl->rModel.getColumnModel( i_context.nColumn )->getHorizontalAlign();
+ switch ( eHorzAlign )
+ {
+ case HorizontalAlignment_CENTER:
+ imagePos.AdjustX(( i_context.aContentArea.GetWidth() - imageSize.Width() ) / 2 );
+ break;
+ case HorizontalAlignment_RIGHT:
+ imagePos.setX( i_context.aContentArea.Right() - imageSize.Width() );
+ break;
+ default:
+ break;
+ }
+
+ }
+ else
+ imageSize.setWidth( i_context.aContentArea.GetWidth() );
+
+ if ( i_context.aContentArea.GetHeight() > imageSize.Height() )
+ {
+ const VerticalAlignment eVertAlign = m_pImpl->rModel.getVerticalAlign();
+ switch ( eVertAlign )
+ {
+ case VerticalAlignment_MIDDLE:
+ imagePos.AdjustY(( i_context.aContentArea.GetHeight() - imageSize.Height() ) / 2 );
+ break;
+ case VerticalAlignment_BOTTOM:
+ imagePos.setY( i_context.aContentArea.Bottom() - imageSize.Height() );
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ imageSize.setHeight( i_context.aContentArea.GetHeight() - 1 );
+ DrawImageFlags const nStyle = m_pImpl->rModel.isEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable;
+ i_context.rDevice.DrawImage( imagePos, imageSize, i_image, nStyle );
+ }
+
+
+ void GridTableRenderer::impl_paintCellContent( CellRenderContext const & i_context )
+ {
+ Any aCellContent;
+ m_pImpl->rModel.getCellContent( i_context.nColumn, m_pImpl->nCurrentRow, aCellContent );
+
+ if ( aCellContent.getValueTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > const xContentInterface( aCellContent, UNO_QUERY );
+ if ( !xContentInterface.is() )
+ // allowed. kind of.
+ return;
+
+ Reference< XGraphic > const xGraphic( aCellContent, UNO_QUERY );
+ ENSURE_OR_RETURN_VOID( xGraphic.is(), "GridTableRenderer::impl_paintCellContent: only XGraphic interfaces (or NULL) are supported for painting." );
+
+ const Image aImage( xGraphic );
+ impl_paintCellImage( i_context, aImage );
+ return;
+ }
+
+ const OUString sText( m_pImpl->aStringConverter.convertToString( aCellContent ) );
+ impl_paintCellText( i_context, sText );
+ }
+
+
+ void GridTableRenderer::impl_paintCellText( CellRenderContext const & i_context, OUString const & i_text )
+ {
+ if ( i_context.bSelected )
+ {
+ ::Color const textColor = i_context.bHasControlFocus
+ ? lcl_getEffectiveColor( m_pImpl->rModel.getActiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetHighlightTextColor )
+ : lcl_getEffectiveColor( m_pImpl->rModel.getInactiveSelectionTextColor(), i_context.rStyle, &StyleSettings::GetDeactiveTextColor );
+ i_context.rDevice.SetTextColor( textColor );
+ }
+ else
+ {
+ ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getTextColor(), i_context.rStyle, &StyleSettings::GetFieldTextColor );
+ i_context.rDevice.SetTextColor( textColor );
+ }
+
+ tools::Rectangle const textRect( lcl_getTextRenderingArea( i_context.aContentArea ) );
+ DrawTextFlags nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, i_context.nColumn ) | DrawTextFlags::Clip;
+ if ( !m_pImpl->rModel.isEnabled() )
+ nDrawTextFlags |= DrawTextFlags::Disable;
+ i_context.rDevice.DrawText( textRect, i_text, nDrawTextFlags );
+ }
+
+
+ void GridTableRenderer::ShowCellCursor( vcl::Window& _rView, const tools::Rectangle& _rCursorRect)
+ {
+ _rView.ShowFocus( _rCursorRect );
+ }
+
+
+ void GridTableRenderer::HideCellCursor( vcl::Window& _rView )
+ {
+ _rView.HideFocus();
+ }
+
+
+ bool GridTableRenderer::FitsIntoCell( Any const & i_cellContent,
+ OutputDevice& i_targetDevice, tools::Rectangle const & i_targetArea ) const
+ {
+ if ( !i_cellContent.hasValue() )
+ return true;
+
+ if ( i_cellContent.getValueTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > const xContentInterface( i_cellContent, UNO_QUERY );
+ if ( !xContentInterface.is() )
+ return true;
+
+ Reference< XGraphic > const xGraphic( i_cellContent, UNO_QUERY );
+ if ( xGraphic.is() )
+ // for the moment, assume it fits. We can always scale it down during painting ...
+ return true;
+
+ OSL_ENSURE( false, "GridTableRenderer::FitsIntoCell: only XGraphic interfaces (or NULL) are supported for painting." );
+ return true;
+ }
+
+ OUString const sText( m_pImpl->aStringConverter.convertToString( i_cellContent ) );
+ if ( sText.isEmpty() )
+ return true;
+
+ tools::Rectangle const aTargetArea( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, i_targetArea ) ) );
+
+ tools::Long const nTextHeight = i_targetDevice.GetTextHeight();
+ if ( nTextHeight > aTargetArea.GetHeight() )
+ return false;
+
+ tools::Long const nTextWidth = i_targetDevice.GetTextWidth( sText );
+ return nTextWidth <= aTargetArea.GetWidth();
+ }
+
+
+ bool GridTableRenderer::GetFormattedCellString( Any const & i_cellValue, OUString & o_cellString ) const
+ {
+ o_cellString = m_pImpl->aStringConverter.convertToString( i_cellValue );
+
+ return true;
+ }
+
+
+} // namespace svt::table
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */