]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
fixed warnings about truncating 64 bit integers
[wxWidgets.git] / src / generic / grid.cpp
index c68571a1a2d3362a16fd7730884a832b2727b051..4a491aae1d6874681611430114a1c80ed5988824 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "grid.h"
-#endif
-
 // For compilers that support precompilatixon, includes "wx/wx.h".
 #include "wx/wxprec.h"
 
     #include "wx/combobox.h"
     #include "wx/valtext.h"
     #include "wx/intl.h"
+    #include "wx/math.h"
 #endif
 
 #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"
@@ -109,6 +107,7 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_DCLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_DCLICK)
+DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_BEGIN_DRAG)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK)
@@ -141,6 +140,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
 
     DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow)
     DECLARE_EVENT_TABLE()
@@ -163,6 +163,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
 
     DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow)
     DECLARE_EVENT_TABLE()
@@ -184,6 +185,7 @@ private:
     void OnMouseWheel( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& event );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
     void OnPaint( wxPaintEvent& event );
 
     DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow)
@@ -205,7 +207,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 );
 
@@ -221,6 +223,7 @@ private:
     void OnMouseEvent( wxMouseEvent& event );
     void OnKeyDown( wxKeyEvent& );
     void OnKeyUp( wxKeyEvent& );
+    void OnChar( wxKeyEvent& );
     void OnEraseBackground( wxEraseEvent& );
     void OnFocus( wxFocusEvent& );
 
@@ -234,27 +237,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()
@@ -412,6 +425,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
 // ----------------------------------------------------------------------------
@@ -425,6 +439,7 @@ static inline int GetScrollY(int y)
 {
     return (y + GRID_SCROLL_LINE_Y - 1) / GRID_SCROLL_LINE_Y;
 }
+#endif
 
 // ============================================================================
 // implementation
@@ -499,9 +514,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
         }
@@ -520,12 +537,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
     }
 }
 
@@ -543,8 +562,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)
@@ -692,48 +743,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;
     }
 }
 
@@ -795,6 +844,7 @@ void wxGridCellNumberEditor::Create(wxWindow* parent,
                                     wxWindowID id,
                                     wxEvtHandler* evtHandler)
 {
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         // create a spin ctrl
@@ -806,6 +856,7 @@ void wxGridCellNumberEditor::Create(wxWindow* parent,
         wxGridCellEditor::Create(parent, id, evtHandler);
     }
     else
+#endif
     {
         // just a text control
         wxGridCellTextEditor::Create(parent, id, evtHandler);
@@ -828,19 +879,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());
     }
@@ -853,6 +906,7 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
     long value = 0;
     wxString text;
 
+#if wxUSE_SPINCTRL
     if ( HasRange() )
     {
         value = Spin()->GetValue();
@@ -861,9 +915,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 )
@@ -879,11 +934,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());
     }
@@ -894,29 +951,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;
         }
     }
 
@@ -925,24 +963,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);
 
@@ -950,7 +974,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();
 }
 
@@ -985,18 +1020,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;
 }
 
 // ----------------------------------------------------------------------------
@@ -1032,7 +1070,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;
@@ -1048,7 +1086,8 @@ 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)) &&
+            !wxIsSameDouble(value, m_valueOld) )
     {
         if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT))
             grid->GetTable()->SetValueAsDouble(row, col, value);
@@ -1071,24 +1110,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);
 
@@ -1153,42 +1183,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;
@@ -1351,12 +1362,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 '-':
@@ -1367,6 +1372,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
 {
@@ -1440,6 +1465,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)
@@ -1448,30 +1481,27 @@ 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,
                                      wxGrid* grid)
 {
     wxString value = Combo()->GetValue();
-    bool changed = value != m_startValue;
-
-    if ( changed )
-        grid->GetTable()->SetValue(row, col, value);
+    if ( value == m_startValue )
+        return false;
 
-    m_startValue = wxEmptyString;
-    if (m_allowOthers)
-        Combo()->SetValue(m_startValue);
-    else
-        Combo()->SetSelection(0);
+    grid->GetTable()->SetValue(row, col, value);
 
-    return changed;
+    return true;
 }
 
 void wxGridCellChoiceEditor::Reset()
@@ -1509,6 +1539,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() )
@@ -1528,7 +1570,6 @@ void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
                 m_editor->HandleReturn(event);
             break;
 
