]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
correction for Fit() which didn't handle properly windows positioned at (-1, -1)
[wxWidgets.git] / src / generic / grid.cpp
index b966f83d1c76ce389b49d865b8c0234eb34671be..00f2271e51043493535b3fca4d78d97dcbfa65b7 100644 (file)
@@ -255,7 +255,8 @@ public:
 // data structures used for the data type registry
 // ----------------------------------------------------------------------------
 
-struct wxGridDataTypeInfo {
+struct wxGridDataTypeInfo
+{
     wxGridDataTypeInfo(const wxString& typeName,
                        wxGridCellRenderer* renderer,
                        wxGridCellEditor* editor)
@@ -273,9 +274,11 @@ struct wxGridDataTypeInfo {
 WX_DEFINE_ARRAY(wxGridDataTypeInfo*, wxGridDataTypeInfoArray);
 
 
-class WXDLLEXPORT wxGridTypeRegistry {
+class WXDLLEXPORT wxGridTypeRegistry
+{
 public:
     ~wxGridTypeRegistry();
+
     void RegisterDataType(const wxString& typeName,
                      wxGridCellRenderer* renderer,
                      wxGridCellEditor* editor);
@@ -287,9 +290,6 @@ private:
     wxGridDataTypeInfoArray m_typeinfo;
 };
 
-
-
-
 // ----------------------------------------------------------------------------
 // conditional compilation
 // ----------------------------------------------------------------------------
@@ -367,6 +367,8 @@ void wxGridCellEditor::Destroy()
 {
     if (m_control)
     {
+        m_control->PopEventHandler(TRUE /* delete it*/);
+
         m_control->Destroy();
         m_control = NULL;
     }
@@ -481,7 +483,13 @@ void wxGridCellTextEditor::SetSize(const wxRect& rectOrig)
     // unix
     //
 #if defined(__WXGTK__)
-    rect.Inflate(rect.x ? 1 : 0, rect.y ? 1 : 0);
+    if (rect.x != 0)
+    {
+        rect.x += 1;
+        rect.y += 1;
+        rect.width -= 1;
+        rect.height -= 1;
+    }
 #else // !GTK
     int extra_x = ( rect.x > 2 )? 2 : 1;
     int extra_y = ( rect.y > 2 )? 2 : 1;
@@ -635,9 +643,12 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
     }
     else
     {
-        wxFAIL_MSG( _T("this cell doesn't have numeric value") );
-
-        return;
+        wxString sValue = table->GetValue(row, col);
+        if (! sValue.ToLong(&m_valueOld))
+        {
+            wxFAIL_MSG( _T("this cell doesn't have numeric value") );
+            return;
+        }
     }
 
     if ( HasRange() )
@@ -668,7 +679,10 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
 
     if ( changed )
     {
-        grid->GetTable()->SetValueAsLong(row, col, value);
+        if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
+            grid->GetTable()->SetValueAsLong(row, col, value);
+        else
+            grid->GetTable()->SetValue(row, col, wxString::Format("%ld", value));
     }
 
     return changed;
@@ -728,9 +742,12 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
     }
     else
     {
-        wxFAIL_MSG( _T("this cell doesn't have float value") );
-
-        return;
+        wxString sValue = table->GetValue(row, col);
+        if (! sValue.ToDouble(&m_valueOld))
+        {
+            wxFAIL_MSG( _T("this cell doesn't have float value") );
+            return;
+        }
     }
 
     DoBeginEdit(GetString());
@@ -742,7 +759,10 @@ bool wxGridCellFloatEditor::EndEdit(int row, int col,
     double value;
     if ( Text()->GetValue().ToDouble(&value) && (value != m_valueOld) )
     {
-        grid->GetTable()->SetValueAsDouble(row, col, value);
+        if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT))
+            grid->GetTable()->SetValueAsDouble(row, col, value);
+        else
+            grid->GetTable()->SetValue(row, col, wxString::Format("%f", value));
 
         return TRUE;
     }
@@ -789,17 +809,46 @@ void wxGridCellBoolEditor::Create(wxWindow* parent,
 
 void wxGridCellBoolEditor::SetSize(const wxRect& r)
 {
+    bool resize = FALSE;
+    wxSize size = m_control->GetSize();
+    wxCoord minSize = wxMin(r.width, r.height);
+
+    // check if the checkbox is not too big/small for this cell
+    wxSize sizeBest = m_control->GetBestSize();
+    if ( !(size == sizeBest) )
+    {
+        // reset to default size if it had been made smaller
+        size = sizeBest;
+
+        resize = TRUE;
+    }
+
+    if ( size.x >= minSize || size.y >= minSize )
+    {
+        // leave 1 pixel margin
+        size.x = size.y = minSize - 2;
+
+        resize = TRUE;
+    }
+
+    if ( resize )
+    {
+        m_control->SetSize(size);
+    }
+
     // position it in the centre of the rectangle (TODO: support alignment?)
-    int w, h;
-    m_control->GetSize(&w, &h);
 
+#if defined(__WXGTK__) || defined (__WXMOTIF__)
     // the checkbox without label still has some space to the right in wxGTK,
     // so shift it to the right
-#if defined(__WXGTK__) || defined (__WXMOTIF__)
-    w -= 8;
-#endif // GTK && Motif
+    size.x -= 8;
+#elif defined(__WXMSW__)
+    // here too...
+    size.x -= 6;
+    size.y -= 2;
+#endif
 
-    m_control->Move(r.x + r.width/2 - w/2, r.y + r.height/2 - h/2);
+    m_control->Move(r.x + r.width/2 - size.x/2, r.y + r.height/2 - size.y/2);
 }
 
 void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
@@ -898,11 +947,16 @@ void wxGridCellChoiceEditor::Create(wxWindow* parent,
     wxGridCellEditor::Create(parent, id, evtHandler);
 }
 
-void wxGridCellChoiceEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),
-                                             wxGridCellAttr * WXUNUSED(attr))
+void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell,
+                                             wxGridCellAttr * attr)
 {
     // as we fill the entire client area, don't do anything here to minimize
     // flicker
+
+    // TODO: It doesn't actually fill the client area since the height of a
+    // combo always defaults to the standard...  Until someone has time to
+    // figure out the right rectangle to paint, just do it the normal way...
+    wxGridCellEditor::PaintBackground(rectCell, attr);
 }
 
 void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
