Exemplo n.º 1
0
void wxSheetCellStringRendererRefData::SetTextColoursAndFont(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        bool isSelected)
{
    dc.SetBackgroundMode( wxTRANSPARENT );

    // TODO some special colours for attr.IsReadOnly() case?

    // different coloured text when the sheet is disabled
    if ( sheet.IsEnabled() )
    {
        if ( isSelected )
        {
            dc.SetTextBackground( sheet.GetSelectionBackground() );
            dc.SetTextForeground( sheet.GetSelectionForeground() );
        }
        else
        {
            dc.SetTextBackground( attr.GetBackgroundColour() );
            dc.SetTextForeground( attr.GetForegroundColour() );
        }
    }
    else
    {
        dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
        dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
    }

    dc.SetFont( attr.GetFont() );
}
Exemplo n.º 2
0
wxSize wxSheetCellStringRendererRefData::DoGetBestSize(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxString& text)
{
    wxArrayString lines;
    long w=0, h=0;
    if (sheet.StringToLines(text, lines) > 0)
    {
        dc.SetFont(attr.GetFont());
        sheet.GetTextBoxSize(dc, lines, &w, &h);
    }

    return (attr.GetOrientation() == wxHORIZONTAL) ? wxSize(w, h) : wxSize(h, w);
}
Exemplo n.º 3
0
void wxSheetCellAutoWrapStringRendererRefData::Draw(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxRect& rectCell,
        const wxSheetCoords& coords,
        bool isSelected)
{
    wxSheetCellRendererRefData::Draw(sheet, attr, dc, rectCell, coords, isSelected);
    SetTextColoursAndFont(sheet, attr, dc, isSelected);

    int align = attr.GetAlignment();
    int orient = attr.GetOrientation();

    wxRect rect = rectCell;
    rect.Inflate(-1);

    sheet.DrawTextRectangle(dc, GetTextLines(sheet, dc, attr, rect, coords),
                            rect, align, orient);
}
Exemplo n.º 4
0
void wxSheetCellEnumRendererRefData::Draw( wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxRect& rectCell,
        const wxSheetCoords& coords,
        bool isSelected )
{
    wxSheetCellRendererRefData::Draw(sheet, attr, dc, rectCell, coords, isSelected);
    SetTextColoursAndFont(sheet, attr, dc, isSelected);

    // draw the text right aligned by default FIXME why?
    int align = attr.GetAlignment(); // | wxRIGHT;
    int orient = attr.GetOrientation();

    wxRect rect = rectCell;
    rect.Inflate(-1);

    sheet.DrawTextRectangle(dc, GetString(sheet, coords), rect, align, orient);
}
Exemplo n.º 5
0
void wxSheetCellBitmapRendererRefData::Draw(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc, const wxRect& rect_,
        const wxSheetCoords& coords,
        bool isSelected)
{
    wxSheetCellRendererRefData::Draw(sheet, attr, dc, rect_, coords, isSelected);

    wxRect rect(rect_);

    wxSize bmpSize;
    if (m_bitmap.Ok())
    {
        bmpSize.x = m_bitmap.GetWidth();
        bmpSize.y = m_bitmap.GetHeight();
    }

    wxSize txtSize(wxSheetCellStringRendererRefData::GetBestSize(sheet, attr, dc, coords));

    if ((txtSize.x == 0) && (bmpSize.x == 0))
        return;

    int margin = 2;

    if ((txtSize.x == 0) || (bmpSize.x == 0))
        margin = 0;


    int txt_align = attr.GetAlignment();
    int bmp_align = m_align;
    wxRect bmpRect(wxPoint(0,0), bmpSize);
    wxRect txtRect(wxPoint(0,0), txtSize);
    if (txtSize.x > 0) txtRect.Inflate(1);
    rect.Inflate(-1);
    AlignBmpTextRects(rect, bmp_align, txt_align, margin, bmpRect, txtRect);
    rect.Inflate(1);

    //dc.SetBrush(*wxTRANSPARENT_BRUSH);
    //dc.SetPen(*wxRED_PEN);
    //dc.DrawRectangle(txtRect);
    //dc.SetPen(*wxGREEN_PEN);
    //dc.DrawRectangle(bmpRect);

    if ((txtRect.width > 0) && (txtRect.height > 0))
        wxSheetCellStringRendererRefData::DoDraw(sheet, attr, dc, txtRect, coords, isSelected);

    if (m_bitmap.Ok() && (bmpRect.width > 0) && (bmpRect.height > 0))
    {
        dc.SetClippingRegion(rect);
        bmpRect.SetPosition(wxSheet::AlignInRect(m_align, bmpRect, bmpSize));
        dc.DrawBitmap(m_bitmap, bmpRect.x, bmpRect.y, true);
        dc.DestroyClippingRegion();
    }
}
Exemplo n.º 6
0
wxArrayString
wxSheetCellAutoWrapStringRendererRefData::GetTextLines(wxSheet& sheet,
        wxDC& dc,
        const wxSheetCellAttr& attr,
        const wxRect& rect,
        const wxSheetCoords& coords)
{
    wxString data( sheet.GetCellValue(coords) );

    wxArrayString lines;
    dc.SetFont(attr.GetFont());

    //Taken from wxSheet again!
    wxCoord x = 0, y = 0, curr_x = 0;
    wxCoord max_x = rect.GetWidth();

    wxStringTokenizer tk(data, _T(" \n\t\r"));
    wxString thisline;

    while ( tk.HasMoreTokens() )
    {
        wxString tok( tk.GetNextToken() );
        //FIXME: this causes us to print an extra unnecesary
        //       space at the end of the line. But it
        //       is invisible , simplifies the size calculation
        //       and ensures tokens are separated in the display
        tok += _T(" ");

        dc.GetTextExtent(tok, &x, &y);
        if ( curr_x + x > max_x)
        {
            lines.Add( thisline );
            thisline = tok;
            curr_x = x;
        }
        else
        {
            thisline += tok;
            curr_x += x;
        }
    }

    lines.Add( thisline ); //Add last line

    return lines;
}
Exemplo n.º 7
0
void wxSheetCellRendererRefData::Draw( wxSheet& sheet,
                                       const wxSheetCellAttr& attr,
                                       wxDC& dc,
                                       const wxRect& rect,
                                       const wxSheetCoords& UNUSE(coords),
                                       bool isSelected )
{
    dc.SetBackgroundMode( wxSOLID );

    // grey out fields if the sheet is disabled
    if ( sheet.IsEnabled() )
    {
        if ( isSelected )
            dc.SetBrush( wxBrush(sheet.GetSelectionBackground(), wxSOLID) );
        else
            dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) );
    }
    else
        dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID));

    dc.SetPen( *wxTRANSPARENT_PEN );
    dc.DrawRectangle(rect);