-
         default:
             event.Skip();
     }
@@ -1583,18 +1624,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 );
@@ -1605,8 +1646,8 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
 // wxGridCellStringRenderer
 // ----------------------------------------------------------------------------
 
-void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid,
-                                                     wxGridCellAttr& attr,
+void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid,
+                                                     const wxGridCellAttr& attr,
                                                      wxDC& dc,
                                                      bool isSelected)
 {
@@ -1630,14 +1671,14 @@ 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() );
 }
 
-wxSize wxGridCellStringRenderer::DoGetBestSize(wxGridCellAttr& attr,
+wxSize wxGridCellStringRenderer::DoGetBestSize(const wxGridCellAttr& attr,
                                                wxDC& dc,
                                                const wxString& text)
 {
@@ -1758,7 +1799,7 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
 // wxGridCellNumberRenderer
 // ----------------------------------------------------------------------------
 
-wxString wxGridCellNumberRenderer::GetString(wxGrid& grid, int row, int col)
+wxString wxGridCellNumberRenderer::GetString(const wxGrid& grid, int row, int col)
 {
     wxGridTableBase *table = grid.GetTable();
     wxString text;
@@ -1824,7 +1865,7 @@ wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const
     return renderer;
 }
 
-wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col)
+wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col)
 {
     wxGridTableBase *table = grid.GetTable();
 
@@ -1918,7 +1959,7 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
     else
     {
         wxString tmp = params.BeforeFirst(_T(','));
-        if ( !!tmp )
+        if ( !tmp.empty() )
         {
             long width;
             if ( tmp.ToLong(&width) )
@@ -1929,21 +1970,19 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
             {
                 wxLogDebug(_T("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str());
             }
-
         }
-                tmp = params.AfterFirst(_T(','));
-                if ( !!tmp )
-                {
-                    long precision;
+        tmp = params.AfterFirst(_T(','));
+        if ( !tmp.empty() )
+        {
+            long precision;
             if ( tmp.ToLong(&precision) )
-                    {
+            {
                 SetPrecision((int)precision);
-                    }
-                    else
-                    {
+            }
+            else
+            {
                 wxLogDebug(_T("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str());
-        }
-
+            }
         }
     }
 }
@@ -2132,8 +2171,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
@@ -2417,7 +2456,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--;
                 }
             }
@@ -2450,7 +2491,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--;
                 }
             }
@@ -2548,8 +2591,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--;
                 }
             }
@@ -2596,8 +2640,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);
 
@@ -2619,11 +2663,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;
@@ -2631,10 +2685,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...
@@ -2889,6 +2943,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 )
@@ -3474,6 +3529,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,
@@ -3528,6 +3584,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();
+}
+
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3540,6 +3601,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,
@@ -3593,6 +3655,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();
+}
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3605,6 +3671,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,
@@ -3623,6 +3690,16 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
     int client_width = 0;
     GetClientSize( &client_width, &client_height );
 
+    // VZ: any reason for this ifdef? (FIXME)
+#ifdef __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 // !__WXGTK__
     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 );
@@ -3632,6 +3709,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 // __WXGTK__/!__WXGTK__
 }
 
 
@@ -3659,6 +3737,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();
+}
 
 
 //////////////////////////////////////////////////////////////////////
@@ -3671,6 +3753,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 )
@@ -3692,11 +3775,6 @@ wxGridWindow::wxGridWindow( wxGrid *parent,
 }
 
 
-wxGridWindow::~wxGridWindow()
-{
-}
-
-
 void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     wxPaintDC dc( this );
@@ -3722,6 +3800,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 );
 }
 
@@ -3743,6 +3824,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) )
 {
 }
@@ -3820,7 +3906,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 )
@@ -3831,6 +3917,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()
 
@@ -3855,6 +3942,7 @@ wxGrid::wxGrid( wxWindow *parent,
     m_rowMinHeights(GRID_HASH_SIZE)
 {
     Create();
+    SetBestFittingSize(size);
 }
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
@@ -3869,7 +3957,7 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id,
     m_rowMinHeights = wxLongToLongHashMap(GRID_HASH_SIZE) ;
 
     Create() ;
-
+    SetBestFittingSize(size);
 
     return true;
 }
@@ -3990,15 +4078,15 @@ void wxGrid::Create()
     wxColour lfg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
     wxColour lbg = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
 #endif
