]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/generic/grid.h
Rename web library to webview.
[wxWidgets.git] / include / wx / generic / grid.h
index 8611b6ad6cfe967cf875534d1931bb46b8c30fe8..c65d2e2f507548910c20c091d1272bb8e3be9624 100644 (file)
@@ -16,6 +16,8 @@
 
 #if wxUSE_GRID
 
+#include "wx/hashmap.h"
+
 #include "wx/scrolwin.h"
 
 // ----------------------------------------------------------------------------
@@ -42,11 +44,11 @@ extern WXDLLIMPEXP_DATA_ADV(const char) wxGridNameStr[];
 #define WXGRID_DEFAULT_SCROLLBAR_WIDTH        16
 
 // type names for grid table values
-#define wxGRID_VALUE_STRING     _T("string")
-#define wxGRID_VALUE_BOOL       _T("bool")
-#define wxGRID_VALUE_NUMBER     _T("long")
-#define wxGRID_VALUE_FLOAT      _T("double")
-#define wxGRID_VALUE_CHOICE     _T("choice")
+#define wxGRID_VALUE_STRING     wxT("string")
+#define wxGRID_VALUE_BOOL       wxT("bool")
+#define wxGRID_VALUE_NUMBER     wxT("long")
+#define wxGRID_VALUE_FLOAT      wxT("double")
+#define wxGRID_VALUE_CHOICE     wxT("choice")
 
 #define wxGRID_VALUE_TEXT wxGRID_VALUE_STRING
 #define wxGRID_VALUE_LONG wxGRID_VALUE_NUMBER
@@ -85,11 +87,14 @@ class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
 class WXDLLIMPEXP_FWD_CORE wxSpinCtrl;
 #endif
 
+class wxGridFixedIndicesSet;
+
 class wxGridOperations;
 class wxGridRowOperations;
 class wxGridColumnOperations;
 class wxGridDirectionOperations;
 
+
 // ----------------------------------------------------------------------------
 // macros
 // ----------------------------------------------------------------------------
@@ -105,16 +110,10 @@ class wxGridDirectionOperations;
 //     class is not documented and is not public at all
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_ADV wxGridCellWorker : public wxClientDataContainer
+class WXDLLIMPEXP_ADV wxGridCellWorker : public wxClientDataContainer, public wxRefCounter
 {
 public:
-    wxGridCellWorker() { m_nRef = 1; }
-
-    // this class is ref counted: it is created with ref count of 1, so
-    // calling DecRef() once will delete it. Calling IncRef() allows to lock
-    // it until the matching DecRef() is called
-    void IncRef() { m_nRef++; }
-    void DecRef() { if ( --m_nRef == 0 ) delete this; }
+    wxGridCellWorker() { }
 
     // interpret renderer parameters: arbitrary string whose interpretatin is
     // left to the derived classes
@@ -126,8 +125,6 @@ protected:
     virtual ~wxGridCellWorker();
 
 private:
-    size_t m_nRef;
-
     // suppress the stupid gcc warning about the class having private dtor and
     // no friends
     friend class wxGridCellWorkerDummyFriend;
@@ -168,129 +165,6 @@ public:
     virtual wxGridCellRenderer *Clone() const = 0;
 };
 
-// the default renderer for the cells containing string data
-class WXDLLIMPEXP_ADV wxGridCellStringRenderer : public wxGridCellRenderer
-{
-public:
-    // draw the string
-    virtual void Draw(wxGrid& grid,
-                      wxGridCellAttr& attr,
-                      wxDC& dc,
-                      const wxRect& rect,
-                      int row, int col,
-                      bool isSelected);
-
-    // return the string extent
-    virtual wxSize GetBestSize(wxGrid& grid,
-                               wxGridCellAttr& attr,
-                               wxDC& dc,
-                               int row, int col);
-
-    virtual wxGridCellRenderer *Clone() const
-        { return new wxGridCellStringRenderer; }
-
-protected:
-    // set the text colours before drawing
-    void SetTextColoursAndFont(const wxGrid& grid,
-                               const wxGridCellAttr& attr,
-                               wxDC& dc,
-                               bool isSelected);
-
-    // calc the string extent for given string/font
-    wxSize DoGetBestSize(const wxGridCellAttr& attr,
-                         wxDC& dc,
-                         const wxString& text);
-};
-
-// the default renderer for the cells containing numeric (long) data
-class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer
-{
-public:
-    // draw the string right aligned
-    virtual void Draw(wxGrid& grid,
-                      wxGridCellAttr& attr,
-                      wxDC& dc,
-                      const wxRect& rect,
-                      int row, int col,
-                      bool isSelected);
-
-    virtual wxSize GetBestSize(wxGrid& grid,
-                               wxGridCellAttr& attr,
-                               wxDC& dc,
-                               int row, int col);
-
-    virtual wxGridCellRenderer *Clone() const
-        { return new wxGridCellNumberRenderer; }
-
-protected:
-    wxString GetString(const wxGrid& grid, int row, int col);
-};
-
-class WXDLLIMPEXP_ADV wxGridCellFloatRenderer : public wxGridCellStringRenderer
-{
-public:
-    wxGridCellFloatRenderer(int width = -1, int precision = -1);
-
-    // get/change formatting parameters
-    int GetWidth() const { return m_width; }
-    void SetWidth(int width) { m_width = width; m_format.clear(); }
-    int GetPrecision() const { return m_precision; }
-    void SetPrecision(int precision) { m_precision = precision; m_format.clear(); }
-
-    // draw the string right aligned with given width/precision
-    virtual void Draw(wxGrid& grid,
-                      wxGridCellAttr& attr,
-                      wxDC& dc,
-                      const wxRect& rect,
-                      int row, int col,
-                      bool isSelected);
-
-    virtual wxSize GetBestSize(wxGrid& grid,
-                               wxGridCellAttr& attr,
-                               wxDC& dc,
-                               int row, int col);
-
-    // parameters string format is "width[,precision]"
-    virtual void SetParameters(const wxString& params);
-
-    virtual wxGridCellRenderer *Clone() const;
-
-protected:
-    wxString GetString(const wxGrid& grid, int row, int col);
-
-private:
-    // formatting parameters
-    int m_width,
-        m_precision;
-
-    wxString m_format;
-};
-
-// renderer for boolean fields
-class WXDLLIMPEXP_ADV wxGridCellBoolRenderer : public wxGridCellRenderer
-{
-public:
-    // draw a check mark or nothing
-    virtual void Draw(wxGrid& grid,
-                      wxGridCellAttr& attr,
-                      wxDC& dc,
-                      const wxRect& rect,
-                      int row, int col,
-                      bool isSelected);
-
-    // return the checkmark size
-    virtual wxSize GetBestSize(wxGrid& grid,
-                               wxGridCellAttr& attr,
-                               wxDC& dc,
-                               int row, int col);
-
-    virtual wxGridCellRenderer *Clone() const
-        { return new wxGridCellBoolRenderer; }
-
-private:
-    static wxSize ms_sizeCheckMark;
-};
-
 // ----------------------------------------------------------------------------
 // wxGridCellEditor:  This class is responsible for providing and manipulating
 // the in-place edit controls for the grid.  Instances of wxGridCellEditor
