]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
wxVariant is in wxBase so should be forward declared using WXDLLIMPEXP_BASE and not...
[wxWidgets.git] / src / generic / grid.cpp
index a90958f27d1a284ac347b7e4a165398f15795710..a04ed8c350e2b923b46d723f275a3b8a5ad5602f 100644 (file)
@@ -47,6 +47,7 @@
 #include "wx/textfile.h"
 #include "wx/spinctrl.h"
 #include "wx/tokenzr.h"
+#include "wx/renderer.h"
 
 #include "wx/grid.h"
 #include "wx/generic/gridsel.h"
@@ -142,6 +143,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
 
     DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow)
     DECLARE_EVENT_TABLE()
@@ -164,6 +166,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
 
     DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow)
     DECLARE_EVENT_TABLE()
@@ -185,6 +188,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
     void OnPaint( wxPaintEvent& event );
 
     DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow)
@@ -206,7 +210,7 @@ public:
                   wxGridRowLabelWindow *rowLblWin,
                   wxGridColLabelWindow *colLblWin,
                   wxWindowID id, const wxPoint &pos, const wxSize &size );
-    ~wxGridWindow();
+    ~wxGridWindow(){}
 
     void ScrollWindow( int dx, int dy, const wxRect *rect );
 
@@ -222,6 +226,7 @@ private:
     void OnMouseEvent( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
     void OnEraseBackground( wxEraseEvent& );
     void OnFocus( wxFocusEvent& );
 
@@ -235,27 +240,37 @@ private:
 class wxGridCellEditorEvtHandler : public wxEvtHandler
 {
 public:
-    wxGridCellEditorEvtHandler()
-        : m_grid(0), m_editor(0)
-        { }
     wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor)
-        : m_grid(grid), m_editor(editor)
-        { }
+        : m_grid(grid),
+          m_editor(editor),
+          m_inSetFocus(false)
+    {
+    }
 
+    void OnKillFocus(wxFocusEvent& event);
     void OnKeyDown(wxKeyEvent& event);
     void OnChar(wxKeyEvent& event);
 
+    void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; }
+
 private:
     wxGrid*             m_grid;
     wxGridCellEditor*   m_editor;
-    DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
+
+    // Work around the fact that a focus kill event can be sent to
+    // a combobox within a set focus event.
+    bool                m_inSetFocus;
+    
     DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
     DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler)
 };
 
 
-IMPLEMENT_DYNAMIC_CLASS( wxGridCellEditorEvtHandler, wxEvtHandler )
+IMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler)
+
 BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler )
+    EVT_KILL_FOCUS( wxGridCellEditorEvtHandler::OnKillFocus )
     EVT_KEY_DOWN( wxGridCellEditorEvtHandler::OnKeyDown )
     EVT_CHAR( wxGridCellEditorEvtHandler::OnChar )
 END_EVENT_TABLE()
@@ -413,6 +428,7 @@ static const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
 // in these hash tables is the number of rows/columns)
 static const int GRID_HASH_SIZE = 100;
 
+#if 0
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -426,6 +442,7 @@ static inline int GetScrollY(int y)
 {
     return (y + GRID_SCROLL_LINE_Y - 1) / GRID_SCROLL_LINE_Y;
 }
+#endif
 
 // ============================================================================
 // implementation
@@ -500,9 +517,11 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
             m_colBgOld = m_control->GetBackgroundColour();
             m_control->SetBackgroundColour(attr->GetBackgroundColour());
 
+// Workaround for GTK+1 font setting problem on some platforms
+#if !defined(__WXGTK__) || defined(__WXGTK20__)
             m_fontOld = m_control->GetFont();
             m_control->SetFont(attr->GetFont());
-
+#endif
             // can't do anything more in the base class version, the other
             // attributes may only be used by the derived classes
         }
@@ -521,12 +540,14 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
             m_control->SetBackgroundColour(m_colBgOld);
             m_colBgOld = wxNullColour;
         }
-
+// Workaround for GTK+1 font setting problem on some platforms
+#if !defined(__WXGTK__) || defined(__WXGTK20__)
         if ( m_fontOld.Ok() )
         {
             m_control->SetFont(m_fontOld);
             m_fontOld = wxNullFont;
         }
+#endif
     }
 }
 
@@ -544,8 +565,40 @@ void wxGridCellEditor::HandleReturn(wxKeyEvent& event)
 
 bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event)
 {
-    // accept the simple key presses, not anything with Ctrl/Alt/Meta
-    return !(event.ControlDown() || event.AltDown());
+    bool ctrl = event.ControlDown();
+    bool alt  = event.AltDown();
+#ifdef __WXMAC__
+    // On the Mac the Alt key is more like shift and is used for entry of
+    // valid characters, so check for Ctrl and Meta instead.
+    alt = event.MetaDown();
+#endif
+
+    // Assume it's not a valid char if ctrl or alt is down, but if both are
+    // down then it may be because of an AltGr key combination, so let them
+    // through in that case.
+    if ((ctrl || alt) && !(ctrl && alt))
+        return false;
+
+#if wxUSE_UNICODE
+    int key = event.GetUnicodeKey();
+    bool keyOk = true;
+
+    // if the unicode key code is not really a unicode character (it may
+    // be a function key or etc., the platforms appear to always give us a
+    // small value in this case) then fallback to the ascii key code but
+    // don't do anything for function keys or etc.
+    if (key <= 127)
+    {
+        key = event.GetKeyCode();
+        keyOk = (key <= 127);
+    }
+    return keyOk;
+#else // !wxUSE_UNICODE
+    int key = event.GetKeyCode();
+    if (key <= 255)
+        return true;
+    return false;
+#endif // wxUSE_UNICODE/!wxUSE_UNICODE
 }
 
 void wxGridCellEditor::StartingKey(wxKeyEvent& event)
