/************************************************************** * * 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 /** === end UNO includes === **/ #include #include #include #include #include #include #include #include //...................................................................................................................... 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 ... arbitrary .. _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 //......................................................................................................................