]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/generic/grid.h
fix wxDEFINE_EVENT_REFERENCE in wxEVENTS_COMPATIBILITY_2_8 case
[wxWidgets.git] / include / wx / generic / grid.h
index 546bf7ea26b2603cce1883ff69854f1f86634a13..a83b0d857e3f5b19b509d62f8461f3f84991428e 100644 (file)
@@ -22,7 +22,7 @@
 // constants
 // ----------------------------------------------------------------------------
 
 // constants
 // ----------------------------------------------------------------------------
 
-extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxGridNameStr[];
+extern WXDLLIMPEXP_DATA_ADV(const char) wxGridNameStr[];
 
 // Default parameters for wxGrid
 //
 
 // Default parameters for wxGrid
 //
@@ -77,6 +77,7 @@ class WXDLLIMPEXP_FWD_ADV wxGridWindow;
 class WXDLLIMPEXP_FWD_ADV wxGridTypeRegistry;
 class WXDLLIMPEXP_FWD_ADV wxGridSelection;
 
 class WXDLLIMPEXP_FWD_ADV wxGridTypeRegistry;
 class WXDLLIMPEXP_FWD_ADV wxGridSelection;
 
+class WXDLLIMPEXP_FWD_CORE wxHeaderCtrl;
 class WXDLLIMPEXP_FWD_CORE wxCheckBox;
 class WXDLLIMPEXP_FWD_CORE wxComboBox;
 class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
 class WXDLLIMPEXP_FWD_CORE wxCheckBox;
 class WXDLLIMPEXP_FWD_CORE wxComboBox;
 class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
@@ -89,6 +90,7 @@ class wxGridRowOperations;
 class wxGridColumnOperations;
 class wxGridDirectionOperations;
 
 class wxGridColumnOperations;
 class wxGridDirectionOperations;
 
+
 // ----------------------------------------------------------------------------
 // macros
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // macros
 // ----------------------------------------------------------------------------
@@ -167,129 +169,6 @@ public:
     virtual wxGridCellRenderer *Clone() const = 0;
 };
 
     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
 // ----------------------------------------------------------------------------
 // wxGridCellEditor:  This class is responsible for providing and manipulating
 // the in-place edit controls for the grid.  Instances of wxGridCellEditor
@@ -326,13 +205,26 @@ public:
     // version just fills it with background colour from the attribute
     virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
 
     // 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;
 
     // 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().
+    virtual bool EndEdit(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;
 
     // Reset the value in the control back to its starting value
     virtual void Reset() = 0;
@@ -392,245 +284,6 @@ protected:
     DECLARE_NO_COPY_CLASS(wxGridCellEditor)
 };
 
     DECLARE_NO_COPY_CLASS(wxGridCellEditor)
 };
 
-#if wxUSE_TEXTCTRL
-
-// the editor for string/text data
-class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor
-{
-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)
-};
-
-// the editor for numeric (long) data
-class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor
-{
-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;
-
-    long m_valueOld;
-
-    DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor)
-};
-
-// the editor for floating point numbers (double) data
-class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor
-{
-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)
-};
-
-#endif // wxUSE_TEXTCTRL
-
-#if wxUSE_CHECKBOX
-
-// the editor for boolean data
-class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor
-{
-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)
-};
-
-#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
-{
-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)
-};
-
-#endif // wxUSE_COMBOBOX
 
 // ----------------------------------------------------------------------------
 // wxGridCellAttr: this class can be used to alter the cells appearance in
 
 // ----------------------------------------------------------------------------
 // wxGridCellAttr: this class can be used to alter the cells appearance in
@@ -913,12 +566,15 @@ public:
     // would break the existing code overriding them, so instead we provide
     // these const synonyms which can be used from const-correct code
     int GetRowsCount() const
     // would break the existing code overriding them, so instead we provide
     // these const synonyms which can be used from const-correct code
     int GetRowsCount() const
-        { return wx_const_cast(wxGridTableBase *, this)->GetNumberRows(); }
+        { return const_cast<wxGridTableBase *>(this)->GetNumberRows(); }
     int GetColsCount() const
     int GetColsCount() const