@@ -693,48 +746,46 @@ void wxGridCellTextEditor::DoReset(const wxString& startValue)
 
 bool wxGridCellTextEditor::IsAcceptedKey(wxKeyEvent& event)
 {
-    if ( wxGridCellEditor::IsAcceptedKey(event) )
-    {
-        int keycode = event.GetKeyCode();
-        switch ( keycode )
-        {
-            case WXK_NUMPAD0:
-            case WXK_NUMPAD1:
-            case WXK_NUMPAD2:
-            case WXK_NUMPAD3:
-            case WXK_NUMPAD4:
-            case WXK_NUMPAD5:
-            case WXK_NUMPAD6:
-            case WXK_NUMPAD7:
-            case WXK_NUMPAD8:
-            case WXK_NUMPAD9:
-            case WXK_MULTIPLY:
-            case WXK_NUMPAD_MULTIPLY:
-            case WXK_ADD:
-            case WXK_NUMPAD_ADD:
-            case WXK_SUBTRACT:
-            case WXK_NUMPAD_SUBTRACT:
-            case WXK_DECIMAL:
-            case WXK_NUMPAD_DECIMAL:
-            case WXK_DIVIDE:
-            case WXK_NUMPAD_DIVIDE:
-                return true;
-
-            default:
-                // accept 8 bit chars too if isprint() agrees
-                if ( (keycode < 255) && (wxIsprint(keycode)) )
-                    return true;
-        }
-    }
-
-    return false;
+    return wxGridCellEditor::IsAcceptedKey(event);
 }
 
 void wxGridCellTextEditor::StartingKey(wxKeyEvent& event)
 {
-    if ( !Text()->EmulateKeyPress(event) )
+    // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no
+    // longer an appropriate way to get the character into the text control.
+    // Do it ourselves instead.  We know that if we get this far that we have
+    // a valid character, so not a whole lot of testing needs to be done.
+
+    wxTextCtrl* tc = Text();
+    wxChar ch;
+    long pos;
+
+#if wxUSE_UNICODE
+    ch = event.GetUnicodeKey();
+    if (ch <= 127)
+        ch = (wxChar)event.GetKeyCode();
+#else
+    ch = (wxChar)event.GetKeyCode();
+#endif
+    switch (ch)
     {
-        event.Skip();
+        case WXK_DELETE:
+            // delete the character at the cursor
+            pos = tc->GetInsertionPoint();
+            if (pos < tc->GetLastPosition())
+                tc->Remove(pos, pos+1);
+            break;
+
+        case WXK_BACK:
+            // delete the character before the cursor
+            pos = tc->GetInsertionPoint();
+            if (pos > 0)
+                tc->Remove(pos-1, pos);
+            break;
+
+        default:
+            tc->WriteText(ch);
+            break;
     }
 }
 
@@ -796,6 +847,7 @@ void wxGridCellNumberEditor::Create(wxWindow* parent,
                                     wxWindowID id,
                                     wxEvtHandler* evtHandler)
 {
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         // create a spin ctrl
@@ -807,6 +859,7 @@ void wxGridCellNumberEditor::Create(wxWindow* parent,
         wxGridCellEditor::Create(parent, id, evtHandler);
     }
     else
+#endif
     {
         // just a text control
         wxGridCellTextEditor::Create(parent, id, evtHandler);
@@ -829,19 +882,21 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
     {
         m_valueOld = 0;
         wxString sValue = table->GetValue(row, col);
-        if (! sValue.ToLong(&m_valueOld) && ! sValue.IsEmpty())
+        if (! sValue.ToLong(&m_valueOld) && ! sValue.empty())
         {
             wxFAIL_MSG( _T("this cell doesn't have numeric value") );
             return;
         }
     }
 
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         Spin()->SetValue((int)m_valueOld);
         Spin()->SetFocus();
     }
     else
+#endif
     {
         DoBeginEdit(GetString());
     }
@@ -854,6 +909,7 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
     long value = 0;
     wxString text;
 
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         value = Spin()->GetValue();
@@ -862,9 +918,10 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
             text = wxString::Format(wxT("%ld"), value);
     }
     else
+#endif
     {
         text = Text()->GetValue();
-        changed = (text.IsEmpty() || text.ToLong(&value)) && (value != m_valueOld);
+        changed = (text.empty() || text.ToLong(&value)) && (value != m_valueOld);
     }
 
     if ( changed )
@@ -880,11 +937,13 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
 
 void wxGridCellNumberEditor::Reset()
 {
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         Spin()->SetValue((int)m_valueOld);
     }
     else
+#endif
     {
         DoReset(GetString());
     }
@@ -895,29 +954,10 @@ bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event)
     if ( wxGridCellEditor::IsAcceptedKey(event) )
     {
         int keycode = event.GetKeyCode();
-        switch ( keycode )
+        if ( (keycode < 128) &&
+             (wxIsdigit(keycode) || keycode == '+' || keycode == '-'))
         {
-            case WXK_NUMPAD0:
-            case WXK_NUMPAD1:
-            case WXK_NUMPAD2:
-            case WXK_NUMPAD3:
-            case WXK_NUMPAD4:
-            case WXK_NUMPAD5:
-            case WXK_NUMPAD6:
-            case WXK_NUMPAD7:
-            case WXK_NUMPAD8:
-            case WXK_NUMPAD9:
-            case WXK_ADD:
-            case WXK_NUMPAD_ADD:
-            case WXK_SUBTRACT:
-            case WXK_NUMPAD_SUBTRACT:
-            case WXK_UP:
-            case WXK_DOWN:
-                return true;
-
-            default:
-                if ( (keycode < 128) && wxIsdigit(keycode) )
-                    return true;
+            return true;
         }
     }
 
@@ -926,24 +966,10 @@ bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event)
 
 void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
 {
+    int keycode = event.GetKeyCode();
     if ( !HasRange() )
     {
-        int keycode = event.GetKeyCode();
-        if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
-            || keycode ==  WXK_NUMPAD0
-            || keycode ==  WXK_NUMPAD1
-            || keycode ==  WXK_NUMPAD2
-            || keycode ==  WXK_NUMPAD3
-            || keycode ==  WXK_NUMPAD4
-            || keycode ==  WXK_NUMPAD5
-            || keycode ==  WXK_NUMPAD6
-            || keycode ==  WXK_NUMPAD7
-            || keycode ==  WXK_NUMPAD8
-            || keycode ==  WXK_NUMPAD9
-            || keycode ==  WXK_ADD
-            || keycode ==  WXK_NUMPAD_ADD
-            || keycode ==  WXK_SUBTRACT
-            || keycode ==  WXK_NUMPAD_SUBTRACT)
+        if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-')
         {
             wxGridCellTextEditor::StartingKey(event);
 
@@ -951,7 +977,18 @@ void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
             return;
         }
     }