@@ -327,13 +201,28 @@ public:
     // version just fills it with background colour from the attribute
     virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
 
+
+    // The methods called by wxGrid when a cell is edited: first BeginEdit() is
+    // called, then EndEdit() is and if it returns true and if the change is
+    // not vetoed by a user-defined event handler, finally ApplyEdit() is called
+
     // Fetch the value from the table and prepare the edit control
     // to begin editing.  Set the focus to the edit control.
     virtual void BeginEdit(int row, int col, wxGrid* grid) = 0;
 
-    // Complete the editing of the current cell. Returns true if the value has
-    // changed.  If necessary, the control may be destroyed.
-    virtual bool EndEdit(int row, int col, wxGrid* grid) = 0;
+    // Returns false if nothing changed, otherwise returns true and return the
+    // new value in its string form in the newval output parameter.
+    //
+    // This should also store the new value in its real type internally so that
+    // it could be used by ApplyEdit() but it must not modify the grid as the
+    // change could still be vetoed.
+    virtual bool EndEdit(int row, int col, const wxGrid *grid,
+                         const wxString& oldval, wxString *newval) = 0;
+
+    // Complete the editing of the current cell by storing the value saved by
+    // the previous call to EndEdit() in the grid
+    virtual void ApplyEdit(int row, int col, wxGrid* grid) = 0;
+
 
     // Reset the value in the control back to its starting value
     virtual void Reset() = 0;
@@ -390,248 +279,90 @@ protected:
     // no friends
     friend class wxGridCellEditorDummyFriend;
 
-    DECLARE_NO_COPY_CLASS(wxGridCellEditor)
+    wxDECLARE_NO_COPY_CLASS(wxGridCellEditor);
 };
 
-#if wxUSE_TEXTCTRL
+// ----------------------------------------------------------------------------
+// wxGridHeaderRenderer and company: like wxGridCellRenderer but for headers
+// ----------------------------------------------------------------------------
 
-// the editor for string/text data
-class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor
+// Base class for corner window renderer: it is the simplest of all renderers
+// and only has a single function
+class WXDLLIMPEXP_ADV wxGridCornerHeaderRenderer
 {
 public:
-    wxGridCellTextEditor();
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-    virtual void SetSize(const wxRect& rect);
-
-    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(int row, int col, wxGrid* grid);
-
-    virtual void Reset();
-    virtual void StartingKey(wxKeyEvent& event);
-    virtual void HandleReturn(wxKeyEvent& event);
-
-    // parameters string format is "max_width"
-    virtual void SetParameters(const wxString& params);
-
-    virtual wxGridCellEditor *Clone() const
-        { return new wxGridCellTextEditor; }
-
-    // added GetValue so we can get the value which is in the control
-    virtual wxString GetValue() const;
-
-protected:
-    wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; }
-
-    // parts of our virtual functions reused by the derived classes
-    void DoCreate(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler,
-                  long style = 0);
-    void DoBeginEdit(const wxString& startValue);
-    void DoReset(const wxString& startValue);
-
-private:
-    size_t   m_maxChars;        // max number of chars allowed
-    wxString m_startValue;
-
-    DECLARE_NO_COPY_CLASS(wxGridCellTextEditor)
+    // Draw the border around the corner window.
+    virtual void DrawBorder(const wxGrid& grid,
+                            wxDC& dc,
+                            wxRect& rect) const = 0;
+
+    // make the dtor of a class with virtual functions virtual to avoid g++
+    // warnings, even though this class is not supposed to be used
+    // polymorphically
+    virtual ~wxGridCornerHeaderRenderer() { }
 };
 
-// the editor for numeric (long) data
-class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor
+
+// Base class for the row/column header cells renderers
+class WXDLLIMPEXP_ADV wxGridHeaderLabelsRenderer
+    : public wxGridCornerHeaderRenderer
 {
 public:
-    // allows to specify the range - if min == max == -1, no range checking is
-    // done
-    wxGridCellNumberEditor(int min = -1, int max = -1);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(int row, int col, wxGrid* grid);
-
-    virtual void Reset();
-    virtual void StartingKey(wxKeyEvent& event);
-
-    // parameters string format is "min,max"
-    virtual void SetParameters(const wxString& params);
-
-    virtual wxGridCellEditor *Clone() const
-        { return new wxGridCellNumberEditor(m_min, m_max); }
-
-    // added GetValue so we can get the value which is in the control
-    virtual wxString GetValue() const;
-
-protected:
-#if wxUSE_SPINCTRL
-    wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; }
-#endif
-
-    // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl
-    bool HasRange() const
-    {
-#if wxUSE_SPINCTRL
-        return m_min != m_max;
-#else
-        return false;
-#endif
-    }
-
-    // string representation of m_valueOld
-    wxString GetString() const
-        { return wxString::Format(_T("%ld"), m_valueOld); }
-
-private:
-    int m_min,
-        m_max;
+    // Draw header cell label
+    virtual void DrawLabel(const wxGrid& grid,
+                           wxDC& dc,
+                           const wxString& value,
+                           const wxRect& rect,
+                           int horizAlign,
+                           int vertAlign,
+                           int textOrientation) const;
+};
 
