]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/generic/grid.h
add support for sorting to grid columns
[wxWidgets.git] / include / wx / generic / grid.h
index b9d4935c456689cd59df12b80c878aebae85f3cf..98427527e8dcf2f32e2ae2c357e1cdf110459879 100644 (file)
@@ -22,7 +22,7 @@
 // constants
 // ----------------------------------------------------------------------------
 
-extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxGridNameStr[];
+extern WXDLLIMPEXP_DATA_ADV(const char) wxGridNameStr[];
 
 // 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_CORE wxHeaderCtrl;
 class WXDLLIMPEXP_FWD_CORE wxCheckBox;
 class WXDLLIMPEXP_FWD_CORE wxComboBox;
 class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
@@ -903,9 +904,25 @@ public:
 
     // You must override these functions in a derived table class
     //
+
+    // return the number of rows and columns in this table
     virtual int GetNumberRows() = 0;
     virtual int GetNumberCols() = 0;
-    virtual bool IsEmptyCell( int row, int col ) = 0;
+
+    // the methods above are unfortunately non-const even though they should
+    // have been const -- but changing it now is not possible any longer as it
+    // 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 const_cast<wxGridTableBase *>(this)->GetNumberRows(); }
+    int GetColsCount() const
+        { return const_cast<wxGridTableBase *>(this)->GetNumberCols(); }
+
+
+    virtual bool IsEmptyCell( int row, int col )
+    {
+        return GetValue(row, col).empty();
+    }
 
     bool IsEmpty(const wxGridCellCoords& coord)
     {
@@ -1058,7 +1075,6 @@ public:
     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
     //
@@ -1113,14 +1129,19 @@ public:
     // ------------------------
 
     // 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,
-            const wxString& name = wxGridNameStr);
+            const wxString& name = wxGridNameStr)
+    {
+        Init();
+
+        Create(parent, id, pos, size, style, name);
+    }
 
     bool Create(wxWindow *parent,
                 wxWindowID id,
@@ -1292,6 +1313,12 @@ public:
     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;
 
@@ -1359,18 +1386,18 @@ public:
     int      GetColLabelTextOrientation() const;
     wxString GetRowLabelValue( int row ) const;
     wxString GetColLabelValue( int col ) const;
-    wxColour GetGridLineColour() const { return m_gridLineColour; }
 
-    // these methods may be overridden to customize individual grid lines
-    // appearance
-    virtual wxPen GetDefaultGridLinePen();
-    virtual wxPen GetRowGridLinePen(int row);
-    virtual wxPen GetColGridLinePen(int col);
     wxColour GetCellHighlightColour() const { return m_cellHighlightColour; }
     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 ); }
@@ -1383,7 +1410,6 @@ public:
     void     SetColLabelTextOrientation( int textOrientation );
     void     SetRowLabelValue( int row, const wxString& );
     void     SetColLabelValue( int col, const wxString& );
-    void     SetGridLineColour( const wxColour& );
     void     SetCellHighlightColour( const wxColour& );
     void     SetCellHighlightPenWidth(int width);
     void     SetCellHighlightROPenWidth(int width);
@@ -1405,6 +1431,36 @@ public:
     void     DisableDragCell() { EnableDragCell( false ); }
     bool     CanDragCell() const { return m_canDragCell; }
 
+
+    // grid lines
+    // ----------
+
+    // enable or disable drawing of the lines
+    void EnableGridLines(bool enable = true);
+    bool GridLinesEnabled() const { return m_gridLinesEnabled; }
+
+    // by default grid lines stop at last column/row, but this may be changed
+    void ClipHorzGridLines(bool clip)
+        { DoClipGridLines(m_gridLinesClipHorz, clip); }
+    void ClipVertGridLines(bool clip)
+        { DoClipGridLines(m_gridLinesClipVert, clip); }
+    bool AreHorzGridLinesClipped() const { return m_gridLinesClipHorz; }
+    bool AreVertGridLinesClipped() const { return m_gridLinesClipVert; }
+
+    // this can be used to change the global grid lines colour
+    void SetGridLineColour(const wxColour& col);
+    wxColour GetGridLineColour() const { return m_gridLineColour; }
+
+    // these methods may be overridden to customize individual grid lines
+    // appearance
+    virtual wxPen GetDefaultGridLinePen();
+    virtual wxPen GetRowGridLinePen(int row);
+    virtual wxPen GetColGridLinePen(int col);
+
+
+    // attributes
+    // ----------
+
     // this sets the specified attribute for this cell or in this row/col
     void     SetAttr(int row, int col, wxGridCellAttr *attr);
     void     SetRowAttr(int row, wxGridCellAttr *attr);