-
+#if wxUSE_SPINCTRL
+    else
+    {
+        if ( wxIsdigit(keycode) )
+        {
+            wxSpinCtrl* spin = (wxSpinCtrl*)m_control;
+            spin->SetValue(keycode - '0');
+            spin->SetSelection(1,1);
+            return;
+        }
+    }
+#endif
     event.Skip();
 }
 
@@ -986,18 +1023,21 @@ void wxGridCellNumberEditor::SetParameters(const wxString& params)
 // return the value in the spin control if it is there (the text control otherwise)
 wxString wxGridCellNumberEditor::GetValue() const
 {
-  wxString s;
+    wxString s;
 
-  if( HasRange() )
-  {
-    long value = Spin()->GetValue();
-    s.Printf(wxT("%ld"), value);
-  }
-  else
-  {
-    s = Text()->GetValue();
-  }
-  return s;
+#if wxUSE_SPINCTRL
+    if( HasRange() )
+    {
+        long value = Spin()->GetValue();
+        s.Printf(wxT("%ld"), value);
+    }
+    else
+#endif
+    {
+        s = Text()->GetValue();
+    }
+
+    return s;
 }
 
 // ----------------------------------------------------------------------------
@@ -1033,7 +1073,7 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
     {
         m_valueOld = 0.0;
         wxString sValue = table->GetValue(row, col);
-        if (! sValue.ToDouble(&m_valueOld) && ! sValue.IsEmpty())
+        if (! sValue.ToDouble(&m_valueOld) && ! sValue.empty())
         {
             wxFAIL_MSG( _T("this cell doesn't have float value") );
             return;
@@ -1049,7 +1089,7 @@ bool wxGridCellFloatEditor::EndEdit(int row, int col,
     double value = 0.0;
     wxString text(Text()->GetValue());
 
-    if ( (text.IsEmpty() || text.ToDouble(&value)) && (value != m_valueOld) )
+    if ( (text.empty() || text.ToDouble(&value)) && (value != m_valueOld) )
     {
         if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT))
             grid->GetTable()->SetValueAsDouble(row, col, value);
@@ -1072,24 +1112,15 @@ void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)
     char tmpbuf[2];
     tmpbuf[0] = (char) keycode;
     tmpbuf[1] = '\0';
-    bool is_decimal_point = ( wxString(tmpbuf, *wxConvCurrent) ==
-      wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );
-        if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
-            || is_decimal_point
-            || keycode ==  WXK_NUMPAD0
-            || keycode ==  WXK_NUMPAD1
-            || keycode ==  WXK_NUMPAD2
-            || keycode ==  WXK_NUMPAD3
-            || keycode ==  WXK_NUMPAD4
-            || keycode ==  WXK_NUMPAD5
-            || keycode ==  WXK_NUMPAD6
-            || keycode ==  WXK_NUMPAD7
-            || keycode ==  WXK_NUMPAD8
-            || keycode ==  WXK_NUMPAD9
-            || keycode ==  WXK_ADD
-            || keycode ==  WXK_NUMPAD_ADD
-            || keycode ==  WXK_SUBTRACT
-            || keycode ==  WXK_NUMPAD_SUBTRACT)
+    wxString strbuf(tmpbuf, *wxConvCurrent);
+#if wxUSE_INTL
+    bool is_decimal_point = ( strbuf ==
+       wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );
+#else
+    bool is_decimal_point = ( strbuf == _T(".") );
+#endif
+    if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
+         || is_decimal_point )
     {
         wxGridCellTextEditor::StartingKey(event);
 
@@ -1154,42 +1185,23 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
     if ( wxGridCellEditor::IsAcceptedKey(event) )
     {
         int keycode = event.GetKeyCode();
-        switch ( keycode )
-        {
-            case WXK_NUMPAD0:
-            case WXK_NUMPAD1:
-            case WXK_NUMPAD2:
-            case WXK_NUMPAD3:
-            case WXK_NUMPAD4:
-            case WXK_NUMPAD5:
-            case WXK_NUMPAD6:
-            case WXK_NUMPAD7:
-            case WXK_NUMPAD8:
-            case WXK_NUMPAD9:
-            case WXK_ADD:
-            case WXK_NUMPAD_ADD:
-            case WXK_SUBTRACT:
-            case WXK_NUMPAD_SUBTRACT:
-            case WXK_DECIMAL:
-            case WXK_NUMPAD_DECIMAL:
-                return true;
-
-            default:
-            {
-               // additionally accept 'e' as in '1e+6', also '-', '+', and '.'
-                char tmpbuf[2];
-                tmpbuf[0] = (char) keycode;
-                tmpbuf[1] = '\0';
-                bool is_decimal_point =
-                  ( wxString(tmpbuf, *wxConvCurrent) ==
-                    wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
-                                      wxLOCALE_CAT_NUMBER) );
-                if ( (keycode < 128) &&
-                     (wxIsdigit(keycode) || tolower(keycode) == 'e' ||
-                      is_decimal_point || keycode == '+' || keycode == '-') )
-                    return true;
-            }
-        }
+        printf("%d\n", keycode);
+        // accept digits, 'e' as in '1e+6', also '-', '+', and '.'
+        char tmpbuf[2];
+        tmpbuf[0] = (char) keycode;
+        tmpbuf[1] = '\0';
+        wxString strbuf(tmpbuf, *wxConvCurrent);
+#if wxUSE_INTL
+        bool is_decimal_point =
+            ( strbuf == wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
+                                          wxLOCALE_CAT_NUMBER) );
+#else
+        bool is_decimal_point = ( strbuf == _T(".") );
+#endif
+        if ( (keycode < 128) &&
+             (wxIsdigit(keycode) || tolower(keycode) == 'e' ||
+              is_decimal_point || keycode == '+' || keycode == '-') )
+            return true;
     }
 
     return false;
@@ -1352,12 +1364,6 @@ bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event)
         int keycode = event.GetKeyCode();
         switch ( keycode )
         {
-            case WXK_MULTIPLY:
-            case WXK_NUMPAD_MULTIPLY:
-            case WXK_ADD:
-            case WXK_NUMPAD_ADD:
-            case WXK_SUBTRACT:
-            case WXK_NUMPAD_SUBTRACT:
             case WXK_SPACE:
             case '+':
             case '-':
@@ -1368,6 +1374,26 @@ bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event)
     return false;
 }
 
