/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include "cellvalueconversion.hxx"
#include "svtools/table/gridtablerenderer.hxx"
#include "svtools/colorcfg.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/graphic/XGraphic.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/processfactory.hxx>
#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>

//......................................................................................................................
namespace svt { namespace table
{
//......................................................................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::uno::TypeClass_INTERFACE;
    using ::com::sun::star::graphic::XGraphic;
    using ::com::sun::star::style::HorizontalAlignment;
    using ::com::sun::star::style::HorizontalAlignment_LEFT;
    using ::com::sun::star::style::HorizontalAlignment_CENTER;
    using ::com::sun::star::style::HorizontalAlignment_RIGHT;
    using ::com::sun::star::style::VerticalAlignment;
    using ::com::sun::star::style::VerticalAlignment_TOP;
    using ::com::sun::star::style::VerticalAlignment_MIDDLE;
    using ::com::sun::star::style::VerticalAlignment_BOTTOM;
    /** === end UNO using === **/

    //==================================================================================================================
	//= CachedSortIndicator
    //==================================================================================================================
    class CachedSortIndicator
    {
    public:
        CachedSortIndicator()
            :m_lastHeaderHeight( 0 )
            ,m_lastArrowColor( COL_TRANSPARENT )
        {
        }

        BitmapEx const & getBitmapFor( OutputDevice const & i_device, long const i_headerHeight, StyleSettings const & i_style, bool const i_sortAscending );

    private:
        long        m_lastHeaderHeight;
        Color       m_lastArrowColor;
        BitmapEx    m_sortAscending;
        BitmapEx    m_sortDescending;
    };