-    long m_valueOld;
+// Currently the row/column/corner renders don't need any methods other than
+// those already in wxGridHeaderLabelsRenderer but still define separate classes
+// for them for future extensions and also for better type safety (i.e. to
+// avoid inadvertently using a column header renderer for the row headers)
+class WXDLLIMPEXP_ADV wxGridRowHeaderRenderer
+    : public wxGridHeaderLabelsRenderer
+{
+};
 
-    DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor)
+class WXDLLIMPEXP_ADV wxGridColumnHeaderRenderer
+    : public wxGridHeaderLabelsRenderer
+{
 };
 
-// the editor for floating point numbers (double) data
-class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor
+// Also define the default renderers which are used by wxGridCellAttrProvider
+// by default
+class WXDLLIMPEXP_ADV wxGridRowHeaderRendererDefault
+    : public wxGridRowHeaderRenderer
 {
 public:
-    wxGridCellFloatEditor(int width = -1, int precision = -1);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(int row, int col, wxGrid* grid);
-
-    virtual void Reset();
-    virtual void StartingKey(wxKeyEvent& event);
-
-    virtual wxGridCellEditor *Clone() const
-        { return new wxGridCellFloatEditor(m_width, m_precision); }
-
-    // parameters string format is "width,precision"
-    virtual void SetParameters(const wxString& params);
-
-protected:
-    // string representation of m_valueOld
-    wxString GetString() const;
-
-private:
-    int m_width,
-        m_precision;
-    double m_valueOld;
-
-    DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor)
+    virtual void DrawBorder(const wxGrid& grid,
+                            wxDC& dc,
+                            wxRect& rect) const;
 };
 
-#endif // wxUSE_TEXTCTRL
-
-#if wxUSE_CHECKBOX
-
-// the editor for boolean data
-class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor
+// Column header cells renderers
+class WXDLLIMPEXP_ADV wxGridColumnHeaderRendererDefault
+    : public wxGridColumnHeaderRenderer
 {
 public:
-    wxGridCellBoolEditor() { }
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual void SetSize(const wxRect& rect);
-    virtual void Show(bool show, wxGridCellAttr *attr = NULL);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(int row, int col, wxGrid* grid);
-
-    virtual void Reset();
-    virtual void StartingClick();
-    virtual void StartingKey(wxKeyEvent& event);
-
-    virtual wxGridCellEditor *Clone() const
-        { return new wxGridCellBoolEditor; }
-
-    // added GetValue so we can get the value which is in the control, see
-    // also UseStringValues()
-    virtual wxString GetValue() const;
-
-    // set the string values returned by GetValue() for the true and false
-    // states, respectively
-    static void UseStringValues(const wxString& valueTrue = _T("1"),
-                                const wxString& valueFalse = wxEmptyString);
-
-    // return true if the given string is equal to the string representation of
-    // true value which we currently use
-    static bool IsTrueValue(const wxString& value);
-
-protected:
-    wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
-
-private:
-    bool m_startValue;
-
-    static wxString ms_stringValues[2];
-
-    DECLARE_NO_COPY_CLASS(wxGridCellBoolEditor)
+    virtual void DrawBorder(const wxGrid& grid,
+                            wxDC& dc,
+                            wxRect& rect) const;
 };
 
-#endif // wxUSE_CHECKBOX
-
-#if wxUSE_COMBOBOX
-
-// the editor for string data allowing to choose from the list of strings
-class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor
+// Header corner renderer
+class WXDLLIMPEXP_ADV wxGridCornerHeaderRendererDefault
+    : public wxGridCornerHeaderRenderer
 {
 public:
-    // if !allowOthers, user can't type a string not in choices array
-    wxGridCellChoiceEditor(size_t count = 0,
-                           const wxString choices[] = NULL,
-                           bool allowOthers = false);
-    wxGridCellChoiceEditor(const wxArrayString& choices,
-                           bool allowOthers = false);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(int row, int col, wxGrid* grid);
-
-    virtual void Reset();
-
-    // parameters string format is "item1[,item2[...,itemN]]"
-    virtual void SetParameters(const wxString& params);
-
-    virtual wxGridCellEditor *Clone() const;
-
-    // added GetValue so we can get the value which is in the control
-    virtual wxString GetValue() const;
-
-protected:
-    wxComboBox *Combo() const { return (wxComboBox *)m_control; }
-
-// DJC - (MAPTEK) you at least need access to m_choices if you
-//                wish to override this class
-protected:
-    wxString        m_startValue;
-    wxArrayString   m_choices;
-    bool            m_allowOthers;
-
-    DECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor)
+    virtual void DrawBorder(const wxGrid& grid,
+                            wxDC& dc,
+                            wxRect& rect) const;
 };
 
-#endif // wxUSE_COMBOBOX
 
 // ----------------------------------------------------------------------------
 // wxGridCellAttr: this class can be used to alter the cells appearance in