+void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)
+{
+    int keycode = event.GetKeyCode();
+    switch ( keycode )
+    {
+        case WXK_SPACE:
+            CBox()->SetValue(!CBox()->GetValue());
+            break;
+
+        case '+':
+            CBox()->SetValue(true);
+            break;
+
+        case '-':
+            CBox()->SetValue(false);
+            break;
+    }
+}
+
+
 // return the value as "1" for true and the empty string for false
 wxString wxGridCellBoolEditor::GetValue() const
 {
@@ -1441,6 +1467,14 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
     wxASSERT_MSG(m_control,
                  wxT("The wxGridCellEditor must be Created first!"));
 
+    wxGridCellEditorEvtHandler* evtHandler = NULL;
+    if (m_control)
+        evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler);
+
+    // Don't immediately end if we get a kill focus event within BeginEdit
+    if (evtHandler)
+        evtHandler->SetInSetFocus(true);
+
     m_startValue = grid->GetTable()->GetValue(row, col);
 
     if (m_allowOthers)
@@ -1449,12 +1483,15 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
     {
         // find the right position, or default to the first if not found
         int pos = Combo()->FindString(m_startValue);
-        if (pos == -1)
+        if (pos == wxNOT_FOUND)
             pos = 0;
         Combo()->SetSelection(pos);
     }
     Combo()->SetInsertionPointEnd();
     Combo()->SetFocus();
+
+    if (evtHandler)
+        evtHandler->SetInSetFocus(false);
 }
 
 bool wxGridCellChoiceEditor::EndEdit(int row, int col,
@@ -1504,6 +1541,18 @@ wxString wxGridCellChoiceEditor::GetValue() const
 // wxGridCellEditorEvtHandler
 // ----------------------------------------------------------------------------
 
+void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
+{
+    // Don't disable the cell if we're just starting to edit it
+    if (m_inSetFocus)
+        return;
+
+    // accept changes
+    m_grid->DisableCellEditControl();
+
+    event.Skip();
+}
+
 void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
 {
     switch ( event.GetKeyCode() )
@@ -1523,7 +1572,6 @@ void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
                 m_editor->HandleReturn(event);
             break;
 
-
         default:
             event.Skip();
     }
@@ -1578,18 +1626,18 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
     // grey out fields if the grid is disabled
     if( grid.IsEnabled() )
     {
-      if ( isSelected )
-      {
-          dc.SetBrush( wxBrush(grid.GetSelectionBackground(), wxSOLID) );
-      }
-      else
-      {
-          dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) );
-      }
+        if ( isSelected )
+        {
+            dc.SetBrush( wxBrush(grid.GetSelectionBackground(), wxSOLID) );
+        }
+        else
+        {
+            dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) );
+        }
     }
     else
     {
-      dc.SetBrush(wxBrush(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE), wxSOLID));
+        dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID));
     }
 
     dc.SetPen( *wxTRANSPARENT_PEN );
@@ -1625,8 +1673,8 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid,
     }
     else
     {
-      dc.SetTextBackground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE));
-      dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_GRAYTEXT));
+      dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
+      dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
     }
 
     dc.SetFont( attr.GetFont() );
@@ -1913,7 +1961,7 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
     else
     {
         wxString tmp = params.BeforeFirst(_T(','));
-        if ( !!tmp )
+        if ( !tmp.empty() )
         {
             long width;
             if ( tmp.ToLong(&width) )
@@ -1927,7 +1975,7 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
 
         }
                 tmp = params.AfterFirst(_T(','));
-                if ( !!tmp )
+                if ( !tmp.empty() )
                 {
                     long precision;
             if ( tmp.ToLong(&precision) )
@@ -2127,8 +2175,8 @@ void wxGridCellAttr::MergeWith(wxGridCellAttr *mergefrom)
         mergefrom->GetAlignment( &hAlign, &vAlign);
         SetAlignment(hAlign, vAlign);
     }
-
-    mergefrom->GetSize( &m_sizeRows, &m_sizeCols );
+    if ( !HasSize() && mergefrom->HasSize() )
+        mergefrom->GetSize( &m_sizeRows, &m_sizeCols );
 
     // Directly access member functions as GetRender/Editor don't just return
     // m_renderer/m_editor
@@ -2412,7 +2460,9 @@ void wxGridCellAttrData::UpdateAttrRows( size_t pos, int numRows )
                 else
                 {
                     // ...or remove the attribute
-                    m_attrs.RemoveAt((size_t)n);
+                    // No need to DecRef the attribute itself since this is
+                    // done be wxGridCellWithAttr's destructor!
+                    m_attrs.RemoveAt(n);
                     n--; count--;
                 }
             }
@@ -2445,7 +2495,9 @@ void wxGridCellAttrData::UpdateAttrCols( size_t pos, int numCols )
                 else
                 {
                     // ...or remove the attribute
-                    m_attrs.RemoveAt((size_t)n);
+                    // No need to DecRef the attribute itself since this is
+                    // done be wxGridCellWithAttr's destructor!
+                    m_attrs.RemoveAt(n);
                     n--; count--;
                 }
             }
@@ -2543,8 +2595,9 @@ void wxGridRowOrColAttrData::UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols
                     rowOrCol += numRowsOrCols;
                 else
                 {
-                    m_rowsOrCols.RemoveAt((size_t)n);
-                    m_attrs.RemoveAt((size_t)n);
+                    m_rowsOrCols.RemoveAt(n);
+                    m_attrs[n]->DecRef();
+                    m_attrs.RemoveAt(n);
                     n--; count--;
                 }
             }
@@ -2591,8 +2644,8 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                     wxGridCellAttr *attrrow = m_data->m_rowAttrs.GetAttr(row);
                     wxGridCellAttr *attrcol = m_data->m_colAttrs.GetAttr(col);
 