@@ -1208,8 +1262,14 @@ wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid,
 
 wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
 
+// FIXME these checkbox size calculations are really ugly...
+
 // between checkmark and box
-static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
+#ifdef __WXGTK__
+    static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
+#else
+    static const wxCoord wxGRID_CHECKMARK_MARGIN = 2;
+#endif
 
 wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
                                            wxGridCellAttr& WXUNUSED(attr),
@@ -1250,6 +1310,16 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
 
     // draw a check mark in the centre (ignoring alignment - TODO)
     wxSize size = GetBestSize(grid, attr, dc, row, col);
+
+    // don't draw outside the cell
+    wxCoord minSize = wxMin(rect.width, rect.height);
+    if ( size.x >= minSize || size.y >= minSize )
+    {
+        // and even leave (at least) 1 pixel margin
+        size.x = size.y = minSize - 2;
+    }
+
+    // draw a border around checkmark
     wxRect rectMark;
     rectMark.x = rect.x + rect.width/2 - size.x/2;
     rectMark.y = rect.y + rect.height/2 - size.y/2;
@@ -1262,8 +1332,13 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
 
     rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN);
 
+#ifdef __WXMSW__
+    // looks nicer under MSW
+    rectMark.x++;
+#endif // MSW
+
     bool value;
-    if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
+    if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
         value = grid.GetTable()->GetValueAsBool(row, col);
     else
         value = !!grid.GetTable()->GetValue(row, col);