@@ -639,7 +370,7 @@ protected:
 // class may be returned by wxGridTable::GetAttr().
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_ADV wxGridCellAttr : public wxClientDataContainer
+class WXDLLIMPEXP_ADV wxGridCellAttr : public wxClientDataContainer, public wxRefCounter
 {
 public:
     enum wxAttrKind
@@ -657,8 +388,7 @@ public:
     {
         Init(attrDefault);
 
-        // MB: args used to be 0,0 here but wxALIGN_LEFT is 0
-        SetAlignment(-1, -1);
+        SetAlignment(wxALIGN_INVALID, wxALIGN_INVALID);
     }
 
     // VZ: considering the number of members wxGridCellAttr has now, this ctor
@@ -678,12 +408,6 @@ public:
     wxGridCellAttr *Clone() const;
     void MergeWith(wxGridCellAttr *mergefrom);
 
-    // this class is ref counted: it is created with ref count of 1, so
-    // calling DecRef() once will delete it. Calling IncRef() allows to lock
-    // it until the matching DecRef() is called
-    void IncRef() { m_nRef++; }
-    void DecRef() { if ( --m_nRef == 0 ) delete this; }
-
     // setters
     void SetTextColour(const wxColour& colText) { m_colText = colText; }
     void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; }
@@ -708,10 +432,13 @@ public:
     void SetKind(wxAttrKind kind) { m_attrkind = kind; }
 
     // accessors
-    bool HasTextColour() const { return m_colText.Ok(); }
-    bool HasBackgroundColour() const { return m_colBack.Ok(); }
-    bool HasFont() const { return m_font.Ok(); }
-    bool HasAlignment() const { return (m_hAlign != -1 || m_vAlign != -1); }
+    bool HasTextColour() const { return m_colText.IsOk(); }
+    bool HasBackgroundColour() const { return m_colBack.IsOk(); }
+    bool HasFont() const { return m_font.IsOk(); }
+    bool HasAlignment() const
+    {
+        return m_hAlign != wxALIGN_INVALID || m_vAlign != wxALIGN_INVALID;
+    }
     bool HasRenderer() const { return m_renderer != NULL; }
     bool HasEditor() const { return m_editor != NULL; }
     bool HasReadWriteMode() const { return m_isReadOnly != Unset; }
@@ -722,6 +449,15 @@ public:
     const wxColour& GetBackgroundColour() const;
     const wxFont& GetFont() const;
     void GetAlignment(int *hAlign, int *vAlign) const;
+
+    // unlike GetAlignment() which always overwrites its output arguments with
+    // the alignment values to use, falling back on default alignment if this
+    // attribute doesn't have any, this function will preserve the values of
+    // parameters on entry if the corresponding alignment is not set in this
+    // attribute meaning that they can be initialized to default alignment (and
+    // also that they must be initialized, unlike with GetAlignment())
+    void GetNonDefaultAlignment(int *hAlign, int *vAlign) const;
+
     void GetSize(int *num_rows, int *num_cols) const;
     bool GetOverflow() const
         { return m_overflow != SingleCell; }
@@ -761,9 +497,6 @@ private:
     void Init(wxGridCellAttr *attrDefault = NULL);
 
 
-    // the ref count - when it goes to 0, we die
-    size_t   m_nRef;
-
     wxColour m_colText,
              m_colBack;
     wxFont   m_font;
@@ -783,7 +516,7 @@ private:
     wxAttrKind m_attrkind;
 
     // use Clone() instead
-    DECLARE_NO_COPY_CLASS(wxGridCellAttr)
+    wxDECLARE_NO_COPY_CLASS(wxGridCellAttr);
 
     // suppress the stupid gcc warning about the class having private dtor and
     // no friends
@@ -823,12 +556,20 @@ public:
     void UpdateAttrRows( size_t pos, int numRows );
     void UpdateAttrCols( size_t pos, int numCols );
 
+
+    // get renderers for the given row/column header label and the corner
+    // window: unlike cell renderers, these objects are not reference counted
+    // and are never NULL so they are returned by reference
+    virtual const wxGridColumnHeaderRenderer& GetColumnHeaderRenderer(int col);
+    virtual const wxGridRowHeaderRenderer& GetRowHeaderRenderer(int row);
+    virtual const wxGridCornerHeaderRenderer& GetCornerRenderer();
+
 private:
     void InitData();
 
     wxGridCellAttrProviderData *m_data;
 
-    DECLARE_NO_COPY_CLASS(wxGridCellAttrProvider)
+    wxDECLARE_NO_COPY_CLASS(wxGridCellAttrProvider);
 };
 
 // ----------------------------------------------------------------------------
@@ -997,7 +738,7 @@ private:
     wxGridCellAttrProvider *m_attrProvider;
 
     DECLARE_ABSTRACT_CLASS(wxGridTableBase)
-    DECLARE_NO_COPY_CLASS(wxGridTableBase)
+    wxDECLARE_NO_COPY_CLASS(wxGridTableBase);
 };
 
 
@@ -1042,7 +783,7 @@ private:
     int m_comInt1;
     int m_comInt2;
 
-    DECLARE_NO_COPY_CLASS(wxGridTableMessage)
+    wxDECLARE_NO_COPY_CLASS(wxGridTableMessage);
 };
 
 
@@ -1067,14 +808,13 @@ class WXDLLIMPEXP_ADV wxGridStringTable : public wxGridTableBase
 public:
     wxGridStringTable();
     wxGridStringTable( int numRows, int numCols );
-    virtual ~wxGridStringTable();
 
     // these are pure virtual in wxGridTableBase
     //
-    int GetNumberRows();
-    int GetNumberCols();
-    wxString GetValue( int row, int col );
-    void SetValue( int row, int col, const wxString& s );
+    virtual int GetNumberRows() { return m_data.size(); }
+    virtual int GetNumberCols() { return m_numCols; }
+    virtual wxString GetValue( int row, int col );
+    virtual void SetValue( int row, int col, const wxString& s );
 
     // overridden functions from wxGridTableBase
     //
@@ -1094,6 +834,12 @@ public:
 private:
     wxGridStringArray m_data;
 