-                    if((attrcell != attrrow) && (attrrow !=attrcol) && (attrcell != attrcol)){
-                        // Two or move are non NULL
+                    if((attrcell != attrrow) && (attrrow != attrcol) && (attrcell != attrcol)){
+                        // Two or more are non NULL
                         attr = new wxGridCellAttr;
                         attr->SetKind(wxGridCellAttr::Merged);
 
@@ -2614,11 +2667,21 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                         //m_data->m_mergeAttr.SetAttr(attr, row, col);
                     }
                     else
-        {
+                    {
                         // one or none is non null return it or null.
                         if(attrrow) attr = attrrow;
-                        if(attrcol) attr = attrcol;
-                        if(attrcell) attr = attrcell;
+                        if(attrcol)
+                        {
+                            if(attr)
+                                attr->DecRef();
+                            attr = attrcol;
+                        }
+                        if(attrcell)
+                        {
+                            if(attr)
+                                attr->DecRef();
+                            attr = attrcell;
+                        }
                     }
                 }
             break;
@@ -2626,10 +2689,10 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                 attr = m_data->m_cellAttrs.GetAttr(row, col);
             break;
             case (wxGridCellAttr::Col):
-                 attr = m_data->m_colAttrs.GetAttr(col);
+                attr = m_data->m_colAttrs.GetAttr(col);
             break;
             case (wxGridCellAttr::Row):
-            attr = m_data->m_rowAttrs.GetAttr(row);
+                attr = m_data->m_rowAttrs.GetAttr(row);
             break;
             default:
                 // unused as yet...
@@ -2884,6 +2947,7 @@ wxGridCellAttr *wxGridTableBase::GetAttr(int row, int col, wxGridCellAttr::wxAtt
         return (wxGridCellAttr *)NULL;
 }
 
+
 void wxGridTableBase::SetAttr(wxGridCellAttr* attr, int row, int col)
 {
     if ( m_attrProvider )
@@ -3469,6 +3533,7 @@ BEGIN_EVENT_TABLE( wxGridRowLabelWindow, wxWindow )
     EVT_MOUSE_EVENTS( wxGridRowLabelWindow::OnMouseEvent )
     EVT_KEY_DOWN( wxGridRowLabelWindow::OnKeyDown )
     EVT_KEY_UP( wxGridRowLabelWindow::OnKeyUp )
+    EVT_CHAR ( wxGridRowLabelWindow::OnChar )
 END_EVENT_TABLE()
 
 wxGridRowLabelWindow::wxGridRowLabelWindow( wxGrid *parent,
@@ -3523,6 +3588,11 @@ void wxGridRowLabelWindow::OnKeyUp( wxKeyEvent& event )
     if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
 }
 
+void wxGridRowLabelWindow::OnChar( wxKeyEvent& event )
+{
+    if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
+}
+
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3535,6 +3605,7 @@ BEGIN_EVENT_TABLE( wxGridColLabelWindow, wxWindow )
     EVT_MOUSE_EVENTS( wxGridColLabelWindow::OnMouseEvent )
     EVT_KEY_DOWN( wxGridColLabelWindow::OnKeyDown )
     EVT_KEY_UP( wxGridColLabelWindow::OnKeyUp )
+    EVT_CHAR ( wxGridColLabelWindow::OnChar )
 END_EVENT_TABLE()
 
 wxGridColLabelWindow::wxGridColLabelWindow( wxGrid *parent,
@@ -3588,6 +3659,10 @@ void wxGridColLabelWindow::OnKeyUp( wxKeyEvent& event )
     if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
 }
 
+void wxGridColLabelWindow::OnChar( wxKeyEvent& event )
+{
+    if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
+}
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3600,6 +3675,7 @@ BEGIN_EVENT_TABLE( wxGridCornerLabelWindow, wxWindow )
     EVT_PAINT( wxGridCornerLabelWindow::OnPaint)
     EVT_KEY_DOWN( wxGridCornerLabelWindow::OnKeyDown )
     EVT_KEY_UP( wxGridCornerLabelWindow::OnKeyUp )
+    EVT_CHAR ( wxGridCornerLabelWindow::OnChar )
 END_EVENT_TABLE()
 
 wxGridCornerLabelWindow::wxGridCornerLabelWindow( wxGrid *parent,
@@ -3618,6 +3694,15 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
     int client_width = 0;
     GetClientSize( &client_width, &client_height );
 
+#if __WXGTK__
+    wxRect rect;
+    rect.SetX( 1 );
+    rect.SetY( 1 );
+    rect.SetWidth( client_width - 2 );
+    rect.SetHeight( client_height - 2 );
+
+    wxRendererNative::Get().DrawHeaderButton( this, dc, rect, 0 );
+#else
     dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW),1, wxSOLID) );
     dc.DrawLine( client_width-1, client_height-1, client_width-1, 0 );
     dc.DrawLine( client_width-1, client_height-1, 0, client_height-1 );
@@ -3627,6 +3712,7 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
     dc.SetPen( *wxWHITE_PEN );
     dc.DrawLine( 1, 1, client_width-1, 1 );
     dc.DrawLine( 1, 1, 1, client_height-1 );
+#endif
 }
 
 
@@ -3654,6 +3740,10 @@ void wxGridCornerLabelWindow::OnKeyUp( wxKeyEvent& event )
     if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
 }
 
+void wxGridCornerLabelWindow::OnChar( wxKeyEvent& event )
+{
+    if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
+}
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3666,6 +3756,7 @@ BEGIN_EVENT_TABLE( wxGridWindow, wxWindow )
     EVT_MOUSE_EVENTS( wxGridWindow::OnMouseEvent )
     EVT_KEY_DOWN( wxGridWindow::OnKeyDown )
     EVT_KEY_UP( wxGridWindow::OnKeyUp )
+    EVT_CHAR ( wxGridWindow::OnChar )
     EVT_SET_FOCUS( wxGridWindow::OnFocus )
     EVT_KILL_FOCUS( wxGridWindow::OnFocus )
     EVT_ERASE_BACKGROUND( wxGridWindow::OnEraseBackground )
@@ -3687,11 +3778,6 @@ wxGridWindow::wxGridWindow( wxGrid *parent,
 }
 
 
-wxGridWindow::~wxGridWindow()
-{
-}
-
-
 void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     wxPaintDC dc( this );
@@ -3717,6 +3803,9 @@ void wxGridWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
 
 void wxGridWindow::OnMouseEvent( wxMouseEvent& event )
 {
+    if (event.ButtonDown(wxMOUSE_BTN_LEFT) && FindFocus() != this)
+        SetFocus();
+
     m_owner->ProcessGridCellMouseEvent( event );
 }
 
@@ -3738,6 +3827,11 @@ void wxGridWindow::OnKeyUp( wxKeyEvent& event )
     if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
 }
 
+void wxGridWindow::OnChar( wxKeyEvent& event )
+{
+    if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip();
+}
+
 void wxGridWindow::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
 {
 }
@@ -3815,7 +3909,7 @@ wxEND_HANDLERS_TABLE()
 wxCONSTRUCTOR_5( wxGrid , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
 
 /*
- TODO : Expose more information of a list's layout etc. via appropriate objects (à la NotebookPageInfo)
+ TODO : Expose more information of a list's layout etc. via appropriate objects (\81à la NotebookPageInfo)
 */
 #else
 IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow )
@@ -3826,6 +3920,7 @@ BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow )
     EVT_SIZE( wxGrid::OnSize )
     EVT_KEY_DOWN( wxGrid::OnKeyDown )
     EVT_KEY_UP( wxGrid::OnKeyUp )
+    EVT_CHAR ( wxGrid::OnChar )
     EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground )
 END_EVENT_TABLE()
 
@@ -3849,15 +3944,8 @@ wxGrid::wxGrid( wxWindow *parent,
     m_colMinWidths(GRID_HASH_SIZE),
     m_rowMinHeights(GRID_HASH_SIZE)
 {
-    // in order to make sure that a size event is not
-    // trigerred in a unfinished state
-    m_cornerLabelWin = NULL ;
-    m_rowLabelWin = NULL ;
-    m_colLabelWin = NULL ;
-    m_gridWin = NULL ;
-
-    SetBestFittingSize(size);
     Create();
+    SetBestFittingSize(size);
 }
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
@@ -3871,8 +3959,8 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id,
     m_colMinWidths = wxLongToLongHashMap(GRID_HASH_SIZE) ;
     m_rowMinHeights = wxLongToLongHashMap(GRID_HASH_SIZE) ;
 
-    SetBestFittingSize(size);
     Create() ;
+    SetBestFittingSize(size);
 
     return true;
 }
@@ -4167,6 +4255,9 @@ void wxGrid::Init()
 
     m_extraWidth =
     m_extraHeight = 0;
+
+    m_scrollLineX = GRID_SCROLL_LINE_X;
+    m_scrollLineY = GRID_SCROLL_LINE_Y;
 }
 
 // ----------------------------------------------------------------------------
@@ -4296,7 +4387,7 @@ void wxGrid::CalcDimensions()
         y = wxMax( h - 1, 0 );
 
     // do set scrollbar parameters
-    SetScrollbars( GRID_SCROLL_LINE_X, GRID_SCROLL_LINE_Y,
+    SetScrollbars( m_scrollLineX, m_scrollLineY,
                    GetScrollX(w), GetScrollY(h), x, y,
                    GetBatchCount() != 0);
 
@@ -4678,7 +4769,7 @@ wxArrayInt wxGrid::CalcRowLabelsExposed( const wxRegion& reg )
             rowlabels.Add( row );
         }
 
-        iter++ ;
+        ++iter;
     }
 
     return rowlabels;
@@ -4729,7 +4820,7 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg )
             colLabels.Add( col );
         }
 
-        iter++ ;
+        ++iter;
     }
     return colLabels;
 }
@@ -4789,7 +4880,7 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg )
             }
         }
 
-        iter++;
+        ++iter;
     }
 
     return cellsExposed;
@@ -4836,6 +4927,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_ROW:
+                {
                     if ( (row = YToRow( y )) >= 0 )
                     {
                         if ( m_selection )
@@ -4847,6 +4939,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                                                     event.MetaDown() );
                         }
                     }
+                }
+                break;
 
                 // default label to suppress warnings about "enumeration value
                 // 'xxx' not handled in switch
@@ -5058,6 +5152,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_COL:
+                {
                     if ( (col = XToCol( x )) >= 0 )
                     {
                         if ( m_selection )
@@ -5069,6 +5164,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                                                     event.MetaDown() );
                         }
                     }
+                }
+                break;
 
                 // default label to suppress warnings about "enumeration value
                 // 'xxx' not handled in switch
@@ -6431,44 +6528,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
                 // Otherwise fall through to default
 
             default:
-                // is it possible to edit the current cell at all?
-                if ( !IsCellEditControlEnabled() && CanEnableCellControl() )
-                {
-                    // yes, now check whether the cells editor accepts the key
-                    int row = m_currentCellCoords.GetRow();
-                    int col = m_currentCellCoords.GetCol();
-                    wxGridCellAttr* attr = GetCellAttr(row, col);
-                    wxGridCellEditor *editor = attr->GetEditor(this, row, col);
-
-                    // <F2> is special and will always start editing, for
-                    // other keys - ask the editor itself
-                    if ( (event.GetKeyCode() == WXK_F2 && !event.HasModifiers())
-                         || editor->IsAcceptedKey(event) )
-                    {
-                        // ensure cell is visble
-                        MakeCellVisible(row, col);
-                        EnableCellEditControl();
-
-                        // a problem can arise if the cell is not completely
-                        // visible (even after calling MakeCellVisible the
-                        // control is not created and calling StartingKey will
-                        // crash the app
-                        if( editor->IsCreated() && m_cellEditCtrlEnabled ) editor->StartingKey(event);
-                    }
-                    else
-                    {
-                        event.Skip();
-                    }
-
-                    editor->DecRef();
-                    attr->DecRef();
-                }
-                else
-                {
-                    // let others process char events with modifiers or all
-                    // char events for readonly cells
-                    event.Skip();
-                }
+                event.Skip();
                 break;
         }
     }
@@ -6504,6 +6564,48 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
     }
 }
 
+void wxGrid::OnChar( wxKeyEvent& event )
+{
+    // is it possible to edit the current cell at all?
+    if ( !IsCellEditControlEnabled() && CanEnableCellControl() )
+    {
+        // yes, now check whether the cells editor accepts the key
+        int row = m_currentCellCoords.GetRow();
+        int col = m_currentCellCoords.GetCol();
+        wxGridCellAttr* attr = GetCellAttr(row, col);
+        wxGridCellEditor *editor = attr->GetEditor(this, row, col);
+
+        // <F2> is special and will always start editing, for
+        // other keys - ask the editor itself
+        if ( (event.GetKeyCode() == WXK_F2 && !event.HasModifiers())
+             || editor->IsAcceptedKey(event) )
+        {
+            // ensure cell is visble
+            MakeCellVisible(row, col);
+            EnableCellEditControl();
+
+            // a problem can arise if the cell is not completely
+            // visible (even after calling MakeCellVisible the
+            // control is not created and calling StartingKey will
+            // crash the app
+            if ( event.GetKeyCode() != WXK_F2 && editor->IsCreated() && m_cellEditCtrlEnabled )
+                editor->StartingKey(event);
+        }
+        else
+        {
+            event.Skip();
+        }
+
+        editor->DecRef();
+        attr->DecRef();
+    }
+    else
+    {
+        event.Skip();
+    }
+}
+
+
 void wxGrid::OnEraseBackground(wxEraseEvent&)
 {
 }
