#if wxUSE_GRID
+#include "wx/hashmap.h"
+
#include "wx/scrolwin.h"
// ----------------------------------------------------------------------------
#define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16
// type names for grid table values
-#define wxGRID_VALUE_STRING _T("string")
-#define wxGRID_VALUE_BOOL _T("bool")
-#define wxGRID_VALUE_NUMBER _T("long")
-#define wxGRID_VALUE_FLOAT _T("double")
-#define wxGRID_VALUE_CHOICE _T("choice")
+#define wxGRID_VALUE_STRING wxT("string")
+#define wxGRID_VALUE_BOOL wxT("bool")
+#define wxGRID_VALUE_NUMBER wxT("long")
+#define wxGRID_VALUE_FLOAT wxT("double")
+#define wxGRID_VALUE_CHOICE wxT("choice")
#define wxGRID_VALUE_TEXT wxGRID_VALUE_STRING
#define wxGRID_VALUE_LONG wxGRID_VALUE_NUMBER
wxGRID_ROW
};
+// Flags used with wxGrid::Render() to select parts of the grid to draw.
+enum wxGridRenderStyle
+{
+ wxGRID_DRAW_ROWS_HEADER = 0x001,
+ wxGRID_DRAW_COLS_HEADER = 0x002,
+ wxGRID_DRAW_CELL_LINES = 0x004,
+ wxGRID_DRAW_BOX_RECT = 0x008,
+ wxGRID_DRAW_SELECTION = 0x010,
+ wxGRID_DRAW_DEFAULT = wxGRID_DRAW_ROWS_HEADER |
+ wxGRID_DRAW_COLS_HEADER |
+ wxGRID_DRAW_CELL_LINES |
+ wxGRID_DRAW_BOX_RECT
+};
+
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_FWD_CORE wxSpinCtrl;
#endif
+class wxGridFixedIndicesSet;
+
class wxGridOperations;
class wxGridRowOperations;
class wxGridColumnOperations;
class wxGridDirectionOperations;
+
// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------
// class is not documented and is not public at all
// ----------------------------------------------------------------------------
-class WXDLLIMPEXP_ADV wxGridCellWorker : public wxClientDataContainer
+class WXDLLIMPEXP_ADV wxGridCellWorker : public wxClientDataContainer, public wxRefCounter
{
public:
- wxGridCellWorker() { m_nRef = 1; }
+ wxGridCellWorker() { }
- // this class is ref counted: it is created with ref count of 1, so
- // calling DecRef() once will delete it. Calling IncRef() allows to lock
- // it until the matching DecRef() is called
- void IncRef() { m_nRef++; }
- void DecRef() { if ( --m_nRef == 0 ) delete this; }
-
- // interpret renderer parameters: arbitrary string whose interpretatin is
+ // interpret renderer parameters: arbitrary string whose interpretation is
// left to the derived classes
virtual void SetParameters(const wxString& params);
virtual ~wxGridCellWorker();
private:
- size_t m_nRef;
-
// suppress the stupid gcc warning about the class having private dtor and
// no friends
friend class wxGridCellWorkerDummyFriend;
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
// Draws the part of the cell not occupied by the control: the base class
// version just fills it with background colour from the attribute
- virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
+ virtual void PaintBackground(wxDC& dc,
+ const wxRect& rectCell,
+ const wxGridCellAttr& attr);
+
+
+ // The methods called by wxGrid when a cell is edited: first BeginEdit() is
+ // called, then EndEdit() is and if it returns true and if the change is
+ // not vetoed by a user-defined event handler, finally ApplyEdit() is called
// Fetch the value from the table and prepare the edit control
// to begin editing. Set the focus to the edit control.
virtual void BeginEdit(int row, int col, wxGrid* grid) = 0;
- // Complete the editing of the current cell. Returns true if the value has
- // changed. If necessary, the control may be destroyed.
- virtual bool EndEdit(int row, int col, wxGrid* grid) = 0;
+ // Returns false if nothing changed, otherwise returns true and return the
+ // new value in its string form in the newval output parameter.
+ //
+ // This should also store the new value in its real type internally so that
+ // it could be used by ApplyEdit() but it must not modify the grid as the
+ // change could still be vetoed.
+ virtual bool EndEdit(int row, int col, const wxGrid *grid,
+ const wxString& oldval, wxString *newval) = 0;
+
+ // Complete the editing of the current cell by storing the value saved by
+ // the previous call to EndEdit() in the grid
+ virtual void ApplyEdit(int row, int col, wxGrid* grid) = 0;
+
// Reset the value in the control back to its starting value
virtual void Reset() = 0;
// no friends
friend class wxGridCellEditorDummyFriend;
- DECLARE_NO_COPY_CLASS(wxGridCellEditor)
+ wxDECLARE_NO_COPY_CLASS(wxGridCellEditor);
};
-#if wxUSE_TEXTCTRL
+// ----------------------------------------------------------------------------
+// wxGridHeaderRenderer and company: like wxGridCellRenderer but for headers
+// ----------------------------------------------------------------------------
-// the editor for string/text data
-class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor
+// Base class for corner window renderer: it is the simplest of all renderers
+// and only has a single function
+class WXDLLIMPEXP_ADV wxGridCornerHeaderRenderer
{
public:
- wxGridCellTextEditor();
-
- virtual void Create(wxWindow* parent,
- wxWindowID id,
- wxEvtHandler* evtHandler);
- virtual void SetSize(const wxRect& rect);
-
- virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
- virtual bool IsAcceptedKey(wxKeyEvent& event);
- virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
-
- virtual void Reset();
- virtual void StartingKey(wxKeyEvent& event);
- virtual void HandleReturn(wxKeyEvent& event);
-
- // parameters string format is "max_width"
- virtual void SetParameters(const wxString& params);
-
- virtual wxGridCellEditor *Clone() const
- { return new wxGridCellTextEditor; }
-
- // added GetValue so we can get the value which is in the control
- virtual wxString GetValue() const;
-
-protected:
- wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; }
-
- // parts of our virtual functions reused by the derived classes
- void DoCreate(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler,
- long style = 0);
- void DoBeginEdit(const wxString& startValue);
- void DoReset(const wxString& startValue);
-
-private:
- size_t m_maxChars; // max number of chars allowed
- wxString m_startValue;
-
- DECLARE_NO_COPY_CLASS(wxGridCellTextEditor)
+ // Draw the border around the corner window.
+ virtual void DrawBorder(const wxGrid& grid,
+ wxDC& dc,
+ wxRect& rect) const = 0;
+
+ // make the dtor of a class with virtual functions virtual to avoid g++
+ // warnings, even though this class is not supposed to be used
+ // polymorphically
+ virtual ~wxGridCornerHeaderRenderer() { }
};
-// the editor for numeric (long) data
-class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor
+
+// Base class for the row/column header cells renderers
+class WXDLLIMPEXP_ADV wxGridHeaderLabelsRenderer
+ : public wxGridCornerHeaderRenderer
{
public:
- // allows to specify the range - if min == max == -1, no range checking is
- // done
- wxGridCellNumberEditor(int min = -1, int max = -1);
-
- virtual void Create(wxWindow* parent,
- wxWindowID id,
- wxEvtHandler* evtHandler);
-
- virtual bool IsAcceptedKey(wxKeyEvent& event);
- virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
-
- virtual void Reset();
- virtual void StartingKey(wxKeyEvent& event);
-
- // parameters string format is "min,max"
- virtual void SetParameters(const wxString& params);
-
- virtual wxGridCellEditor *Clone() const
- { return new wxGridCellNumberEditor(m_min, m_max); }
-
- // added GetValue so we can get the value which is in the control
- virtual wxString GetValue() const;
-
-protected:
-#if wxUSE_SPINCTRL
- wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; }
-#endif
-
- // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl
- bool HasRange() const
- {
-#if wxUSE_SPINCTRL
- return m_min != m_max;
-#else
- return false;
-#endif
- }
-
- // string representation of m_valueOld
- wxString GetString() const
- { return wxString::Format(_T("%ld"), m_valueOld); }
-
-private:
- int m_min,
- m_max;
+ // Draw header cell label
+ virtual void DrawLabel(const wxGrid& grid,
+ wxDC& dc,
+ const wxString& value,
+ const wxRect& rect,
+ int horizAlign,
+ int vertAlign,
+ int textOrientation) const;
+};
- long m_valueOld;
+// Currently the row/column/corner renders don't need any methods other than
+// those already in wxGridHeaderLabelsRenderer but still define separate classes
+// for them for future extensions and also for better type safety (i.e. to
+// avoid inadvertently using a column header renderer for the row headers)
+class WXDLLIMPEXP_ADV wxGridRowHeaderRenderer
+ : public wxGridHeaderLabelsRenderer
+{
+};
- DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor)
+class WXDLLIMPEXP_ADV wxGridColumnHeaderRenderer
+ : public wxGridHeaderLabelsRenderer
+{
};
-// the editor for floating point numbers (double) data
-class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor
+// Also define the default renderers which are used by wxGridCellAttrProvider
+// by default
+class WXDLLIMPEXP_ADV wxGridRowHeaderRendererDefault
+ : public wxGridRowHeaderRenderer
{
public:
- wxGridCellFloatEditor(int width = -1, int precision = -1);
-
- virtual void Create(wxWindow* parent,
- wxWindowID id,
- wxEvtHandler* evtHandler);
-
- virtual bool IsAcceptedKey(wxKeyEvent& event);
- virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
-
- virtual void Reset();
- virtual void StartingKey(wxKeyEvent& event);
-
- virtual wxGridCellEditor *Clone() const
- { return new wxGridCellFloatEditor(m_width, m_precision); }
-
- // parameters string format is "width,precision"
- virtual void SetParameters(const wxString& params);
-
-protected:
- // string representation of m_valueOld
- wxString GetString() const;
-
-private:
- int m_width,
- m_precision;
- double m_valueOld;
-
- DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor)
+ virtual void DrawBorder(const wxGrid& grid,
+ wxDC& dc,
+ wxRect& rect) const;
};
-#endif // wxUSE_TEXTCTRL
-
-#if wxUSE_CHECKBOX
-
-// the editor for boolean data
-class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor
+// Column header cells renderers
+class WXDLLIMPEXP_ADV wxGridColumnHeaderRendererDefault
+ : public wxGridColumnHeaderRenderer
{
public:
- wxGridCellBoolEditor() { }
-
- virtual void Create(wxWindow* parent,
- wxWindowID id,
- wxEvtHandler* evtHandler);
-
- virtual void SetSize(const wxRect& rect);
- virtual void Show(bool show, wxGridCellAttr *attr = NULL);
-
- virtual bool IsAcceptedKey(wxKeyEvent& event);
- virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
-
- virtual void Reset();
- virtual void StartingClick();
- virtual void StartingKey(wxKeyEvent& event);
-
- virtual wxGridCellEditor *Clone() const
- { return new wxGridCellBoolEditor; }
-
- // added GetValue so we can get the value which is in the control, see
- // also UseStringValues()
- virtual wxString GetValue() const;
-
- // set the string values returned by GetValue() for the true and false
- // states, respectively
- static void UseStringValues(const wxString& valueTrue = _T("1"),
- const wxString& valueFalse = wxEmptyString);
-
- // return true if the given string is equal to the string representation of
- // true value which we currently use
- static bool IsTrueValue(const wxString& value);
-
-protected:
- wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
-
-private:
- bool m_startValue;
-
- static wxString ms_stringValues[2];
-
- DECLARE_NO_COPY_CLASS(wxGridCellBoolEditor)
+ virtual void DrawBorder(const wxGrid& grid,
+ wxDC& dc,
+ wxRect& rect) const;
};
-#endif // wxUSE_CHECKBOX
-
-#if wxUSE_COMBOBOX
-
-// the editor for string data allowing to choose from the list of strings
-class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor
+// Header corner renderer
+class WXDLLIMPEXP_ADV wxGridCornerHeaderRendererDefault
+ : public wxGridCornerHeaderRenderer
{
public:
- // if !allowOthers, user can't type a string not in choices array
- wxGridCellChoiceEditor(size_t count = 0,
- const wxString choices[] = NULL,
- bool allowOthers = false);
- wxGridCellChoiceEditor(const wxArrayString& choices,
- bool allowOthers = false);
-
- virtual void Create(wxWindow* parent,
- wxWindowID id,
- wxEvtHandler* evtHandler);
-
- virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
- virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, wxGrid* grid);
-
- virtual void Reset();
-
- // parameters string format is "item1[,item2[...,itemN]]"
- virtual void SetParameters(const wxString& params);
-
- virtual wxGridCellEditor *Clone() const;
-
- // added GetValue so we can get the value which is in the control
- virtual wxString GetValue() const;
-
-protected:
- wxComboBox *Combo() const { return (wxComboBox *)m_control; }
-
-// DJC - (MAPTEK) you at least need access to m_choices if you
-// wish to override this class
-protected:
- wxString m_startValue;
- wxArrayString m_choices;
- bool m_allowOthers;
-
- DECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor)
+ virtual void DrawBorder(const wxGrid& grid,
+ wxDC& dc,
+ wxRect& rect) const;
};
-#endif // wxUSE_COMBOBOX
// ----------------------------------------------------------------------------
// wxGridCellAttr: this class can be used to alter the cells appearance in
// class may be returned by wxGridTable::GetAttr().
// ----------------------------------------------------------------------------
-class WXDLLIMPEXP_ADV wxGridCellAttr : public wxClientDataContainer
+class WXDLLIMPEXP_ADV wxGridCellAttr : public wxClientDataContainer, public wxRefCounter
{
public:
enum wxAttrKind
{
Init(attrDefault);
- // MB: args used to be 0,0 here but wxALIGN_LEFT is 0
- SetAlignment(-1, -1);
+ SetAlignment(wxALIGN_INVALID, wxALIGN_INVALID);
}
// VZ: considering the number of members wxGridCellAttr has now, this ctor
wxGridCellAttr *Clone() const;
void MergeWith(wxGridCellAttr *mergefrom);
- // this class is ref counted: it is created with ref count of 1, so
- // calling DecRef() once will delete it. Calling IncRef() allows to lock
- // it until the matching DecRef() is called
- void IncRef() { m_nRef++; }
- void DecRef() { if ( --m_nRef == 0 ) delete this; }
-
// setters
void SetTextColour(const wxColour& colText) { m_colText = colText; }
void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; }
void SetKind(wxAttrKind kind) { m_attrkind = kind; }
// accessors
- bool HasTextColour() const { return m_colText.Ok(); }
- bool HasBackgroundColour() const { return m_colBack.Ok(); }
- bool HasFont() const { return m_font.Ok(); }
- bool HasAlignment() const { return (m_hAlign != -1 || m_vAlign != -1); }
+ bool HasTextColour() const { return m_colText.IsOk(); }
+ bool HasBackgroundColour() const { return m_colBack.IsOk(); }
+ bool HasFont() const { return m_font.IsOk(); }
+ bool HasAlignment() const
+ {
+ return m_hAlign != wxALIGN_INVALID || m_vAlign != wxALIGN_INVALID;
+ }
bool HasRenderer() const { return m_renderer != NULL; }
bool HasEditor() const { return m_editor != NULL; }
bool HasReadWriteMode() const { return m_isReadOnly != Unset; }
const wxColour& GetBackgroundColour() const;
const wxFont& GetFont() const;
void GetAlignment(int *hAlign, int *vAlign) const;
+
+ // unlike GetAlignment() which always overwrites its output arguments with
+ // the alignment values to use, falling back on default alignment if this
+ // attribute doesn't have any, this function will preserve the values of
+ // parameters on entry if the corresponding alignment is not set in this
+ // attribute meaning that they can be initialized to default alignment (and
+ // also that they must be initialized, unlike with GetAlignment())
+ void GetNonDefaultAlignment(int *hAlign, int *vAlign) const;
+
void GetSize(int *num_rows, int *num_cols) const;
bool GetOverflow() const
{ return m_overflow != SingleCell; }
void Init(wxGridCellAttr *attrDefault = NULL);
- // the ref count - when it goes to 0, we die
- size_t m_nRef;
-
wxColour m_colText,
m_colBack;
wxFont m_font;
wxAttrKind m_attrkind;
// use Clone() instead
- DECLARE_NO_COPY_CLASS(wxGridCellAttr)
+ wxDECLARE_NO_COPY_CLASS(wxGridCellAttr);
// suppress the stupid gcc warning about the class having private dtor and
// no friends
void UpdateAttrRows( size_t pos, int numRows );
void UpdateAttrCols( size_t pos, int numCols );
+
+ // get renderers for the given row/column header label and the corner
+ // window: unlike cell renderers, these objects are not reference counted
+ // and are never NULL so they are returned by reference
+ virtual const wxGridColumnHeaderRenderer& GetColumnHeaderRenderer(int col);
+ virtual const wxGridRowHeaderRenderer& GetRowHeaderRenderer(int row);
+ virtual const wxGridCornerHeaderRenderer& GetCornerRenderer();
+
private:
void InitData();
wxGridCellAttrProviderData *m_data;
- DECLARE_NO_COPY_CLASS(wxGridCellAttrProvider)
+ wxDECLARE_NO_COPY_CLASS(wxGridCellAttrProvider);
};
// ----------------------------------------------------------------------------
wxGridCellAttrProvider *m_attrProvider;
DECLARE_ABSTRACT_CLASS(wxGridTableBase)
- DECLARE_NO_COPY_CLASS(wxGridTableBase)
+ wxDECLARE_NO_COPY_CLASS(wxGridTableBase);
};
int m_comInt1;
int m_comInt2;
- DECLARE_NO_COPY_CLASS(wxGridTableMessage)
+ wxDECLARE_NO_COPY_CLASS(wxGridTableMessage);
};
public:
wxGridStringTable();
wxGridStringTable( int numRows, int numCols );
- virtual ~wxGridStringTable();
// these are pure virtual in wxGridTableBase
//
- int GetNumberRows();
- int GetNumberCols();
- wxString GetValue( int row, int col );
- void SetValue( int row, int col, const wxString& s );
+ virtual int GetNumberRows() { return static_cast<int>(m_data.size()); }
+ virtual int GetNumberCols() { return m_numCols; }
+ virtual wxString GetValue( int row, int col );
+ virtual void SetValue( int row, int col, const wxString& s );
// overridden functions from wxGridTableBase
//
private:
wxGridStringArray m_data;
+ // notice that while we don't need to store the number of our rows as it's
+ // always equal to the size of m_data array, we do need to store the number
+ // of our columns as we can't retrieve it from m_data when the number of
+ // rows is 0 (see #10818)
+ int m_numCols;
+
// These only get used if you set your own labels, otherwise the
// GetRow/ColLabelValue functions return wxGridTableBase defaults
//
// Grid view classes
// ============================================================================
+// ----------------------------------------------------------------------------
+// wxGridSizesInfo stores information about sizes of the rows or columns.
+//
+// It assumes that most of the columns or rows have default size and so stores
+// the default size separately and uses a hash to map column or row numbers to
+// their non default size for those which don't have the default size.
+// ----------------------------------------------------------------------------
+
+// hash map to store positions as the keys and sizes as the values
+WX_DECLARE_HASH_MAP_WITH_DECL( unsigned, int, wxIntegerHash, wxIntegerEqual,
+ wxUnsignedToIntHashMap, class WXDLLIMPEXP_ADV );
+
+struct WXDLLIMPEXP_ADV wxGridSizesInfo
+{
+ // default ctor, initialize m_sizeDefault and m_customSizes later
+ wxGridSizesInfo() { }
+
+ // ctor used by wxGrid::Get{Col,Row}Sizes()
+ wxGridSizesInfo(int defSize, const wxArrayInt& allSizes);
+
+ // default copy ctor, assignment operator and dtor are ok
+
+ // Get the size of the element with the given index
+ int GetSize(unsigned pos) const;
+
+
+ // default size
+ int m_sizeDefault;
+
+ // position -> size map containing all elements with non-default size
+ wxUnsignedToIntHashMap m_customSizes;
+};
+
// ----------------------------------------------------------------------------
// wxGrid
// ----------------------------------------------------------------------------
wxGridSelectRowsOrColumns = wxGridSelectRows | wxGridSelectColumns
};
+ // Different behaviour of the TAB key when the end (or the beginning, for
+ // Shift-TAB) of the current row is reached:
+ enum TabBehaviour
+ {
+ Tab_Stop, // Do nothing, this is default.
+ Tab_Wrap, // Move to the next (or previous) row.
+ Tab_Leave // Move to the next (or previous) control.
+ };
+
// creation and destruction
// ------------------------
void DrawTextRectangle( wxDC& dc, const wxString&, const wxRect&,
int horizontalAlignment = wxALIGN_LEFT,
int verticalAlignment = wxALIGN_TOP,
- int textOrientation = wxHORIZONTAL );
+ int textOrientation = wxHORIZONTAL ) const;
void DrawTextRectangle( wxDC& dc, const wxArrayString& lines, const wxRect&,
int horizontalAlignment = wxALIGN_LEFT,
int verticalAlignment = wxALIGN_TOP,
- int textOrientation = wxHORIZONTAL );
+ int textOrientation = wxHORIZONTAL ) const;
+ // ------ grid render function for printing
+ //
+ void Render( wxDC& dc,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ const wxGridCellCoords& topLeft = wxGridCellCoords(-1, -1),
+ const wxGridCellCoords& bottomRight = wxGridCellCoords(-1, -1),
+ int style = wxGRID_DRAW_DEFAULT );
// Split a string containing newline characters into an array of
// strings and return the number of lines
bool MoveCursorLeftBlock( bool expandSelection );
bool MoveCursorRightBlock( bool expandSelection );
+ void SetTabBehaviour(TabBehaviour behaviour) { m_tabBehaviour = behaviour; }
+
// ------ label and gridline formatting
//
void SetCellHighlightPenWidth(int width);
void SetCellHighlightROPenWidth(int width);
+
+ // interactive grid mouse operations control
+ // -----------------------------------------
+
+ // functions globally enabling row/column interactive resizing (enabled by
+ // default)
void EnableDragRowSize( bool enable = true );
void DisableDragRowSize() { EnableDragRowSize( false ); }
- bool CanDragRowSize() const { return m_canDragRowSize; }
+
void EnableDragColSize( bool enable = true );
void DisableDragColSize() { EnableDragColSize( false ); }
- bool CanDragColSize() const { return m_canDragColSize; }
+
+ // if interactive resizing is enabled, some rows/columns can still have
+ // fixed size
+ void DisableRowResize(int row) { DoDisableLineResize(row, m_setFixedRows); }
+ void DisableColResize(int col) { DoDisableLineResize(col, m_setFixedCols); }
+
+ // these functions return whether the given row/column can be
+ // effectively resized: for this interactive resizing must be enabled
+ // and this index must not have been passed to DisableRow/ColResize()
+ bool CanDragRowSize(int row) const
+ { return m_canDragRowSize && DoCanResizeLine(row, m_setFixedRows); }
+ bool CanDragColSize(int col) const
+ { return m_canDragColSize && DoCanResizeLine(col, m_setFixedCols); }
+
+ // interactive column reordering (disabled by default)
void EnableDragColMove( bool enable = true );
void DisableDragColMove() { EnableDragColMove( false ); }
bool CanDragColMove() const { return m_canDragColMove; }
+
+ // interactive resizing of grid cells (enabled by default)
void EnableDragGridSize(bool enable = true);
void DisableDragGridSize() { EnableDragGridSize(false); }
bool CanDragGridSize() const { return m_canDragGridSize; }
+ // interactive dragging of cells (disabled by default)
void EnableDragCell( bool enable = true );
void DisableDragCell() { EnableDragCell( false ); }
bool CanDragCell() const { return m_canDragCell; }
void SetRowAttr(int row, wxGridCellAttr *attr);
void SetColAttr(int col, wxGridCellAttr *attr);
+ // the grid can cache attributes for the recently used cells (currently it
+ // only caches one attribute for the most recently used one) and might
+ // notice that its value in the attribute provider has changed -- if this
+ // happens, call this function to force it
+ void RefreshAttr(int row, int col);
+
// returns the attribute we may modify in place: a new one if this cell
// doesn't have any yet or the existing one if it does
//
void GetCellAlignment( int row, int col, int *horiz, int *vert ) const;
bool GetDefaultCellOverflow() const;
bool GetCellOverflow( int row, int col ) const;
- void GetCellSize( int row, int col, int *num_rows, int *num_cols ) const;
+
+ // this function returns 1 in num_rows and num_cols for normal cells,
+ // positive numbers for a cell spanning multiple columns/rows (as set with
+ // SetCellSize()) and _negative_ numbers corresponding to the offset of the
+ // top left cell of the span from this one for the other cells covered by
+ // this cell
+ //
+ // the return value is CellSpan_None, CellSpan_Main or CellSpan_Inside for
+ // each of these cases respectively
+ enum CellSpan
+ {
+ CellSpan_Inside = -1,
+ CellSpan_None = 0,
+ CellSpan_Main
+ };
+
+ CellSpan GetCellSize( int row, int col, int *num_rows, int *num_cols ) const;
+
wxSize GetCellSize(const wxGridCellCoords& coords)
{
wxSize s;
// ------ row and col sizes
void SetDefaultRowSize( int height, bool resizeExistingRows = false );
void SetRowSize( int row, int height );
- void HideRow(int row) { SetRowSize(row, 0); }
- void ShowRow(int row) { SetRowSize(row, -1); }
+ void HideRow(int row) { DoSetRowSize(row, 0); }
+ void ShowRow(int row) { DoSetRowSize(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); }
+ void HideCol(int col) { DoSetColSize(col, 0); }
+ void ShowCol(int col) { DoSetColSize(col, -1); }
+
+ // the row and column sizes can be also set all at once using
+ // wxGridSizesInfo which holds all of them at once
+
+ wxGridSizesInfo GetColSizes() const
+ { return wxGridSizesInfo(GetDefaultColSize(), m_colWidths); }
+ wxGridSizesInfo GetRowSizes() const
+ { return wxGridSizesInfo(GetDefaultRowSize(), m_rowHeights); }
+
+ void SetColSizes(const wxGridSizesInfo& sizeInfo);
+ void SetRowSizes(const wxGridSizesInfo& sizeInfo);
// ------- columns (only, for now) reordering
// 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
{
}
// Allow adjustment of scroll increment. The default is (15, 15).
- void SetScrollLineX(int x) { m_scrollLineX = x; }
- void SetScrollLineY(int y) { m_scrollLineY = y; }
- int GetScrollLineX() const { return m_scrollLineX; }
- int GetScrollLineY() const { return m_scrollLineY; }
+ void SetScrollLineX(int x) { m_xScrollPixelsPerLine = x; }
+ void SetScrollLineY(int y) { m_yScrollPixelsPerLine = y; }
+ int GetScrollLineX() const { return m_xScrollPixelsPerLine; }
+ int GetScrollLineY() const { return m_yScrollPixelsPerLine; }
// ------- drag and drop
#if wxUSE_DRAG_AND_DROP
// unset any existing sorting column
void UnsetSortingColumn() { SetSortingColumn(wxNOT_FOUND); }
-#ifdef WXWIN_COMPATIBILITY_2_8
+#if WXWIN_COMPATIBILITY_2_8
// ------ For compatibility with previous wxGrid only...
//
// ************************************************
void SetLabelAlignment( int orientation, int align )
{
if ( orientation == wxHORIZONTAL )
- SetColLabelAlignment( align, -1 );
+ SetColLabelAlignment( align, wxALIGN_INVALID );
else
- SetRowLabelAlignment( align, -1 );
+ SetRowLabelAlignment( align, wxALIGN_INVALID );
}
int GetLabelAlignment( int orientation, int WXUNUSED(align) ) const
wxGRID_CHECKBOX,
wxGRID_CHOICE,
wxGRID_COMBOBOX };
+
+ wxDEPRECATED_INLINE(bool CanDragRowSize() const, return m_canDragRowSize; )
+ wxDEPRECATED_INLINE(bool CanDragColSize() const, return m_canDragColSize; )
#endif // WXWIN_COMPATIBILITY_2_8
bool m_editable; // applies to whole grid
bool m_cellEditCtrlEnabled; // is in-place edit currently shown?
- int m_scrollLineX; // X scroll increment
- int m_scrollLineY; // Y scroll increment
+ TabBehaviour m_tabBehaviour; // determines how the TAB key behaves
void Init(); // common part of all ctors
void Create();
// it was processed (but not vetoed) and 0 if it wasn't processed
int SendEvent(const wxEventType evtType,
int row, int col,
- wxMouseEvent& e);
+ const wxMouseEvent& e);
int SendEvent(const wxEventType evtType,
const wxGridCellCoords& coords,
- wxMouseEvent& e)
+ const wxMouseEvent& e)
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
- int SendEvent(const wxEventType evtType, int row, int col);
- int SendEvent(const wxEventType evtType, const wxGridCellCoords& coords)
- { return SendEvent(evtType, coords.GetRow(), coords.GetCol()); }
- int SendEvent(const wxEventType evtType)
- { return SendEvent(evtType, m_currentCellCoords); }
+ int SendEvent(const wxEventType evtType,
+ int row, int col,
+ const wxString& s = wxString());
+ int SendEvent(const wxEventType evtType,
+ const wxGridCellCoords& coords,
+ const wxString& s = wxString())
+ { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), s); }
+ int SendEvent(const wxEventType evtType, const wxString& s = wxString())
+ { return SendEvent(evtType, m_currentCellCoords, s); }
+
+ // send wxEVT_GRID_{ROW,COL}_SIZE
+ void SendGridSizeEvent(wxEventType type,
+ int row, int col,
+ const wxMouseEvent& mouseEv);
void OnPaint( wxPaintEvent& );
void OnSize( wxSizeEvent& );
friend class wxGridColLabelWindow;
friend class wxGridRowLabelWindow;
friend class wxGridWindow;
+ friend class wxGridHeaderRenderer;
friend class wxGridHeaderCtrl;
private:
+
// implement wxScrolledWindow method to return m_gridWin size
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
// redraw the grid lines, should be called after changing their attributes
void RedrawGridLines();
+ // draw all grid lines in the given cell region (unlike the public
+ // DrawAllGridLines() which just draws all of them)
+ void DrawRangeGridLines(wxDC& dc, const wxRegion& reg,
+ const wxGridCellCoords& topLeft,
+ const wxGridCellCoords& bottomRight);
+
+ // draw all lines from top to bottom row and left to right column in the
+ // rectangle determined by (top, left)-(bottom, right) -- but notice that
+ // the caller must have set up the clipping correctly, this rectangle is
+ // only used here for optimization
+ void DoDrawGridLines(wxDC& dc,
+ int top, int left,
+ int bottom, int right,
+ int topRow, int leftCol,
+ int bottomRight, int rightCol);
+
// common part of Clip{Horz,Vert}GridLines
void DoClipGridLines(bool& var, bool clip);
// --------------------------------
// process mouse drag event in WXGRID_CURSOR_SELECT_CELL mode
- void DoGridCellDrag(wxMouseEvent& event,
+ bool DoGridCellDrag(wxMouseEvent& event,
const wxGridCellCoords& coords,
bool isFirstDrag);
void DoUpdateResizeColWidth(int w);
void DoStartMoveCol(int col);
- void DoEndDragResizeRow();
- void DoEndDragResizeCol(wxMouseEvent *event = NULL);
+ void DoEndDragResizeRow(const wxMouseEvent& event);
+ void DoEndDragResizeCol(const wxMouseEvent& event);
void DoEndMoveCol(int pos);
+ // process a TAB keypress
+ void DoGridProcessTab(wxKeyboardState& kbdState);
// common implementations of methods defined for both rows and columns
void DeselectLine(int line, const wxGridOperations& oper);
- void DoEndDragResizeLine(const wxGridOperations& oper);
+ bool DoEndDragResizeLine(const wxGridOperations& oper);
int PosToLinePos(int pos, bool clipToMinMax,
const wxGridOperations& oper) const;
int PosToLine(int pos, bool clipToMinMax,
bool DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
int num, bool updateLabels);
+ // common part of Set{Col,Row}Sizes
+ void DoSetSizes(const wxGridSizesInfo& sizeInfo,
+ const wxGridOperations& oper);
+
+ // common part of Disable{Row,Col}Resize and CanDrag{Row,Col}Size
+ void DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed);
+ bool DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const;
+
+ // Helper of Render(): get grid size, origin offset and fill cell arrays
+ void GetRenderSizes( const wxGridCellCoords& topLeft,
+ const wxGridCellCoords& bottomRight,
+ wxPoint& pointOffSet, wxSize& sizeGrid,
+ wxGridCellCoordsArray& renderCells,
+ wxArrayInt& arrayCols, wxArrayInt& arrayRows );
+
+ // Helper of Render(): set the scale to draw the cells at the right size.
+ void SetRenderScale( wxDC& dc, const wxPoint& pos, const wxSize& size,
+ const wxSize& sizeGrid );
+
+ // Helper of Render(): get render start position from passed parameter
+ wxPoint GetRenderPosition( wxDC& dc, const wxPoint& position );
+
+ // Helper of Render(): draws a box around the rendered area
+ void DoRenderBox( wxDC& dc, const int& style,
+ const wxPoint& pointOffSet,
+ const wxSize& sizeCellArea,
+ const wxGridCellCoords& topLeft,
+ const wxGridCellCoords& bottomRight );
+
+ // Implementation of public Set{Row,Col}Size() and {Hide,Show}{Row,Col}().
+ // They interpret their height or width parameter slightly different from
+ // the public methods where -1 in it means "auto fit to the label" for the
+ // compatibility reasons. Here it means "show a previously hidden row or
+ // column" while 0 means "hide it" just as in the public methods. And any
+ // positive values are handled naturally, i.e. they just specify the size.
+ void DoSetRowSize( int row, int height );
+ void DoSetColSize( int col, int width );
+
+
+ // these sets contain the indices of fixed, i.e. non-resizable
+ // interactively, grid rows or columns and are NULL if there are no fixed
+ // elements (which is the default)
+ wxGridFixedIndicesSet *m_setFixedRows,
+ *m_setFixedCols;
+
DECLARE_DYNAMIC_CLASS( wxGrid )
DECLARE_EVENT_TABLE()
- DECLARE_NO_COPY_CLASS(wxGrid)
+ wxDECLARE_NO_COPY_CLASS(wxGrid);
};
// ----------------------------------------------------------------------------
// more than once
void Create(wxGrid *grid)
{
- wxASSERT_MSG( !m_grid, _T("shouldn't be called more than once") );
+ wxASSERT_MSG( !m_grid, wxT("shouldn't be called more than once") );
Init(grid);
}
wxGrid *m_grid;
- DECLARE_NO_COPY_CLASS(wxGridUpdateLocker)
+ wxDECLARE_NO_COPY_CLASS(wxGridUpdateLocker);
};
// ----------------------------------------------------------------------------
// explicitly specifying inline allows gcc < 3.4 to
// handle the deprecation attribute even in the constructor.
- wxDEPRECATED( inline
+ wxDEPRECATED_CONSTRUCTOR(
wxGridEvent(int id,
wxEventType type,
wxObject* obj,
SetEventObject(obj);
}
- wxDEPRECATED( inline
+ wxDEPRECATED_CONSTRUCTOR(
wxGridSizeEvent(int id,
wxEventType type,
wxObject* obj,
SetEventObject(obj);
}
- wxDEPRECATED( inline
+ wxDEPRECATED_CONSTRUCTOR(
wxGridRangeSelectEvent(int id,
wxEventType type,
wxObject* obj,
};
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_LEFT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_RIGHT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_LEFT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_RIGHT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_LEFT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_RIGHT_CLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_LEFT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_RIGHT_DCLICK;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_ROW_SIZE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SIZE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_RANGE_SELECT;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_SELECT_CELL;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_SHOWN;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_HIDDEN;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_CREATED;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_BEGIN_DRAG;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_MOVE;
-extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SORT;
-
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_LEFT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_RIGHT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_ROW_SIZE, wxGridSizeEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_SIZE, wxGridSizeEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_CHANGING, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_CHANGED, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_SELECT_CELL, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_SHOWN, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_CELL_BEGIN_DRAG, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_MOVE, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_COL_SORT, wxGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_GRID_TABBING, wxGridEvent );
typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
typedef void (wxEvtHandler::*wxGridSizeEventFunction)(wxGridSizeEvent&);
typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreatedEvent&);
#define wxGridEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridEventFunction, &func)
+ wxEVENT_HANDLER_CAST(wxGridEventFunction, func)
#define wxGridSizeEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridSizeEventFunction, &func)
+ wxEVENT_HANDLER_CAST(wxGridSizeEventFunction, func)
#define wxGridRangeSelectEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridRangeSelectEventFunction, &func)
+ wxEVENT_HANDLER_CAST(wxGridRangeSelectEventFunction, func)
#define wxGridEditorCreatedEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxGridEditorCreatedEventFunction, &func)
+ wxEVENT_HANDLER_CAST(wxGridEditorCreatedEventFunction, func)
#define wx__DECLARE_GRIDEVT(evt, id, fn) \
wx__DECLARE_EVT1(wxEVT_GRID_ ## evt, id, wxGridEventHandler(fn))
#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_CMD_EDITOR_CREATED(id, fn) wx__DECLARE_GRIDEDITOREVT(EDITOR_CREATED, id, fn)
#define EVT_GRID_CMD_CELL_BEGIN_DRAG(id, fn) wx__DECLARE_GRIDEVT(CELL_BEGIN_DRAG, id, fn)
+#define EVT_GRID_CMD_TABBING(id, fn) wx__DECLARE_GRIDEVT(TABBING, id, fn)
// same as above but for any id (exists mainly for backwards compatibility but
// then it's also true that you rarely have multiple grid in the same window)
#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)
+#define EVT_GRID_TABBING(fn) EVT_GRID_CMD_TABBING(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_CHANGE_LABELS;
extern const int wxEVT_GRID_CHANGE_SEL_LABEL;
-#define EVT_GRID_CREATE_CELL(fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CREATE_CELL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
-#define EVT_GRID_CHANGE_LABELS(fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_LABELS, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
-#define EVT_GRID_CHANGE_SEL_LABEL(fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_SEL_LABEL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CREATE_CELL(fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CREATE_CELL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CHANGE_LABELS(fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_LABELS, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
+#define EVT_GRID_CHANGE_SEL_LABEL(fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_GRID_CHANGE_SEL_LABEL, wxID_ANY, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxGridEventFunction, &fn ), NULL ),
#endif