]> 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 777c2b46b3a059e64df74eef71482a64a3d99427..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;
     }
@@ -423,7 +425,7 @@ void wxGridCellEditor::SetSize(const wxRect& rect)
 {
     wxASSERT_MSG(m_control,
                  wxT("The wxGridCellEditor must be Created first!"));
-    m_control->SetSize(rect);
+    m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
 }
 
 void wxGridCellEditor::HandleReturn(wxKeyEvent& event)
@@ -481,16 +483,24 @@ 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 = rect.x && rect.y ? 2 : 1;
+    int extra_x = ( rect.x > 2 )? 2 : 1;
+    int extra_y = ( rect.y > 2 )? 2 : 1;
 #if defined(__WXMOTIF__)
-    extra *= 2;
+    extra_x *= 2;
+    extra_y *= 2;
 #endif
-    rect.SetLeft( wxMax(0, rect.x - extra) );
-    rect.SetTop( wxMax(0, rect.y - extra) );
-    rect.SetRight( rect.GetRight() + 2*extra );
-    rect.SetBottom( rect.GetBottom() + 2*extra );
+    rect.SetLeft( wxMax(0, rect.x - extra_x) );
+    rect.SetTop( wxMax(0, rect.y - extra_y) );
+    rect.SetRight( rect.GetRight() + 2*extra_x );
+    rect.SetBottom( rect.GetBottom() + 2*extra_y );
 #endif // GTK/!GTK
 
     wxGridCellEditor::SetSize(rect);
@@ -513,7 +523,7 @@ void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue)
     Text()->SetFocus();
 }
 
-bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellTextEditor::EndEdit(int row, int col,
                                    wxGrid* grid)
 {
     wxASSERT_MSG(m_control,
@@ -633,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() )
@@ -648,7 +661,7 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
     }
 }
 
-bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellNumberEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
     bool changed;
@@ -666,7 +679,10 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue,
 
     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;
@@ -700,6 +716,7 @@ void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
 
     event.Skip();
 }
+
 // ----------------------------------------------------------------------------
 // wxGridCellFloatEditor
 // ----------------------------------------------------------------------------
@@ -725,21 +742,27 @@ 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());
 }
 
-bool wxGridCellFloatEditor::EndEdit(int row, int col, bool saveValue,
+bool wxGridCellFloatEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
     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;
     }
@@ -786,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?)
-    wxCoord 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
-#ifdef __WXGTK__
-    w -= 8;
-#endif // GTK
+    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)
@@ -815,7 +867,7 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
     wxASSERT_MSG(m_control,
                  wxT("The wxGridCellEditor must be Created first!"));
 
-    if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+    if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
         m_startValue = grid->GetTable()->GetValueAsBool(row, col);
     else
         m_startValue = !!grid->GetTable()->GetValue(row, col);
@@ -824,7 +876,6 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
 }
 
 bool wxGridCellBoolEditor::EndEdit(int row, int col,
-                                   bool saveValue,
                                    wxGrid* grid)
 {
     wxASSERT_MSG(m_control,
@@ -837,7 +888,7 @@ bool wxGridCellBoolEditor::EndEdit(int row, int col,
 
     if ( changed )
     {
-        if (grid->GetTable()->CanGetValueAs(row, col, wxT("bool")))
+        if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
             grid->GetTable()->SetValueAsBool(row, col, value);
         else
             grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
@@ -896,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)
@@ -911,12 +967,20 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
     m_startValue = grid->GetTable()->GetValue(row, col);
 
     Combo()->SetValue(m_startValue);
+    size_t count = m_choices.GetCount();
+    for (size_t i=0; i<count; i++)
+    {
+        if (m_startValue == m_choices[i])
+        {
+            Combo()->SetSelection(i);
+            break;
+        }
+    }
     Combo()->SetInsertionPointEnd();
     Combo()->SetFocus();
 }
 
-bool wxGridCellChoiceEditor::EndEdit(int row, int col, 
-                                     bool saveValue,
+bool wxGridCellChoiceEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
     wxString value = Combo()->GetValue();
@@ -1093,7 +1157,10 @@ wxString wxGridCellNumberRenderer::GetString(wxGrid& grid, int row, int col)
     {
         text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
     }
-    //else: leave the string empty or put 0 into it?
+    else
+    {
+        text = table->GetValue(row, col);
+    }
 
     return text;
 }
@@ -1151,7 +1218,10 @@ wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col)
 
         text.Printf(m_format, table->GetValueAsDouble(row, col));
     }