@@ -7098,8 +7200,10 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
     int topRow    = internalYToRow(top);
     int rightCol  = internalXToCol(right);
     int bottomRow = internalYToRow(bottom);
-    wxRegion clippedcells(0, 0, cw, ch);
 
+#ifndef __WXMAC__
+    // CS: I don't know why suddenly unscrolled coordinates are used for clipping
+    wxRegion clippedcells(0, 0, cw, ch);
 
     int i, j, cell_rows, cell_cols;
     wxRect rect;
@@ -7123,6 +7227,30 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
             }
         }
     }
+#else
+    wxRegion clippedcells( left , top, right - left, bottom - top);
+
+    int i, j, cell_rows, cell_cols;
+    wxRect rect;
+
+    for (j=topRow; j<bottomRow; j++)
+    {
+        for (i=leftCol; i<rightCol; i++)
+        {
+            GetCellSize( j, i, &cell_rows, &cell_cols );
+            if ((cell_rows > 1) || (cell_cols > 1))
+            {
+                rect = CellToRect(j,i);
+                clippedcells.Subtract(rect);
+            }
+            else if ((cell_rows < 0) || (cell_cols < 0))
+            {
+                rect = CellToRect(j+cell_rows, i+cell_cols);
+                clippedcells.Subtract(rect);
+            }
+        }
+    }
+#endif
     dc.SetClippingRegion( clippedcells );
 
     dc.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID) );
@@ -7181,9 +7309,22 @@ void wxGrid::DrawRowLabels( wxDC& dc ,const wxArrayInt& rows)
 
 void wxGrid::DrawRowLabel( wxDC& dc, int row )
 {
-    if ( GetRowHeight(row) <= 0 )
+    if ( GetRowHeight(row) <= 0 || m_rowLabelWidth <= 0 )
         return;
 
+    wxRect rect;
+#ifdef __WXGTK20__
+    rect.SetX( 1 );
+    rect.SetY( GetRowTop(row) + 1 );
+    rect.SetWidth( m_rowLabelWidth - 2 );
+    rect.SetHeight( GetRowHeight(row) - 2 );
+
+    CalcScrolledPosition( 0, rect.y, NULL, &rect.y );
+
+    wxWindowDC *win_dc = (wxWindowDC*) &dc;
+
+    wxRendererNative::Get().DrawHeaderButton( win_dc->m_owner, dc, rect, 0 );
+#else
     int rowTop = GetRowTop(row),
         rowBottom = GetRowBottom(row) - 1;
 
@@ -7198,7 +7339,7 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row )
     dc.SetPen( *wxWHITE_PEN );
     dc.DrawLine( 1, rowTop, 1, rowBottom );
     dc.DrawLine( 1, rowTop, m_rowLabelWidth-1, rowTop );
-
+#endif
     dc.SetBackgroundMode( wxTRANSPARENT );
     dc.SetTextForeground( GetLabelTextColour() );
     dc.SetFont( GetLabelFont() );
@@ -7206,7 +7347,6 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row )
     int hAlign, vAlign;
     GetRowLabelAlignment( &hAlign, &vAlign );
 
-    wxRect rect;
     rect.SetX( 2 );
     rect.SetY( GetRowTop(row) + 2 );
     rect.SetWidth( m_rowLabelWidth - 4 );
@@ -7231,11 +7371,23 @@ void wxGrid::DrawColLabels( wxDC& dc,const wxArrayInt& cols )
 
 void wxGrid::DrawColLabel( wxDC& dc, int col )
 {
-    if ( GetColWidth(col) <= 0 )
+    if ( GetColWidth(col) <= 0 || m_colLabelHeight <= 0 )
         return;
 
-    int colLeft = GetColLeft(col),
-        colRight = GetColRight(col) - 1;
+    int colLeft = GetColLeft(col);
+
+    wxRect rect;
+#ifdef __WXGTK20__
+    rect.SetX( colLeft + 1 );
+    rect.SetY( 1 );
+    rect.SetWidth( GetColWidth(col) - 2 );
+    rect.SetHeight( m_colLabelHeight - 2 );
+
+    wxWindowDC *win_dc = (wxWindowDC*) &dc;
+
+    wxRendererNative::Get().DrawHeaderButton( win_dc->m_owner, dc, rect, 0 );
+#else
+    int colRight = GetColRight(col) - 1;
 
     dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW),1, wxSOLID) );
     dc.DrawLine( colRight, 0,
@@ -7249,7 +7401,7 @@ void wxGrid::DrawColLabel( wxDC& dc, int col )
     dc.SetPen( *wxWHITE_PEN );
     dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight-1 );
     dc.DrawLine( colLeft, 1, colRight, 1 );
-
+#endif
     dc.SetBackgroundMode( wxTRANSPARENT );
     dc.SetTextForeground( GetLabelTextColour() );
     dc.SetFont( GetLabelFont() );
@@ -7258,7 +7410,6 @@ void wxGrid::DrawColLabel( wxDC& dc, int col )
     GetColLabelAlignment( &hAlign, &vAlign );
     orient = GetColLabelTextOrientation();
 
-    wxRect rect;
     rect.SetX( colLeft + 2 );
     rect.SetY( 2 );
     rect.SetWidth( GetColWidth(col) - 4 );
@@ -7466,6 +7617,16 @@ void wxGrid::ForceRefresh()
     EndBatch();
 }
 
+bool wxGrid::Enable(bool enable)
+{
+    if ( !wxScrolledWindow::Enable(enable) )
+        return false;
+
+    // redraw in the new state
+    m_gridWin->Refresh();
+
+    return true;
+}
 
 //
 // ------ Edit control functions
@@ -7707,6 +7868,10 @@ void wxGrid::HideCellEditControl()
         wxRect rect( CellToRect(row, col) );
         CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y );
         rect.width = m_gridWin->GetClientSize().GetWidth() - rect.x;
+#ifdef __WXMAC__
+        // ensure that the pixels under the focus ring get refreshed as well
+        rect.Inflate(10,10);
+#endif
         m_gridWin->Refresh( false, &rect );
     }
 }