+    // notice that while we don't need to store the number of our rows as it's
+    // always equal to the size of m_data array, we do need to store the number
+    // of our columns as we can't retrieve it from m_data when the number of
+    // rows is 0 (see #10818)
+    int m_numCols;
+
     // These only get used if you set your own labels, otherwise the
     // GetRow/ColLabelValue functions return wxGridTableBase defaults
     //
@@ -1109,6 +855,39 @@ private:
 //  Grid view classes
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// wxGridSizesInfo stores information about sizes of the rows or columns.
+//
+// It assumes that most of the columns or rows have default size and so stores
+// the default size separately and uses a hash to map column or row numbers to
+// their non default size for those which don't have the default size.
+// ----------------------------------------------------------------------------
+
+// hash map to store positions as the keys and sizes as the values
+WX_DECLARE_HASH_MAP_WITH_DECL( unsigned, int, wxIntegerHash, wxIntegerEqual,
+                               wxUnsignedToIntHashMap, class WXDLLIMPEXP_ADV );
+
+struct WXDLLIMPEXP_ADV wxGridSizesInfo
+{
+    // default ctor, initialize m_sizeDefault and m_customSizes later
+    wxGridSizesInfo() { }
+
+    // ctor used by wxGrid::Get{Col,Row}Sizes()
+    wxGridSizesInfo(int defSize, const wxArrayInt& allSizes);
+
+    // default copy ctor, assignment operator and dtor are ok
+
+    // Get the size of the element with the given index
+    int GetSize(unsigned pos) const;
+
+
+    // default size
+    int m_sizeDefault;
+
+    // position -> size map containing all elements with non-default size
+    wxUnsignedToIntHashMap m_customSizes;
+};
+
 // ----------------------------------------------------------------------------
 // wxGrid
 // ----------------------------------------------------------------------------
@@ -1244,12 +1023,12 @@ public:
     void DrawTextRectangle( wxDC& dc, const wxString&, const wxRect&,
                             int horizontalAlignment = wxALIGN_LEFT,
                             int verticalAlignment = wxALIGN_TOP,
-                            int textOrientation = wxHORIZONTAL );
+                            int textOrientation = wxHORIZONTAL ) const;
 
     void DrawTextRectangle( wxDC& dc, const wxArrayString& lines, const wxRect&,
                             int horizontalAlignment = wxALIGN_LEFT,
                             int verticalAlignment = wxALIGN_TOP,
-                            int textOrientation = wxHORIZONTAL );
+                            int textOrientation = wxHORIZONTAL ) const;
 
 
     // Split a string containing newline characters into an array of
@@ -1414,19 +1193,42 @@ public:
     void     SetCellHighlightPenWidth(int width);
     void     SetCellHighlightROPenWidth(int width);
 
+
+    // interactive grid mouse operations control
+    // -----------------------------------------
+
+    // functions globally enabling row/column interactive resizing (enabled by
+    // default)
     void     EnableDragRowSize( bool enable = true );
     void     DisableDragRowSize() { EnableDragRowSize( false ); }
-    bool     CanDragRowSize() const { return m_canDragRowSize; }
+
     void     EnableDragColSize( bool enable = true );
     void     DisableDragColSize() { EnableDragColSize( false ); }
-    bool     CanDragColSize() const { return m_canDragColSize; }
+
+        // if interactive resizing is enabled, some rows/columns can still have
+        // fixed size
+    void DisableRowResize(int row) { DoDisableLineResize(row, m_setFixedRows); }
+    void DisableColResize(int col) { DoDisableLineResize(col, m_setFixedCols); }
+
+        // these functions return whether the given row/column can be
+        // effectively resized: for this interactive resizing must be enabled
+        // and this index must not have been passed to DisableRow/ColResize()
+    bool CanDragRowSize(int row) const
+        { return m_canDragRowSize && DoCanResizeLine(row, m_setFixedRows); }
+    bool CanDragColSize(int col) const
+        { return m_canDragColSize && DoCanResizeLine(col, m_setFixedCols); }
+
+    // interactive column reordering (disabled by default)
     void     EnableDragColMove( bool enable = true );
     void     DisableDragColMove() { EnableDragColMove( false ); }
     bool     CanDragColMove() const { return m_canDragColMove; }
+
+    // interactive resizing of grid cells (enabled by default)
     void     EnableDragGridSize(bool enable = true);
     void     DisableDragGridSize() { EnableDragGridSize(false); }
     bool     CanDragGridSize() const { return m_canDragGridSize; }
 
+    // interactive dragging of cells (disabled by default)
     void     EnableDragCell( bool enable = true );
     void     DisableDragCell() { EnableDragCell( false ); }
     bool     CanDragCell() const { return m_canDragCell; }
@@ -1466,6 +1268,12 @@ public:
     void     SetRowAttr(int row, wxGridCellAttr *attr);
     void     SetColAttr(int col, wxGridCellAttr *attr);
 
+    // the grid can cache attributes for the recently used cells (currently it
+    // only caches one attribute for the most recently used one) and might
+    // notice that its value in the attribute provider has changed -- if this
+    // happens, call this function to force it
+    void RefreshAttr(int row, int col);
+
     // returns the attribute we may modify in place: a new one if this cell
     // doesn't have any yet or the existing one if it does
     //
@@ -1485,8 +1293,10 @@ public:
     //
     int      GetDefaultRowSize() const;
     int      GetRowSize( int row ) const;
+    bool     IsRowShown(int row) const { return GetRowSize(row) != 0; }
     int      GetDefaultColSize() const;
     int      GetColSize( int col ) const;
+    bool     IsColShown(int col) const { return GetColSize(col) != 0; }
     wxColour GetDefaultCellBackgroundColour() const;
     wxColour GetCellBackgroundColour( int row, int col ) const;
     wxColour GetDefaultCellTextColour() const;
@@ -1497,7 +1307,24 @@ public:
     void     GetCellAlignment( int row, int col, int *horiz, int *vert ) const;
     bool     GetDefaultCellOverflow() const;
     bool     GetCellOverflow( int row, int col ) const;
