// constants
// ----------------------------------------------------------------------------
-extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxGridNameStr[];
+extern WXDLLIMPEXP_DATA_ADV(const char) wxGridNameStr[];
// Default parameters for wxGrid
//
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;
// 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().
+ 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;
virtual bool IsAcceptedKey(wxKeyEvent& event);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(const wxString& oldval, wxString *newval);
+ virtual void ApplyEdit(int row, int col, wxGrid* grid);
virtual void Reset();
virtual void StartingKey(wxKeyEvent& event);
private:
size_t m_maxChars; // max number of chars allowed
- wxString m_startValue;
+ wxString m_value;
DECLARE_NO_COPY_CLASS(wxGridCellTextEditor)
};
virtual bool IsAcceptedKey(wxKeyEvent& event);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(const wxString& oldval, wxString *newval);
+ virtual void ApplyEdit(int row, int col, wxGrid* grid);
virtual void Reset();
virtual void StartingKey(wxKeyEvent& event);
#endif
}
- // string representation of m_valueOld
+ // string representation of our value
wxString GetString() const
- { return wxString::Format(_T("%ld"), m_valueOld); }
+ { return wxString::Format(_T("%ld"), m_value); }
private:
int m_min,
m_max;
- long m_valueOld;
+ long m_value;
DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor)
};
virtual bool IsAcceptedKey(wxKeyEvent& event);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(const wxString& oldval, wxString *newval);
+ virtual void ApplyEdit(int row, int col, wxGrid* grid);
virtual void Reset();
virtual void StartingKey(wxKeyEvent& event);
virtual void SetParameters(const wxString& params);
protected:
- // string representation of m_valueOld
+ // string representation of our value
wxString GetString() const;
private:
int m_width,
m_precision;
- double m_valueOld;
+ double m_value;
DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor)
};
virtual bool IsAcceptedKey(wxKeyEvent& event);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(const wxString& oldval, wxString *newval);
+ virtual void ApplyEdit(int row, int col, wxGrid* grid);
virtual void Reset();
virtual void StartingClick();
wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
private:
- bool m_startValue;
+ bool m_value;
static wxString ms_stringValues[2];
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 bool EndEdit(const wxString& oldval, wxString *newval);
+ virtual void ApplyEdit(int row, int col, wxGrid* grid);
virtual void Reset();
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;
+ wxString m_value;
wxArrayString m_choices;
bool m_allowOthers;
// 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
- { 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)
{
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
//
// ------------------------
// 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,
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 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 ); }
//
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;
return s;
}
+ // ------ row and col sizes
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 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() )
- 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
// 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; }
+ // 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; }
#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...
//
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 ); }
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;
+
+ wxGridColLabelWindow *GetColLabelWindow() const
+ {
+ wxASSERT_MSG( !m_useNativeHeader, "no column label window" );
+
+ return reinterpret_cast<wxGridColLabelWindow *>(m_colWindow);
+ }
wxGridTableBase *m_table;
bool m_ownTable;
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;
//Column positions
wxArrayInt m_colAt;
- int m_moveToCol;
bool m_canDragRowSize;
bool m_canDragColSize;
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& );
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& );
friend class wxGridRowLabelWindow;
friend class wxGridWindow;
+ friend class wxGridHeaderCtrl;
+
private:
// implement wxScrolledWindow method to return m_gridWin size
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
// 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
// --------------------------------
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,
SetEventObject(obj);
}
- // explicitly specifying inline allows gcc < 3.4 to
- // handle the deprecation attribute even in the constructor.
+ // explicitly specifying inline allows gcc < 3.4 to
+ // handle the deprecation attribute even in the constructor.
wxDEPRECATED( inline
wxGridEvent(int id,
wxEventType type,
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_CELL_CHANGING;
+extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGED;
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;
typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
typedef void (wxEvtHandler::*wxGridSizeEventFunction)(wxGridSizeEvent&);
#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_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_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_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;