-        { return wx_const_cast(wxGridTableBase *, this)->GetNumberCols(); }
+        { return const_cast<wxGridTableBase *>(this)->GetNumberCols(); }
 
 
 
 
-    virtual bool IsEmptyCell( int row, int col ) = 0;
+    virtual bool IsEmptyCell( int row, int col )
+    {
+        return GetValue(row, col).empty();
+    }
 
     bool IsEmpty(const wxGridCellCoords& coord)
     {
 
     bool IsEmpty(const wxGridCellCoords& coord)
     {
@@ -1071,7 +727,6 @@ public:
     int GetNumberCols();
     wxString GetValue( int row, int col );
     void SetValue( int row, int col, const wxString& s );
     int GetNumberCols();
     wxString GetValue( int row, int col );
     void SetValue( int row, int col, const wxString& s );
-    bool IsEmptyCell( int row, int col );
 
     // overridden functions from wxGridTableBase
     //
 
     // overridden functions from wxGridTableBase
     //
@@ -1126,14 +781,19 @@ public:
     // ------------------------
 
     // ctor and Create() create the grid window, as with the other controls
     // ------------------------
 
     // ctor and Create() create the grid window, as with the other controls
-    wxGrid();
+    wxGrid() { Init(); }
 
     wxGrid(wxWindow *parent,
             wxWindowID id,
             const wxPoint& pos = wxDefaultPosition,
             const wxSize& size = wxDefaultSize,
             long style = wxWANTS_CHARS,
 
     wxGrid(wxWindow *parent,
             wxWindowID id,
             const wxPoint& pos = wxDefaultPosition,
             const wxSize& size = wxDefaultSize,
             long style = wxWANTS_CHARS,
-            const wxString& name = wxGridNameStr);
+            const wxString& name = wxGridNameStr)
+    {
+        Init();
+
+        Create(parent, id, pos, size, style, name);
+    }
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
@@ -1305,6 +965,12 @@ public:
     wxGridCellCoords XYToCell(const wxPoint& pos) const
         { return XYToCell(pos.x, pos.y); }
 
     wxGridCellCoords XYToCell(const wxPoint& pos) const
         { return XYToCell(pos.x, pos.y); }
 
+    // these functions return the index of the row/columns corresponding to the
+    // given logical position in pixels
+    //
+    // if clipToMinMax is false (default, wxNOT_FOUND is returned if the
+    // position is outside any row/column, otherwise the first/last element is
+    // returned in this case
     int  YToRow( int y, bool clipToMinMax = false ) const;
     int  XToCol( int x, bool clipToMinMax = false ) const;
 
     int  YToRow( int y, bool clipToMinMax = false ) const;
     int  XToCol( int x, bool clipToMinMax = false ) const;
 
@@ -1377,7 +1043,13 @@ public:
     int      GetCellHighlightPenWidth() const { return m_cellHighlightPenWidth; }
     int      GetCellHighlightROPenWidth() const { return m_cellHighlightROPenWidth; }
 
     int      GetCellHighlightPenWidth() const { return m_cellHighlightPenWidth; }
     int      GetCellHighlightROPenWidth() const { return m_cellHighlightROPenWidth; }
 
-    void     SetUseNativeColLabels( bool native = true );
+    // this one will use wxHeaderCtrl for the column labels
+    void UseNativeColHeader(bool native = true);
+
+    // this one will still draw them manually but using the native renderer
+    // instead of using the same appearance as for the row labels
+    void SetUseNativeColLabels( bool native = true );
+
     void     SetRowLabelSize( int width );
     void     SetColLabelSize( int height );
     void     HideRowLabels() { SetRowLabelSize( 0 ); }
     void     SetRowLabelSize( int width );
     void     SetColLabelSize( int height );
     void     HideRowLabels() { SetRowLabelSize( 0 ); }
@@ -1465,8 +1137,10 @@ public:
     //
     int      GetDefaultRowSize() const;
     int      GetRowSize( int row ) const;
     //
     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;
     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;
     wxColour GetDefaultCellBackgroundColour() const;
     wxColour GetCellBackgroundColour( int row, int col ) const;
     wxColour GetDefaultCellTextColour() const;
@@ -1485,39 +1159,68 @@ public:
         return s;
     }
 
         return s;
     }
 