-    void     GetCellSize( int row, int col, int *num_rows, int *num_cols ) const;
+
+    // this function returns 1 in num_rows and num_cols for normal cells,
+    // positive numbers for a cell spanning multiple columns/rows (as set with
+    // SetCellSize()) and _negative_ numbers corresponding to the offset of the
+    // top left cell of the span from this one for the other cells covered by
+    // this cell
+    //
+    // the return value is CellSpan_None, CellSpan_Main or CellSpan_Inside for
+    // each of these cases respectively
+    enum CellSpan
+    {
+        CellSpan_Inside = -1,
+        CellSpan_None = 0,
+        CellSpan_Main
+    };
+
+    CellSpan GetCellSize( int row, int col, int *num_rows, int *num_cols ) const;
+
     wxSize GetCellSize(const wxGridCellCoords& coords)
     {
         wxSize s;
@@ -1516,6 +1343,17 @@ public:
     void     HideCol(int col) { SetColSize(col, 0); }
     void     ShowCol(int col) { SetColSize(col, -1); }
 
+    // the row and column sizes can be also set all at once using
+    // wxGridSizesInfo which holds all of them at once
+
+    wxGridSizesInfo GetColSizes() const
+        { return wxGridSizesInfo(GetDefaultColSize(), m_colWidths); }
+    wxGridSizesInfo GetRowSizes() const
+        { return wxGridSizesInfo(GetDefaultRowSize(), m_rowHeights); }
+
+    void SetColSizes(const wxGridSizesInfo& sizeInfo);
+    void SetRowSizes(const wxGridSizesInfo& sizeInfo);
+
 
     // ------- columns (only, for now) reordering
 
@@ -1530,6 +1368,10 @@ public:
     // only the display and hit testing code really cares about display
     // positions at all
 
+    // set the positions of all columns at once (this method uses the same
+    // conventions as wxHeaderCtrl::SetColumnsOrder() for the order array)
+    void SetColumnsOrder(const wxArrayInt& order);
+
     // return the column index corresponding to the given (valid) position
     int GetColAt(int pos) const
     {
@@ -1747,11 +1589,22 @@ public:
     wxWindow* GetGridColLabelWindow() const    { return m_colWindow; }
     wxWindow* GetGridCornerLabelWindow() const { return (wxWindow*)m_cornerLabelWin; }
 
+    // This one can only be called if we are using the native header window
+    wxHeaderCtrl *GetGridColHeader() const
+    {
+        wxASSERT_MSG( m_useNativeHeader, "no column header window" );
+
+        // static_cast<> doesn't work without the full class declaration in
+        // view and we prefer to avoid adding more compile-time dependencies
+        // even at the cost of using reinterpret_cast<>
+        return reinterpret_cast<wxHeaderCtrl *>(m_colWindow);
+    }
+
     // Allow adjustment of scroll increment. The default is (15, 15).
-    void SetScrollLineX(int x) { m_scrollLineX = x; }
-    void SetScrollLineY(int y) { m_scrollLineY = y; }
-    int GetScrollLineX() const { return m_scrollLineX; }
-    int GetScrollLineY() const { return m_scrollLineY; }
+    void SetScrollLineX(int x) { m_xScrollPixelsPerLine = x; }
+    void SetScrollLineY(int y) { m_yScrollPixelsPerLine = y; }
+    int GetScrollLineX() const { return m_xScrollPixelsPerLine; }
+    int GetScrollLineY() const { return m_yScrollPixelsPerLine; }
 
     // ------- drag and drop
 #if wxUSE_DRAG_AND_DROP
@@ -1856,9 +1709,9 @@ public:
     void SetLabelAlignment( int orientation, int align )
         {
             if ( orientation == wxHORIZONTAL )
-                SetColLabelAlignment( align, -1 );
+                SetColLabelAlignment( align, wxALIGN_INVALID );
             else
-                SetRowLabelAlignment( align, -1 );
+                SetRowLabelAlignment( align, wxALIGN_INVALID );
         }
 
     int GetLabelAlignment( int orientation, int WXUNUSED(align) ) const
@@ -1944,6 +1797,9 @@ public:
            wxGRID_CHECKBOX,
            wxGRID_CHOICE,
            wxGRID_COMBOBOX };
+
+    wxDEPRECATED_INLINE(bool CanDragRowSize() const, return m_canDragRowSize; )
+    wxDEPRECATED_INLINE(bool CanDragColSize() const, return m_canDragColSize; )
 #endif // WXWIN_COMPATIBILITY_2_8
 
 
@@ -1970,16 +1826,6 @@ protected:
     // wxGridColLabelWindow, use accessors below when the real type matters
     wxWindow *m_colWindow;
 
-    wxHeaderCtrl *GetColHeader() const
-    {
-        wxASSERT_MSG( m_useNativeHeader, "no column header window" );
-
-        // static_cast<> doesn't work without the full class declaration in
-        // view and we prefer to avoid adding more compile-time dependencies
-        // even at the cost of using reinterpret_cast<>
-        return reinterpret_cast<wxHeaderCtrl *>(m_colWindow);
-    }
-
     wxGridColLabelWindow *GetColLabelWindow() const
     {
         wxASSERT_MSG( !m_useNativeHeader, "no column label window" );
@@ -2206,9 +2052,6 @@ protected:
     bool       m_editable;              // applies to whole grid
     bool       m_cellEditCtrlEnabled;   // is in-place edit currently shown?
 
-    int m_scrollLineX; // X scroll increment
-    int m_scrollLineY; // Y scroll increment
-
     void Init();        // common part of all ctors
     void Create();
     void CreateColumnWindow();
@@ -2221,16 +2064,25 @@ protected:
     // it was processed (but not vetoed) and 0 if it wasn't processed
     int SendEvent(const wxEventType evtType,
                   int row, int col,
-                  wxMouseEvent& e);
+                  const wxMouseEvent& e);
     int SendEvent(const wxEventType evtType,
                   const wxGridCellCoords& coords,
-                  wxMouseEvent& e)
+                  const wxMouseEvent& e)
         { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
-    int SendEvent(const wxEventType evtType, int row, int col);
-    int SendEvent(const wxEventType evtType, const wxGridCellCoords& coords)
-        { return SendEvent(evtType, coords.GetRow(), coords.GetCol()); }
-    int SendEvent(const wxEventType evtType)
-        { return SendEvent(evtType, m_currentCellCoords); }
+    int SendEvent(const wxEventType evtType,
+                  int row, int col,
+                  const wxString& s = wxString());
+    int SendEvent(const wxEventType evtType,
+                  const wxGridCellCoords& coords,
+                  const wxString& s = wxString())
+        { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), s); }
+    int SendEvent(const wxEventType evtType, const wxString& s = wxString())
+        { return SendEvent(evtType, m_currentCellCoords, s); }
+
+    // send wxEVT_GRID_{ROW,COL}_SIZE
+    void SendGridSizeEvent(wxEventType type,
+                           int row, int col,
+                           const wxMouseEvent& mouseEv);
 
     void OnPaint( wxPaintEvent& );
     void OnSize( wxSizeEvent& );
