]> git.saurik.com Git - wxWidgets.git/commitdiff
pass ApplyEdit() arguments to EndEdit() too for better backwards compatibility (close...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 6 Mar 2009 10:38:45 +0000 (10:38 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 6 Mar 2009 10:38:45 +0000 (10:38 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59365 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
include/wx/generic/grideditors.h
interface/wx/grid.h
src/generic/grid.cpp
src/generic/grideditors.cpp

index c70ac4e4304dddbe675e09463088aaa9bc949de3..9c16160f286e7589a1377593447ab8e0dd41dfa6 100644 (file)
@@ -218,8 +218,10 @@ public:
     // 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
     // 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;
+    // 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
 
     // Complete the editing of the current cell by storing the value saved by
     // the previous call to EndEdit() in the grid
index a3a8d60c32aece122fdcb21365d8bbe5077a3a5e..b20efd93dc356c9e0d2fdba66a35c0b2b54cfb5a 100644 (file)
-/////////////////////////////////////////////////////////////////////////////
-// Name:        wx/generic/grideditors.h
-// Purpose:     wxGridCellEditorEvtHandler and wxGrid editors
-// Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn)
-// Modified by: Santiago Palacios
-// Created:     1/08/1999
-// RCS-ID:      $Id$
-// Copyright:   (c) Michael Bedward
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef _WX_GENERIC_GRID_EDITORS_H_
-#define _WX_GENERIC_GRID_EDITORS_H_
-
-#include "wx/defs.h"
-
-#if wxUSE_GRID
-
-class wxGridCellEditorEvtHandler : public wxEvtHandler
-{
-public:
-    wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor)
-        : m_grid(grid),
-          m_editor(editor),
-          m_inSetFocus(false)
-    {
-    }
-
-    void OnKillFocus(wxFocusEvent& event);
-    void OnKeyDown(wxKeyEvent& event);
-    void OnChar(wxKeyEvent& event);
-
-    void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; }
-
-private:
-    wxGrid             *m_grid;
-    wxGridCellEditor   *m_editor;
-
-    // Work around the fact that a focus kill event can be sent to
-    // a combobox within a set focus event.
-    bool                m_inSetFocus;
-
-    DECLARE_EVENT_TABLE()
-    DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
-    wxDECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler);
-};
-
-
-#if wxUSE_TEXTCTRL
-
-// the editor for string/text data
-class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor
-{
-public:
-    wxGridCellTextEditor();
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-    virtual void SetSize(const wxRect& rect);
-
-    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(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_value;
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellTextEditor);
-};
-
-// the editor for numeric (long) data
-class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor
-{
-public:
-    // allows to specify the range - if min == max == -1, no range checking is
-    // done
-    wxGridCellNumberEditor(int min = -1, int max = -1);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(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 our value
-    wxString GetString() const
-        { return wxString::Format(_T("%ld"), m_value); }
-
-private:
-    int m_min,
-        m_max;
-
-    long m_value;
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellNumberEditor);
-};
-
-// the editor for floating point numbers (double) data
-class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor
-{
-public:
-    wxGridCellFloatEditor(int width = -1, int precision = -1);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(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 our value
-    wxString GetString() const;
-
-private:
-    int m_width,
-        m_precision;
-    double m_value;
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellFloatEditor);
-};
-
-#endif // wxUSE_TEXTCTRL
-
-#if wxUSE_CHECKBOX
-
-// the editor for boolean data
-class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor
-{
-public:
-    wxGridCellBoolEditor() { }
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual void SetSize(const wxRect& rect);
-    virtual void Show(bool show, wxGridCellAttr *attr = NULL);
-
-    virtual bool IsAcceptedKey(wxKeyEvent& event);
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(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_value;
-
-    static wxString ms_stringValues[2];
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellBoolEditor);
-};
-
-#endif // wxUSE_CHECKBOX
-
-#if wxUSE_COMBOBOX
-
-// the editor for string data allowing to choose from the list of strings
-class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor
-{
-public:
-    // if !allowOthers, user can't type a string not in choices array
-    wxGridCellChoiceEditor(size_t count = 0,
-                           const wxString choices[] = NULL,
-                           bool allowOthers = false);
-    wxGridCellChoiceEditor(const wxArrayString& choices,
-                           bool allowOthers = false);
-
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
-
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(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; }
-
-    wxString        m_value;
-    wxArrayString   m_choices;
-    bool            m_allowOthers;
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor);
-};
-
-#endif // wxUSE_COMBOBOX
-
-#if wxUSE_COMBOBOX
-
-class WXDLLIMPEXP_ADV wxGridCellEnumEditor : public wxGridCellChoiceEditor
-{
-public:
-    wxGridCellEnumEditor( const wxString& choices = wxEmptyString );
-    virtual ~wxGridCellEnumEditor() {}
-
-    virtual wxGridCellEditor*  Clone() const;
-
-    virtual void BeginEdit(int row, int col, wxGrid* grid);
-    virtual bool EndEdit(const wxString& oldval, wxString *newval);
-    virtual void ApplyEdit(int row, int col, wxGrid* grid);
-
-private:
-    long m_index;
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellEnumEditor);
-};
-
-#endif // wxUSE_COMBOBOX
-
-class WXDLLIMPEXP_ADV wxGridCellAutoWrapStringEditor : public wxGridCellTextEditor
-{
-public:
-    wxGridCellAutoWrapStringEditor() : wxGridCellTextEditor() { }
-    virtual void Create(wxWindow* parent,
-                        wxWindowID id,
-                        wxEvtHandler* evtHandler);
-
-    virtual wxGridCellEditor *Clone() const
-        { return new wxGridCellAutoWrapStringEditor; }
-
-    wxDECLARE_NO_COPY_CLASS(wxGridCellAutoWrapStringEditor);
-};
-
-#endif // wxUSE_GRID
-#endif // _WX_GENERIC_GRID_EDITORS_H_
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        wx/generic/grideditors.h\r
+// Purpose:     wxGridCellEditorEvtHandler and wxGrid editors\r
+// Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn)\r
+// Modified by: Santiago Palacios\r
+// Created:     1/08/1999\r
+// RCS-ID:      $Id$\r
+// Copyright:   (c) Michael Bedward\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_GENERIC_GRID_EDITORS_H_\r
+#define _WX_GENERIC_GRID_EDITORS_H_\r
+\r
+#include "wx/defs.h"\r
+\r
+#if wxUSE_GRID\r
+\r
+class wxGridCellEditorEvtHandler : public wxEvtHandler\r
+{\r
+public:\r
+    wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor)\r
+        : m_grid(grid),\r
+          m_editor(editor),\r
+          m_inSetFocus(false)\r
+    {\r
+    }\r
+\r
+    void OnKillFocus(wxFocusEvent& event);\r
+    void OnKeyDown(wxKeyEvent& event);\r
+    void OnChar(wxKeyEvent& event);\r
+\r
+    void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; }\r
+\r
+private:\r
+    wxGrid             *m_grid;\r
+    wxGridCellEditor   *m_editor;\r
+\r
+    // Work around the fact that a focus kill event can be sent to\r
+    // a combobox within a set focus event.\r
+    bool                m_inSetFocus;\r
+\r
+    DECLARE_EVENT_TABLE()\r
+    DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler);\r
+};\r
+\r
+\r
+#if wxUSE_TEXTCTRL\r
+\r
+// the editor for string/text data\r
+class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor\r
+{\r
+public:\r
+    wxGridCellTextEditor();\r
+\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+    virtual void SetSize(const wxRect& rect);\r
+\r
+    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);\r
+\r
+    virtual bool IsAcceptedKey(wxKeyEvent& event);\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+    virtual void Reset();\r
+    virtual void StartingKey(wxKeyEvent& event);\r
+    virtual void HandleReturn(wxKeyEvent& event);\r
+\r
+    // parameters string format is "max_width"\r
+    virtual void SetParameters(const wxString& params);\r
+\r
+    virtual wxGridCellEditor *Clone() const\r
+        { return new wxGridCellTextEditor; }\r
+\r
+    // added GetValue so we can get the value which is in the control\r
+    virtual wxString GetValue() const;\r
+\r
+protected:\r
+    wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; }\r
+\r
+    // parts of our virtual functions reused by the derived classes\r
+    void DoCreate(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler,\r
+                  long style = 0);\r
+    void DoBeginEdit(const wxString& startValue);\r
+    void DoReset(const wxString& startValue);\r
+\r
+private:\r
+    size_t   m_maxChars;        // max number of chars allowed\r
+    wxString m_value;\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellTextEditor);\r
+};\r
+\r
+// the editor for numeric (long) data\r
+class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor\r
+{\r
+public:\r
+    // allows to specify the range - if min == max == -1, no range checking is\r
+    // done\r
+    wxGridCellNumberEditor(int min = -1, int max = -1);\r
+\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+\r
+    virtual bool IsAcceptedKey(wxKeyEvent& event);\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+    virtual void Reset();\r
+    virtual void StartingKey(wxKeyEvent& event);\r
+\r
+    // parameters string format is "min,max"\r
+    virtual void SetParameters(const wxString& params);\r
+\r
+    virtual wxGridCellEditor *Clone() const\r
+        { return new wxGridCellNumberEditor(m_min, m_max); }\r
+\r
+    // added GetValue so we can get the value which is in the control\r
+    virtual wxString GetValue() const;\r
+\r
+protected:\r
+#if wxUSE_SPINCTRL\r
+    wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; }\r
+#endif\r
+\r
+    // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl\r
+    bool HasRange() const\r
+    {\r
+#if wxUSE_SPINCTRL\r
+        return m_min != m_max;\r
+#else\r
+        return false;\r
+#endif\r
+    }\r
+\r
+    // string representation of our value\r
+    wxString GetString() const\r
+        { return wxString::Format(_T("%ld"), m_value); }\r
+\r
+private:\r
+    int m_min,\r
+        m_max;\r
+\r
+    long m_value;\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellNumberEditor);\r
+};\r
+\r
+// the editor for floating point numbers (double) data\r
+class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor\r
+{\r
+public:\r
+    wxGridCellFloatEditor(int width = -1, int precision = -1);\r
+\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+\r
+    virtual bool IsAcceptedKey(wxKeyEvent& event);\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+    virtual void Reset();\r
+    virtual void StartingKey(wxKeyEvent& event);\r
+\r
+    virtual wxGridCellEditor *Clone() const\r
+        { return new wxGridCellFloatEditor(m_width, m_precision); }\r
+\r
+    // parameters string format is "width,precision"\r
+    virtual void SetParameters(const wxString& params);\r
+\r
+protected:\r
+    // string representation of our value\r
+    wxString GetString() const;\r
+\r
+private:\r
+    int m_width,\r
+        m_precision;\r
+    double m_value;\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellFloatEditor);\r
+};\r
+\r
+#endif // wxUSE_TEXTCTRL\r
+\r
+#if wxUSE_CHECKBOX\r
+\r
+// the editor for boolean data\r
+class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor\r
+{\r
+public:\r
+    wxGridCellBoolEditor() { }\r
+\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+\r
+    virtual void SetSize(const wxRect& rect);\r
+    virtual void Show(bool show, wxGridCellAttr *attr = NULL);\r
+\r
+    virtual bool IsAcceptedKey(wxKeyEvent& event);\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+    virtual void Reset();\r
+    virtual void StartingClick();\r
+    virtual void StartingKey(wxKeyEvent& event);\r
+\r
+    virtual wxGridCellEditor *Clone() const\r
+        { return new wxGridCellBoolEditor; }\r
+\r
+    // added GetValue so we can get the value which is in the control, see\r
+    // also UseStringValues()\r
+    virtual wxString GetValue() const;\r
+\r
+    // set the string values returned by GetValue() for the true and false\r
+    // states, respectively\r
+    static void UseStringValues(const wxString& valueTrue = _T("1"),\r
+                                const wxString& valueFalse = wxEmptyString);\r
+\r
+    // return true if the given string is equal to the string representation of\r
+    // true value which we currently use\r
+    static bool IsTrueValue(const wxString& value);\r
+\r
+protected:\r
+    wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }\r
+\r
+private:\r
+    bool m_value;\r
+\r
+    static wxString ms_stringValues[2];\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellBoolEditor);\r
+};\r
+\r
+#endif // wxUSE_CHECKBOX\r
+\r
+#if wxUSE_COMBOBOX\r
+\r
+// the editor for string data allowing to choose from the list of strings\r
+class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor\r
+{\r
+public:\r
+    // if !allowOthers, user can't type a string not in choices array\r
+    wxGridCellChoiceEditor(size_t count = 0,\r
+                           const wxString choices[] = NULL,\r
+                           bool allowOthers = false);\r
+    wxGridCellChoiceEditor(const wxArrayString& choices,\r
+                           bool allowOthers = false);\r
+\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+\r
+    virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);\r
+\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+    virtual void Reset();\r
+\r
+    // parameters string format is "item1[,item2[...,itemN]]"\r
+    virtual void SetParameters(const wxString& params);\r
+\r
+    virtual wxGridCellEditor *Clone() const;\r
+\r
+    // added GetValue so we can get the value which is in the control\r
+    virtual wxString GetValue() const;\r
+\r
+protected:\r
+    wxComboBox *Combo() const { return (wxComboBox *)m_control; }\r
+\r
+    wxString        m_value;\r
+    wxArrayString   m_choices;\r
+    bool            m_allowOthers;\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor);\r
+};\r
+\r
+#endif // wxUSE_COMBOBOX\r
+\r
+#if wxUSE_COMBOBOX\r
+\r
+class WXDLLIMPEXP_ADV wxGridCellEnumEditor : public wxGridCellChoiceEditor\r
+{\r
+public:\r
+    wxGridCellEnumEditor( const wxString& choices = wxEmptyString );\r
+    virtual ~wxGridCellEnumEditor() {}\r
+\r
+    virtual wxGridCellEditor*  Clone() const;\r
+\r
+    virtual void BeginEdit(int row, int col, wxGrid* grid);\r
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,\r
+                         const wxString& oldval, wxString *newval);\r
+    virtual void ApplyEdit(int row, int col, wxGrid* grid);\r
+\r
+private:\r
+    long m_index;\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellEnumEditor);\r
+};\r
+\r
+#endif // wxUSE_COMBOBOX\r
+\r
+class WXDLLIMPEXP_ADV wxGridCellAutoWrapStringEditor : public wxGridCellTextEditor\r
+{\r
+public:\r
+    wxGridCellAutoWrapStringEditor() : wxGridCellTextEditor() { }\r
+    virtual void Create(wxWindow* parent,\r
+                        wxWindowID id,\r
+                        wxEvtHandler* evtHandler);\r
+\r
+    virtual wxGridCellEditor *Clone() const\r
+        { return new wxGridCellAutoWrapStringEditor; }\r
+\r
+    wxDECLARE_NO_COPY_CLASS(wxGridCellAutoWrapStringEditor);\r
+};\r
+\r
+#endif // wxUSE_GRID\r
+\r
+#endif // _WX_GENERIC_GRID_EDITORS_H_\r
index f6b9ef2ff0a0ea9a45394481a98f848f0fa9c805..22f1ff4f59a4f80dfaa2e3788b5aaa4cad410ab6 100644 (file)
@@ -218,14 +218,21 @@ public:
         This function must check if the current value of the editing control is
         valid and different from the original value (available as @a oldval in
         its string form and possibly saved internally using its real type by
         This function must check if the current value of the editing control is
         valid and different from the original value (available as @a oldval in
         its string form and possibly saved internally using its real type by
-        BeginEdit()). If it isn't, it just returns @false, otherwise it fills
-        @a newval with the representation of the new value in the string form,
-        if necessary saves it using its real type internally, and returns @true.
+        BeginEdit()). If it isn't, it just returns @false, otherwise it must do
+        the following:
+            # Save the new value internally so that ApplyEdit() could apply it.
+            # Fill @a newval (which is never @NULL) with the string
+            representation of the new value.
+            # Return @true
+
+        Notice that it must @em not modify the grid as the change could still
+        be vetoed.
 
         If the user-defined wxEVT_GRID_CELL_CHANGING event handler doesn't veto
         this change, ApplyEdit() will be called next.
     */
 
         If the user-defined wxEVT_GRID_CELL_CHANGING event handler doesn't veto
         this change, ApplyEdit() will be called next.
     */