@@ -1685,7 +1760,8 @@ void wxGridCellAttrProvider::UpdateAttrCols( size_t pos, int numCols )
 
 wxGridTypeRegistry::~wxGridTypeRegistry()
 {
-    for (size_t i=0; i<m_typeinfo.Count(); i++)
+    size_t count = m_typeinfo.Count();
+    for ( size_t i = 0; i < count; i++ )
         delete m_typeinfo[i];
 }
 
@@ -2586,10 +2662,10 @@ void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     wxRegion reg = GetUpdateRegion();
     m_owner->CalcCellsExposed( reg );
     m_owner->DrawGridCellArea( dc );
-    m_owner->DrawGridSpace( dc );
 #if WXGRID_DRAW_LINES
     m_owner->DrawAllGridLines( dc, reg );
 #endif
+    m_owner->DrawGridSpace( dc );
     m_owner->DrawHighlight( dc );
 }
 
@@ -2867,6 +2943,11 @@ void wxGrid::Init()
 
     m_inOnKeyDown = FALSE;
     m_batchCount = 0;
+
+    m_extraWidth =
+    m_extraHeight = 50;
+
+    CalcDimensions();
 }
 
 // ----------------------------------------------------------------------------
@@ -2953,8 +3034,8 @@ void wxGrid::CalcDimensions()
 
     if ( m_numRows > 0  &&  m_numCols > 0 )
     {
-        int right = GetColRight( m_numCols-1 ) + 50;
-        int bottom = GetRowBottom( m_numRows-1 ) + 50;
+        int right = GetColRight( m_numCols-1 ) + m_extraWidth;
+        int bottom = GetRowBottom( m_numRows-1 ) + m_extraHeight;
 
         // TODO: restore the scroll position that we had before sizing
         //
@@ -3803,7 +3884,10 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
             // Hide the edit control, so it
             // won't interfer with drag-shrinking.
             if ( IsCellEditControlEnabled() )
+            {
                 HideCellEditControl();
+                SaveEditControlValue();
+            }
 
             // Have we captured the mouse yet?
             if (! m_winCapture)
@@ -3873,206 +3957,205 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     m_isDragging = FALSE;
     m_startDragPos = wxDefaultPosition;
 
-//      if ( coords == wxGridNoCellCoords && m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
-//      {
-//          ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-//      }
-
-//      if ( coords != wxGridNoCellCoords )
-//      {
-        // VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
-        //     immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
-        //     wxGTK
+    // VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
+    //     immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
+    //     wxGTK
 #if 0
-        if ( event.Entering() || event.Leaving() )
-        {
-            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-            m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
-        }
-        else
+    if ( event.Entering() || event.Leaving() )
+    {
+        ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+        m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
+    }
+    else
 #endif // 0
 
-        // ------------ Left button pressed
-        //
-        if ( event.LeftDown() && coords != wxGridNoCellCoords )
+    // ------------ Left button pressed
+    //
+    if ( event.LeftDown() && coords != wxGridNoCellCoords )
+    {
+        if ( event.ShiftDown() )
         {
-            DisableCellEditControl();
-            if ( event.ShiftDown() )
-            {
-                SelectBlock( m_currentCellCoords, coords );
-            }
-            else if ( XToEdgeOfCol(x) < 0  &&
-                      YToEdgeOfRow(y) < 0 )
+            SelectBlock( m_currentCellCoords, coords );
+        }
+        else if ( XToEdgeOfCol(x) < 0  &&
+                  YToEdgeOfRow(y) < 0 )
+        {
+            if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
+                             coords.GetRow(),
+                             coords.GetCol(),
+                             event ) )
             {
-                if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
-                                 coords.GetRow(),
-                                 coords.GetCol(),
-                                 event ) )
+                DisableCellEditControl();
+                MakeCellVisible( coords );
+
+                // if this is the second click on this cell then start
+                // the edit control
+                if ( m_waitForSlowClick &&
+                     (coords == m_currentCellCoords) &&
+                     CanEnableCellControl())
                 {
-                    MakeCellVisible( coords );
-
-                    // if this is the second click on this cell then start
-                    // the edit control
-                    if ( m_waitForSlowClick &&
-                         (coords == m_currentCellCoords) &&
-                         CanEnableCellControl())
-                    {
-                        EnableCellEditControl();
+                    EnableCellEditControl();
 
-                        wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
-                        attr->GetEditor(this, coords.GetRow(), coords.GetCol())->StartingClick();
-                        attr->DecRef();
+                    wxGridCellAttr* attr = GetCellAttr(m_currentCellCoords);
+                    attr->GetEditor(this, coords.GetRow(), coords.GetCol())->StartingClick();
+                    attr->DecRef();
 
-                        m_waitForSlowClick = FALSE;
-                    }
-                    else
-                    {
-                        SetCurrentCell( coords );
-                        m_waitForSlowClick = TRUE;
-                    }
+                    m_waitForSlowClick = FALSE;
+                }
+                else
+                {
+                    SetCurrentCell( coords );
+                    m_waitForSlowClick = TRUE;
                 }
             }
         }