-    m_cornerLabelWin->SetDefaultForegroundColour(lfg);
-    m_cornerLabelWin->SetDefaultBackgroundColour(lbg);
-    m_rowLabelWin->SetDefaultForegroundColour(lfg);
-    m_rowLabelWin->SetDefaultBackgroundColour(lbg);
-    m_colLabelWin->SetDefaultForegroundColour(lfg);
-    m_colLabelWin->SetDefaultBackgroundColour(lbg);
+    m_cornerLabelWin->SetOwnForegroundColour(lfg);
+    m_cornerLabelWin->SetOwnBackgroundColour(lbg);
+    m_rowLabelWin->SetOwnForegroundColour(lfg);
+    m_rowLabelWin->SetOwnBackgroundColour(lbg);
+    m_colLabelWin->SetOwnForegroundColour(lfg);
+    m_colLabelWin->SetOwnBackgroundColour(lbg);
 
-    m_gridWin->SetDefaultForegroundColour(gfg);
-    m_gridWin->SetDefaultBackgroundColour(gbg);
+    m_gridWin->SetOwnForegroundColour(gfg);
+    m_gridWin->SetOwnBackgroundColour(gbg);
 
     Init();
 }
@@ -4139,6 +4227,7 @@ void wxGrid::Init()
     m_canDragRowSize = true;
     m_canDragColSize = true;
     m_canDragGridSize = true;
+    m_canDragCell = false;
     m_dragLastPos  = -1;
     m_dragRowOrCol = -1;
     m_isDragging = false;
@@ -4163,6 +4252,9 @@ void wxGrid::Init()
 
     m_extraWidth =
     m_extraHeight = 0;
+
+    m_scrollLineX = GRID_SCROLL_LINE_X;
+    m_scrollLineY = GRID_SCROLL_LINE_Y;
 }
 
 // ----------------------------------------------------------------------------
@@ -4292,7 +4384,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);
 
@@ -4312,16 +4404,16 @@ void wxGrid::CalcWindowSizes()
     int cw, ch;
     GetClientSize( &cw, &ch );
 
-    if ( m_cornerLabelWin->IsShown() )
+    if ( m_cornerLabelWin && m_cornerLabelWin->IsShown() )
         m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight );
 
-    if ( m_colLabelWin->IsShown() )
+    if (  m_colLabelWin && m_colLabelWin->IsShown() )
         m_colLabelWin->SetSize( m_rowLabelWidth, 0, cw-m_rowLabelWidth, m_colLabelHeight);
 
-    if ( m_rowLabelWin->IsShown() )
+    if ( m_rowLabelWin && m_rowLabelWin->IsShown() )
         m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, ch-m_colLabelHeight);
 
-    if ( m_gridWin->IsShown() )
+    if ( m_gridWin && m_gridWin->IsShown() )
         m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, cw-m_rowLabelWidth, ch-m_colLabelHeight);
 }
 
@@ -4674,7 +4766,7 @@ wxArrayInt wxGrid::CalcRowLabelsExposed( const wxRegion& reg )
             rowlabels.Add( row );
         }
 
-        iter++ ;
+        ++iter;
     }
 
     return rowlabels;
@@ -4725,7 +4817,7 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg )
             colLabels.Add( col );
         }
 
-        iter++ ;
+        ++iter;
     }
     return colLabels;
 }
@@ -4785,7 +4877,7 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg )
             }
         }
 
-        iter++;
+        ++iter;
     }
 
     return cellsExposed;
@@ -4832,6 +4924,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_ROW:
+                {
                     if ( (row = YToRow( y )) >= 0 )
                     {
                         if ( m_selection )
@@ -4843,6 +4936,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
                                                     event.MetaDown() );
                         }
                     }
+                }
+                break;
 
                 // default label to suppress warnings about "enumeration value
                 // 'xxx' not handled in switch
@@ -5054,6 +5149,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                 break;
 
                 case WXGRID_CURSOR_SELECT_COL:
+                {
                     if ( (col = XToCol( x )) >= 0 )
                     {
                         if ( m_selection )
@@ -5065,6 +5161,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                                                     event.MetaDown() );
                         }
                     }
+                }
+                break;
 
                 // default label to suppress warnings about "enumeration value
                 // 'xxx' not handled in switch