@@ -8002,7 +8167,7 @@ void wxGrid::MakeCellVisible( int row, int col )
             //
             // Sometimes GRID_SCROLL_LINE/2 is not enough, so just add a full
             // scroll unit...
-            ypos += GRID_SCROLL_LINE_Y;
+            ypos += m_scrollLineY;
         }
 
         if ( left < 0 )
@@ -8017,15 +8182,15 @@ void wxGrid::MakeCellVisible( int row, int col )
             xpos = x0 + (right - cw);
 
             // see comment for ypos above
-            xpos += GRID_SCROLL_LINE_X;
+            xpos += m_scrollLineX;
         }
 
         if ( xpos != -1  ||  ypos != -1 )
         {
             if ( xpos != -1 )
-                xpos /= GRID_SCROLL_LINE_X;
+                xpos /= m_scrollLineX;
             if ( ypos != -1 )
-                ypos /= GRID_SCROLL_LINE_Y;
+                ypos /= m_scrollLineY;
             Scroll( xpos, ypos );
             AdjustScrollbars();
         }
@@ -8889,14 +9054,24 @@ void wxGrid::SetDefaultCellFont( const wxFont& font )
     m_defaultCellAttr->SetFont(font);
 }
 
+
+// For editors and renderers the type registry takes precedence over the
+// default attr, so we need to register the new editor/renderer for the string
+// data type in order to make setting a default editor/renderer appear to
+// work correctly.
+
 void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer)
 {
-    m_defaultCellAttr->SetRenderer(renderer);
+    RegisterDataType(wxGRID_VALUE_STRING,
+                     renderer,
+                     GetDefaultEditorForType(wxGRID_VALUE_STRING));
 }
 
 void wxGrid::SetDefaultEditor(wxGridCellEditor *editor)
 {
-    m_defaultCellAttr->SetEditor(editor);
+    RegisterDataType(wxGRID_VALUE_STRING,
+                     GetDefaultRendererForType(wxGRID_VALUE_STRING),
+                     editor);
 }
 
 // ----------------------------------------------------------------------------
@@ -9104,9 +9279,10 @@ wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
 wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const
 {
     wxGridCellAttr *attr = (wxGridCellAttr *)NULL;
+    bool canHave = ((wxGrid*)this)->CanHaveAttributes();
 
-    wxCHECK_MSG( m_table, attr,
-                  _T("we may only be called if CanHaveAttributes() returned true and then m_table should be !NULL") );
+    wxCHECK_MSG( canHave, attr, _T("Cell attributes not allowed"));
+    wxCHECK_MSG( m_table, attr, _T("must have a table") );
 
     attr = m_table->GetAttr(row, col, wxGridCellAttr::Cell);
     if ( !attr )
@@ -9526,26 +9702,30 @@ void wxGrid::SetColSize( int col, int width )
 void wxGrid::SetColMinimalWidth( int col, int width )
 {
     if (width > GetColMinimalAcceptableWidth()) {
-        m_colMinWidths[col] = width;
+        wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)col;
+        m_colMinWidths[key] = width;
     }
 }
 
 void wxGrid::SetRowMinimalHeight( int row, int width )
 {
     if (width > GetRowMinimalAcceptableHeight()) {
-       m_rowMinHeights[row] = width;
+        wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)row;
+        m_rowMinHeights[key] = width;
     }
 }
 
 int wxGrid::GetColMinimalWidth(int col) const
 {
-    wxLongToLongHashMap::const_iterator it = m_colMinWidths.find(col);
+    wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)col;
+    wxLongToLongHashMap::const_iterator it = m_colMinWidths.find(key);
     return it != m_colMinWidths.end() ? (int)it->second : m_minAcceptableColWidth;
 }
 
 int wxGrid::GetRowMinimalHeight(int row) const
 {
-    wxLongToLongHashMap::const_iterator it = m_rowMinHeights.find(row);
+    wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)row;
+    wxLongToLongHashMap::const_iterator it = m_rowMinHeights.find(key);
     return it != m_rowMinHeights.end() ? (int)it->second : m_minAcceptableRowHeight;
 }
 
@@ -9756,8 +9936,8 @@ void wxGrid::AutoSize()
     // won't get the scrollbars if we're sized exactly to this width
     // CalcDimension adds m_extraWidth + 1 etc. to calculate the necessary
     // scrollbar steps
-    wxSize sizeFit(GetScrollX(size.x + m_extraWidth + 1) * GRID_SCROLL_LINE_X,
-                   GetScrollY(size.y + m_extraHeight + 1) * GRID_SCROLL_LINE_Y);
+    wxSize sizeFit(GetScrollX(size.x + m_extraWidth + 1) * m_scrollLineX,
+                   GetScrollY(size.y + m_extraHeight + 1) * m_scrollLineY);
 
     // distribute the extra space between the columns/rows to avoid having
     // extra white space
@@ -9877,7 +10057,7 @@ wxSize wxGrid::DoGetBestSize() const
 
     if (!width) width=100;
     if (!height) height=80;
-    
+
     // Round up to a multiple the scroll rate NOTE: this still doesn't get rid
     // of the scrollbars, is there any magic incantaion for that?
     int xpu, ypu;
@@ -9886,16 +10066,16 @@ wxSize wxGrid::DoGetBestSize() const
         width  += 1 + xpu - (width  % xpu);
     if (ypu)
         height += 1 + ypu - (height % ypu);
-    
+
     // limit to 1/4 of the screen size
     int maxwidth, maxheight;
     wxDisplaySize( & maxwidth, & maxheight );
     maxwidth /= 2;
-    maxheight /= 2;    
+    maxheight /= 2;
     if ( width > maxwidth ) width = maxwidth;
     if ( height > maxheight ) height = maxheight;
 
-    
+
     wxSize best(width, height);
     // NOTE: This size should be cached, but first we need to add calls to
     // InvalidateBestSize everywhere that could change the results of this
@@ -10113,7 +10293,7 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
     }
     else
     {
-        rect = wxRect( 0, 0, 0, 0 );
+        rect = wxRect(0,0,0,0);
     }
 
     cellRect = CellToRect( bottomRight );
@@ -10188,7 +10368,7 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
     m_gridWin->GetClientSize( &cw, &ch );
 
     if (right < 0 || bottom < 0 || left > cw || top > ch)
-        return wxRect( 0, 0, 0, 0);
+        return wxRect(0,0,0,0);
 
     rect.SetLeft( wxMax(0, left) );
     rect.SetTop( wxMax(0, top) );