-    //else: leave the string empty or put 0 into it?
+    else
+    {
+        text = table->GetValue(row, col);
+    }
 
     return text;
 }
@@ -1192,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),
@@ -1211,7 +1287,7 @@ wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
         checkSize = size.y + wxGRID_CHECKMARK_MARGIN;
 
         // FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result
-#ifdef __WXGTK__
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
         checkSize -= size.y / 2;
 #endif
 
@@ -1234,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;
@@ -1246,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);
@@ -1326,40 +1417,48 @@ void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const
 
 
 // GetRenderer and GetEditor use a slightly different decision path about
-// which to use.  If a non-default attr object has one then it is used,
-// otherwise the default editor or renderer passed in is used.  It should be
-// the default for the data type of the cell.  If it is NULL (because the
-// table has a type that the grid does not have in its registry,) then the
-// grid's default editor or renderer is used.
-
-wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGridCellRenderer* def) const
-{
-    if ((m_defGridAttr != this || def == NULL) && HasRenderer())
-        return m_renderer;
-    else if (def)
-        return def;
-    else if (m_defGridAttr != this)
-        return m_defGridAttr->GetRenderer(NULL);
-    else
-    {
+// which attribute to use.  If a non-default attr object has one then it is
+// used, otherwise the default editor or renderer is fetched from the grid and
+// used.  It should be the default for the data type of the cell.  If it is
+// NULL (because the table has a type that the grid does not have in its
+// registry,) then the grid's default editor or renderer is used.
+
+wxGridCellRenderer* wxGridCellAttr::GetRenderer(wxGrid* grid, int row, int col) const
+{
+    if ((m_defGridAttr != this || grid == NULL) && HasRenderer())
+        return m_renderer;      // use local attribute
+
+    wxGridCellRenderer* renderer = NULL;
+    if (grid)                   // get renderer for the data type
+        renderer =  grid->GetDefaultRendererForCell(row, col);
+
+    if (! renderer)
+        // if we still don't have one then use the grid default
+        renderer = m_defGridAttr->GetRenderer(NULL,0,0);
+
+    if (! renderer)
         wxFAIL_MSG(wxT("Missing default cell attribute"));
-        return NULL;
-    }
+
+    return renderer;
 }
 
-wxGridCellEditor* wxGridCellAttr::GetEditor(wxGridCellEditor* def) const
+wxGridCellEditor* wxGridCellAttr::GetEditor(wxGrid* grid, int row, int col) const
 {
-    if ((m_defGridAttr != this || def == NULL) && HasEditor())
-        return m_editor;
-    else if (def)
-        return def;
-    else if (m_defGridAttr != this)
-        return m_defGridAttr->GetEditor(NULL);
-    else
-    {
+    if ((m_defGridAttr != this || grid == NULL) && HasEditor())
+        return m_editor;      // use local attribute
+
+    wxGridCellEditor* editor = NULL;
+    if (grid)                   // get renderer for the data type
+        editor =  grid->GetDefaultEditorForCell(row, col);
+
+    if (! editor)
+        // if we still don't have one then use the grid default
+        editor = m_defGridAttr->GetEditor(NULL,0,0);
+
+    if (! editor)
         wxFAIL_MSG(wxT("Missing default cell attribute"));
-        return NULL;
-    }
+
+    return editor;
 }
 
 // ----------------------------------------------------------------------------
@@ -1661,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];
 }
 
@@ -2565,6 +2665,7 @@ void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 #if WXGRID_DRAW_LINES
     m_owner->DrawAllGridLines( dc, reg );
 #endif
+    m_owner->DrawGridSpace( dc );
     m_owner->DrawHighlight( dc );
 }
 
@@ -2591,40 +2692,9 @@ void wxGridWindow::OnKeyDown( wxKeyEvent& event )
     if ( !m_owner->ProcessEvent( event ) ) event.Skip();
 }
 