+    }
 
 
-        // ------------ Left double click
-        //
-        else if ( event.LeftDClick() && coords != wxGridNoCellCoords )
+    // ------------ Left double click
+    //
+    else if ( event.LeftDClick() && coords != wxGridNoCellCoords )
+    {
+        DisableCellEditControl();
+
+        if ( XToEdgeOfCol(x) < 0  &&  YToEdgeOfRow(y) < 0 )
         {
-            DisableCellEditControl();
-            if ( XToEdgeOfCol(x) < 0  &&  YToEdgeOfRow(y) < 0 )
-            {
-                SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
-                           coords.GetRow(),
-                           coords.GetCol(),
-                           event );
-            }
+            SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
+                       coords.GetRow(),
+                       coords.GetCol(),
+                       event );
         }
+    }
 
 
-        // ------------ Left button released
-        //
-        else if ( event.LeftUp() )
+    // ------------ Left button released
+    //
+    else if ( event.LeftUp() )
+    {
+        if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
         {
-            if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
+            if ( IsSelection() )
             {
-                if ( IsSelection() )
+                if (m_winCapture)
                 {
-                    if (m_winCapture)
-                    {
-                        m_winCapture->ReleaseMouse();
-                        m_winCapture = NULL;
-                    }
-                    SendEvent( wxEVT_GRID_RANGE_SELECT, -1, -1, event );
+                    m_winCapture->ReleaseMouse();
+                    m_winCapture = NULL;
                 }
-
-                // Show the edit control, if it has been hidden for
-                // drag-shrinking.
-                ShowCellEditControl();
+                SendEvent( wxEVT_GRID_RANGE_SELECT, -1, -1, event );
             }
-            else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
-            {
-                ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-                DoEndDragResizeRow();
 
-                // Note: we are ending the event *after* doing
-                // default processing in this case
-                //
-                SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
-            }
-            else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
-            {
-                ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-                DoEndDragResizeCol();
+            // Show the edit control, if it has been hidden for
+            // drag-shrinking.
+            ShowCellEditControl();
+        }
+        else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
+        {
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+            DoEndDragResizeRow();
 
-                // Note: we are ending the event *after* doing
-                // default processing in this case
-                //
-                SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
-            }
+            // Note: we are ending the event *after* doing
+            // default processing in this case
+            //
+            SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
+        }
+        else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
+        {
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+            DoEndDragResizeCol();
 
-            m_dragLastPos = -1;
+            // Note: we are ending the event *after* doing
+            // default processing in this case
+            //
+            SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
         }
 
+        m_dragLastPos = -1;
+    }
 
-        // ------------ Right button down
-        //
-        else if ( event.RightDown() && coords != wxGridNoCellCoords )
+
+    // ------------ Right button down
+    //
+    else if ( event.RightDown() && coords != wxGridNoCellCoords )
+    {
+        DisableCellEditControl();
+        if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
+                         coords.GetRow(),
+                         coords.GetCol(),
+                         event ) )
         {
-            DisableCellEditControl();
-            if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
-                             coords.GetRow(),
-                             coords.GetCol(),
-                             event ) )
-            {
-                // no default action at the moment
-            }
+            // no default action at the moment
         }