@@ -1425,9 +1481,6 @@ public:
     void     SetColFormatFloat(int col, int width = -1, int precision = -1);
     void     SetColFormatCustom(int col, const wxString& typeName);
 
-    void     EnableGridLines( bool enable = true );
-    bool     GridLinesEnabled() const { return m_gridLinesEnabled; }
-
     // ------ row and col formatting
     //
     int      GetDefaultRowSize() const;
@@ -1458,33 +1511,48 @@ public:
 
     void     SetColSize( int col, int width );
 
-    //Column positions
-    int GetColAt( int colPos ) const
+    // 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
+
+    // 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() )
-            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;
     }
 
+
+
     // 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
@@ -1666,7 +1734,7 @@ public:
     // 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; }
 
     // Allow adjustment of scroll increment. The default is (15, 15).
@@ -1681,6 +1749,31 @@ public:
 #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...
     //
@@ -1695,12 +1788,10 @@ public:
             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 ); }
@@ -1861,9 +1952,30 @@ protected:
     bool m_created;
 
     wxGridWindow             *m_gridWin;
-    wxGridRowLabelWindow     *m_rowLabelWin;
-    wxGridColLabelWindow     *m_colLabelWin;
     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;
+
+    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" );
+
+        return reinterpret_cast<wxGridColLabelWindow *>(m_colWindow);
+    }
 
     wxGridTableBase          *m_table;
     bool                      m_ownTable;
@@ -1911,7 +2023,11 @@ protected:
     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;
@@ -1948,6 +2064,8 @@ protected:
 
     wxColour   m_gridLineColour;
     bool       m_gridLinesEnabled;
+    bool       m_gridLinesClipHorz,
+               m_gridLinesClipVert;
     wxColour   m_cellHighlightColour;
     int        m_cellHighlightPenWidth;
     int        m_cellHighlightROPenWidth;
@@ -2043,7 +2161,6 @@ protected:
 
     //Column positions
     wxArrayInt m_colAt;
-    int m_moveToCol;
 
     bool    m_canDragRowSize;
     bool    m_canDragColSize;
@@ -2082,9 +2199,9 @@ protected:
     int m_scrollLineX; // X scroll increment
     int m_scrollLineY; // Y scroll increment
 
+    void Init();        // common part of all ctors
     void Create();
-    void Init();
-    void InitVars();
+    void CreateColumnWindow();
     void CalcDimensions();
     void CalcWindowSizes();
     bool Redimension( wxGridTableMessage& );
@@ -2143,10 +2260,34 @@ protected:
     friend class wxGridRowLabelWindow;
     friend class wxGridWindow;
 
+    friend class wxGridHeaderCtrl;
+
 private:
     // implement wxScrolledWindow method to return m_gridWin size
     virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
 
+    // redraw the grid lines, should be called after changing their attributes
+    void RedrawGridLines();
+
+    // 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);
+
+
+    // 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
     // --------------------------------
 
@@ -2183,16 +2324,25 @@ private:
     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 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);