-// We are trapping erase background events to reduce flicker under MSW
-// and GTK but this can leave junk in the space beyond the last row and
-// col.  So here we paint these spaces if they are visible.
-//
+
 void wxGridWindow::OnEraseBackground(wxEraseEvent& event)
 {
-    int cw, ch;
-    GetClientSize( &cw, &ch );
-
-    int right, bottom;
-    m_owner->CalcUnscrolledPosition( cw, ch, &right, &bottom );
-
-    wxRect rightRect;
-    rightRect = m_owner->CellToRect( 0, m_owner->GetNumberCols()-1 );
-
-    wxRect bottomRect;
-    bottomRect = m_owner->CellToRect( m_owner->GetNumberRows()-1, 0 );
-
-    if ( right > rightRect.GetRight()  ||  bottom > bottomRect.GetBottom() )
-    {
-        int left, top;
-        m_owner->CalcUnscrolledPosition( 0, 0, &left, &top );
-
-        wxClientDC dc( this );
-        m_owner->PrepareDC( dc );
-        dc.SetBrush( wxBrush(m_owner->GetDefaultCellBackgroundColour(), wxSOLID) );
-        dc.SetPen( *wxTRANSPARENT_PEN );
-
-        if ( right > rightRect.GetRight() )
-            dc.DrawRectangle( rightRect.GetRight()+1, top, right - rightRect.GetRight(), ch );
-
-        if ( bottom > bottomRect.GetBottom() )
-            dc.DrawRectangle( left, bottomRect.GetBottom()+1, cw, bottom - bottomRect.GetBottom() );
-    }
 }
 
 
@@ -2851,6 +2921,7 @@ void wxGrid::Init()
     m_winCapture = (wxWindow *)NULL;
     m_canDragRowSize = TRUE;
     m_canDragColSize = TRUE;
+    m_canDragGridSize = TRUE;
     m_dragLastPos  = -1;
     m_dragRowOrCol = -1;
     m_isDragging = FALSE;
@@ -2872,6 +2943,11 @@ void wxGrid::Init()
 
     m_inOnKeyDown = FALSE;
     m_batchCount = 0;
+
+    m_extraWidth =
+    m_extraHeight = 50;
+
+    CalcDimensions();
 }
 
 // ----------------------------------------------------------------------------
@@ -2958,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
         //
@@ -3808,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)
@@ -3878,201 +3957,203 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     m_isDragging = FALSE;
     m_startDragPos = wxDefaultPosition;
 
+    // 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
+#endif // 0
 
-    if ( coords != wxGridNoCellCoords )
+    // ------------ Left button pressed
+    //
+    if ( event.LeftDown() && 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
-#if 0
-        if ( event.Entering() || event.Leaving() )
+        if ( event.ShiftDown() )
         {
-            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
-            m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
+            SelectBlock( m_currentCellCoords, coords );
         }
-        else
-#endif // 0
-
-        // ------------ Left button pressed
-        //
-        if ( event.LeftDown() )
+        else if ( XToEdgeOfCol(x) < 0  &&
+                  YToEdgeOfRow(y) < 0 )
         {
-            DisableCellEditControl();
-            if ( event.ShiftDown() )
-            {
-                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(GetDefaultEditorForCell(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() )
+    // ------------ 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() )
+    // ------------ 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() )
+    // ------------ 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
+    //
+    else if ( event.Moving() && !event.IsButton() )
+    {
+        int dragRow = YToEdgeOfRow( y );
+        int dragCol = XToEdgeOfCol( x );
 
-        // ------------ Moving and no button action
+        // 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() )
-                        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() )
-                        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);
         }
     }
 }
@@ -4093,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,
@@ -4131,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,
@@ -4193,8 +4276,10 @@ void wxGrid::ClearGrid()
 {
     if ( m_table )
     {
+        if (IsCellEditControlEnabled())
+            DisableCellEditControl();
+
         m_table->Clear();
-        SetEditControlValue();
         if ( !GetBatchCount() ) m_gridWin->Refresh();
     }
 }
@@ -4243,7 +4328,6 @@ bool wxGrid::InsertRows( int pos, int numRows, bool WXUNUSED(updateLabels) )
             if ( !GetBatchCount() ) Refresh();
         }
 