+    }
 
 
-        // ------------ Right double click
-        //
-        else if ( event.RightDClick() && coords != wxGridNoCellCoords )
+    // ------------ Right double click
+    //
+    else if ( event.RightDClick() && coords != wxGridNoCellCoords )
+    {
+        DisableCellEditControl();
+        if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
+                         coords.GetRow(),
+                         coords.GetCol(),
+                         event ) )
         {
-            DisableCellEditControl();
-            if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
-                             coords.GetRow(),
-                             coords.GetCol(),
-                             event ) )
-            {
-                // no default action at the moment
-            }
+            // no default action at the moment
         }
+    }
 
-        // ------------ Moving and no button action
+    // ------------ Moving and no button action
+    //
+    else if ( event.Moving() && !event.IsButton() )
+    {
+        int dragRow = YToEdgeOfRow( y );
+        int dragCol = XToEdgeOfCol( x );
+
+        // Dragging on the corner of a cell to resize in both
+        // directions is not implemented yet...
         //
-        else if ( event.Moving() && !event.IsButton() )
+        if ( dragRow >= 0  &&  dragCol >= 0 )
         {
-            int dragRow = YToEdgeOfRow( y );
-            int dragCol = XToEdgeOfCol( x );
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+            return;
+        }
 
-            // Dragging on the corner of a cell to resize in both
-            // directions is not implemented yet...
-            //
-            if ( dragRow >= 0  &&  dragCol >= 0 )
-            {
-                ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-                return;
-            }
+        if ( dragRow >= 0 )
+        {
+            m_dragRowOrCol = dragRow;
 
-            if ( dragRow >= 0 )
+            if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
             {
-                m_dragRowOrCol = dragRow;
-
-                if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
-                {
-                    if ( CanDragRowSize() && CanDragGridSize() )
-                        ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
-                }
-
-                return;
+                if ( CanDragRowSize() && CanDragGridSize() )
+                    ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
             }
 
             if ( dragCol >= 0 )
             {
                 m_dragRowOrCol = dragCol;
+            }
 
-                if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
-                {
-                    if ( CanDragColSize() && CanDragGridSize() )
-                        ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
-                }
+            return;
+        }
 
-                return;
-            }
+        if ( dragCol >= 0 )
+        {
+            m_dragRowOrCol = dragCol;
 
-            // Neither on a row or col edge
-            //
-            if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
+            if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
             {
-                ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+                if ( CanDragColSize() && CanDragGridSize() )
+                    ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
             }
+
+            return;
         }
+
+        // Neither on a row or col edge
+        //
+        if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
+        {
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+        }
+    }
 }
 
 
@@ -4091,6 +4174,7 @@ void wxGrid::DoEndDragResizeRow()
         dc.SetLogicalFunction( wxINVERT );
         dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
         HideCellEditControl();
+        SaveEditControlValue();
 
         int rowTop = GetRowTop(m_dragRowOrCol);
         SetRowSize( m_dragRowOrCol,
@@ -4129,6 +4213,7 @@ void wxGrid::DoEndDragResizeCol()
         dc.SetLogicalFunction( wxINVERT );
         dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch );
         HideCellEditControl();