+    // ------ row and col sizes
     void     SetDefaultRowSize( int height, bool resizeExistingRows = false );
     void     SetRowSize( int row, int height );
     void     SetDefaultRowSize( int height, bool resizeExistingRows = false );
     void     SetRowSize( int row, int height );
-    void     SetDefaultColSize( int width, bool resizeExistingCols = false );
+    void     HideRow(int row) { SetRowSize(row, 0); }
+    void     ShowRow(int row) { SetRowSize(row, -1); }
 
 
+    void     SetDefaultColSize( int width, bool resizeExistingCols = false );
     void     SetColSize( int col, int width );
     void     SetColSize( int col, int width );
+    void     HideCol(int col) { SetColSize(col, 0); }
+    void     ShowCol(int col) { SetColSize(col, -1); }
 
 
-    //Column positions
-    int GetColAt( int colPos ) const
+
+    // ------- columns (only, for now) reordering
+
+    // columns index <-> positions mapping: by default, the position of the
+    // column is the same as its index, but the columns can also be reordered
+    // (either by calling SetColPos() explicitly or by the user dragging the
+    // columns around) in which case their indices don't correspond to their
+    // positions on display any longer
+    //
+    // internally we always work with indices except for the functions which
+    // have "Pos" in their names (and which work with columns, not pixels) and
+    // 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
     {
     {
-        if ( m_colAt.IsEmpty() )
-            return colPos;
-        else
-            return m_colAt[colPos];
+        return m_colAt.empty() ? pos : m_colAt[pos];
     }
 
     }
 
-    void SetColPos( int colID, int newPos );
+    // reorder the columns so that the column with the given index is now shown
+    // as the position pos
+    void SetColPos(int idx, int pos);
 
 
-    int GetColPos( int colID ) const
+    // return the position at which the column with the given index is
+    // displayed: notice that this is a slow operation as we don't maintain the
+    // reverse mapping currently
+    int GetColPos(int idx) const
     {
         if ( m_colAt.IsEmpty() )
     {
         if ( m_colAt.IsEmpty() )
-            return colID;
-        else
+            return idx;
+
+        for ( int i = 0; i < m_numCols; i++ )
         {
         {
-            for ( int i = 0; i < m_numCols; i++ )
-            {
-                if ( m_colAt[i] == colID )
-                    return i;
-            }
+            if ( m_colAt[i] == idx )
+                return i;
         }
 
         }
 
-        return -1;
+        wxFAIL_MSG( "invalid column index" );
+
+        return wxNOT_FOUND;
     }
 
     }
 
+    // reset the columns positions to the default order
+    void ResetColPos();
+
+
     // automatically size the column or row to fit to its contents, if
     // setAsMin is true, this optimal width will also be set as minimal width
     // for this column
     // automatically size the column or row to fit to its contents, if
     // setAsMin is true, this optimal width will also be set as minimal width
     // for this column
@@ -1699,9 +1402,20 @@ public:
     // Accessors for component windows
     wxWindow* GetGridWindow() const            { return (wxWindow*)m_gridWin; }
     wxWindow* GetGridRowLabelWindow() const    { return (wxWindow*)m_rowLabelWin; }
     // Accessors for component windows
     wxWindow* GetGridWindow() const            { return (wxWindow*)m_gridWin; }
     wxWindow* GetGridRowLabelWindow() const    { return (wxWindow*)m_rowLabelWin; }
-    wxWindow* GetGridColLabelWindow() const    { return (wxWindow*)m_colLabelWin; }
+    wxWindow* GetGridColLabelWindow() const    { return m_colWindow; }
     wxWindow* GetGridCornerLabelWindow() const { return (wxWindow*)m_cornerLabelWin; }
 
     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; }
     // Allow adjustment of scroll increment. The default is (15, 15).
     void SetScrollLineX(int x) { m_scrollLineX = x; }
     void SetScrollLineY(int y) { m_scrollLineY = y; }