-        SetEditControlValue();
         return ok;
     }
     else
@@ -4351,7 +4435,6 @@ bool wxGrid::InsertCols( int pos, int numCols, bool WXUNUSED(updateLabels) )
             if ( !GetBatchCount() ) Refresh();
         }
 
-        SetEditControlValue();
         return ok;
     }
     else
@@ -4520,7 +4603,6 @@ void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(event) )
          m_numRows && m_numCols )
     {
         m_currentCellCoords.Set(0, 0);
-        SetEditControlValue();
         ShowCellEditControl();
     }
 
@@ -4662,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() )
                 {
@@ -4679,20 +4753,26 @@ 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();
                     int col = m_currentCellCoords.GetCol();
                     wxGridCellAttr* attr = GetCellAttr(row, col);
-                    attr->GetEditor(GetDefaultEditorForCell(row, col))->StartingKey(event);
+                    attr->GetEditor(this, row, col)->StartingKey(event);
                     attr->DecRef();
                 }
                 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;
@@ -4719,7 +4799,6 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
          m_currentCellCoords != wxGridNoCellCoords )
     {
         HideCellEditControl();
-        SaveEditControlValue();
         DisableCellEditControl();
 
         // Clear the old current cell highlight
@@ -4733,8 +4812,6 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
 
     m_currentCellCoords = coords;
 
-    SetEditControlValue();
-
     if ( m_displayed )
     {
         wxClientDC dc(m_gridWin);
@@ -4812,6 +4889,37 @@ void wxGrid::DrawGridCellArea( wxDC& dc )
 }
 
 
+void wxGrid::DrawGridSpace( wxDC& dc )
+{
+    if ( m_numRows  &&  m_numCols )
+    {
+        int cw, ch;
+        m_gridWin->GetClientSize( &cw, &ch );
+
+        int right, bottom;
+        CalcUnscrolledPosition( cw, ch, &right, &bottom );
+
+        if ( right > GetColRight(m_numCols-1)  ||
+             bottom > GetRowBottom(m_numRows-1) )
+        {
+            int left, top;
+            CalcUnscrolledPosition( 0, 0, &left, &top );
+
+            dc.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID) );
+            dc.SetPen( *wxTRANSPARENT_PEN );
+
+            if ( right > GetColRight(m_numCols-1) )
+                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),
+                                  cw, bottom - GetRowBottom(m_numRows-1) );
+        }
+    }
+}
+
+
 void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
 {
     int row = coords.GetRow();
@@ -4839,14 +4947,13 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
     // if the editor is shown, we should use it and not the renderer
     if ( isCurrent && IsCellEditControlEnabled() )
     {
-        attr->GetEditor(GetDefaultEditorForCell(row, col))->
-            PaintBackground(rect, attr);
+        attr->GetEditor(this, row, col)->PaintBackground(rect, attr);
     }
     else
     {
         // but all the rest is drawn by the cell renderer and hence may be
         // customized
-        attr->GetRenderer(GetDefaultRendererForCell(row,col))->
+        attr->GetRenderer(this, row, col)->
             Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
 
     }
@@ -4955,6 +5062,7 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg )
 
     int top, bottom, left, right;
 
+#ifndef __WXGTK__
     if (reg.IsEmpty())
     {
       int cw, ch;
@@ -4972,6 +5080,12 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg )
       CalcUnscrolledPosition( x, y, &left, &top );
       CalcUnscrolledPosition( x + w, y + h, &right, &bottom );
     }
+#else
+      int cw, ch;
+      m_gridWin->GetClientSize(&cw, &ch);
+      CalcUnscrolledPosition( 0, 0, &left, &top );
+      CalcUnscrolledPosition( cw, ch, &right, &bottom );
+#endif
 
     // avoid drawing grid lines past the last row and col
     //
@@ -5277,7 +5391,6 @@ void wxGrid::EnableCellEditControl( bool enable )
             // do it before ShowCellEditControl()
             m_cellEditCtrlEnabled = enable;
 
-            SetEditControlValue();
             ShowCellEditControl();
         }
         else
@@ -5347,16 +5460,17 @@ void wxGrid::ShowCellEditControl()
             rect.y--;
 
             wxGridCellAttr* attr = GetCellAttr(row, col);