-    virtual bool EndEdit(const wxString& oldval, wxString* newval) = 0;
+    virtual bool EndEdit(int row, int col, const wxGrid* grid,
+                         const wxString& oldval, wxString* newval) = 0;
 
     /**
         Effectively save the changes in the grid.
 
     /**
         Effectively save the changes in the grid.
index 91dce5ee8aa6ec6d6893a0da68362d7b85daa59e..d7ec66fcb2981b07e435f1bc010314c812277c49 100644 (file)
@@ -5976,7 +5976,7 @@ void wxGrid::SaveEditControlValue()
         wxGridCellEditor* editor = attr->GetEditor(this, row, col);
 
         wxString newval;
         wxGridCellEditor* editor = attr->GetEditor(this, row, col);
 
         wxString newval;
-        bool changed = editor->EndEdit(oldval, &newval);
+        bool changed = editor->EndEdit(row, col, this, oldval, &newval);
 
         if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 )
         {
 
         if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 )
         {
index 1ece439bf7749e83f3c2d1ded181e1622a1c789b..6ef0c4a2c2b5d66e5b71803a916ee02fda3f31a4 100644 (file)
-///////////////////////////////////////////////////////////////////////////
-// Name:        src/generic/grideditors.cpp
-// Purpose:     wxGridCellEditorEvtHandler and wxGrid editors
-// Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn)
-// Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios
-// Created:     1/08/1999
-// RCS-ID:      $Id$
-// Copyright:   (c) Michael Bedward (mbedward@ozemail.com.au)
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-// For compilers that support precompilation, includes "wx/wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-    #pragma hdrstop
-#endif
-
-#if wxUSE_GRID
-
-#include "wx/grid.h"
-
-#ifndef WX_PRECOMP
-    #include "wx/utils.h"
-    #include "wx/dcclient.h"
-    #include "wx/settings.h"
-    #include "wx/log.h"
-    #include "wx/textctrl.h"
-    #include "wx/checkbox.h"
-    #include "wx/combobox.h"
-    #include "wx/valtext.h"
-    #include "wx/intl.h"
-    #include "wx/math.h"
-    #include "wx/listbox.h"
-#endif
-
-#include "wx/textfile.h"
-#include "wx/spinctrl.h"
-#include "wx/tokenzr.h"
-#include "wx/renderer.h"
-#include "wx/headerctrl.h"
-
-#include "wx/generic/gridsel.h"
-#include "wx/generic/grideditors.h"
-#include "wx/generic/private/grid.h"
-
-#if defined(__WXMOTIF__)
-    #define WXUNUSED_MOTIF(identifier)  WXUNUSED(identifier)
-#else
-    #define WXUNUSED_MOTIF(identifier)  identifier
-#endif
-
-#if defined(__WXGTK__)
-    #define WXUNUSED_GTK(identifier)    WXUNUSED(identifier)
-#else
-    #define WXUNUSED_GTK(identifier)    identifier
-#endif
-
-// Required for wxIs... functions
-#include <ctype.h>
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// wxGridCellEditorEvtHandler
-// ----------------------------------------------------------------------------
-
-void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)
-{
-    // Don't disable the cell if we're just starting to edit it
-    if ( m_inSetFocus )
-    {
-        event.Skip();
-        return;
-    }
-
-    // accept changes
-    m_grid->DisableCellEditControl();
-
-    // notice that we must not skip the event here because the call above may
-    // delete the control which received the kill focus event in the first
-    // place and if we pretend not having processed the event, the search for a
-    // handler for it will continue using the now deleted object resulting in a
-    // crash
-}
-
-void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
-{
-    switch ( event.GetKeyCode() )
-    {
-        case WXK_ESCAPE:
-            m_editor->Reset();
-            m_grid->DisableCellEditControl();
-            break;
-
-        case WXK_TAB:
-            m_grid->GetEventHandler()->ProcessEvent( event );
-            break;
-
-        case WXK_RETURN:
-        case WXK_NUMPAD_ENTER:
-            if (!m_grid->GetEventHandler()->ProcessEvent(event))
-                m_editor->HandleReturn(event);
-            break;
-
-        default:
-            event.Skip();
-            break;
-    }
-}
-
-void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event)
-{
-    int row = m_grid->GetGridCursorRow();
-    int col = m_grid->GetGridCursorCol();
-    wxRect rect = m_grid->CellToRect( row, col );
-    int cw, ch;
-    m_grid->GetGridWindow()->GetClientSize( &cw, &ch );
-
-    // if cell width is smaller than grid client area, cell is wholly visible
-    bool wholeCellVisible = (rect.GetWidth() < cw);
-
-    switch ( event.GetKeyCode() )
-    {
-        case WXK_ESCAPE:
-        case WXK_TAB:
-        case WXK_RETURN:
-        case WXK_NUMPAD_ENTER:
-            break;
-
-        case WXK_HOME:
-        {
-            if ( wholeCellVisible )
-            {
-                // no special processing needed...
-                event.Skip();
-                break;
-            }
-
-            // do special processing for partly visible cell...
-
-            // get the widths of all cells previous to this one
-            int colXPos = 0;
-            for ( int i = 0; i < col; i++ )
-            {
-                colXPos += m_grid->GetColSize(i);
-            }
-
-            int xUnit = 1, yUnit = 1;
-            m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit);
-            if (col != 0)
-            {
-                m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL));
-            }
-            else
-            {
-                m_grid->Scroll(colXPos / xUnit, m_grid->GetScrollPos(wxVERTICAL));
-            }
-            event.Skip();
-            break;
-        }
-
-        case WXK_END:
-        {
-            if ( wholeCellVisible )
-            {
-                // no special processing needed...
-                event.Skip();
-                break;
-            }
-
-            // do special processing for partly visible cell...
-
-            int textWidth = 0;
-            wxString value = m_grid->GetCellValue(row, col);
-            if ( wxEmptyString != value )
-            {
-                // get width of cell CONTENTS (text)
-                int y;
-                wxFont font = m_grid->GetCellFont(row, col);
-                m_grid->GetTextExtent(value, &textWidth, &y, NULL, NULL, &font);
-
-                // try to RIGHT align the text by scrolling
-                int client_right = m_grid->GetGridWindow()->GetClientSize().GetWidth();
-
-                // (m_grid->GetScrollLineX()*2) is a factor for not scrolling to far,
-                // otherwise the last part of the cell content might be hidden below the scroll bar
-                // FIXME: maybe there is a more suitable correction?
-                textWidth -= (client_right - (m_grid->GetScrollLineX() * 2));
-                if ( textWidth < 0 )
-                {
-                    textWidth = 0;
-                }
-            }
-
-            // get the widths of all cells previous to this one
-            int colXPos = 0;
-            for ( int i = 0; i < col; i++ )
-            {
-                colXPos += m_grid->GetColSize(i);
-            }
-
-            // and add the (modified) text width of the cell contents
-            // as we'd like to see the last part of the cell contents
-            colXPos += textWidth;
-
-            int xUnit = 1, yUnit = 1;
-            m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit);
-            m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL));
-            event.Skip();
-            break;
-        }
-
-        default:
-            event.Skip();
-            break;
-    }
-}
-
-// ----------------------------------------------------------------------------
-// wxGridCellEditor
-// ----------------------------------------------------------------------------
-
-wxGridCellEditor::wxGridCellEditor()
-{
-    m_control = NULL;
-    m_attr = NULL;
-}
-
-wxGridCellEditor::~wxGridCellEditor()
-{
-    Destroy();
-}
-
-void wxGridCellEditor::Create(wxWindow* WXUNUSED(parent),
-                              wxWindowID WXUNUSED(id),
-                              wxEvtHandler* evtHandler)
-{
-    if ( evtHandler )
-        m_control->PushEventHandler(evtHandler);
-}
-
-void wxGridCellEditor::PaintBackground(const wxRect& rectCell,
-                                       wxGridCellAttr *attr)
-{
-    // erase the background because we might not fill the cell
-    wxClientDC dc(m_control->GetParent());
-    wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow);
-    if (gridWindow)
-        gridWindow->GetOwner()->PrepareDC(dc);
-
-    dc.SetPen(*wxTRANSPARENT_PEN);
-    dc.SetBrush(wxBrush(attr->GetBackgroundColour()));
-    dc.DrawRectangle(rectCell);
-
-    // redraw the control we just painted over
-    m_control->Refresh();
-}
-
-void wxGridCellEditor::Destroy()
-{
-    if (m_control)
-    {
-        m_control->PopEventHandler( true /* delete it*/ );
-
-        m_control->Destroy();
-        m_control = NULL;
-    }
-}
-
-void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
-{
-    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
-
-    m_control->Show(show);
-
-    if ( show )
-    {
-        // set the colours/fonts if we have any
-        if ( attr )
-        {
-            m_colFgOld = m_control->GetForegroundColour();
-            m_control->SetForegroundColour(attr->GetTextColour());
-
-            m_colBgOld = m_control->GetBackgroundColour();
-            m_control->SetBackgroundColour(attr->GetBackgroundColour());
-
-// Workaround for GTK+1 font setting problem on some platforms
-#if !defined(__WXGTK__) || defined(__WXGTK20__)
-            m_fontOld = m_control->GetFont();
-            m_control->SetFont(attr->GetFont());
-#endif
-
-            // can't do anything more in the base class version, the other
-            // attributes may only be used by the derived classes
-        }
-    }
-    else
-    {
-        // restore the standard colours fonts
-        if ( m_colFgOld.Ok() )
-        {
-            m_control->SetForegroundColour(m_colFgOld);
-            m_colFgOld = wxNullColour;
-        }
-
-        if ( m_colBgOld.Ok() )
-        {
-            m_control->SetBackgroundColour(m_colBgOld);
-            m_colBgOld = wxNullColour;
-        }
-
-// Workaround for GTK+1 font setting problem on some platforms
-#if !defined(__WXGTK__) || defined(__WXGTK20__)
-        if ( m_fontOld.Ok() )
-        {
-            m_control->SetFont(m_fontOld);
-            m_fontOld = wxNullFont;
-        }
-#endif
-    }
-}
-
-void wxGridCellEditor::SetSize(const wxRect& rect)
-{
-    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
-
-    m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
-}
-
-void wxGridCellEditor::HandleReturn(wxKeyEvent& event)
-{
-    event.Skip();
-}
-
-bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event)
-{
-    bool ctrl = event.ControlDown();
-    bool alt  = event.AltDown();
-
-#ifdef __WXMAC__
-    // On the Mac the Alt key is more like shift and is used for entry of
-    // valid characters, so check for Ctrl and Meta instead.
-    alt = event.MetaDown();
-#endif
-
-    // Assume it's not a valid char if ctrl or alt is down, but if both are
-    // down then it may be because of an AltGr key combination, so let them
-    // through in that case.
-    if ((ctrl || alt) && !(ctrl && alt))
-        return false;
-
-#if wxUSE_UNICODE
-    // if the unicode key code is not really a unicode character (it may
-    // be a function key or etc., the platforms appear to always give us a
-    // small value in this case) then fallback to the ASCII key code but
-    // don't do anything for function keys or etc.
-    if ( event.GetUnicodeKey() > 127 && event.GetKeyCode() > 127 )
-        return false;
-#else
-    if ( event.GetKeyCode() > 255 )
-        return false;
-#endif
-
-    return true;
-}
-
-void wxGridCellEditor::StartingKey(wxKeyEvent& event)
-{
-    event.Skip();
-}
-
-void wxGridCellEditor::StartingClick()
-{
-}
-
-#if wxUSE_TEXTCTRL
-
-// ----------------------------------------------------------------------------
-// wxGridCellTextEditor
-// ----------------------------------------------------------------------------
-
-wxGridCellTextEditor::wxGridCellTextEditor()
-{
-    m_maxChars = 0;
-}
-
-void wxGridCellTextEditor::Create(wxWindow* parent,
-                                  wxWindowID id,
-                                  wxEvtHandler* evtHandler)
-{
-    DoCreate(parent, id, evtHandler);
-}
-
-void wxGridCellTextEditor::DoCreate(wxWindow* parent,
-                                    wxWindowID id,
-                                    wxEvtHandler* evtHandler,
-                                    long style)
-{
-    style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER;
-
-    m_control = new wxTextCtrl(parent, id, wxEmptyString,
-                               wxDefaultPosition, wxDefaultSize,
-                               style);
-
-    // set max length allowed in the textctrl, if the parameter was set
-    if ( m_maxChars != 0 )
-    {
-        Text()->SetMaxLength(m_maxChars);
-    }
-
-    wxGridCellEditor::Create(parent, id, evtHandler);
-}
-
-void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),
-                                           wxGridCellAttr * WXUNUSED(attr))
-{
-    // as we fill the entire client area,
-    // don't do anything here to minimize flicker
-}
-
-void wxGridCellTextEditor::SetSize(const wxRect& rectOrig)
-{
-    wxRect rect(rectOrig);
-
-    // Make the edit control large enough to allow for internal margins
-    //
-    // TODO: remove this if the text ctrl sizing is improved esp. for unix
-    //
-#if defined(__WXGTK__)
-    if (rect.x != 0)
-    {
-        rect.x += 1;
-        rect.y += 1;
-        rect.width -= 1;
-        rect.height -= 1;
-    }
-#elif defined(__WXMSW__)
-    if ( rect.x == 0 )
-        rect.x += 2;
-    else
-        rect.x += 3;
-
-    if ( rect.y == 0 )
-        rect.y += 2;
-    else
-        rect.y += 3;
-
-    rect.width -= 2;
-    rect.height -= 2;
-#else
-    int extra_x = ( rect.x > 2 ) ? 2 : 1;
-    int extra_y = ( rect.y > 2 ) ? 2 : 1;
-
-    #if defined(__WXMOTIF__)
-        extra_x *= 2;
-        extra_y *= 2;
-    #endif
-
-    rect.SetLeft( wxMax(0, rect.x - extra_x) );
-    rect.SetTop( wxMax(0, rect.y - extra_y) );
-    rect.SetRight( rect.GetRight() + 2 * extra_x );
-    rect.SetBottom( rect.GetBottom() + 2 * extra_y );
-#endif
-
-    wxGridCellEditor::SetSize(rect);
-}
-
-void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
-
-    m_value = grid->GetTable()->GetValue(row, col);
-
-    DoBeginEdit(m_value);
-}
-
-void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue)
-{
-    Text()->SetValue(startValue);
-    Text()->SetInsertionPointEnd();
-    Text()->SetSelection(-1, -1);
-    Text()->SetFocus();
-}
-
-bool wxGridCellTextEditor::EndEdit(const wxString& WXUNUSED(oldval),
-                                   wxString *newval)
-{
-    wxCHECK_MSG( m_control, false,
-                 "wxGridCellTextEditor must be created first!" );
-
-    const wxString value = Text()->GetValue();
-    if ( value == m_value )
-        return false;
-
-    m_value = value;
-
-    if ( newval )
-        *newval = m_value;
-
-    return true;
-}
-
-void wxGridCellTextEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    grid->GetTable()->SetValue(row, col, m_value);
-    m_value.clear();
-}
-
-void wxGridCellTextEditor::Reset()
-{
-    wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" );
-
-    DoReset(m_value);
-}
-
-void wxGridCellTextEditor::DoReset(const wxString& startValue)
-{
-    Text()->SetValue(startValue);
-    Text()->SetInsertionPointEnd();
-}
-
-bool wxGridCellTextEditor::IsAcceptedKey(wxKeyEvent& event)
-{
-    return wxGridCellEditor::IsAcceptedKey(event);
-}
-
-void wxGridCellTextEditor::StartingKey(wxKeyEvent& event)
-{
-    // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no
-    // longer an appropriate way to get the character into the text control.
-    // Do it ourselves instead.  We know that if we get this far that we have
-    // a valid character, so not a whole lot of testing needs to be done.
-
-    wxTextCtrl* tc = Text();
-    wxChar ch;
-    long pos;
-
-#if wxUSE_UNICODE
-    ch = event.GetUnicodeKey();
-    if (ch <= 127)
-        ch = (wxChar)event.GetKeyCode();
-#else
-    ch = (wxChar)event.GetKeyCode();
-#endif
-
-    switch (ch)
-    {
-        case WXK_DELETE:
-            // delete the character at the cursor
-            pos = tc->GetInsertionPoint();
-            if (pos < tc->GetLastPosition())
-                tc->Remove(pos, pos + 1);
-            break;
-
-        case WXK_BACK:
-            // delete the character before the cursor
-            pos = tc->GetInsertionPoint();
-            if (pos > 0)
-                tc->Remove(pos - 1, pos);
-            break;
-
-        default:
-            tc->WriteText(ch);
-            break;
-    }
-}
-
-void wxGridCellTextEditor::HandleReturn( wxKeyEvent&
-                                         WXUNUSED_GTK(WXUNUSED_MOTIF(event)) )
-{
-#if defined(__WXMOTIF__) || defined(__WXGTK__)
-    // wxMotif needs a little extra help...
-    size_t pos = (size_t)( Text()->GetInsertionPoint() );
-    wxString s( Text()->GetValue() );
-    s = s.Left(pos) + wxT("\n") + s.Mid(pos);
-    Text()->SetValue(s);
-    Text()->SetInsertionPoint( pos );
-#else
-    // the other ports can handle a Return key press
-    //
-    event.Skip();
-#endif
-}
-
-void wxGridCellTextEditor::SetParameters(const wxString& params)
-{
-    if ( !params )
-    {
-        // reset to default
-        m_maxChars = 0;
-    }
-    else
-    {
-        long tmp;
-        if ( params.ToLong(&tmp) )
-        {
-            m_maxChars = (size_t)tmp;
-        }
-        else
-        {
-            wxLogDebug( _T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str() );
-        }
-    }
-}
-
-// return the value in the text control
-wxString wxGridCellTextEditor::GetValue() const
-{
-    return Text()->GetValue();
-}
-
-// ----------------------------------------------------------------------------
-// wxGridCellNumberEditor
-// ----------------------------------------------------------------------------
-
-wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max)
-{
-    m_min = min;
-    m_max = max;
-}
-
-void wxGridCellNumberEditor::Create(wxWindow* parent,
-                                    wxWindowID id,
-                                    wxEvtHandler* evtHandler)
-{
-#if wxUSE_SPINCTRL
-    if ( HasRange() )
-    {
-        // create a spin ctrl
-        m_control = new wxSpinCtrl(parent, wxID_ANY, wxEmptyString,
-                                   wxDefaultPosition, wxDefaultSize,
-                                   wxSP_ARROW_KEYS,
-                                   m_min, m_max);
-
-        wxGridCellEditor::Create(parent, id, evtHandler);
-    }
-    else
-#endif
-    {
-        // just a text control
-        wxGridCellTextEditor::Create(parent, id, evtHandler);
-
-#if wxUSE_VALIDATORS
-        Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
-#endif
-    }
-}
-
-void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    // first get the value
-    wxGridTableBase *table = grid->GetTable();
-    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
-    {
-        m_value = table->GetValueAsLong(row, col);
-    }
-    else
-    {
-        m_value = 0;
-        wxString sValue = table->GetValue(row, col);
-        if (! sValue.ToLong(&m_value) && ! sValue.empty())
-        {
-            wxFAIL_MSG( _T("this cell doesn't have numeric value") );
-            return;
-        }
-    }
-
-#if wxUSE_SPINCTRL
-    if ( HasRange() )
-    {
-        Spin()->SetValue((int)m_value);
-        Spin()->SetFocus();
-    }
-    else
-#endif
-    {
-        DoBeginEdit(GetString());
-    }
-}
-
-bool wxGridCellNumberEditor::EndEdit(const wxString& oldval, wxString *newval)
-{
-    long value = 0;
-    wxString text;
-
-#if wxUSE_SPINCTRL
-    if ( HasRange() )
-    {
-        value = Spin()->GetValue();
-        if ( value == m_value )
-            return false;
-
-        text.Printf(wxT("%ld"), value);
-    }
-    else // using unconstrained input
-#endif // wxUSE_SPINCTRL
-    {
-        text = Text()->GetValue();
-        if ( text.empty() )
-        {
-            if ( oldval.empty() )
-                return false;
-        }
-        else // non-empty text now (maybe 0)
-        {
-            if ( !text.ToLong(&value) )
-                return false;
-
-            // if value == m_value == 0 but old text was "" and new one is
-            // "0" something still did change
-            if ( value == m_value && (value || !oldval.empty()) )
-                return false;
-        }
-    }
-
-    m_value = value;
-
-    if ( newval )
-        *newval = text;
-
-    return true;
-}
-
-void wxGridCellNumberEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    wxGridTableBase * const table = grid->GetTable();
-    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )
-        table->SetValueAsLong(row, col, m_value);
-    else
-        table->SetValue(row, col, wxString::Format("%ld", m_value));
-}
-
-void wxGridCellNumberEditor::Reset()
-{
-#if wxUSE_SPINCTRL
-    if ( HasRange() )
-    {
-        Spin()->SetValue((int)m_value);
-    }
-    else
-#endif
-    {
-        DoReset(GetString());
-    }
-}
-
-bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event)
-{
-    if ( wxGridCellEditor::IsAcceptedKey(event) )
-    {
-        int keycode = event.GetKeyCode();
-        if ( (keycode < 128) &&
-             (wxIsdigit(keycode) || keycode == '+' || keycode == '-'))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
-{
-    int keycode = event.GetKeyCode();
-    if ( !HasRange() )
-    {
-        if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-')
-        {
-            wxGridCellTextEditor::StartingKey(event);
-
-            // skip Skip() below
-            return;
-        }
-    }
-#if wxUSE_SPINCTRL
-    else
-    {
-        if ( wxIsdigit(keycode) )
-        {
-            wxSpinCtrl* spin = (wxSpinCtrl*)m_control;
-            spin->SetValue(keycode - '0');
-            spin->SetSelection(1,1);
-            return;
-        }
-    }
-#endif
-
-    event.Skip();
-}
-
-void wxGridCellNumberEditor::SetParameters(const wxString& params)
-{
-    if ( !params )
-    {
-        // reset to default
-        m_min =
-        m_max = -1;
-    }
-    else
-    {
-        long tmp;
-        if ( params.BeforeFirst(_T(',')).ToLong(&tmp) )
-        {
-            m_min = (int)tmp;
-
-            if ( params.AfterFirst(_T(',')).ToLong(&tmp) )
-            {
-                m_max = (int)tmp;
-
-                // skip the error message below
-                return;
-            }
-        }
-
-        wxLogDebug(_T("Invalid wxGridCellNumberEditor parameter string '%s' ignored"), params.c_str());
-    }
-}
-
-// return the value in the spin control if it is there (the text control otherwise)
-wxString wxGridCellNumberEditor::GetValue() const
-{
-    wxString s;
-
-#if wxUSE_SPINCTRL
-    if ( HasRange() )
-    {
-        long value = Spin()->GetValue();
-        s.Printf(wxT("%ld"), value);
-    }
-    else
-#endif
-    {
-        s = Text()->GetValue();
-    }
-
-    return s;
-}
-
-// ----------------------------------------------------------------------------
-// wxGridCellFloatEditor
-// ----------------------------------------------------------------------------
-
-wxGridCellFloatEditor::wxGridCellFloatEditor(int width, int precision)
-{
-    m_width = width;
-    m_precision = precision;
-}
-
-void wxGridCellFloatEditor::Create(wxWindow* parent,
-                                   wxWindowID id,
-                                   wxEvtHandler* evtHandler)
-{
-    wxGridCellTextEditor::Create(parent, id, evtHandler);
-
-#if wxUSE_VALIDATORS
-    Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
-#endif
-}
-
-void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    // first get the value
-    wxGridTableBase * const table = grid->GetTable();
-    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
-    {
-        m_value = table->GetValueAsDouble(row, col);
-    }
-    else
-    {
-        m_value = 0.0;
-
-        const wxString value = table->GetValue(row, col);
-        if ( !value.empty() )
-        {
-            if ( !value.ToDouble(&m_value) )
-            {
-                wxFAIL_MSG( _T("this cell doesn't have float value") );
-                return;
-            }
-        }
-    }
-
-    DoBeginEdit(GetString());
-}
-
-bool wxGridCellFloatEditor::EndEdit(const wxString& oldval, wxString *newval)
-{
-    const wxString text(Text()->GetValue());
-
-    double value;
-    if ( !text.empty() )
-    {
-        if ( !text.ToDouble(&value) )
-            return false;
-    }
-    else // new value is empty string
-    {
-        if ( oldval.empty() )
-            return false;           // nothing changed
-
-        value = 0.;
-    }
-
-    // the test for empty strings ensures that we don't skip the value setting
-    // when "" is replaced by "0" or vice versa as "" numeric value is also 0.
-    if ( wxIsSameDouble(value, m_value) && !text.empty() && !oldval.empty() )
-        return false;           // nothing changed
-
-    m_value = value;
-
-    if ( newval )
-        *newval = text;
-
-    return true;
-}
-
-void wxGridCellFloatEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    wxGridTableBase * const table = grid->GetTable();
-
-    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) )
-        table->SetValueAsDouble(row, col, m_value);
-    else
-        table->SetValue(row, col, Text()->GetValue());
-}
-
-void wxGridCellFloatEditor::Reset()
-{
-    DoReset(GetString());
-}
-
-void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)
-{
-    int keycode = event.GetKeyCode();
-    char tmpbuf[2];
-    tmpbuf[0] = (char) keycode;
-    tmpbuf[1] = '\0';
-    wxString strbuf(tmpbuf, *wxConvCurrent);
-
-#if wxUSE_INTL
-    bool is_decimal_point = ( strbuf ==
-       wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );
-#else
-    bool is_decimal_point = ( strbuf == _T(".") );
-#endif
-
-    if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
-         || is_decimal_point )
-    {
-        wxGridCellTextEditor::StartingKey(event);
-
-        // skip Skip() below
-        return;
-    }
-
-    event.Skip();
-}
-
-void wxGridCellFloatEditor::SetParameters(const wxString& params)
-{
-    if ( !params )
-    {
-        // reset to default
-        m_width =
-        m_precision = -1;
-    }
-    else
-    {
-        long tmp;
-        if ( params.BeforeFirst(_T(',')).ToLong(&tmp) )
-        {
-            m_width = (int)tmp;
-
-            if ( params.AfterFirst(_T(',')).ToLong(&tmp) )
-            {
-                m_precision = (int)tmp;
-
-                // skip the error message below
-                return;
-            }
-        }
-
-        wxLogDebug(_T("Invalid wxGridCellFloatEditor parameter string '%s' ignored"), params.c_str());
-    }
-}
-
-wxString wxGridCellFloatEditor::GetString() const
-{
-    wxString fmt;
-    if ( m_precision == -1 && m_width != -1)
-    {
-        // default precision
-        fmt.Printf(_T("%%%d.f"), m_width);
-    }
-    else if ( m_precision != -1 && m_width == -1)
-    {
-        // default width
-        fmt.Printf(_T("%%.%df"), m_precision);
-    }
-    else if ( m_precision != -1 && m_width != -1 )
-    {
-        fmt.Printf(_T("%%%d.%df"), m_width, m_precision);
-    }
-    else
-    {
-        // default width/precision
-        fmt = _T("%f");
-    }
-
-    return wxString::Format(fmt, m_value);
-}
-
-bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
-{
-    if ( wxGridCellEditor::IsAcceptedKey(event) )
-    {
-        const int keycode = event.GetKeyCode();
-        if ( isascii(keycode) )
-        {
-            char tmpbuf[2];
-            tmpbuf[0] = (char) keycode;
-            tmpbuf[1] = '\0';
-            wxString strbuf(tmpbuf, *wxConvCurrent);
-
-#if wxUSE_INTL
-            const wxString decimalPoint =
-                wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);
-#else
-            const wxString decimalPoint(_T('.'));
-#endif
-
-            // accept digits, 'e' as in '1e+6', also '-', '+', and '.'
-            if ( wxIsdigit(keycode) ||
-                    tolower(keycode) == 'e' ||
-                        keycode == decimalPoint ||
-                            keycode == '+' ||
-                                keycode == '-' )
-            {
-                return true;
-            }
-        }
-    }
-
-    return false;
-}
-
-#endif // wxUSE_TEXTCTRL
-
-#if wxUSE_CHECKBOX
-
-// ----------------------------------------------------------------------------
-// wxGridCellBoolEditor
-// ----------------------------------------------------------------------------
-
-// the default values for GetValue()
-wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") };
-
-void wxGridCellBoolEditor::Create(wxWindow* parent,
-                                  wxWindowID id,
-                                  wxEvtHandler* evtHandler)
-{
-    m_control = new wxCheckBox(parent, id, wxEmptyString,
-                               wxDefaultPosition, wxDefaultSize,
-                               wxNO_BORDER);
-
-    wxGridCellEditor::Create(parent, id, evtHandler);
-}
-
-void wxGridCellBoolEditor::SetSize(const wxRect& r)
-{
-    bool resize = false;
-    wxSize size = m_control->GetSize();
-    wxCoord minSize = wxMin(r.width, r.height);
-
-    // check if the checkbox is not too big/small for this cell
-    wxSize sizeBest = m_control->GetBestSize();
-    if ( !(size == sizeBest) )
-    {
-        // reset to default size if it had been made smaller
-        size = sizeBest;
-
-        resize = true;
-    }
-
-    if ( size.x >= minSize || size.y >= minSize )
-    {
-        // leave 1 pixel margin
-        size.x = size.y = minSize - 2;
-
-        resize = true;
-    }
-
-    if ( resize )
-    {
-        m_control->SetSize(size);
-    }
-
-    // position it in the centre of the rectangle (TODO: support alignment?)
-
-#if defined(__WXGTK__) || defined (__WXMOTIF__)
-    // the checkbox without label still has some space to the right in wxGTK,
-    // so shift it to the right
-    size.x -= 8;
-#elif defined(__WXMSW__)
-    // here too, but in other way
-    size.x += 1;
-    size.y -= 2;
-#endif
-
-    int hAlign = wxALIGN_CENTRE;
-    int vAlign = wxALIGN_CENTRE;
-    if (GetCellAttr())
-        GetCellAttr()->GetAlignment(& hAlign, & vAlign);
-
-    int x = 0, y = 0;
-    if (hAlign == wxALIGN_LEFT)
-    {
-        x = r.x + 2;
-
-#ifdef __WXMSW__
-        x += 2;
-#endif
-
-        y = r.y + r.height / 2 - size.y / 2;
-    }
-    else if (hAlign == wxALIGN_RIGHT)
-    {
-        x = r.x + r.width - size.x - 2;
-        y = r.y + r.height / 2 - size.y / 2;
-    }
-    else if (hAlign == wxALIGN_CENTRE)
-    {
-        x = r.x + r.width / 2 - size.x / 2;
-        y = r.y + r.height / 2 - size.y / 2;
-    }
-
-    m_control->Move(x, y);
-}
-
-void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
-{
-    m_control->Show(show);
-
-    if ( show )
-    {
-        wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY;
-        CBox()->SetBackgroundColour(colBg);
-    }
-}
-
-void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    wxASSERT_MSG(m_control,
-                 wxT("The wxGridCellEditor must be created first!"));
-
-    if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
-    {
-        m_value = grid->GetTable()->GetValueAsBool(row, col);
-    }
-    else
-    {
-        wxString cellval( grid->GetTable()->GetValue(row, col) );
-
-        if ( cellval == ms_stringValues[false] )
-            m_value = false;
-        else if ( cellval == ms_stringValues[true] )
-            m_value = true;
-        else
-        {
-            // do not try to be smart here and convert it to true or false
-            // because we'll still overwrite it with something different and
-            // this risks to be very surprising for the user code, let them
-            // know about it
-            wxFAIL_MSG( _T("invalid value for a cell with bool editor!") );
-        }
-    }
-
-    CBox()->SetValue(m_value);
-    CBox()->SetFocus();
-}
-
-bool wxGridCellBoolEditor::EndEdit(const wxString& WXUNUSED(oldval),
-                                   wxString *newval)
-{
-    bool value = CBox()->GetValue();
-    if ( value == m_value )
-        return false;
-
-    m_value = value;
-
-    if ( newval )
-        *newval = GetValue();
-
-    return true;
-}
-
-void wxGridCellBoolEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    wxGridTableBase * const table = grid->GetTable();
-    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) )
-        table->SetValueAsBool(row, col, m_value);
-    else
-        table->SetValue(row, col, GetValue());
-}
-
-void wxGridCellBoolEditor::Reset()
-{
-    wxASSERT_MSG(m_control,
-                 wxT("The wxGridCellEditor must be created first!"));
-
-    CBox()->SetValue(m_value);
-}
-
-void wxGridCellBoolEditor::StartingClick()
-{
-    CBox()->SetValue(!CBox()->GetValue());
-}
-
-bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event)
-{
-    if ( wxGridCellEditor::IsAcceptedKey(event) )
-    {
-        int keycode = event.GetKeyCode();
-        switch ( keycode )
-        {
-            case WXK_SPACE:
-            case '+':
-            case '-':
-                return true;
-        }
-    }
-
-    return false;
-}
-
-void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)
-{
-    int keycode = event.GetKeyCode();
-    switch ( keycode )
-    {
-        case WXK_SPACE:
-            CBox()->SetValue(!CBox()->GetValue());
-            break;
-
-        case '+':
-            CBox()->SetValue(true);
-            break;
-
-        case '-':
-            CBox()->SetValue(false);
-            break;
-    }
-}
-
-wxString wxGridCellBoolEditor::GetValue() const
-{
-  return ms_stringValues[CBox()->GetValue()];
-}
-
-/* static */ void
-wxGridCellBoolEditor::UseStringValues(const wxString& valueTrue,
-                                      const wxString& valueFalse)
-{
-    ms_stringValues[false] = valueFalse;
-    ms_stringValues[true] = valueTrue;
-}
-
-/* static */ bool
-wxGridCellBoolEditor::IsTrueValue(const wxString& value)
-{
-    return value == ms_stringValues[true];
-}
-
-#endif // wxUSE_CHECKBOX
-
-#if wxUSE_COMBOBOX
-
-// ----------------------------------------------------------------------------
-// wxGridCellChoiceEditor
-// ----------------------------------------------------------------------------
-
-wxGridCellChoiceEditor::wxGridCellChoiceEditor(const wxArrayString& choices,
-                                               bool allowOthers)
-    : m_choices(choices),
-      m_allowOthers(allowOthers) { }
-
-wxGridCellChoiceEditor::wxGridCellChoiceEditor(size_t count,
-                                               const wxString choices[],
-                                               bool allowOthers)
-                      : m_allowOthers(allowOthers)
-{
-    if ( count )
-    {
-        m_choices.Alloc(count);
-        for ( size_t n = 0; n < count; n++ )
-        {
-            m_choices.Add(choices[n]);
-        }
-    }
-}
-
-wxGridCellEditor *wxGridCellChoiceEditor::Clone() const
-{
-    wxGridCellChoiceEditor *editor = new wxGridCellChoiceEditor;
-    editor->m_allowOthers = m_allowOthers;
-    editor->m_choices = m_choices;
-
-    return editor;
-}
-
-void wxGridCellChoiceEditor::Create(wxWindow* parent,
-                                    wxWindowID id,
-                                    wxEvtHandler* evtHandler)
-{
-    int style = wxTE_PROCESS_ENTER |
-                wxTE_PROCESS_TAB |
-                wxBORDER_NONE;
-
-    if ( !m_allowOthers )
-        style |= wxCB_READONLY;
-    m_control = new wxComboBox(parent, id, wxEmptyString,
-                               wxDefaultPosition, wxDefaultSize,
-                               m_choices,
-                               style);
-
-    wxGridCellEditor::Create(parent, id, evtHandler);
-}
-
-void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell,
-                                             wxGridCellAttr * attr)
-{
-    // as we fill the entire client area, don't do anything here to minimize
-    // flicker
-
-    // TODO: It doesn't actually fill the client area since the height of a
-    // combo always defaults to the standard.  Until someone has time to
-    // figure out the right rectangle to paint, just do it the normal way.
-    wxGridCellEditor::PaintBackground(rectCell, attr);
-}
-
-void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    wxASSERT_MSG(m_control,
-                 wxT("The wxGridCellEditor must be created first!"));
-
-    wxGridCellEditorEvtHandler* evtHandler = NULL;
-    if (m_control)
-        evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler);
-
-    // Don't immediately end if we get a kill focus event within BeginEdit
-    if (evtHandler)
-        evtHandler->SetInSetFocus(true);
-
-    m_value = grid->GetTable()->GetValue(row, col);
-
-    Reset(); // this updates combo box to correspond to m_value
-
-    Combo()->SetFocus();
-
-    if (evtHandler)
-    {
-        // When dropping down the menu, a kill focus event
-        // happens after this point, so we can't reset the flag yet.
-#if !defined(__WXGTK20__)
-        evtHandler->SetInSetFocus(false);
-#endif
-    }
-}
-
-bool wxGridCellChoiceEditor::EndEdit(const wxString& WXUNUSED(oldval),
-                                     wxString *newval)
-{
-    const wxString value = Combo()->GetValue();
-    if ( value == m_value )
-        return false;
-
-    m_value = value;
-
-    if ( newval )
-        *newval = value;
-
-    return true;
-}
-
-void wxGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    grid->GetTable()->SetValue(row, col, m_value);
-}
-
-void wxGridCellChoiceEditor::Reset()
-{
-    if (m_allowOthers)
-    {
-        Combo()->SetValue(m_value);
-        Combo()->SetInsertionPointEnd();
-    }
-    else // the combobox is read-only
-    {
-        // find the right position, or default to the first if not found
-        int pos = Combo()->FindString(m_value);
-        if (pos == wxNOT_FOUND)
-            pos = 0;
-        Combo()->SetSelection(pos);
-    }
-}
-
-void wxGridCellChoiceEditor::SetParameters(const wxString& params)
-{
-    if ( !params )
-    {
-        // what can we do?
-        return;
-    }
-
-    m_choices.Empty();
-
-    wxStringTokenizer tk(params, _T(','));
-    while ( tk.HasMoreTokens() )
-    {
-        m_choices.Add(tk.GetNextToken());
-    }
-}
-
-// return the value in the text control
-wxString wxGridCellChoiceEditor::GetValue() const
-{
-  return Combo()->GetValue();
-}
-
-#endif // wxUSE_COMBOBOX
-
-#if wxUSE_COMBOBOX
-
-// ----------------------------------------------------------------------------
-// wxGridCellEnumEditor
-// ----------------------------------------------------------------------------
-
-// A cell editor which displays an enum number as a textual equivalent. eg
-// data in cell is 0,1,2 ... n the cell could be displayed as
-// "John","Fred"..."Bob" in the combo choice box
-
-wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
-                     :wxGridCellChoiceEditor()
-{
-    m_index = -1;
-
-    if (!choices.empty())
-        SetParameters(choices);
-}
-
-wxGridCellEditor *wxGridCellEnumEditor::Clone() const
-{
-    wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
-    editor->m_index = m_index;
-    return editor;
-}
-
-void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)
-{
-    wxASSERT_MSG(m_control,
-                 wxT("The wxGridCellEnumEditor must be Created first!"));
-
-    wxGridTableBase *table = grid->GetTable();
-
-    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
-    {
-        m_index = table->GetValueAsLong(row, col);
-    }
-    else
-    {
-        wxString startValue = table->GetValue(row, col);
-        if (startValue.IsNumber() && !startValue.empty())
-        {
-            startValue.ToLong(&m_index);
-        }
-        else
-        {
-            m_index = -1;
-        }
-    }
-
-    Combo()->SetSelection(m_index);
-    Combo()->SetInsertionPointEnd();
-    Combo()->SetFocus();
-
-}
-
-bool wxGridCellEnumEditor::EndEdit(const wxString& WXUNUSED(oldval),
-                                   wxString *newval)
-{
-    long idx = Combo()->GetSelection();
-    if ( idx == m_index )
-        return false;
-
-    m_index = idx;
-
-    if ( newval )
-        newval->Printf("%ld", m_index);
-
-    return true;
-}
-
-void wxGridCellEnumEditor::ApplyEdit(int row, int col, wxGrid* grid)
-{
-    wxGridTableBase * const table = grid->GetTable();
-    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )
-        table->SetValueAsLong(row, col, m_index);
-    else
-        table->SetValue(row, col, wxString::Format("%ld", m_index));
-}
-
-#endif // wxUSE_COMBOBOX
-
-// ----------------------------------------------------------------------------
-// wxGridCellAutoWrapStringEditor
-// ----------------------------------------------------------------------------
-
-void
-wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,
-                                       wxWindowID id,
-                                       wxEvtHandler* evtHandler)
-{
-    wxGridCellTextEditor::DoCreate(parent, id, evtHandler,
-                                    wxTE_MULTILINE | wxTE_RICH);
-}
-
-
-#endif // wxUSE_GRID
+///////////////////////////////////////////////////////////////////////////\r
+// Name:        src/generic/grideditors.cpp\r
+// Purpose:     wxGridCellEditorEvtHandler and wxGrid editors\r
+// Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn)\r
+// Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios\r
+// Created:     1/08/1999\r
+// RCS-ID:      $Id$\r
+// Copyright:   (c) Michael Bedward (mbedward@ozemail.com.au)\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// For compilers that support precompilation, includes "wx/wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifdef __BORLANDC__\r
+    #pragma hdrstop\r
+#endif\r
+\r
+#if wxUSE_GRID\r
+\r
+#include "wx/grid.h"\r
+\r
+#ifndef WX_PRECOMP\r
+    #include "wx/utils.h"\r
+    #include "wx/dcclient.h"\r
+    #include "wx/settings.h"\r
+    #include "wx/log.h"\r
+    #include "wx/textctrl.h"\r
+    #include "wx/checkbox.h"\r
+    #include "wx/combobox.h"\r
+    #include "wx/valtext.h"\r
+    #include "wx/intl.h"\r
+    #include "wx/math.h"\r
+    #include "wx/listbox.h"\r
+#endif\r
+\r
+#include "wx/textfile.h"\r
+#include "wx/spinctrl.h"\r
+#include "wx/tokenzr.h"\r
+#include "wx/renderer.h"\r
+#include "wx/headerctrl.h"\r
+\r
+#include "wx/generic/gridsel.h"\r
+#include "wx/generic/grideditors.h"\r
+#include "wx/generic/private/grid.h"\r
+\r
+#if defined(__WXMOTIF__)\r
+    #define WXUNUSED_MOTIF(identifier)  WXUNUSED(identifier)\r
+#else\r
+    #define WXUNUSED_MOTIF(identifier)  identifier\r
+#endif\r
+\r
+#if defined(__WXGTK__)\r
+    #define WXUNUSED_GTK(identifier)    WXUNUSED(identifier)\r
+#else\r
+    #define WXUNUSED_GTK(identifier)    identifier\r
+#endif\r
+\r
+// Required for wxIs... functions\r
+#include <ctype.h>\r
+\r
+// ============================================================================\r
+// implementation\r
+// ============================================================================\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellEditorEvtHandler\r
+// ----------------------------------------------------------------------------\r
+\r
+void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event)\r
+{\r
+    // Don't disable the cell if we're just starting to edit it\r
+    if ( m_inSetFocus )\r
+    {\r
+        event.Skip();\r
+        return;\r
+    }\r
+\r
+    // accept changes\r
+    m_grid->DisableCellEditControl();\r
+\r
+    // notice that we must not skip the event here because the call above may\r
+    // delete the control which received the kill focus event in the first\r
+    // place and if we pretend not having processed the event, the search for a\r
+    // handler for it will continue using the now deleted object resulting in a\r
+    // crash\r
+}\r
+\r
+void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)\r
+{\r
+    switch ( event.GetKeyCode() )\r
+    {\r
+        case WXK_ESCAPE:\r
+            m_editor->Reset();\r
+            m_grid->DisableCellEditControl();\r
+            break;\r
+\r
+        case WXK_TAB:\r
+            m_grid->GetEventHandler()->ProcessEvent( event );\r
+            break;\r
+\r
+        case WXK_RETURN:\r
+        case WXK_NUMPAD_ENTER:\r
+            if (!m_grid->GetEventHandler()->ProcessEvent(event))\r
+                m_editor->HandleReturn(event);\r
+            break;\r
+\r
+        default:\r
+            event.Skip();\r
+            break;\r
+    }\r
+}\r
+\r
+void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event)\r
+{\r
+    int row = m_grid->GetGridCursorRow();\r
+    int col = m_grid->GetGridCursorCol();\r
+    wxRect rect = m_grid->CellToRect( row, col );\r
+    int cw, ch;\r
+    m_grid->GetGridWindow()->GetClientSize( &cw, &ch );\r
+\r
+    // if cell width is smaller than grid client area, cell is wholly visible\r
+    bool wholeCellVisible = (rect.GetWidth() < cw);\r
+\r
+    switch ( event.GetKeyCode() )\r
+    {\r
+        case WXK_ESCAPE:\r
+        case WXK_TAB:\r
+        case WXK_RETURN:\r
+        case WXK_NUMPAD_ENTER:\r
+            break;\r
+\r
+        case WXK_HOME:\r
+        {\r
+            if ( wholeCellVisible )\r
+            {\r
+                // no special processing needed...\r
+                event.Skip();\r
+                break;\r
+            }\r
+\r
+            // do special processing for partly visible cell...\r
+\r
+            // get the widths of all cells previous to this one\r
+            int colXPos = 0;\r
+            for ( int i = 0; i < col; i++ )\r
+            {\r
+                colXPos += m_grid->GetColSize(i);\r
+            }\r
+\r
+            int xUnit = 1, yUnit = 1;\r
+            m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit);\r
+            if (col != 0)\r
+            {\r
+                m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL));\r
+            }\r
+            else\r
+            {\r
+                m_grid->Scroll(colXPos / xUnit, m_grid->GetScrollPos(wxVERTICAL));\r
+            }\r
+            event.Skip();\r
+            break;\r
+        }\r
+\r
+        case WXK_END:\r
+        {\r
+            if ( wholeCellVisible )\r
+            {\r
+                // no special processing needed...\r
+                event.Skip();\r
+                break;\r
+            }\r
+\r
+            // do special processing for partly visible cell...\r
+\r
+            int textWidth = 0;\r
+            wxString value = m_grid->GetCellValue(row, col);\r
+            if ( wxEmptyString != value )\r
+            {\r
+                // get width of cell CONTENTS (text)\r
+                int y;\r
+                wxFont font = m_grid->GetCellFont(row, col);\r
+                m_grid->GetTextExtent(value, &textWidth, &y, NULL, NULL, &font);\r
+\r
+                // try to RIGHT align the text by scrolling\r
+                int client_right = m_grid->GetGridWindow()->GetClientSize().GetWidth();\r
+\r
+                // (m_grid->GetScrollLineX()*2) is a factor for not scrolling to far,\r
+                // otherwise the last part of the cell content might be hidden below the scroll bar\r
+                // FIXME: maybe there is a more suitable correction?\r
+                textWidth -= (client_right - (m_grid->GetScrollLineX() * 2));\r
+                if ( textWidth < 0 )\r
+                {\r
+                    textWidth = 0;\r
+                }\r
+            }\r
+\r
+            // get the widths of all cells previous to this one\r
+            int colXPos = 0;\r
+            for ( int i = 0; i < col; i++ )\r
+            {\r
+                colXPos += m_grid->GetColSize(i);\r
+            }\r
+\r
+            // and add the (modified) text width of the cell contents\r
+            // as we'd like to see the last part of the cell contents\r
+            colXPos += textWidth;\r
+\r
+            int xUnit = 1, yUnit = 1;\r
+            m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit);\r
+            m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL));\r
+            event.Skip();\r
+            break;\r
+        }\r
+\r
+        default:\r
+            event.Skip();\r
+            break;\r
+    }\r
+}\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+wxGridCellEditor::wxGridCellEditor()\r
+{\r
+    m_control = NULL;\r
+    m_attr = NULL;\r
+}\r
+\r
+wxGridCellEditor::~wxGridCellEditor()\r
+{\r
+    Destroy();\r
+}\r
+\r
+void wxGridCellEditor::Create(wxWindow* WXUNUSED(parent),\r
+                              wxWindowID WXUNUSED(id),\r
+                              wxEvtHandler* evtHandler)\r
+{\r
+    if ( evtHandler )\r
+        m_control->PushEventHandler(evtHandler);\r
+}\r
+\r
+void wxGridCellEditor::PaintBackground(const wxRect& rectCell,\r
+                                       wxGridCellAttr *attr)\r
+{\r
+    // erase the background because we might not fill the cell\r
+    wxClientDC dc(m_control->GetParent());\r
+    wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow);\r
+    if (gridWindow)\r
+        gridWindow->GetOwner()->PrepareDC(dc);\r
+\r
+    dc.SetPen(*wxTRANSPARENT_PEN);\r
+    dc.SetBrush(wxBrush(attr->GetBackgroundColour()));\r
+    dc.DrawRectangle(rectCell);\r
+\r
+    // redraw the control we just painted over\r
+    m_control->Refresh();\r
+}\r
+\r
+void wxGridCellEditor::Destroy()\r
+{\r
+    if (m_control)\r
+    {\r
+        m_control->PopEventHandler( true /* delete it*/ );\r
+\r
+        m_control->Destroy();\r
+        m_control = NULL;\r
+    }\r
+}\r
+\r
+void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)\r
+{\r
+    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    m_control->Show(show);\r
+\r
+    if ( show )\r
+    {\r
+        // set the colours/fonts if we have any\r
+        if ( attr )\r
+        {\r
+            m_colFgOld = m_control->GetForegroundColour();\r
+            m_control->SetForegroundColour(attr->GetTextColour());\r
+\r
+            m_colBgOld = m_control->GetBackgroundColour();\r
+            m_control->SetBackgroundColour(attr->GetBackgroundColour());\r
+\r
+// Workaround for GTK+1 font setting problem on some platforms\r
+#if !defined(__WXGTK__) || defined(__WXGTK20__)\r
+            m_fontOld = m_control->GetFont();\r
+            m_control->SetFont(attr->GetFont());\r
+#endif\r
+\r
+            // can't do anything more in the base class version, the other\r
+            // attributes may only be used by the derived classes\r
+        }\r
+    }\r
+    else\r
+    {\r
+        // restore the standard colours fonts\r
+        if ( m_colFgOld.Ok() )\r
+        {\r
+            m_control->SetForegroundColour(m_colFgOld);\r
+            m_colFgOld = wxNullColour;\r
+        }\r
+\r
+        if ( m_colBgOld.Ok() )\r
+        {\r
+            m_control->SetBackgroundColour(m_colBgOld);\r
+            m_colBgOld = wxNullColour;\r
+        }\r
+\r
+// Workaround for GTK+1 font setting problem on some platforms\r
+#if !defined(__WXGTK__) || defined(__WXGTK20__)\r
+        if ( m_fontOld.Ok() )\r
+        {\r
+            m_control->SetFont(m_fontOld);\r
+            m_fontOld = wxNullFont;\r
+        }\r
+#endif\r
+    }\r
+}\r
+\r
+void wxGridCellEditor::SetSize(const wxRect& rect)\r
+{\r
+    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);\r
+}\r
+\r
+void wxGridCellEditor::HandleReturn(wxKeyEvent& event)\r
+{\r
+    event.Skip();\r
+}\r
+\r
+bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event)\r
+{\r
+    bool ctrl = event.ControlDown();\r
+    bool alt  = event.AltDown();\r
+\r
+#ifdef __WXMAC__\r
+    // On the Mac the Alt key is more like shift and is used for entry of\r
+    // valid characters, so check for Ctrl and Meta instead.\r
+    alt = event.MetaDown();\r
+#endif\r
+\r
+    // Assume it's not a valid char if ctrl or alt is down, but if both are\r
+    // down then it may be because of an AltGr key combination, so let them\r
+    // through in that case.\r
+    if ((ctrl || alt) && !(ctrl && alt))\r
+        return false;\r
+\r
+#if wxUSE_UNICODE\r
+    // if the unicode key code is not really a unicode character (it may\r
+    // be a function key or etc., the platforms appear to always give us a\r
+    // small value in this case) then fallback to the ASCII key code but\r
+    // don't do anything for function keys or etc.\r
+    if ( event.GetUnicodeKey() > 127 && event.GetKeyCode() > 127 )\r
+        return false;\r
+#else\r
+    if ( event.GetKeyCode() > 255 )\r
+        return false;\r
+#endif\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellEditor::StartingKey(wxKeyEvent& event)\r
+{\r
+    event.Skip();\r
+}\r
+\r
+void wxGridCellEditor::StartingClick()\r
+{\r
+}\r
+\r
+#if wxUSE_TEXTCTRL\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellTextEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+wxGridCellTextEditor::wxGridCellTextEditor()\r
+{\r
+    m_maxChars = 0;\r
+}\r
+\r
+void wxGridCellTextEditor::Create(wxWindow* parent,\r
+                                  wxWindowID id,\r
+                                  wxEvtHandler* evtHandler)\r
+{\r
+    DoCreate(parent, id, evtHandler);\r
+}\r
+\r
+void wxGridCellTextEditor::DoCreate(wxWindow* parent,\r
+                                    wxWindowID id,\r
+                                    wxEvtHandler* evtHandler,\r
+                                    long style)\r
+{\r
+    style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER;\r
+\r
+    m_control = new wxTextCtrl(parent, id, wxEmptyString,\r
+                               wxDefaultPosition, wxDefaultSize,\r
+                               style);\r
+\r
+    // set max length allowed in the textctrl, if the parameter was set\r
+    if ( m_maxChars != 0 )\r
+    {\r
+        Text()->SetMaxLength(m_maxChars);\r
+    }\r
+\r
+    wxGridCellEditor::Create(parent, id, evtHandler);\r
+}\r
+\r
+void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell),\r
+                                           wxGridCellAttr * WXUNUSED(attr))\r
+{\r
+    // as we fill the entire client area,\r
+    // don't do anything here to minimize flicker\r
+}\r
+\r
+void wxGridCellTextEditor::SetSize(const wxRect& rectOrig)\r
+{\r
+    wxRect rect(rectOrig);\r
+\r
+    // Make the edit control large enough to allow for internal margins\r
+    //\r
+    // TODO: remove this if the text ctrl sizing is improved esp. for unix\r
+    //\r
+#if defined(__WXGTK__)\r
+    if (rect.x != 0)\r
+    {\r
+        rect.x += 1;\r
+        rect.y += 1;\r
+        rect.width -= 1;\r
+        rect.height -= 1;\r
+    }\r
+#elif defined(__WXMSW__)\r
+    if ( rect.x == 0 )\r
+        rect.x += 2;\r
+    else\r
+        rect.x += 3;\r
+\r
+    if ( rect.y == 0 )\r
+        rect.y += 2;\r
+    else\r
+        rect.y += 3;\r
+\r
+    rect.width -= 2;\r
+    rect.height -= 2;\r
+#else\r
+    int extra_x = ( rect.x > 2 ) ? 2 : 1;\r
+    int extra_y = ( rect.y > 2 ) ? 2 : 1;\r
+\r
+    #if defined(__WXMOTIF__)\r
+        extra_x *= 2;\r
+        extra_y *= 2;\r
+    #endif\r
+\r
+    rect.SetLeft( wxMax(0, rect.x - extra_x) );\r
+    rect.SetTop( wxMax(0, rect.y - extra_y) );\r
+    rect.SetRight( rect.GetRight() + 2 * extra_x );\r
+    rect.SetBottom( rect.GetBottom() + 2 * extra_y );\r
+#endif\r
+\r
+    wxGridCellEditor::SetSize(rect);\r
+}\r
+\r
+void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    m_value = grid->GetTable()->GetValue(row, col);\r
+\r
+    DoBeginEdit(m_value);\r
+}\r
+\r
+void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue)\r
+{\r
+    Text()->SetValue(startValue);\r
+    Text()->SetInsertionPointEnd();\r
+    Text()->SetSelection(-1, -1);\r
+    Text()->SetFocus();\r
+}\r
+\r
+bool wxGridCellTextEditor::EndEdit(int WXUNUSED(row),\r
+                                   int WXUNUSED(col),\r
+                                   const wxGrid* WXUNUSED(grid),\r
+                                   const wxString& WXUNUSED(oldval),\r
+                                   wxString *newval)\r
+{\r
+    wxCHECK_MSG( m_control, false,\r
+                 "wxGridCellTextEditor must be created first!" );\r
+\r
+    const wxString value = Text()->GetValue();\r
+    if ( value == m_value )\r
+        return false;\r
+\r
+    m_value = value;\r
+\r
+    if ( newval )\r
+        *newval = m_value;\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellTextEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    grid->GetTable()->SetValue(row, col, m_value);\r
+    m_value.clear();\r
+}\r
+\r
+void wxGridCellTextEditor::Reset()\r
+{\r
+    wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" );\r
+\r
+    DoReset(m_value);\r
+}\r
+\r
+void wxGridCellTextEditor::DoReset(const wxString& startValue)\r
+{\r
+    Text()->SetValue(startValue);\r
+    Text()->SetInsertionPointEnd();\r
+}\r
+\r
+bool wxGridCellTextEditor::IsAcceptedKey(wxKeyEvent& event)\r
+{\r
+    return wxGridCellEditor::IsAcceptedKey(event);\r
+}\r
+\r
+void wxGridCellTextEditor::StartingKey(wxKeyEvent& event)\r
+{\r
+    // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no\r
+    // longer an appropriate way to get the character into the text control.\r
+    // Do it ourselves instead.  We know that if we get this far that we have\r
+    // a valid character, so not a whole lot of testing needs to be done.\r
+\r
+    wxTextCtrl* tc = Text();\r
+    wxChar ch;\r
+    long pos;\r
+\r
+#if wxUSE_UNICODE\r
+    ch = event.GetUnicodeKey();\r
+    if (ch <= 127)\r
+        ch = (wxChar)event.GetKeyCode();\r
+#else\r
+    ch = (wxChar)event.GetKeyCode();\r
+#endif\r
+\r
+    switch (ch)\r
+    {\r
+        case WXK_DELETE:\r
+            // delete the character at the cursor\r
+            pos = tc->GetInsertionPoint();\r
+            if (pos < tc->GetLastPosition())\r
+                tc->Remove(pos, pos + 1);\r
+            break;\r
+\r
+        case WXK_BACK:\r
+            // delete the character before the cursor\r
+            pos = tc->GetInsertionPoint();\r
+            if (pos > 0)\r
+                tc->Remove(pos - 1, pos);\r
+            break;\r
+\r
+        default:\r
+            tc->WriteText(ch);\r
+            break;\r
+    }\r
+}\r
+\r
+void wxGridCellTextEditor::HandleReturn( wxKeyEvent&\r
+                                         WXUNUSED_GTK(WXUNUSED_MOTIF(event)) )\r
+{\r
+#if defined(__WXMOTIF__) || defined(__WXGTK__)\r
+    // wxMotif needs a little extra help...\r
+    size_t pos = (size_t)( Text()->GetInsertionPoint() );\r
+    wxString s( Text()->GetValue() );\r
+    s = s.Left(pos) + wxT("\n") + s.Mid(pos);\r
+    Text()->SetValue(s);\r
+    Text()->SetInsertionPoint( pos );\r
+#else\r
+    // the other ports can handle a Return key press\r
+    //\r
+    event.Skip();\r
+#endif\r
+}\r
+\r
+void wxGridCellTextEditor::SetParameters(const wxString& params)\r
+{\r
+    if ( !params )\r
+    {\r
+        // reset to default\r
+        m_maxChars = 0;\r
+    }\r
+    else\r
+    {\r
+        long tmp;\r
+        if ( params.ToLong(&tmp) )\r
+        {\r
+            m_maxChars = (size_t)tmp;\r
+        }\r
+        else\r
+        {\r
+            wxLogDebug( _T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str() );\r
+        }\r
+    }\r
+}\r
+\r
+// return the value in the text control\r
+wxString wxGridCellTextEditor::GetValue() const\r
+{\r
+    return Text()->GetValue();\r
+}\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellNumberEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max)\r
+{\r
+    m_min = min;\r
+    m_max = max;\r
+}\r
+\r
+void wxGridCellNumberEditor::Create(wxWindow* parent,\r
+                                    wxWindowID id,\r
+                                    wxEvtHandler* evtHandler)\r
+{\r
+#if wxUSE_SPINCTRL\r
+    if ( HasRange() )\r
+    {\r
+        // create a spin ctrl\r
+        m_control = new wxSpinCtrl(parent, wxID_ANY, wxEmptyString,\r
+                                   wxDefaultPosition, wxDefaultSize,\r
+                                   wxSP_ARROW_KEYS,\r
+                                   m_min, m_max);\r
+\r
+        wxGridCellEditor::Create(parent, id, evtHandler);\r
+    }\r
+    else\r
+#endif\r
+    {\r
+        // just a text control\r
+        wxGridCellTextEditor::Create(parent, id, evtHandler);\r
+\r
+#if wxUSE_VALIDATORS\r
+        Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));\r
+#endif\r
+    }\r
+}\r
+\r
+void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    // first get the value\r
+    wxGridTableBase *table = grid->GetTable();\r
+    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )\r
+    {\r
+        m_value = table->GetValueAsLong(row, col);\r
+    }\r
+    else\r
+    {\r
+        m_value = 0;\r
+        wxString sValue = table->GetValue(row, col);\r
+        if (! sValue.ToLong(&m_value) && ! sValue.empty())\r
+        {\r
+            wxFAIL_MSG( _T("this cell doesn't have numeric value") );\r
+            return;\r
+        }\r
+    }\r
+\r
+#if wxUSE_SPINCTRL\r
+    if ( HasRange() )\r
+    {\r
+        Spin()->SetValue((int)m_value);\r
+        Spin()->SetFocus();\r
+    }\r
+    else\r
+#endif\r
+    {\r
+        DoBeginEdit(GetString());\r
+    }\r
+}\r
+\r
+bool wxGridCellNumberEditor::EndEdit(int WXUNUSED(row),\r
+                                     int WXUNUSED(col),\r
+                                     const wxGrid* WXUNUSED(grid),\r
+                                     const wxString& oldval, wxString *newval)\r
+{\r
+    long value = 0;\r
+    wxString text;\r
+\r
+#if wxUSE_SPINCTRL\r
+    if ( HasRange() )\r
+    {\r
+        value = Spin()->GetValue();\r
+        if ( value == m_value )\r
+            return false;\r
+\r
+        text.Printf(wxT("%ld"), value);\r
+    }\r
+    else // using unconstrained input\r
+#endif // wxUSE_SPINCTRL\r
+    {\r
+        text = Text()->GetValue();\r
+        if ( text.empty() )\r
+        {\r
+            if ( oldval.empty() )\r
+                return false;\r
+        }\r
+        else // non-empty text now (maybe 0)\r
+        {\r
+            if ( !text.ToLong(&value) )\r
+                return false;\r
+\r
+            // if value == m_value == 0 but old text was "" and new one is\r
+            // "0" something still did change\r
+            if ( value == m_value && (value || !oldval.empty()) )\r
+                return false;\r
+        }\r
+    }\r
+\r
+    m_value = value;\r
+\r
+    if ( newval )\r
+        *newval = text;\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellNumberEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxGridTableBase * const table = grid->GetTable();\r
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )\r
+        table->SetValueAsLong(row, col, m_value);\r
+    else\r
+        table->SetValue(row, col, wxString::Format("%ld", m_value));\r
+}\r
+\r
+void wxGridCellNumberEditor::Reset()\r
+{\r
+#if wxUSE_SPINCTRL\r
+    if ( HasRange() )\r
+    {\r
+        Spin()->SetValue((int)m_value);\r
+    }\r
+    else\r
+#endif\r
+    {\r
+        DoReset(GetString());\r
+    }\r
+}\r
+\r
+bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event)\r
+{\r
+    if ( wxGridCellEditor::IsAcceptedKey(event) )\r
+    {\r
+        int keycode = event.GetKeyCode();\r
+        if ( (keycode < 128) &&\r
+             (wxIsdigit(keycode) || keycode == '+' || keycode == '-'))\r
+        {\r
+            return true;\r
+        }\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)\r
+{\r
+    int keycode = event.GetKeyCode();\r
+    if ( !HasRange() )\r
+    {\r
+        if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-')\r
+        {\r
+            wxGridCellTextEditor::StartingKey(event);\r
+\r
+            // skip Skip() below\r
+            return;\r
+        }\r
+    }\r
+#if wxUSE_SPINCTRL\r
+    else\r
+    {\r
+        if ( wxIsdigit(keycode) )\r
+        {\r
+            wxSpinCtrl* spin = (wxSpinCtrl*)m_control;\r
+            spin->SetValue(keycode - '0');\r
+            spin->SetSelection(1,1);\r
+            return;\r
+        }\r
+    }\r
+#endif\r
+\r
+    event.Skip();\r
+}\r
+\r
+void wxGridCellNumberEditor::SetParameters(const wxString& params)\r
+{\r
+    if ( !params )\r
+    {\r
+        // reset to default\r
+        m_min =\r
+        m_max = -1;\r
+    }\r
+    else\r
+    {\r
+        long tmp;\r
+        if ( params.BeforeFirst(_T(',')).ToLong(&tmp) )\r
+        {\r
+            m_min = (int)tmp;\r
+\r
+            if ( params.AfterFirst(_T(',')).ToLong(&tmp) )\r
+            {\r
+                m_max = (int)tmp;\r
+\r
+                // skip the error message below\r
+                return;\r
+            }\r
+        }\r
+\r
+        wxLogDebug(_T("Invalid wxGridCellNumberEditor parameter string '%s' ignored"), params.c_str());\r
+    }\r
+}\r
+\r
+// return the value in the spin control if it is there (the text control otherwise)\r
+wxString wxGridCellNumberEditor::GetValue() const\r
+{\r
+    wxString s;\r
+\r
+#if wxUSE_SPINCTRL\r
+    if ( HasRange() )\r
+    {\r
+        long value = Spin()->GetValue();\r
+        s.Printf(wxT("%ld"), value);\r
+    }\r
+    else\r
+#endif\r
+    {\r
+        s = Text()->GetValue();\r
+    }\r
+\r
+    return s;\r
+}\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellFloatEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+wxGridCellFloatEditor::wxGridCellFloatEditor(int width, int precision)\r
+{\r
+    m_width = width;\r
+    m_precision = precision;\r
+}\r
+\r
+void wxGridCellFloatEditor::Create(wxWindow* parent,\r
+                                   wxWindowID id,\r
+                                   wxEvtHandler* evtHandler)\r
+{\r
+    wxGridCellTextEditor::Create(parent, id, evtHandler);\r
+\r
+#if wxUSE_VALIDATORS\r
+    Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));\r
+#endif\r
+}\r
+\r
+void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    // first get the value\r
+    wxGridTableBase * const table = grid->GetTable();\r
+    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )\r
+    {\r
+        m_value = table->GetValueAsDouble(row, col);\r
+    }\r
+    else\r
+    {\r
+        m_value = 0.0;\r
+\r
+        const wxString value = table->GetValue(row, col);\r
+        if ( !value.empty() )\r
+        {\r
+            if ( !value.ToDouble(&m_value) )\r
+            {\r
+                wxFAIL_MSG( _T("this cell doesn't have float value") );\r
+                return;\r
+            }\r
+        }\r
+    }\r
+\r
+    DoBeginEdit(GetString());\r
+}\r
+\r
+bool wxGridCellFloatEditor::EndEdit(int WXUNUSED(row),\r
+                                    int WXUNUSED(col),\r
+                                    const wxGrid* WXUNUSED(grid),\r
+                                    const wxString& oldval, wxString *newval)\r
+{\r
+    const wxString text(Text()->GetValue());\r
+\r
+    double value;\r
+    if ( !text.empty() )\r
+    {\r
+        if ( !text.ToDouble(&value) )\r
+            return false;\r
+    }\r
+    else // new value is empty string\r
+    {\r
+        if ( oldval.empty() )\r
+            return false;           // nothing changed\r
+\r
+        value = 0.;\r
+    }\r
+\r
+    // the test for empty strings ensures that we don't skip the value setting\r
+    // when "" is replaced by "0" or vice versa as "" numeric value is also 0.\r
+    if ( wxIsSameDouble(value, m_value) && !text.empty() && !oldval.empty() )\r
+        return false;           // nothing changed\r
+\r
+    m_value = value;\r
+\r
+    if ( newval )\r
+        *newval = text;\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellFloatEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxGridTableBase * const table = grid->GetTable();\r
+\r
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) )\r
+        table->SetValueAsDouble(row, col, m_value);\r
+    else\r
+        table->SetValue(row, col, Text()->GetValue());\r
+}\r
+\r
+void wxGridCellFloatEditor::Reset()\r
+{\r
+    DoReset(GetString());\r
+}\r
+\r
+void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)\r
+{\r
+    int keycode = event.GetKeyCode();\r
+    char tmpbuf[2];\r
+    tmpbuf[0] = (char) keycode;\r
+    tmpbuf[1] = '\0';\r
+    wxString strbuf(tmpbuf, *wxConvCurrent);\r
+\r
+#if wxUSE_INTL\r
+    bool is_decimal_point = ( strbuf ==\r
+       wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );\r
+#else\r
+    bool is_decimal_point = ( strbuf == _T(".") );\r
+#endif\r
+\r
+    if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'\r
+         || is_decimal_point )\r
+    {\r
+        wxGridCellTextEditor::StartingKey(event);\r
+\r
+        // skip Skip() below\r
+        return;\r
+    }\r
+\r
+    event.Skip();\r
+}\r
+\r
+void wxGridCellFloatEditor::SetParameters(const wxString& params)\r
+{\r
+    if ( !params )\r
+    {\r
+        // reset to default\r
+        m_width =\r
+        m_precision = -1;\r
+    }\r
+    else\r
+    {\r
+        long tmp;\r
+        if ( params.BeforeFirst(_T(',')).ToLong(&tmp) )\r
+        {\r
+            m_width = (int)tmp;\r
+\r
+            if ( params.AfterFirst(_T(',')).ToLong(&tmp) )\r
+            {\r
+                m_precision = (int)tmp;\r
+\r
+                // skip the error message below\r
+                return;\r
+            }\r
+        }\r
+\r
+        wxLogDebug(_T("Invalid wxGridCellFloatEditor parameter string '%s' ignored"), params.c_str());\r
+    }\r
+}\r
+\r
+wxString wxGridCellFloatEditor::GetString() const\r
+{\r
+    wxString fmt;\r
+    if ( m_precision == -1 && m_width != -1)\r
+    {\r
+        // default precision\r
+        fmt.Printf(_T("%%%d.f"), m_width);\r
+    }\r
+    else if ( m_precision != -1 && m_width == -1)\r
+    {\r
+        // default width\r
+        fmt.Printf(_T("%%.%df"), m_precision);\r
+    }\r
+    else if ( m_precision != -1 && m_width != -1 )\r
+    {\r
+        fmt.Printf(_T("%%%d.%df"), m_width, m_precision);\r
+    }\r
+    else\r
+    {\r
+        // default width/precision\r
+        fmt = _T("%f");\r
+    }\r
+\r
+    return wxString::Format(fmt, m_value);\r
+}\r
+\r
+bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)\r
+{\r
+    if ( wxGridCellEditor::IsAcceptedKey(event) )\r
+    {\r
+        const int keycode = event.GetKeyCode();\r
+        if ( isascii(keycode) )\r
+        {\r
+            char tmpbuf[2];\r
+            tmpbuf[0] = (char) keycode;\r
+            tmpbuf[1] = '\0';\r
+            wxString strbuf(tmpbuf, *wxConvCurrent);\r
+\r
+#if wxUSE_INTL\r
+            const wxString decimalPoint =\r
+                wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER);\r
+#else\r
+            const wxString decimalPoint(_T('.'));\r
+#endif\r
+\r
+            // accept digits, 'e' as in '1e+6', also '-', '+', and '.'\r
+            if ( wxIsdigit(keycode) ||\r
+                    tolower(keycode) == 'e' ||\r
+                        keycode == decimalPoint ||\r
+                            keycode == '+' ||\r
+                                keycode == '-' )\r
+            {\r
+                return true;\r
+            }\r
+        }\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+#endif // wxUSE_TEXTCTRL\r
+\r
+#if wxUSE_CHECKBOX\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellBoolEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+// the default values for GetValue()\r
+wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") };\r
+\r
+void wxGridCellBoolEditor::Create(wxWindow* parent,\r
+                                  wxWindowID id,\r
+                                  wxEvtHandler* evtHandler)\r
+{\r
+    m_control = new wxCheckBox(parent, id, wxEmptyString,\r
+                               wxDefaultPosition, wxDefaultSize,\r
+                               wxNO_BORDER);\r
+\r
+    wxGridCellEditor::Create(parent, id, evtHandler);\r
+}\r
+\r
+void wxGridCellBoolEditor::SetSize(const wxRect& r)\r
+{\r
+    bool resize = false;\r
+    wxSize size = m_control->GetSize();\r
+    wxCoord minSize = wxMin(r.width, r.height);\r
+\r
+    // check if the checkbox is not too big/small for this cell\r
+    wxSize sizeBest = m_control->GetBestSize();\r
+    if ( !(size == sizeBest) )\r
+    {\r
+        // reset to default size if it had been made smaller\r
+        size = sizeBest;\r
+\r
+        resize = true;\r
+    }\r
+\r
+    if ( size.x >= minSize || size.y >= minSize )\r
+    {\r
+        // leave 1 pixel margin\r
+        size.x = size.y = minSize - 2;\r
+\r
+        resize = true;\r
+    }\r
+\r
+    if ( resize )\r
+    {\r
+        m_control->SetSize(size);\r
+    }\r
+\r
+    // position it in the centre of the rectangle (TODO: support alignment?)\r
+\r
+#if defined(__WXGTK__) || defined (__WXMOTIF__)\r
+    // the checkbox without label still has some space to the right in wxGTK,\r
+    // so shift it to the right\r
+    size.x -= 8;\r
+#elif defined(__WXMSW__)\r
+    // here too, but in other way\r
+    size.x += 1;\r
+    size.y -= 2;\r
+#endif\r
+\r
+    int hAlign = wxALIGN_CENTRE;\r
+    int vAlign = wxALIGN_CENTRE;\r
+    if (GetCellAttr())\r
+        GetCellAttr()->GetAlignment(& hAlign, & vAlign);\r
+\r
+    int x = 0, y = 0;\r
+    if (hAlign == wxALIGN_LEFT)\r
+    {\r
+        x = r.x + 2;\r
+\r
+#ifdef __WXMSW__\r
+        x += 2;\r
+#endif\r
+\r
+        y = r.y + r.height / 2 - size.y / 2;\r
+    }\r
+    else if (hAlign == wxALIGN_RIGHT)\r
+    {\r
+        x = r.x + r.width - size.x - 2;\r
+        y = r.y + r.height / 2 - size.y / 2;\r
+    }\r
+    else if (hAlign == wxALIGN_CENTRE)\r
+    {\r
+        x = r.x + r.width / 2 - size.x / 2;\r
+        y = r.y + r.height / 2 - size.y / 2;\r
+    }\r
+\r
+    m_control->Move(x, y);\r
+}\r
+\r
+void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)\r
+{\r
+    m_control->Show(show);\r
+\r
+    if ( show )\r
+    {\r
+        wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY;\r
+        CBox()->SetBackgroundColour(colBg);\r
+    }\r
+}\r
+\r
+void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxASSERT_MSG(m_control,\r
+                 wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))\r
+    {\r
+        m_value = grid->GetTable()->GetValueAsBool(row, col);\r
+    }\r
+    else\r
+    {\r
+        wxString cellval( grid->GetTable()->GetValue(row, col) );\r
+\r
+        if ( cellval == ms_stringValues[false] )\r
+            m_value = false;\r
+        else if ( cellval == ms_stringValues[true] )\r
+            m_value = true;\r
+        else\r
+        {\r
+            // do not try to be smart here and convert it to true or false\r
+            // because we'll still overwrite it with something different and\r
+            // this risks to be very surprising for the user code, let them\r
+            // know about it\r
+            wxFAIL_MSG( _T("invalid value for a cell with bool editor!") );\r
+        }\r
+    }\r
+\r
+    CBox()->SetValue(m_value);\r
+    CBox()->SetFocus();\r
+}\r
+\r
+bool wxGridCellBoolEditor::EndEdit(int WXUNUSED(row),\r
+                                   int WXUNUSED(col),\r
+                                   const wxGrid* WXUNUSED(grid),\r
+                                   const wxString& WXUNUSED(oldval),\r
+                                   wxString *newval)\r
+{\r
+    bool value = CBox()->GetValue();\r
+    if ( value == m_value )\r
+        return false;\r
+\r
+    m_value = value;\r
+\r
+    if ( newval )\r
+        *newval = GetValue();\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellBoolEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxGridTableBase * const table = grid->GetTable();\r
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) )\r
+        table->SetValueAsBool(row, col, m_value);\r
+    else\r
+        table->SetValue(row, col, GetValue());\r
+}\r
+\r
+void wxGridCellBoolEditor::Reset()\r
+{\r
+    wxASSERT_MSG(m_control,\r
+                 wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    CBox()->SetValue(m_value);\r
+}\r
+\r
+void wxGridCellBoolEditor::StartingClick()\r
+{\r
+    CBox()->SetValue(!CBox()->GetValue());\r
+}\r
+\r
+bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event)\r
+{\r
+    if ( wxGridCellEditor::IsAcceptedKey(event) )\r
+    {\r
+        int keycode = event.GetKeyCode();\r
+        switch ( keycode )\r
+        {\r
+            case WXK_SPACE:\r
+            case '+':\r
+            case '-':\r
+                return true;\r
+        }\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)\r
+{\r
+    int keycode = event.GetKeyCode();\r
+    switch ( keycode )\r
+    {\r
+        case WXK_SPACE:\r
+            CBox()->SetValue(!CBox()->GetValue());\r
+            break;\r
+\r
+        case '+':\r
+            CBox()->SetValue(true);\r
+            break;\r
+\r
+        case '-':\r
+            CBox()->SetValue(false);\r
+            break;\r
+    }\r
+}\r
+\r
+wxString wxGridCellBoolEditor::GetValue() const\r
+{\r
+  return ms_stringValues[CBox()->GetValue()];\r
+}\r
+\r
+/* static */ void\r
+wxGridCellBoolEditor::UseStringValues(const wxString& valueTrue,\r
+                                      const wxString& valueFalse)\r
+{\r
+    ms_stringValues[false] = valueFalse;\r
+    ms_stringValues[true] = valueTrue;\r
+}\r
+\r
+/* static */ bool\r
+wxGridCellBoolEditor::IsTrueValue(const wxString& value)\r
+{\r
+    return value == ms_stringValues[true];\r
+}\r
+\r
+#endif // wxUSE_CHECKBOX\r
+\r
+#if wxUSE_COMBOBOX\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellChoiceEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+wxGridCellChoiceEditor::wxGridCellChoiceEditor(const wxArrayString& choices,\r
+                                               bool allowOthers)\r
+    : m_choices(choices),\r
+      m_allowOthers(allowOthers) { }\r
+\r
+wxGridCellChoiceEditor::wxGridCellChoiceEditor(size_t count,\r
+                                               const wxString choices[],\r
+                                               bool allowOthers)\r
+                      : m_allowOthers(allowOthers)\r
+{\r
+    if ( count )\r
+    {\r
+        m_choices.Alloc(count);\r
+        for ( size_t n = 0; n < count; n++ )\r
+        {\r
+            m_choices.Add(choices[n]);\r
+        }\r
+    }\r
+}\r
+\r
+wxGridCellEditor *wxGridCellChoiceEditor::Clone() const\r
+{\r
+    wxGridCellChoiceEditor *editor = new wxGridCellChoiceEditor;\r
+    editor->m_allowOthers = m_allowOthers;\r
+    editor->m_choices = m_choices;\r
+\r
+    return editor;\r
+}\r
+\r
+void wxGridCellChoiceEditor::Create(wxWindow* parent,\r
+                                    wxWindowID id,\r
+                                    wxEvtHandler* evtHandler)\r
+{\r
+    int style = wxTE_PROCESS_ENTER |\r
+                wxTE_PROCESS_TAB |\r
+                wxBORDER_NONE;\r
+\r
+    if ( !m_allowOthers )\r
+        style |= wxCB_READONLY;\r
+    m_control = new wxComboBox(parent, id, wxEmptyString,\r
+                               wxDefaultPosition, wxDefaultSize,\r
+                               m_choices,\r
+                               style);\r
+\r
+    wxGridCellEditor::Create(parent, id, evtHandler);\r
+}\r
+\r
+void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell,\r
+                                             wxGridCellAttr * attr)\r
+{\r
+    // as we fill the entire client area, don't do anything here to minimize\r
+    // flicker\r
+\r
+    // TODO: It doesn't actually fill the client area since the height of a\r
+    // combo always defaults to the standard.  Until someone has time to\r
+    // figure out the right rectangle to paint, just do it the normal way.\r
+    wxGridCellEditor::PaintBackground(rectCell, attr);\r
+}\r
+\r
+void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxASSERT_MSG(m_control,\r
+                 wxT("The wxGridCellEditor must be created first!"));\r
+\r
+    wxGridCellEditorEvtHandler* evtHandler = NULL;\r
+    if (m_control)\r
+        evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler);\r
+\r
+    // Don't immediately end if we get a kill focus event within BeginEdit\r
+    if (evtHandler)\r
+        evtHandler->SetInSetFocus(true);\r
+\r
+    m_value = grid->GetTable()->GetValue(row, col);\r
+\r
+    Reset(); // this updates combo box to correspond to m_value\r
+\r
+    Combo()->SetFocus();\r
+\r
+    if (evtHandler)\r
+    {\r
+        // When dropping down the menu, a kill focus event\r
+        // happens after this point, so we can't reset the flag yet.\r
+#if !defined(__WXGTK20__)\r
+        evtHandler->SetInSetFocus(false);\r
+#endif\r
+    }\r
+}\r
+\r
+bool wxGridCellChoiceEditor::EndEdit(int WXUNUSED(row),\r
+                                     int WXUNUSED(col),\r
+                                     const wxGrid* WXUNUSED(grid),\r
+                                     const wxString& WXUNUSED(oldval),\r
+                                     wxString *newval)\r
+{\r
+    const wxString value = Combo()->GetValue();\r
+    if ( value == m_value )\r
+        return false;\r
+\r
+    m_value = value;\r
+\r
+    if ( newval )\r
+        *newval = value;\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    grid->GetTable()->SetValue(row, col, m_value);\r
+}\r
+\r
+void wxGridCellChoiceEditor::Reset()\r
+{\r
+    if (m_allowOthers)\r
+    {\r
+        Combo()->SetValue(m_value);\r
+        Combo()->SetInsertionPointEnd();\r
+    }\r
+    else // the combobox is read-only\r
+    {\r
+        // find the right position, or default to the first if not found\r
+        int pos = Combo()->FindString(m_value);\r
+        if (pos == wxNOT_FOUND)\r
+            pos = 0;\r
+        Combo()->SetSelection(pos);\r
+    }\r
+}\r
+\r
+void wxGridCellChoiceEditor::SetParameters(const wxString& params)\r
+{\r
+    if ( !params )\r
+    {\r
+        // what can we do?\r
+        return;\r
+    }\r
+\r
+    m_choices.Empty();\r
+\r
+    wxStringTokenizer tk(params, _T(','));\r
+    while ( tk.HasMoreTokens() )\r
+    {\r
+        m_choices.Add(tk.GetNextToken());\r
+    }\r
+}\r
+\r
+// return the value in the text control\r
+wxString wxGridCellChoiceEditor::GetValue() const\r
+{\r
+  return Combo()->GetValue();\r
+}\r
+\r
+#endif // wxUSE_COMBOBOX\r
+\r
+#if wxUSE_COMBOBOX\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellEnumEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+// A cell editor which displays an enum number as a textual equivalent. eg\r
+// data in cell is 0,1,2 ... n the cell could be displayed as\r
+// "John","Fred"..."Bob" in the combo choice box\r
+\r
+wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)\r
+                     :wxGridCellChoiceEditor()\r
+{\r
+    m_index = -1;\r
+\r
+    if (!choices.empty())\r
+        SetParameters(choices);\r
+}\r
+\r
+wxGridCellEditor *wxGridCellEnumEditor::Clone() const\r
+{\r
+    wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();\r
+    editor->m_index = m_index;\r
+    return editor;\r
+}\r
+\r
+void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxASSERT_MSG(m_control,\r
+                 wxT("The wxGridCellEnumEditor must be Created first!"));\r
+\r
+    wxGridTableBase *table = grid->GetTable();\r
+\r
+    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )\r
+    {\r
+        m_index = table->GetValueAsLong(row, col);\r
+    }\r
+    else\r
+    {\r
+        wxString startValue = table->GetValue(row, col);\r
+        if (startValue.IsNumber() && !startValue.empty())\r
+        {\r
+            startValue.ToLong(&m_index);\r
+        }\r
+        else\r
+        {\r
+            m_index = -1;\r
+        }\r
+    }\r
+\r
+    Combo()->SetSelection(m_index);\r
+    Combo()->SetInsertionPointEnd();\r
+    Combo()->SetFocus();\r
+\r
+}\r
+\r
+bool wxGridCellEnumEditor::EndEdit(int WXUNUSED(row),\r
+                                   int WXUNUSED(col),\r
+                                   const wxGrid* WXUNUSED(grid),\r
+                                   const wxString& WXUNUSED(oldval),\r
+                                   wxString *newval)\r
+{\r
+    long idx = Combo()->GetSelection();\r
+    if ( idx == m_index )\r
+        return false;\r
+\r
+    m_index = idx;\r
+\r
+    if ( newval )\r
+        newval->Printf("%ld", m_index);\r
+\r
+    return true;\r
+}\r
+\r
+void wxGridCellEnumEditor::ApplyEdit(int row, int col, wxGrid* grid)\r
+{\r
+    wxGridTableBase * const table = grid->GetTable();\r
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )\r
+        table->SetValueAsLong(row, col, m_index);\r
+    else\r
+        table->SetValue(row, col, wxString::Format("%ld", m_index));\r
+}\r
+\r
+#endif // wxUSE_COMBOBOX\r
+\r
+// ----------------------------------------------------------------------------\r
+// wxGridCellAutoWrapStringEditor\r
+// ----------------------------------------------------------------------------\r
+\r
+void\r
+wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,\r
+                                       wxWindowID id,\r
+                                       wxEvtHandler* evtHandler)\r
+{\r
+    wxGridCellTextEditor::DoCreate(parent, id, evtHandler,\r
+                                    wxTE_MULTILINE | wxTE_RICH);\r
+}\r
+\r
+\r
+#endif // wxUSE_GRID\r