@@ -1714,6 +1428,31 @@ public:
 #endif // wxUSE_DRAG_AND_DROP
 
 
 #endif // wxUSE_DRAG_AND_DROP
 
 
+    // ------- sorting support
+
+    // wxGrid doesn't support sorting on its own but it can indicate the sort
+    // order in the column header (currently only if native header control is
+    // used though)
+
+    // return the column currently displaying the sort indicator or wxNOT_FOUND
+    // if none
+    int GetSortingColumn() const { return m_sortCol; }
+
+    // return true if this column is currently used for sorting
+    bool IsSortingBy(int col) const { return GetSortingColumn() == col; }
+
+    // return the current sorting order (on GetSortingColumn()): true for
+    // ascending sort and false for descending; it doesn't make sense to call
+    // it if GetSortingColumn() returns wxNOT_FOUND
+    bool IsSortOrderAscending() const { return m_sortIsAscending; }
+
+    // set the sorting column (or unsets any existing one if wxNOT_FOUND) and
+    // the order in which to sort
+    void SetSortingColumn(int col, bool ascending = true);
+
+    // unset any existing sorting column
+    void UnsetSortingColumn() { SetSortingColumn(wxNOT_FOUND); }
+
 #ifdef WXWIN_COMPATIBILITY_2_8
     // ------ For compatibility with previous wxGrid only...
     //
 #ifdef WXWIN_COMPATIBILITY_2_8
     // ------ For compatibility with previous wxGrid only...
     //
@@ -1728,12 +1467,10 @@ public:
             int x, int y, int w = wxDefaultCoord, int h = wxDefaultCoord,
             long style = wxWANTS_CHARS,
             const wxString& name = wxPanelNameStr )
             int x, int y, int w = wxDefaultCoord, int h = wxDefaultCoord,
             long style = wxWANTS_CHARS,
             const wxString& name = wxPanelNameStr )
-        : wxScrolledWindow( parent, wxID_ANY, wxPoint(x,y), wxSize(w,h),
-                            (style|wxWANTS_CHARS), name )
-        {
-            InitVars();
-            Create();
-        }
+    {
+        Init();
+        Create(parent, wxID_ANY, wxPoint(x, y), wxSize(w, h), style, name);
+    }
 
     void SetCellValue( const wxString& val, int row, int col )
         { SetCellValue( row, col, val ); }
 
     void SetCellValue( const wxString& val, int row, int col )
         { SetCellValue( row, col, val ); }
@@ -1894,9 +1631,20 @@ protected:
     bool m_created;
 
     wxGridWindow             *m_gridWin;
     bool m_created;
 
     wxGridWindow             *m_gridWin;
-    wxGridRowLabelWindow     *m_rowLabelWin;
-    wxGridColLabelWindow     *m_colLabelWin;
     wxGridCornerLabelWindow  *m_cornerLabelWin;
     wxGridCornerLabelWindow  *m_cornerLabelWin;
+    wxGridRowLabelWindow     *m_rowLabelWin;
+
+    // the real type of the column window depends on m_useNativeHeader value:
+    // if it is true, its dynamic type is wxHeaderCtrl, otherwise it is
+    // wxGridColLabelWindow, use accessors below when the real type matters
+    wxWindow *m_colWindow;
+
+    wxGridColLabelWindow *GetColLabelWindow() const
+    {
+        wxASSERT_MSG( !m_useNativeHeader, "no column label window" );
+
+        return reinterpret_cast<wxGridColLabelWindow *>(m_colWindow);
+    }
 
     wxGridTableBase          *m_table;
     bool                      m_ownTable;
 
     wxGridTableBase          *m_table;
     bool                      m_ownTable;
@@ -1944,7 +1692,11 @@ protected:
     wxArrayInt m_colWidths;
     wxArrayInt m_colRights;
 
     wxArrayInt m_colWidths;
     wxArrayInt m_colRights;
 
-    bool m_nativeColumnLabels;
+    int m_sortCol;
+    bool m_sortIsAscending;
+
+    bool m_useNativeHeader,
+         m_nativeColumnLabels;
 
     // get the col/row coords
     int GetColWidth(int col) const;
 
     // get the col/row coords
     int GetColWidth(int col) const;