	//------------------------------------------------------------------------------------------------------------------
    BitmapEx const & CachedSortIndicator::getBitmapFor( OutputDevice const & i_device, long const i_headerHeight,
        StyleSettings const & i_style, bool const i_sortAscending )
    {
        BitmapEx & rBitmap( i_sortAscending ? m_sortAscending : m_sortDescending );
        if ( !rBitmap || ( i_headerHeight != m_lastHeaderHeight ) || ( i_style.GetActiveColor() != m_lastArrowColor ) )
        {
            long const nSortIndicatorWidth = 2 * i_headerHeight / 3;
            long const nSortIndicatorHeight = 2 * nSortIndicatorWidth / 3;

            Point const aBitmapPos( 0, 0 );
            Size const aBitmapSize( nSortIndicatorWidth, nSortIndicatorHeight );
            VirtualDevice aDevice( i_device, 0, 0 );
            aDevice.SetOutputSizePixel( aBitmapSize );

            DecorationView aDecoView( &aDevice );
            aDecoView.DrawSymbol(
                Rectangle( aBitmapPos, aBitmapSize ),
                i_sortAscending ? SYMBOL_SPIN_UP : SYMBOL_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;

        GridTableRenderer_Impl( ITableModel& _rModel )
            :rModel( _rModel )
            ,nCurrentRow( ROW_INVALID )
            ,bUseGridLines( true )
            ,aSortIndicator( )
            ,aStringConverter( ::comphelper::ComponentContext( ::comphelper::getProcessServiceFactory() ) )
        {
        }
    };

    //==================================================================================================================
	//= helper
    //==================================================================================================================
    namespace
    {
        static Rectangle lcl_getContentArea( GridTableRenderer_Impl const & i_impl, Rectangle const & i_cellArea )
        {
            Rectangle aContentArea( i_cellArea );
            if ( i_impl.bUseGridLines )
            {
                --aContentArea.Right();
                --aContentArea.Bottom();
            }
            return aContentArea;
        }
        static Rectangle lcl_getTextRenderingArea( Rectangle const & i_contentArea )
        {
            Rectangle aTextArea( i_contentArea );
            aTextArea.Left() += 2; aTextArea.Right() -= 2;
            ++aTextArea.Top(); --aTextArea.Bottom();
            return aTextArea;
        }

        static sal_uLong lcl_getAlignmentTextDrawFlags( GridTableRenderer_Impl const & i_impl, ColPos const i_columnPos )
        {
            sal_uLong nVertFlag = TEXT_DRAW_TOP;
            VerticalAlignment const eVertAlign = i_impl.rModel.getVerticalAlign();
            switch ( eVertAlign )
            {
            case VerticalAlignment_MIDDLE:  nVertFlag = TEXT_DRAW_VCENTER;  break;
            case VerticalAlignment_BOTTOM:  nVertFlag = TEXT_DRAW_BOTTOM;   break;
            default:
                break;
            }

            sal_uLong nHorzFlag = TEXT_DRAW_LEFT;
            HorizontalAlignment const eHorzAlign = i_impl.rModel.getColumnCount() > 0
                                                ?  i_impl.rModel.getColumnModel( i_columnPos )->getHorizontalAlign()
                                                :  HorizontalAlignment_CENTER;
            switch ( eHorzAlign )
            {
            case HorizontalAlignment_CENTER:    nHorzFlag = TEXT_DRAW_CENTER;   break;
            case HorizontalAlignment_RIGHT:     nHorzFlag = TEXT_DRAW_RIGHT;    break;
            default:
                break;
            }

            return nVertFlag | nHorzFlag;
        }

    }

    //==================================================================================================================
	//= GridTableRenderer
    //==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    GridTableRenderer::GridTableRenderer( ITableModel& _rModel )
        :m_pImpl( new GridTableRenderer_Impl( _rModel ) )
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    GridTableRenderer::~GridTableRenderer()
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    RowPos GridTableRenderer::getCurrentRow() const
    {
        return m_pImpl->nCurrentRow;
    }

    //------------------------------------------------------------------------------------------------------------------
    bool GridTableRenderer::useGridLines() const
    {
        return m_pImpl->bUseGridLines;
    }

    //------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::useGridLines( bool const i_use )
    {
        m_pImpl->bUseGridLines = i_use;
    }

    //------------------------------------------------------------------------------------------------------------------
    namespace
    {
        Color lcl_getEffectiveColor(
            ::boost::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(
        OutputDevice& _rDevice, const Rectangle& _rArea, bool _bIsColHeaderArea, bool _bIsRowHeaderArea,
        const StyleSettings& _rStyle )
	{
		OSL_PRECOND( _bIsColHeaderArea || _bIsRowHeaderArea,
            "GridTableRenderer::PaintHeaderArea: invalid area flags!" );

        _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR );

        Color const background = lcl_getEffectiveColor( m_pImpl->rModel.getHeaderBackgroundColor(), _rStyle, &StyleSettings::GetDialogColor );
		_rDevice.SetFillColor( background );

        _rDevice.SetLineColor();
        _rDevice.DrawRect( _rArea );

        // delimiter lines at bottom/right
        ::boost::optional< ::Color > aLineColor( m_pImpl->rModel.getLineColor() );
        ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
        _rDevice.SetLineColor( lineColor );
        _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
        _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );

        _rDevice.Pop();
		(void)_bIsColHeaderArea;
		(void)_bIsRowHeaderArea;
    }

    //------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::PaintColumnHeader( ColPos _nCol, bool _bActive, bool _bSelected,
        OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle )
    {
        _rDevice.Push( PUSH_LINECOLOR);

        String 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 );
        _rDevice.SetTextColor( textColor );

		Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) );
        sal_uLong nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, _nCol ) | TEXT_DRAW_CLIP;
        if ( !m_pImpl->rModel.isEnabled() )
            nDrawTextFlags |= TEXT_DRAW_DISABLE;
        _rDevice.DrawText( aTextRect, sHeaderText, nDrawTextFlags );

        ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() );
        ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
		_rDevice.SetLineColor( lineColor );
		_rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight());
		_rDevice.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 != NULL )
            aCurrentSortOrder = pSortAdapter->getCurrentSortOrder();
        if ( aCurrentSortOrder.nColumnPos == _nCol )
        {
            long const nHeaderHeight( _rArea.GetHeight() );
            BitmapEx const aIndicatorBitmap = m_pImpl->aSortIndicator.getBitmapFor( _rDevice, nHeaderHeight, _rStyle,
                aCurrentSortOrder.eSortDirection == ColumnSortAscending );
            Size const aBitmapSize( aIndicatorBitmap.GetSizePixel() );
            long const nSortIndicatorPaddingX = 2;
            long const nSortIndicatorPaddingY = ( nHeaderHeight - aBitmapSize.Height() ) / 2;

            if ( ( nDrawTextFlags & TEXT_DRAW_RIGHT ) != 0 )
            {
                // text is right aligned => draw the sort indicator at the left hand side
                _rDevice.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
                _rDevice.DrawBitmapEx(
                    Point( _rArea.Right() - nSortIndicatorPaddingX - aBitmapSize.Width(), nSortIndicatorPaddingY ),
                    aIndicatorBitmap
                );
            }
        }

        _rDevice.Pop();

        (void)_bActive;
        // no special painting for the active column at the moment

        (void)_bSelected;
        // selection for column header not yet implemented
    }

    //------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::PrepareRow( RowPos _nRow, bool i_hasControlFocus, bool _bSelected,
        OutputDevice& _rDevice, const Rectangle& _rRowArea, const StyleSettings& _rStyle )
    {
        // remember the row for subsequent calls to the other ->ITableRenderer methods
        m_pImpl->nCurrentRow = _nRow;

        _rDevice.Push( PUSH_FILLCOLOR | PUSH_LINECOLOR);

        ::Color backgroundColor = _rStyle.GetFieldColor();

        ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() );
        ::Color lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;

        ::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 );
            if ( !aLineColor )
                lineColor = backgroundColor;
		}
        else
        {
            ::boost::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() );
                }
            }
        }

        //m_pImpl->bUseGridLines ? _rDevice.SetLineColor( lineColor ) : _rDevice.SetLineColor();
        _rDevice.SetLineColor();
        _rDevice.SetFillColor( backgroundColor );
        _rDevice.DrawRect( _rRowArea );

        _rDevice.Pop();
    }

    //------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::PaintRowHeader( bool i_hasControlFocus, bool _bSelected, OutputDevice& _rDevice, const Rectangle& _rArea,
		const StyleSettings& _rStyle )
    {
        _rDevice.Push( PUSH_LINECOLOR | PUSH_TEXTCOLOR );

        ::boost::optional< ::Color > const aLineColor( m_pImpl->rModel.getLineColor() );
        ::Color const lineColor = !aLineColor ? _rStyle.GetSeparatorColor() : *aLineColor;
        _rDevice.SetLineColor( lineColor );
        _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );

        Any const rowHeading( m_pImpl->rModel.getRowHeading( m_pImpl->nCurrentRow ) );
        ::rtl::OUString const rowTitle( m_pImpl->aStringConverter.convertToString( rowHeading ) );
        if ( rowTitle.getLength() )
        {
            ::Color const textColor = lcl_getEffectiveColor( m_pImpl->rModel.getHeaderTextColor(), _rStyle, &StyleSettings::GetFieldTextColor );
            _rDevice.SetTextColor( textColor );

		    Rectangle const aTextRect( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, _rArea ) ) );
            sal_uLong nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, 0 ) | TEXT_DRAW_CLIP;
            if ( !m_pImpl->rModel.isEnabled() )
                nDrawTextFlags |= TEXT_DRAW_DISABLE;
                // TODO: is using the horizontal alignment of the 0'th column a good idea here? This is pretty ... arbitray ..
            _rDevice.DrawText( aTextRect, rowTitle, nDrawTextFlags );
        }

        (void)i_hasControlFocus;
        (void)_bSelected;
        _rDevice.Pop();
    }

    //------------------------------------------------------------------------------------------------------------------
    struct GridTableRenderer::CellRenderContext
    {
        OutputDevice&           rDevice;
        Rectangle const         aContentArea;
        StyleSettings const &   rStyle;
        ColPos const            nColumn;
        bool const              bSelected;
        bool const              bHasControlFocus;

        CellRenderContext( OutputDevice& i_device, 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,
		OutputDevice& _rDevice, const Rectangle& _rArea, const StyleSettings& _rStyle )
    {
        _rDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );

        Rectangle const aContentArea( lcl_getContentArea( *m_pImpl, _rArea ) );
        CellRenderContext const aRenderContext( _rDevice, aContentArea, _rStyle, i_column, _bSelected, i_hasControlFocus );
        impl_paintCellContent( aRenderContext );

        if ( m_pImpl->bUseGridLines )
        {
            ::boost::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 );
		    }

            _rDevice.SetLineColor( lineColor );
		    _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() );
		    _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight() );
        }

		_rDevice.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.X() += ( i_context.aContentArea.GetWidth() - imageSize.Width() ) / 2;
                break;
            case HorizontalAlignment_RIGHT:
                imagePos.X() = i_context.aContentArea.Right() - imageSize.Width();
                break;
            default:
                break;
            }

        }
        else
	        imageSize.Width() = i_context.aContentArea.GetWidth();

        if ( i_context.aContentArea.GetHeight() > imageSize.Height() )
        {
            const VerticalAlignment eVertAlign = m_pImpl->rModel.getVerticalAlign();
            switch ( eVertAlign )
            {
            case VerticalAlignment_MIDDLE:
		        imagePos.Y() += ( i_context.aContentArea.GetHeight() - imageSize.Height() ) / 2;
                break;
            case VerticalAlignment_BOTTOM:
		        imagePos.Y() = i_context.aContentArea.Bottom() - imageSize.Height();
                break;
            default:
                break;
            }
        }
        else
	        imageSize.Height() = i_context.aContentArea.GetHeight() - 1;
        sal_uInt16 const nStyle = m_pImpl->rModel.isEnabled() ? 0 : IMAGE_DRAW_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 ::rtl::OUString sText( m_pImpl->aStringConverter.convertToString( aCellContent ) );
        impl_paintCellText( i_context, sText );
    }

    //------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::impl_paintCellText( CellRenderContext const & i_context, ::rtl::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 );
        }

        Rectangle const textRect( lcl_getTextRenderingArea( i_context.aContentArea ) );
        sal_uLong nDrawTextFlags = lcl_getAlignmentTextDrawFlags( *m_pImpl, i_context.nColumn ) | TEXT_DRAW_CLIP;
        if ( !m_pImpl->rModel.isEnabled() )
            nDrawTextFlags |= TEXT_DRAW_DISABLE;
        i_context.rDevice.DrawText( textRect, i_text, nDrawTextFlags );
    }

	//------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::ShowCellCursor( Window& _rView, const Rectangle& _rCursorRect)
    {
        _rView.ShowFocus( _rCursorRect );
    }

	//------------------------------------------------------------------------------------------------------------------
    void GridTableRenderer::HideCellCursor( Window& _rView, const Rectangle& _rCursorRect)
    {
	    (void)_rCursorRect;
        _rView.HideFocus();
    }

	//------------------------------------------------------------------------------------------------------------------
    bool GridTableRenderer::FitsIntoCell( Any const & i_cellContent, ColPos const i_colPos, RowPos const i_rowPos,
        bool const i_active, bool const i_selected, OutputDevice& i_targetDevice, 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;
        }

        ::rtl::OUString const sText( m_pImpl->aStringConverter.convertToString( i_cellContent ) );
        if ( sText.getLength() == 0 )
            return true;

        Rectangle const aTargetArea( lcl_getTextRenderingArea( lcl_getContentArea( *m_pImpl, i_targetArea ) ) );

        long const nTextHeight = i_targetDevice.GetTextHeight();
        if ( nTextHeight > aTargetArea.GetHeight() )
            return false;

        long const nTextWidth = i_targetDevice.GetTextWidth( sText );
        if ( nTextWidth > aTargetArea.GetWidth() ) 
            return false;

        OSL_UNUSED( i_active );
        OSL_UNUSED( i_selected );
        OSL_UNUSED( i_rowPos );
        OSL_UNUSED( i_colPos );
        return true;
    }

	//------------------------------------------------------------------------------------------------------------------
    bool GridTableRenderer::GetFormattedCellString( Any const & i_cellValue, ColPos const i_colPos, RowPos const i_rowPos, ::rtl::OUString & o_cellString ) const
    {
        o_cellString = m_pImpl->aStringConverter.convertToString( i_cellValue );

        OSL_UNUSED( i_colPos );
        OSL_UNUSED( i_rowPos );
        return true;
    }

//......................................................................................................................
} } // namespace svt::table
//......................................................................................................................