-            wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
+            wxGridCellEditor* editor = attr->GetEditor(this, row, col);
             if ( !editor->IsCreated() )
             {
                 editor->Create(m_gridWin, -1,
                                new wxGridCellEditorEvtHandler(this, editor));
             }
 
+            editor->Show( TRUE, attr );
+            
             editor->SetSize( rect );
 
-            editor->Show( TRUE, attr );
             editor->BeginEdit(row, col, this);
             attr->DecRef();
          }
@@ -5372,20 +5486,13 @@ void wxGrid::HideCellEditControl()
         int col = m_currentCellCoords.GetCol();
 
         wxGridCellAttr* attr = GetCellAttr(row, col);
-        attr->GetEditor(GetDefaultEditorForCell(row, col))->Show( FALSE );
+        attr->GetEditor(this, row, col)->Show( FALSE );
         attr->DecRef();
         m_gridWin->SetFocus();
     }
 }
 
 
-void wxGrid::SetEditControlValue( const wxString& value )
-{
-    // RD: The new Editors get the value from the table themselves now.  This
-    // method can probably be removed...
-}
-
-
 void wxGrid::SaveEditControlValue()
 {
     if ( IsCellEditControlEnabled() )
@@ -5394,8 +5501,8 @@ void wxGrid::SaveEditControlValue()
         int col = m_currentCellCoords.GetCol();
 
         wxGridCellAttr* attr = GetCellAttr(row, col);
-        wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
-        bool changed = editor->EndEdit(row, col, TRUE, this);
+        wxGridCellEditor* editor = attr->GetEditor(this, row, col);
+        bool changed = editor->EndEdit(row, col, this);
 
         attr->DecRef();
 
@@ -6327,12 +6434,12 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert )
 
 wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
 {
-    return m_defaultCellAttr->GetRenderer(NULL);
+    return m_defaultCellAttr->GetRenderer(NULL,0,0);
 }
 
 wxGridCellEditor *wxGrid::GetDefaultEditor() const
 {
-    return m_defaultCellAttr->GetEditor(NULL);
+    return m_defaultCellAttr->GetEditor(NULL,0,0);
 }
 
 // ----------------------------------------------------------------------------
@@ -6373,7 +6480,7 @@ void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert )
 wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col)
 {
     wxGridCellAttr* attr = GetCellAttr(row, col);
-    wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
+    wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col);
     attr->DecRef();
     return renderer;
 }
@@ -6381,7 +6488,7 @@ wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col)
 wxGridCellEditor* wxGrid::GetCellEditor(int row, int col)
 {
     wxGridCellAttr* attr = GetCellAttr(row, col);
-    wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col));
+    wxGridCellEditor* editor = attr->GetEditor(this, row, col);
     attr->DecRef();
     return editor;
 }
@@ -6659,6 +6766,11 @@ void wxGrid::EnableDragColSize( bool enable )
     m_canDragColSize = enable;
 }
 
+void wxGrid::EnableDragGridSize( bool enable )
+{
+    m_canDragGridSize = enable;
+}
+
 
 void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows )
 {
@@ -6742,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);
@@ -6750,7 +6866,7 @@ void wxGrid::AutoSizeColumn( int col, bool setAsMin )
     for ( int row = 0; row < m_numRows; row++ )
     {
         wxGridCellAttr* attr = GetCellAttr(row, col);
-        wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
+        wxGridCellRenderer* renderer = attr->GetRenderer(this, row, col);
         if ( renderer )
         {
             width = renderer->GetBestSize(*this, *attr, dc, row, col).x;
@@ -6790,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 )
 {
@@ -6814,15 +6973,13 @@ void wxGrid::SetCellValue( int row, int col, const wxString& s )
             DrawCell( dc, wxGridCellCoords(row, col) );
         }
 
-#if 0  // TODO: edit in place
-
         if ( m_currentCellCoords.GetRow() == row &&
-             m_currentCellCoords.GetCol() == col )
+             m_currentCellCoords.GetCol() == col &&
+             IsCellEditControlEnabled())
         {
-            SetEditControlValue( s );
+            HideCellEditControl();
+            ShowCellEditControl(); // will reread data from table
         }
-#endif
-
     }
 }