@@ -2078,7 +1830,6 @@ protected:
 
     //Column positions
     wxArrayInt m_colAt;
 
     //Column positions
     wxArrayInt m_colAt;
-    int m_moveToCol;
 
     bool    m_canDragRowSize;
     bool    m_canDragColSize;
 
     bool    m_canDragRowSize;
     bool    m_canDragColSize;
@@ -2117,9 +1868,9 @@ protected:
     int m_scrollLineX; // X scroll increment
     int m_scrollLineY; // Y scroll increment
 
     int m_scrollLineX; // X scroll increment
     int m_scrollLineY; // Y scroll increment
 
+    void Init();        // common part of all ctors
     void Create();
     void Create();
-    void Init();
-    void InitVars();
+    void CreateColumnWindow();
     void CalcDimensions();
     void CalcWindowSizes();
     bool Redimension( wxGridTableMessage& );
     void CalcDimensions();
     void CalcWindowSizes();
     bool Redimension( wxGridTableMessage& );
@@ -2134,11 +1885,15 @@ protected:
                   const wxGridCellCoords& coords,
                   wxMouseEvent& e)
         { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
                   const wxGridCellCoords& coords,
                   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); }
 
     void OnPaint( wxPaintEvent& );
     void OnSize( wxSizeEvent& );
 
     void OnPaint( wxPaintEvent& );
     void OnSize( wxSizeEvent& );
@@ -2178,6 +1933,8 @@ protected:
     friend class wxGridRowLabelWindow;
     friend class wxGridWindow;
 
     friend class wxGridRowLabelWindow;
     friend class wxGridWindow;
 
+    friend class wxGridHeaderCtrl;
+
 private:
     // implement wxScrolledWindow method to return m_gridWin size
     virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
 private:
     // implement wxScrolledWindow method to return m_gridWin size
     virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
@@ -2188,6 +1945,25 @@ private:
     // common part of Clip{Horz,Vert}GridLines
     void DoClipGridLines(bool& var, bool clip);
 
     // common part of Clip{Horz,Vert}GridLines
     void DoClipGridLines(bool& var, bool clip);
 
+    // update the sorting indicator shown in the specified column (whose index
+    // must be valid)
+    //
+    // this will use GetSortingColumn() and IsSortOrderAscending() to determine
+    // the sorting indicator to effectively show
+    void UpdateColumnSortingIndicator(int col);
+
+    // 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
+    // position
+    //
+    // this always returns a valid position, even if the coordinate is out of
+    // bounds (in which case first/last column is returned)
+    int XToPos(int x) const;
+
 
     // event handlers and their helpers
     // --------------------------------
 
     // event handlers and their helpers
     // --------------------------------
@@ -2225,16 +2001,25 @@ private:
     void ProcessColLabelMouseEvent(wxMouseEvent& event);
     void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
 
     void ProcessColLabelMouseEvent(wxMouseEvent& event);
     void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
 
+    void DoColHeaderClick(int col);
+
+    void DoStartResizeCol(int col);
+    void DoUpdateResizeCol(int x);
+    void DoUpdateResizeColWidth(int w);
+    void DoStartMoveCol(int col);
+
     void DoEndDragResizeRow();
     void DoEndDragResizeRow();
-    void DoEndDragResizeCol();
-    void DoEndDragMoveCol();
+    void DoEndDragResizeCol(wxMouseEvent *event = NULL);
+    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);
 
 
     // common implementations of methods defined for both rows and columns
     void DeselectLine(int line, const wxGridOperations& oper);
     void DoEndDragResizeLine(const wxGridOperations& oper);
-    int  PosToLine(int pos, bool clipToMinMax,
-                   const wxGridOperations& oper) const;
+    int PosToLinePos(int pos, bool clipToMinMax,
+                     const wxGridOperations& oper) const;
+    int PosToLine(int pos, bool clipToMinMax,
+                  const wxGridOperations& oper) const;
     int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const;
 
     bool DoMoveCursor(bool expandSelection,
     int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const;
 
     bool DoMoveCursor(bool expandSelection,
@@ -2326,7 +2111,9 @@ public:
         SetEventObject(obj);
     }
 
         SetEventObject(obj);
     }
 