-    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,
@@ -2260,35 +2410,46 @@ private:
 // Grid event class and event types
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_ADV wxGridEvent : public wxNotifyEvent
+class WXDLLIMPEXP_ADV wxGridEvent : public wxNotifyEvent,
+                                    public wxKeyboardState
 {
 public:
     wxGridEvent()
-        : wxNotifyEvent(), m_row(-1), m_col(-1), m_x(-1), m_y(-1),
-        m_selecting(0), m_control(0), m_meta(0), m_shift(0), m_alt(0)
-        {
-        }
+        : wxNotifyEvent()
+    {
+        Init(-1, -1, -1, -1, false);
+    }
+
+    wxGridEvent(int id,
+                wxEventType type,
+                wxObject* obj,
+                int row = -1, int col = -1,
+                int x = -1, int y = -1,
+                bool sel = true,
+                const wxKeyboardState& kbd = wxKeyboardState())
+        : wxNotifyEvent(type, id),
+          wxKeyboardState(kbd)
+    {
+        Init(row, col, x, y, sel);
+        SetEventObject(obj);
+    }
 
-    wxGridEvent(int id, wxEventType type, wxObject* obj,
-                int row=-1, int col=-1, int x=-1, int y=-1, bool sel = true,
-                bool control = false, bool shift = false, bool alt = false, bool meta = false);
+    // 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,
+                int row, int col,
+                int x, int y,
+                bool sel,
+                bool control,
+                bool shift = false, bool alt = false, bool meta = false));
 
     virtual int GetRow() { return m_row; }
     virtual int GetCol() { return m_col; }
     wxPoint     GetPosition() { return wxPoint( m_x, m_y ); }
     bool        Selecting() { return m_selecting; }
-    bool        ControlDown() { return m_control; }
-    bool        MetaDown() { return m_meta; }
-    bool        ShiftDown() { return m_shift; }
-    bool        AltDown() { return m_alt; }
-    bool        CmdDown()
-    {
-#if defined(__WXMAC__) || defined(__WXCOCOA__)
-        return MetaDown();
-#else
-        return ControlDown();
-#endif
-    }
 
     virtual wxEvent *Clone() const { return new wxGridEvent(*this); }
 
@@ -2298,41 +2459,57 @@ protected:
     int         m_x;
     int         m_y;
     bool        m_selecting;
-    bool        m_control;
-    bool        m_meta;
-    bool        m_shift;
-    bool        m_alt;
+
+private:
+    void Init(int row, int col, int x, int y, bool sel)
+    {
+        m_row = row;
+        m_col = col;
+        m_x = x;
+        m_y = y;
+        m_selecting = sel;
+    }
 
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxGridEvent)
 };
 
-class WXDLLIMPEXP_ADV wxGridSizeEvent : public wxNotifyEvent
+class WXDLLIMPEXP_ADV wxGridSizeEvent : public wxNotifyEvent,
+                                        public wxKeyboardState
 {
 public:
     wxGridSizeEvent()
-        : wxNotifyEvent(), m_rowOrCol(-1), m_x(-1), m_y(-1),
-        m_control(0), m_meta(0), m_shift(0), m_alt(0)
-        {
-        }
+        : wxNotifyEvent()
+    {
+        Init(-1, -1, -1);
+    }
 
-    wxGridSizeEvent(int id, wxEventType type, wxObject* obj,
-                int rowOrCol=-1, int x=-1, int y=-1,
-                bool control = false, bool shift = false, bool alt = false, bool meta = false);
+    wxGridSizeEvent(int id,
+                    wxEventType type,
+                    wxObject* obj,
+                    int rowOrCol = -1,
+                    int x = -1, int y = -1,
+                    const wxKeyboardState& kbd = wxKeyboardState())
+        : wxNotifyEvent(type, id),
+          wxKeyboardState(kbd)
+    {
+        Init(rowOrCol, x, y);
+
+        SetEventObject(obj);
+    }
+
+    wxDEPRECATED( inline
+    wxGridSizeEvent(int id,
+                    wxEventType type,
+                    wxObject* obj,
+                    int rowOrCol,
+                    int x, int y,
+                    bool control,
+                    bool shift = false,
+                    bool alt = false,
+                    bool meta = false) );
 
     int         GetRowOrCol() { return m_rowOrCol; }
     wxPoint     GetPosition() { return wxPoint( m_x, m_y ); }
-    bool        ControlDown() { return m_control; }
-    bool        MetaDown() { return m_meta; }
-    bool        ShiftDown() { return m_shift; }
-    bool        AltDown() { return m_alt; }
-    bool        CmdDown()
-    {
-#if defined(__WXMAC__) || defined(__WXCOCOA__)
-        return MetaDown();
-#else
-        return ControlDown();
-#endif
-    }
 
     virtual wxEvent *Clone() const { return new wxGridSizeEvent(*this); }
 
@@ -2340,36 +2517,55 @@ protected:
     int         m_rowOrCol;
     int         m_x;
     int         m_y;
-    bool        m_control;
-    bool        m_meta;
-    bool        m_shift;
-    bool        m_alt;
+
+private:
+    void Init(int rowOrCol, int x, int y)
+    {
+        m_rowOrCol = rowOrCol;
+        m_x = x;
+        m_y = y;
+    }
 
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxGridSizeEvent)
 };
 
 