@@ -5346,6 +5444,7 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     XYToCell( x, y, coords );
 
     int cell_rows, cell_cols;
+    bool isFirstDrag = !m_isDragging;
     GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
     if ((cell_rows < 0) || (cell_cols < 0))
     {
@@ -5396,6 +5495,19 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                         m_selectingKeyboard = coords;
                     HighlightBlock ( m_selectingKeyboard, coords );
                 }
+                else if ( CanDragCell() )
+                {
+                    if ( isFirstDrag )
+                    {
+                        if ( m_selectingKeyboard == wxGridNoCellCoords)
+                            m_selectingKeyboard = coords;
+
+                        SendEvent( wxEVT_GRID_CELL_BEGIN_DRAG,
+                                   coords.GetRow(),
+                                   coords.GetCol(),
+                                   event );
+                    }
+                }
                 else
                 {
                     if ( !IsSelection() )
@@ -5543,11 +5655,17 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
 
         if ( XToEdgeOfCol(x) < 0  &&  YToEdgeOfRow(y) < 0 )
         {
-            SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
-                       coords.GetRow(),
-                       coords.GetCol(),
-                       event );
+            if ( !SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
+                             coords.GetRow(),
+                             coords.GetCol(),
+                             event ) )
+            {
+                // we want double click to select a cell and start editing
+                // (i.e. to behave in same way as sequence of two slow clicks):
+                m_waitForSlowClick = true;
+            }
         }
+
     }
 
 
@@ -6407,44 +6525,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;
         }
     }
@@ -6480,6 +6561,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&)
 {
 }
@@ -7074,8 +7197,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;
@@ -7099,6 +7224,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) );
@@ -7157,9 +7306,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;
 
@@ -7174,7 +7336,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() );
@@ -7182,7 +7344,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 );
@@ -7207,11 +7368,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,
@@ -7225,7 +7398,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() );
@@ -7234,7 +7407,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 );
@@ -7393,7 +7565,7 @@ void wxGrid::StringToLines( const wxString& value, wxArrayString& lines )
 }
 
 
-void wxGrid::GetTextBoxSize( wxDC& dc,
+void wxGrid::GetTextBoxSize( const wxDC& dc,
                              const wxArrayString& lines,
                              long *width, long *height )
 {
@@ -7442,6 +7614,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
@@ -7678,11 +7860,17 @@ void wxGrid::HideCellEditControl()
         editor->Show( false );
         editor->DecRef();
         attr->DecRef();
+
         m_gridWin->SetFocus();
+
         // refresh whole row to the right
         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 );
     }
 }
@@ -7978,7 +8166,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 )
@@ -7993,15 +8181,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();
         }
@@ -8865,14 +9053,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);
 }
 
 // ----------------------------------------------------------------------------
@@ -9080,9 +9278,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 )
@@ -9389,6 +9588,10 @@ void wxGrid::EnableDragGridSize( bool enable )
     m_canDragGridSize = enable;
 }
 
+void wxGrid::EnableDragCell( bool enable )
+{
+    m_canDragCell = enable;
+}
 
 void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows )
 {
@@ -9498,26 +9701,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;
 }
 
@@ -9537,7 +9744,7 @@ void wxGrid::SetRowMinimalAcceptableHeight( int height )
     if ( height<0 )
         return;
     m_minAcceptableRowHeight = height;
-};
+}
 
 int  wxGrid::GetColMinimalAcceptableWidth() const
 {
@@ -9728,8 +9935,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
@@ -9847,13 +10054,33 @@ wxSize wxGrid::DoGetBestSize() const
     width = self->SetOrCalcColumnSizes(true);
     height = self->SetOrCalcRowSizes(true);
 
+    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;
+    GetScrollPixelsPerUnit(&xpu, &ypu);
+    if (xpu)
+        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;
     if ( width > maxwidth ) width = maxwidth;
     if ( height > maxheight ) height = maxheight;
 
-    return wxSize( width, height );
+
+    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
+    // calculation.
+    // CacheBestSize(size);
+    return best;
 }
 
 void wxGrid::Fit()
@@ -10065,7 +10292,7 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
     }
     else
     {
-        rect = wxRect( 0, 0, 0, 0 );
+        rect = wxRect(0,0,0,0);
     }
 
     cellRect = CellToRect( bottomRight );
@@ -10140,7 +10367,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) );