#ifdef TEST_SELECTION_BLOCKS // colouring for identifying different blocks
    if (isSelected)
    {
        int i = sheet.GetSelection()->Index(coords);
        wxColour c(GetRainbow(i*10));
        dc.SetBrush( wxBrush(c, wxSOLID) );
        dc.DrawRectangle(rect);

        wxFont font = dc.GetFont();
        dc.SetFont(*wxSMALL_FONT);
        dc.DrawText(wxString::Format(wxT("%d"), i), rect.x, rect.y);
    }
#endif // TEST_SELECTION_BLOCKS

    //FIXME - border drawing code, maybe it goes here?
    //dc.SetPen( wxPen(sheet.GetGridLineColour(), 1, wxSOLID) );
    //dc.DrawRectangle(rect.x-1, rect.y-1, rect.width+2, rect.height+2);
}
Exemplo n.º 8
0
void wxSheetCellAttr::SetDefaultAttr(const wxSheetCellAttr& defAttr) 
{ 
    wxCHECK_RET(m_refData, wxT("wxSheetCellAttr not initializied"));    
    if (M_CELLATTRDATA->m_defaultAttr)
    {
        delete M_CELLATTRDATA->m_defaultAttr;
        M_CELLATTRDATA->m_defaultAttr = NULL;
    }
    // don't set defAttr to this, you don't gain anything, but a memory leak
    //if (defAttr.Ok() && (defAttr.m_refData != m_refData))
    //    M_CELLATTRDATA->m_defaultAttr = new wxSheetCellAttr(defAttr);
    
    if (defAttr.Ok())
    {
        wxSheetCellAttr attr(defAttr);
        while (attr.Ok())
        {
            wxCHECK_RET((*this) != attr, wxT("wxSheet attributes are linked recursively"));
            attr = attr.GetDefaultAttr();
        }

        M_CELLATTRDATA->m_defaultAttr = new wxSheetCellAttr(defAttr);
    }
}
Exemplo n.º 9
0
wxSize wxSheetCellAutoWrapStringRendererRefData::GetBestSize(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxSheetCoords& coords)
{
    wxCoord x, y, height, width = sheet.GetColWidth(coords.GetCol()) -10;
    int count = 250; //Limit iterations..

    wxRect rect(0, 0, width, 10);

    // M is a nice large character 'y' gives descender!.
    dc.SetFont(attr.GetFont());
    dc.GetTextExtent(wxT("My"), &x, &y);

    do     // Search for a shape no taller than the golden ratio.
    {
        width += 10;
        rect.SetWidth(width);
        height = y * GetTextLines(sheet,dc,attr,rect,coords).GetCount();
        count--;
    } while (count && (width < (height*1.68)) );

    return wxSize(width, height);
}
Exemplo n.º 10
0
bool wxSheetCellAttr::Copy(const wxSheetCellAttr& other) 
{ 
    wxCHECK_MSG(other.Ok(), false, wxT("Attr to copy from is not created"));
    
    if (!Create())
        return false;
    
    M_CELLATTRDATA->m_foreColour = ((wxSheetCellAttrRefData*)other.GetRefData())->m_foreColour;
    M_CELLATTRDATA->m_backColour = ((wxSheetCellAttrRefData*)other.GetRefData())->m_backColour;
    M_CELLATTRDATA->m_font       = ((wxSheetCellAttrRefData*)other.GetRefData())->m_font;
    M_CELLATTRDATA->m_attrTypes  = ((wxSheetCellAttrRefData*)other.GetRefData())->m_attrTypes;
    if (other.HasEditor())
        SetEditor(((wxSheetCellAttrRefData*)other.m_refData)->m_editor->Clone());
    if (other.HasRenderer())
        SetRenderer(((wxSheetCellAttrRefData*)other.m_refData)->m_renderer->Clone());
    
    SetDefaultAttr(other.GetDefaultAttr());
    return true;
}
Exemplo n.º 11
0
void wxSheetCellAttrProvider::SetAttr(const wxSheetCoords& coords, 
                                      const wxSheetCellAttr &attr, 
                                      wxSheetAttr_Type type)
{
    switch (wxSheet::GetCellCoordsType(coords))
    {
        case wxSHEET_CELL_GRID :
        {
            switch (type)
            {   
                case wxSHEET_AttrCell :
                {
                    if (attr.Ok()) m_cellAttrs.SetValue(coords, attr);
                    else           m_cellAttrs.RemoveValue(coords);            
                    return;
                } 
                case wxSHEET_AttrRow :
                {
                    if (attr.Ok()) m_rowAttrs.SetValue(coords.m_row, attr);
                    else           m_rowAttrs.RemoveValue(coords.m_row);
                    return;
                }
                case wxSHEET_AttrCol :
                {
                    if (attr.Ok()) m_colAttrs.SetValue(coords.m_col, attr);
                    else           m_colAttrs.RemoveValue(coords.m_col);
                    return;
                }
                default :
                {
                    wxFAIL_MSG(wxT("Unhandled attr type for grid coords"));
                    return;
                }
            }
            break;
        }
        case wxSHEET_CELL_ROWLABEL :
        {
            switch (type)
            {
                case wxSHEET_AttrCell :
                {
                    if (attr.Ok()) m_rowLabelAttrs.SetValue(coords.m_row, attr);
                    else           m_rowLabelAttrs.RemoveValue(coords.m_row);
                    return;
                } 
                default : 
                {
                    wxFAIL_MSG(wxT("Unhandled attr type for row label coords"));
                    return;
                }
            }
            break;
        }
        case wxSHEET_CELL_COLLABEL :
        {
            switch (type)
            {
                case wxSHEET_AttrCell :
                {
                    if (attr.Ok()) m_colLabelAttrs.SetValue(coords.m_col, attr);
                    else           m_colLabelAttrs.RemoveValue(coords.m_col);
                    return;
                } 
                default : 
                {
                    wxFAIL_MSG(wxT("Unhandled attr type for col label coords"));
                    return;
                }
            }
            break;
        }
        default :
            wxFAIL_MSG(wxString::Format(wxT("Unhandled coords (%d, %d) in wxSheetCellAttrProvider::SetAttr"), coords.m_row, coords.m_col));
            break;
    }
}
Exemplo n.º 12
0
bool wxSheetCellAttr::MergeWith(const wxSheetCellAttr &other)
{
    wxCHECK_MSG(Ok() && other.Ok(), false, wxT("this or Attr to MergeWith from is not created"));
    
    if ( !HasForegoundColour() && other.HasForegoundColour() )
        SetForegroundColour(other.GetForegroundColour());
    if ( !HasBackgroundColour() && other.HasBackgroundColour() )
        SetBackgroundColour(other.GetBackgroundColour());
    if ( !HasFont() && other.HasFont() )
        SetFont(other.GetFont());
    if ( !HasAlignment() && other.HasAlignment() )
        SetAlignment(other.GetAlignment());
    if ( !HasOrientation() && other.HasOrientation() )
        SetOrientation(other.GetOrientation());
    if ( !HasLevel() && other.HasLevel() )
        SetLevel(other.GetLevel());
    if ( !HasReadWriteMode() && other.HasReadWriteMode() )
        SetReadOnly(other.GetReadOnly());
    if ( !HasOverflowMode() && other.HasOverflowMode() )
        SetOverflow(other.GetOverflow());
    if ( !HasOverflowMarkerMode() && other.HasOverflowMarkerMode() )
        SetOverflowMarker(other.GetOverflowMarker());
    if ( !HasShowEditorMode() && other.HasShowEditorMode() )
        SetShowEditor(other.GetShowEditor());
    
    // Directly access m_renderer/m_editor as GetRender/Editor may return different one

    // Maybe add support for merge of Render and Editor?
    if ( !HasRenderer() && other.HasRenderer() )
        SetRenderer(((wxSheetCellAttrRefData*)other.m_refData)->m_renderer->Clone());
    if ( !HasEditor() && other.HasEditor() )
        SetEditor(((wxSheetCellAttrRefData*)other.m_refData)->m_editor->Clone());

    if ( !HasDefaultAttr() && other.HasDefaultAttr() )
        SetDefaultAttr(other.GetDefaultAttr());
    
    return true;
}
Exemplo n.º 13
0
void wxSheetCellBoolRendererRefData::Draw(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc, const wxRect& rect,
        const wxSheetCoords& coords,
        bool isSelected)
{
    wxSheetCellRendererRefData::Draw(sheet, attr, dc, rect, coords, isSelected);

    // draw a check mark in the centre (ignoring alignment - TODO)
    wxSize size = GetBestSize(sheet, attr, dc, coords);

    // don't draw outside the cell
    wxCoord minSize = wxMin(rect.width, rect.height) - 1;
    if ((size.x >= minSize) || (size.y >= minSize))
        size.x = size.y = minSize - 2; // leave (at least) 1 pixel margin

    // draw a border around checkmark
    int align = attr.GetAlignment();

    wxRect rectBorder(rect.GetPosition(), size);

    if ((align & wxALIGN_RIGHT) != 0)
        rectBorder.x += rect.width - size.x - 2;
    else if ((align & wxALIGN_CENTRE_HORIZONTAL) != 0)
        rectBorder.x += rect.width/2 - size.x/2;
    else // wxALIGN_LEFT
        rectBorder.x += 2;

    if ((align & wxALIGN_BOTTOM) != 0)
        rectBorder.y += rect.height - size.y - 2;
    else if ((align & wxALIGN_CENTRE_VERTICAL) != 0)
        rectBorder.y += rect.height/2 - size.y/2;
    else // wxALIGN_TOP
        rectBorder.y += 2;

    bool value = false;
    if ( sheet.GetTable() && sheet.GetTable()->CanGetValueAs(coords, wxSHEET_VALUE_BOOL) )
        value = sheet.GetTable()->GetValueAsBool(coords);
    else
    {
        wxString strValue( sheet.GetCellValue(coords) );
        value = !( strValue.IsEmpty() || (strValue == wxT("0")) ||
                   (strValue.Lower() == wxT("f")) || (strValue.Lower() == wxT("false")));
    }

    if ( value )
    {
        wxRect rectMark = rectBorder;
#ifdef __WXMSW__
        // MSW DrawCheckMark() is weird (and should probably be changed...)
        rectMark.Inflate(-wxSHEET_CHECKMARK_MARGIN/2);
        rectMark.x++;
        rectMark.y++;
#else // !MSW
        rectMark.Inflate(-wxSHEET_CHECKMARK_MARGIN);
#endif // MSW/!MSW

        dc.SetTextForeground(attr.GetForegroundColour());
        dc.DrawCheckMark(rectMark);
    }

    dc.SetBrush(*wxTRANSPARENT_BRUSH);
    dc.SetPen(wxPen(attr.GetForegroundColour(), 1, wxSOLID));
    dc.DrawRectangle(rectBorder);
}
Exemplo n.º 14
0
void wxSheetCellStringRendererRefData::DoDraw(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxRect& rectCell,
        const wxSheetCoords& coords,
        bool isSelected)
{
    wxRect rect = rectCell;
    rect.Inflate(-1);

    int align = attr.GetAlignment();
    int orient = attr.GetOrientation();

    wxString value( sheet.GetCellValue(coords) );
    int best_width = DoGetBestSize(sheet, attr, dc, value).GetWidth();
    wxSheetCoords cellSpan(sheet.GetCellSpan(coords)); // shouldn't get here if <=0
    int cell_rows = cellSpan.m_row;
    int cell_cols = cellSpan.m_col;

    bool is_grid_cell = coords.IsGridCell();
    // no overflow for row/col/corner labels
    bool overflow = is_grid_cell && (orient == wxSHEET_AttrOrientHoriz) ? attr.GetOverflow() : false;
    int overflowCols = 0;
    int num_cols = sheet.GetNumberCols();
    // this is the right col which includes overflow
    int rightCol = coords.m_col + cell_cols - 1;

    // Check if this cell should overflow to right and for how many cells
    if (overflow)
    {
        bool is_editing = sheet.IsCellEditControlShown();
        wxSheetCoords editorCell = is_editing ? sheet.GetEditControlCoords() : wxNullSheetCoords;
        int row = coords.GetRow(), col = coords.GetCol();
        wxSheetCoords ownerCell;
        if ((best_width > rectCell.width) && (col < num_cols-1) && sheet.GetTable())
        {
            wxSheetCoords cell;
            for (cell.m_col = col+cell_cols; cell.m_col < num_cols; cell.m_col++)
            {
                bool is_empty = true;
                for (cell.m_row = row; cell.m_row < row+cell_rows; cell.m_row++)
                {
                    // check w/ anchor cell for spanned cell block
                    ownerCell = sheet.GetCellOwner(cell);
                    if ( sheet.GetTable()->HasValue(ownerCell) ||
                            (ownerCell == editorCell) )
                    {
                        is_empty = false;
                        break;
                    }
                }

                if (is_empty)
                    rect.width += sheet.GetColWidth(cell.m_col);
                else
                {
                    cell.m_col--;
                    break;
                }

                if (rect.width >= best_width)
                    break;
            }
            // this may extend out of sheet
            overflowCols = cell.m_col - col - cell_cols + 1;
            rightCol = wxMin(coords.m_col+cell_cols-1+overflowCols, num_cols - 1);
        }

        // redraw overflow cells individually for proper selection hilight
        if (overflowCols > 0)
        {
            // if overflowed then it's left aligned (yes I know ALIGN_LEFT=0)
            align &= ~wxSHEET_AttrAlignHoriz_Mask;
            align |= wxSHEET_AttrAlignLeft;

            wxRect clip(rect);
            clip.x += rectCell.width;

            int col_width;
            wxSheetCoords cell(coords);
            // draw each cell individually since it may be selected or not
            for (cell.m_col = col+cell_cols; cell.m_col <= rightCol; cell.m_col++)
            {
                col_width = sheet.GetColWidth(cell.m_col);
                clip.width = col_width - 1;
                dc.DestroyClippingRegion();
                dc.SetClippingRegion(clip);
                SetTextColoursAndFont(sheet, attr, dc, sheet.IsCellSelected(cell));
                sheet.DrawTextRectangle(dc, value, rect, align, orient);
                clip.x += col_width - 1;
            }

            rect = rectCell;
            rect.Inflate(-1);
            rect.width++;
            dc.DestroyClippingRegion();
        }
    }

    // Draw the text
    SetTextColoursAndFont(sheet, attr, dc, isSelected);
    sheet.DrawTextRectangle(dc, value, rect, align, orient);

    if (attr.GetOverflowMarker())
    {
        // Draw a marker to show that the contents has been clipped off
        int cellRight = sheet.GetColRight(rightCol);
        if (cellRight - rect.x < best_width)
        {
            int bmpWidth   = s_overflowBitmap.GetWidth();
            int bmpHeight  = s_overflowBitmap.GetHeight();
            int cellWidth  = sheet.GetColWidth(rightCol);
            int cellHeight = sheet.GetRowHeight(coords.m_row);

            if ((bmpWidth < cellWidth-3) && (bmpHeight < cellHeight-3))
            {
                int cellTop = sheet.GetRowTop(coords.m_row);

                int x = cellRight - bmpWidth - 2;
                int y = cellTop + (cellHeight - bmpHeight)/2;
                wxRect r(x-2, cellTop, bmpWidth+4-1, cellHeight-1);
                wxSheetCellAttr rightAttr(attr);
                if (overflowCols > 0)
                {
                    wxSheetCoords clipCell(coords.m_row, rightCol);
                    isSelected = sheet.IsCellSelected(clipCell);
                    rightAttr = sheet.GetAttr(clipCell);
                }

                // clear background for bitmap
                wxSheetCellRendererRefData::Draw(sheet, rightAttr, dc, r, coords, isSelected);
                dc.DrawBitmap( s_overflowBitmap, x, y, true );
            }
        }
    }
}
Exemplo n.º 15
0
void wxSheetCellRolColLabelRendererRefData::Draw(wxSheet& sheet,
        const wxSheetCellAttr& attr,
        wxDC& dc,
        const wxRect& rectCell,
        const wxSheetCoords& coords,
        bool isSelected)
{
    // erase this cells background
    wxRect rect(rectCell);

#ifdef FIXME_CANT_SET_COLOURS_FOR_NATIVE_RENDERER // __WXGTK20__
    SetTextColoursAndFont(sheet, attr, dc, isSelected);

    wxWindow *win = sheet.GetWindowForCoords(coords);
    wxCHECK_RET(win, wxT("Invalid coords in wxSheetCellRolColLabelRendererRefData::Draw"));
    wxRendererNative::Get().DrawHeaderButton( win, dc, rect, 0 );

#else // !__WXGTK20__

    wxSheetCellRendererRefData::Draw(sheet, attr, dc, rect, coords, isSelected);

    int left   = rectCell.x;
    int top    = rectCell.y;
    int right  = rectCell.GetRight();
    int bottom = rectCell.GetBottom();

    //dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW),1, wxSOLID) );
    // right side
    //dc.DrawLine( right, top, right, bottom );
    // left side
    //if (coords.m_col == -1)
    //    dc.DrawLine( left, top, left, bottom );
    // top side
    //if (coords.m_row == -1)
    //    dc.DrawLine( left, top, right, top );
    // bottom
    //dc.DrawLine( left, bottom, right, bottom );

    dc.SetPen( *wxWHITE_PEN );
    // left highlight
    dc.DrawLine( left, top, left, bottom );
    // top highlight
    dc.DrawLine( left, top, right, top );

#endif // __WXGTK__

    SetTextColoursAndFont(sheet, attr, dc, isSelected);

    wxString value( sheet.GetCellValue(coords) );

    if (!value.IsEmpty())
    {
        int align  = attr.GetAlignment();
        int orient = attr.GetOrientation();
        rect.Deflate(2); // want margins
        sheet.DrawTextRectangle(dc, value, rect, align, orient);
    }

#if 0
    // test code for sizing, draws corner tick marks
    if (1)
    {
        rect = rectCell;
        dc.SetPen(*wxGREEN_PEN);
        dc.DrawLine(left, top, left+25, top);
        dc.DrawLine(right-25, bottom, right, bottom);
        dc.DrawLine(left, top, left, top+10);
        dc.DrawLine(right, bottom-10, right, bottom);
        wxRect r(rectCell);
        dc.SetPen(*wxCYAN_PEN);
        dc.DrawLine(r.x, r.y, r.x+25, r.y);
        dc.DrawLine(r.GetRight()-25, r.GetBottom(), r.GetRight(), r.GetBottom());
        dc.DrawLine(r.x, r.y, r.x, r.y+10);
        dc.DrawLine(r.GetRight(), r.GetBottom()-10, r.GetRight(), r.GetBottom());
    }
#endif // 0
}