+        SaveEditControlValue();
 
         int colLeft = GetColLeft(m_dragRowOrCol);
         SetColSize( m_dragRowOrCol,
@@ -4659,14 +4744,6 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 MovePageDown();
                 break;
 
-            // We don't want these keys to trigger the edit control, any others?
-            case WXK_SHIFT:
-            case WXK_ALT:
-            case WXK_CONTROL:
-            case WXK_CAPITAL:
-                event.Skip();
-                break;
-
             case WXK_SPACE:
                 if ( !IsEditable() )
                 {
@@ -4676,9 +4753,14 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 // Otherwise fall through to default
 
             default:
-                // now try the cell edit control
-                //
-                if ( !IsCellEditControlEnabled() && CanEnableCellControl() )
+                // alphanumeric keys or F2 (special key just for this) enable
+                // the cell edit control
+                if ( !(event.AltDown() ||
+                       event.MetaDown() ||
+                       event.ControlDown()) &&
+                     (isalnum(event.KeyCode()) || event.KeyCode() == WXK_F2) &&
+                     !IsCellEditControlEnabled() &&
+                     CanEnableCellControl() )
                 {
                     EnableCellEditControl();
                     int row = m_currentCellCoords.GetRow();
@@ -4689,7 +4771,8 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 }
                 else
                 {
-                    // let others process char events for readonly cells
+                    // let others process char events with modifiers or all
+                    // char events for readonly cells
                     event.Skip();
                 }
                 break;
@@ -4826,11 +4909,11 @@ void wxGrid::DrawGridSpace( wxDC& dc )
             dc.SetPen( *wxTRANSPARENT_PEN );
 
             if ( right > GetColRight(m_numCols-1) )
-                dc.DrawRectangle( GetColRight(m_numCols-1)+1, top,
+                dc.DrawRectangle( GetColRight(m_numCols-1), top,
                                   right - GetColRight(m_numCols-1), ch );
 
             if ( bottom > GetRowBottom(m_numRows-1) )
-                dc.DrawRectangle( left, GetRowBottom(m_numRows-1)+1,
+                dc.DrawRectangle( left, GetRowBottom(m_numRows-1),
                                   cw, bottom - GetRowBottom(m_numRows-1) );
         }
     }
@@ -5384,9 +5467,10 @@ void wxGrid::ShowCellEditControl()
                                new wxGridCellEditorEvtHandler(this, editor));
             }
 
+            editor->Show( TRUE, attr );
+            
             editor->SetSize( rect );
 
-            editor->Show( TRUE, attr );
             editor->BeginEdit(row, col, this);
             attr->DecRef();
          }
@@ -6770,6 +6854,10 @@ int wxGrid::GetColMinimalWidth(int col) const
     return obj ? (int)obj : WXGRID_MIN_COL_WIDTH;
 }
 
+// ----------------------------------------------------------------------------
+// auto sizing
+// ----------------------------------------------------------------------------
+
 void wxGrid::AutoSizeColumn( int col, bool setAsMin )
 {
     wxClientDC dc(m_gridWin);
@@ -6818,17 +6906,60 @@ void wxGrid::AutoSizeColumn( int col, bool setAsMin )
     }
 }
 
-void wxGrid::AutoSizeColumns( bool setAsMin )
+int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin)
 {
+    int width = m_rowLabelWidth;
+
     for ( int col = 0; col < m_numCols; col++ )
     {
-        AutoSizeColumn(col, setAsMin);
+        if ( !calcOnly )
+        {
+            AutoSizeColumn(col, setAsMin);
+        }
+
+        width += GetColWidth(col);
     }
+
+    return width;
 }
 
-//
-// ------ cell value accessor functions
-//
+int wxGrid::SetOrCalcRowSizes(bool calcOnly, bool setAsMin)
+{
+    int height = m_colLabelHeight;
+
+    for ( int row = 0; row < m_numRows; row++ )
+    {
+        // if ( !calcOnly ) AutoSizeRow(row, setAsMin) -- TODO
+
+        height += GetRowHeight(row);
+    }
+
+    return height;
+}
+
+void wxGrid::AutoSize()
+{
+    // set the size too
+    SetSize(SetOrCalcColumnSizes(FALSE), SetOrCalcRowSizes(FALSE));
+}
+
+wxSize wxGrid::DoGetBestSize() const
+{
+    // don't set sizes, only calculate them
+    wxGrid *self = (wxGrid *)this;  // const_cast
+
+    return wxSize(self->SetOrCalcColumnSizes(TRUE),
+                  self->SetOrCalcRowSizes(TRUE));
+}
+
+void wxGrid::Fit()
+{
+    AutoSize();
+}
+
+// ----------------------------------------------------------------------------
+// cell value accessor functions
+// ----------------------------------------------------------------------------
 
 void wxGrid::SetCellValue( int row, int col, const wxString& s )
 {