-class WXDLLIMPEXP_ADV wxGridRangeSelectEvent : public wxNotifyEvent
+class WXDLLIMPEXP_ADV wxGridRangeSelectEvent : public wxNotifyEvent,
+                                               public wxKeyboardState
 {
 public:
     wxGridRangeSelectEvent()
         : wxNotifyEvent()
-        {
-            m_topLeft     = wxGridNoCellCoords;
-            m_bottomRight = wxGridNoCellCoords;
-            m_selecting   = false;
-            m_control     = false;
-            m_meta        = false;
-            m_shift       = false;
-            m_alt         = false;
-        }
+    {
+        Init(wxGridNoCellCoords, wxGridNoCellCoords, false);
+    }
 
-    wxGridRangeSelectEvent(int id, wxEventType type, wxObject* obj,
+    wxGridRangeSelectEvent(int id,
+                           wxEventType type,
+                           wxObject* obj,
                            const wxGridCellCoords& topLeft,
                            const wxGridCellCoords& bottomRight,
                            bool sel = true,
-                           bool control = false, bool shift = false,
-                           bool alt = false, bool meta = false);
+                           const wxKeyboardState& kbd = wxKeyboardState())
+        : wxNotifyEvent(type, id),
+          wxKeyboardState(kbd)
+    {
+        Init(topLeft, bottomRight, sel);
+
+        SetEventObject(obj);
+    }
+
+    wxDEPRECATED( inline
+    wxGridRangeSelectEvent(int id,
+                           wxEventType type,
+                           wxObject* obj,
+                           const wxGridCellCoords& topLeft,
+                           const wxGridCellCoords& bottomRight,
+                           bool sel,
+                           bool control,
+                           bool shift = false,
+                           bool alt = false,
+                           bool meta = false) );
 
     wxGridCellCoords GetTopLeftCoords() { return m_topLeft; }
     wxGridCellCoords GetBottomRightCoords() { return m_bottomRight; }
@@ -2378,35 +2574,29 @@ public:
     int         GetLeftCol()   { return m_topLeft.GetCol(); }
     int         GetRightCol()  { return m_bottomRight.GetCol(); }
     bool        Selecting() { return m_selecting; }
-    bool        ControlDown()  { return m_control; }
-    bool        MetaDown()     { return m_meta; }
-    bool        ShiftDown()    { return m_shift; }
-    bool        AltDown()      { return m_alt; }
-    bool        CmdDown()
-    {
-#if defined(__WXMAC__) || defined(__WXCOCOA__)
-        return MetaDown();
-#else
-        return ControlDown();
-#endif
-    }
 
     virtual wxEvent *Clone() const { return new wxGridRangeSelectEvent(*this); }
 
 protected:
+    void Init(const wxGridCellCoords& topLeft,
+              const wxGridCellCoords& bottomRight,
+              bool selecting)
+    {
+        m_topLeft = topLeft;
+        m_bottomRight = bottomRight;
+        m_selecting = selecting;
+    }
+
     wxGridCellCoords  m_topLeft;
     wxGridCellCoords  m_bottomRight;
     bool              m_selecting;
-    bool              m_control;
-    bool              m_meta;
-    bool              m_shift;
-    bool              m_alt;
 
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxGridRangeSelectEvent)
 };
 
 
-class WXDLLIMPEXP_ADV wxGridEditorCreatedEvent : public wxCommandEvent {
+class WXDLLIMPEXP_ADV wxGridEditorCreatedEvent : public wxCommandEvent
+{
 public:
     wxGridEditorCreatedEvent()
         : wxCommandEvent()
@@ -2455,6 +2645,7 @@ 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;
 
 
 typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
@@ -2497,6 +2688,7 @@ 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_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_SELECT_CELL(id, fn)         wx__DECLARE_GRIDEVT(SELECT_CELL, id, fn)
@@ -2518,6 +2710,7 @@ 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_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_SELECT_CELL(fn)         EVT_GRID_CMD_SELECT_CELL(wxID_ANY, fn)