@@ -2269,10 +2121,12 @@ protected:
     friend class wxGridColLabelWindow;
     friend class wxGridRowLabelWindow;
     friend class wxGridWindow;
+    friend class wxGridHeaderRenderer;
 
     friend class wxGridHeaderCtrl;
 
 private:
+
     // implement wxScrolledWindow method to return m_gridWin size
     virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
 
@@ -2289,10 +2143,9 @@ private:
     // the sorting indicator to effectively show
     void UpdateColumnSortingIndicator(int col);
 
-    // update column right positions after their order changed (does nothing if
-    // we only use the default widths as in this case m_colRights is not used
-    // neither)
-    void UpdateColumnRights();
+    // update the grid after changing the columns order (common part of
+    // SetColPos() and ResetColPos())
+    void RefreshAfterColPosChange();
 
 
     // return the position (not index) of the column at the given logical pixel
@@ -2346,14 +2199,14 @@ private:
     void DoUpdateResizeColWidth(int w);
     void DoStartMoveCol(int col);
 
-    void DoEndDragResizeRow();
-    void DoEndDragResizeCol(wxMouseEvent *event = NULL);
+    void DoEndDragResizeRow(const wxMouseEvent& event);
+    void DoEndDragResizeCol(const wxMouseEvent& event);
     void DoEndMoveCol(int pos);
 
 
     // common implementations of methods defined for both rows and columns
     void DeselectLine(int line, const wxGridOperations& oper);
-    void DoEndDragResizeLine(const wxGridOperations& oper);
+    bool DoEndDragResizeLine(const wxGridOperations& oper);
     int PosToLinePos(int pos, bool clipToMinMax,
                      const wxGridOperations& oper) const;
     int PosToLine(int pos, bool clipToMinMax,
@@ -2375,9 +2228,25 @@ private:
     bool DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
                        int num, bool updateLabels);
 
+    // common part of Set{Col,Row}Sizes
+    void DoSetSizes(const wxGridSizesInfo& sizeInfo,
+                    const wxGridOperations& oper);
+
+    // common part of Disable{Row,Col}Resize and CanDrag{Row,Col}Size
+    void DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed);
+    bool DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const;
+
+
+
+    // these sets contain the indices of fixed, i.e. non-resizable
+    // interactively, grid rows or columns and are NULL if there are no fixed
+    // elements (which is the default)
+    wxGridFixedIndicesSet *m_setFixedRows,
+                          *m_setFixedCols;
+
     DECLARE_DYNAMIC_CLASS( wxGrid )
     DECLARE_EVENT_TABLE()
-    DECLARE_NO_COPY_CLASS(wxGrid)
+    wxDECLARE_NO_COPY_CLASS(wxGrid);
 };
 
 // ----------------------------------------------------------------------------
@@ -2397,7 +2266,7 @@ public:
     // more than once
     void Create(wxGrid *grid)
     {
-        wxASSERT_MSG( !m_grid, _T("shouldn't be called more than once") );
+        wxASSERT_MSG( !m_grid, wxT("shouldn't be called more than once") );
 
         Init(grid);
     }
@@ -2418,7 +2287,7 @@ private:
 
     wxGrid *m_grid;
 
-    DECLARE_NO_COPY_CLASS(wxGridUpdateLocker)
+    wxDECLARE_NO_COPY_CLASS(wxGridUpdateLocker);
 };
 
 // ----------------------------------------------------------------------------
@@ -2451,7 +2320,7 @@ public:
 
     // explicitly specifying inline allows gcc < 3.4 to
     // handle the deprecation attribute even in the constructor.