-    wxDEPRECATED(
+    // explicitly specifying inline allows gcc < 3.4 to
+    // handle the deprecation attribute even in the constructor.
+    wxDEPRECATED( inline
     wxGridEvent(int id,
                 wxEventType type,
                 wxObject* obj,
     wxGridEvent(int id,
                 wxEventType type,
                 wxObject* obj,
@@ -2387,7 +2174,7 @@ public:
         SetEventObject(obj);
     }
 
         SetEventObject(obj);
     }
 
-    wxDEPRECATED(
+    wxDEPRECATED( inline
     wxGridSizeEvent(int id,
                     wxEventType type,
                     wxObject* obj,
     wxGridSizeEvent(int id,
                     wxEventType type,
                     wxObject* obj,
@@ -2445,7 +2232,7 @@ public:
         SetEventObject(obj);
     }
 
         SetEventObject(obj);
     }
 
-    wxDEPRECATED(
+    wxDEPRECATED( inline
     wxGridRangeSelectEvent(int id,
                            wxEventType type,
                            wxObject* obj,
     wxGridRangeSelectEvent(int id,
                            wxEventType type,
                            wxObject* obj,
@@ -2517,25 +2304,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;
-
+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&);
 
 typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
 typedef void (wxEvtHandler::*wxGridSizeEventFunction)(wxGridSizeEvent&);
@@ -2543,16 +2331,16 @@ typedef void (wxEvtHandler::*wxGridRangeSelectEventFunction)(wxGridRangeSelectEv
 typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreatedEvent&);
 
 #define wxGridEventHandler(func) \
 typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreatedEvent&);
 
 #define wxGridEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridEventFunction, func)
 
 #define wxGridSizeEventHandler(func) \
 
 #define wxGridSizeEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridSizeEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridSizeEventFunction, func)
 
 #define wxGridRangeSelectEventHandler(func) \
 
 #define wxGridRangeSelectEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridRangeSelectEventFunction, &func)
+    wxEVENT_HANDLER_CAST(wxGridRangeSelectEventFunction, func)
 
 #define wxGridEditorCreatedEventHandler(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))
 
 #define wx__DECLARE_GRIDEVT(evt, id, fn) \
     wx__DECLARE_EVT1(wxEVT_GRID_ ## evt, id, wxGridEventHandler(fn))
@@ -2577,8 +2365,10 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
 #define EVT_GRID_CMD_ROW_SIZE(id, fn)            wx__DECLARE_GRIDSIZEEVT(ROW_SIZE, id, fn)
 #define EVT_GRID_CMD_COL_SIZE(id, fn)            wx__DECLARE_GRIDSIZEEVT(COL_SIZE, id, fn)
 #define EVT_GRID_CMD_COL_MOVE(id, fn)            wx__DECLARE_GRIDEVT(COL_MOVE, id, fn)
 #define EVT_GRID_CMD_ROW_SIZE(id, fn)            wx__DECLARE_GRIDSIZEEVT(ROW_SIZE, id, fn)
 #define EVT_GRID_CMD_COL_SIZE(id, fn)            wx__DECLARE_GRIDSIZEEVT(COL_SIZE, id, fn)
 #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_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)
 #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)
@@ -2598,14 +2388,27 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
 #define EVT_GRID_ROW_SIZE(fn)            EVT_GRID_CMD_ROW_SIZE(wxID_ANY, fn)
 #define EVT_GRID_COL_SIZE(fn)            EVT_GRID_CMD_COL_SIZE(wxID_ANY, fn)
 #define EVT_GRID_COL_MOVE(fn)            EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn)
 #define EVT_GRID_ROW_SIZE(fn)            EVT_GRID_CMD_ROW_SIZE(wxID_ANY, fn)
 #define EVT_GRID_COL_SIZE(fn)            EVT_GRID_CMD_COL_SIZE(wxID_ANY, fn)
 #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_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)
 
 #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;
 #if 0  // TODO: implement these ?  others ?
 
 extern const int wxEVT_GRID_CREATE_CELL;