-    wxDEPRECATED( inline
+    wxDEPRECATED_CONSTRUCTOR(
     wxGridEvent(int id,
                 wxEventType type,
                 wxObject* obj,
@@ -2512,7 +2381,7 @@ public:
         SetEventObject(obj);
     }
 
-    wxDEPRECATED( inline
+    wxDEPRECATED_CONSTRUCTOR(
     wxGridSizeEvent(int id,
                     wxEventType type,
                     wxObject* obj,
@@ -2570,7 +2439,7 @@ public:
         SetEventObject(obj);
     }
 
-    wxDEPRECATED( inline
+    wxDEPRECATED_CONSTRUCTOR(
     wxGridRangeSelectEvent(int id,
                            wxEventType type,
                            wxObject* obj,
@@ -2642,26 +2511,26 @@ private:
 };
 
 
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_LEFT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_RIGHT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_LEFT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_RIGHT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_LEFT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_RIGHT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_LEFT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_RIGHT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_ROW_SIZE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SIZE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_RANGE_SELECT;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_SELECT_CELL;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_SHOWN;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_HIDDEN;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_CREATED;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_BEGIN_DRAG;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_MOVE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SORT;
-
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_LEFT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_RIGHT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_ROW_SIZE, wxGridSizeEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_SIZE, wxGridSizeEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_CHANGING, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_CHANGED, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_SELECT_CELL, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_SHOWN, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_BEGIN_DRAG, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_MOVE, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_SORT, wxGridEvent );
 
 typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
 typedef void (wxEvtHandler::*wxGridSizeEventFunction)(wxGridSizeEvent&);
@@ -2669,16 +2538,16 @@ typedef void (wxEvtHandler::*wxGridRangeSelectEventFunction)(wxGridRangeSelectEv
 typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreatedEvent&);
 
 #define wxGridEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridEventFunction, func)
 
 #define wxGridSizeEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridSizeEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridSizeEventFunction, func)
 
 #define wxGridRangeSelectEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridRangeSelectEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridRangeSelectEventFunction, func)
 
 #define wxGridEditorCreatedEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridEditorCreatedEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridEditorCreatedEventFunction, func)
 
 #define wx__DECLARE_GRIDEVT(evt, id, fn) \
     wx__DECLARE_EVT1(wxEVT_GRID_ ## evt, id, wxGridEventHandler(fn))
@@ -2705,7 +2574,8 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
 #define EVT_GRID_CMD_COL_MOVE(id, fn)            wx__DECLARE_GRIDEVT(COL_MOVE, id, fn)
 #define EVT_GRID_CMD_COL_SORT(id, fn)            wx__DECLARE_GRIDEVT(COL_SORT, id, fn)
 #define EVT_GRID_CMD_RANGE_SELECT(id, fn)        wx__DECLARE_GRIDRANGESELEVT(RANGE_SELECT, id, fn)
-#define EVT_GRID_CMD_CELL_CHANGE(id, fn)         wx__DECLARE_GRIDEVT(CELL_CHANGE, id, fn)
+#define EVT_GRID_CMD_CELL_CHANGING(id, fn)       wx__DECLARE_GRIDEVT(CELL_CHANGING, id, fn)
+#define EVT_GRID_CMD_CELL_CHANGED(id, fn)        wx__DECLARE_GRIDEVT(CELL_CHANGED, id, fn)
 #define EVT_GRID_CMD_SELECT_CELL(id, fn)         wx__DECLARE_GRIDEVT(SELECT_CELL, id, fn)
 #define EVT_GRID_CMD_EDITOR_SHOWN(id, fn)        wx__DECLARE_GRIDEVT(EDITOR_SHOWN, id, fn)
 #define EVT_GRID_CMD_EDITOR_HIDDEN(id, fn)       wx__DECLARE_GRIDEVT(EDITOR_HIDDEN, id, fn)
@@ -2727,22 +2597,34 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
 #define EVT_GRID_COL_MOVE(fn)            EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn)
 #define EVT_GRID_COL_SORT(fn)            EVT_GRID_CMD_COL_SORT(wxID_ANY, fn)
 #define EVT_GRID_RANGE_SELECT(fn)        EVT_GRID_CMD_RANGE_SELECT(wxID_ANY, fn)
-#define EVT_GRID_CELL_CHANGE(fn)         EVT_GRID_CMD_CELL_CHANGE(wxID_ANY, fn)
+#define EVT_GRID_CELL_CHANGING(fn)       EVT_GRID_CMD_CELL_CHANGING(wxID_ANY, fn)
+#define EVT_GRID_CELL_CHANGED(fn)        EVT_GRID_CMD_CELL_CHANGED(wxID_ANY, fn)
 #define EVT_GRID_SELECT_CELL(fn)         EVT_GRID_CMD_SELECT_CELL(wxID_ANY, fn)
 #define EVT_GRID_EDITOR_SHOWN(fn)        EVT_GRID_CMD_EDITOR_SHOWN(wxID_ANY, fn)
 #define EVT_GRID_EDITOR_HIDDEN(fn)       EVT_GRID_CMD_EDITOR_HIDDEN(wxID_ANY, fn)
 #define EVT_GRID_EDITOR_CREATED(fn)      EVT_GRID_CMD_EDITOR_CREATED(wxID_ANY, fn)
 #define EVT_GRID_CELL_BEGIN_DRAG(fn)     EVT_GRID_CMD_CELL_BEGIN_DRAG(wxID_ANY, fn)
 
+// we used to have a single wxEVT_GRID_CELL_CHANGE event but it was split into
+// wxEVT_GRID_CELL_CHANGING and CHANGED ones in wx 2.9.0, however the CHANGED
+// is basically the same as the old CHANGE event so we keep the name for
+// compatibility
+#if WXWIN_COMPATIBILITY_2_8
+    #define wxEVT_GRID_CELL_CHANGE wxEVT_GRID_CELL_CHANGED
+
+    #define EVT_GRID_CMD_CELL_CHANGE EVT_GRID_CMD_CELL_CHANGED
+    #define EVT_GRID_CELL_CHANGE EVT_GRID_CELL_CHANGED
+#endif // WXWIN_COMPATIBILITY_2_8
+
 #if 0  // TODO: implement these ?  others ?
 
 extern const int wxEVT_GRID_CREATE_CELL;
 extern const int wxEVT_GRID_CHANGE_LABELS;
 extern const int wxEVT_GRID_CHANGE_SEL_LABEL;
 
-#define EVT_GRID_CREATE_CELL(fn)      DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CREATE_CELL,      wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
-#define EVT_GRID_CHANGE_LABELS(fn)    DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_LABELS,    wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
-#define EVT_GRID_CHANGE_SEL_LABEL(fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_SEL_LABEL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CREATE_CELL(fn)      wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CREATE_CELL,      wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CHANGE_LABELS(fn)    wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_LABELS,    wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CHANGE_SEL_LABEL(fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_SEL_LABEL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
 
 #endif