From 763163a80ae0d5a0684633e72f928302578c1214 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 22 Dec 2008 22:58:49 +0000 Subject: [PATCH] split wxEVT_GRID_CELL_CHANGE into wxEVT_GRID_CELL_CHANGING/ED pair for consistency with all the other controls; provide access to new/old value of the cell in the event object git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57505 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 10 ++ include/wx/generic/grid.h | 88 ++++++++++----- include/wx/generic/gridctrl.h | 5 +- interface/wx/grid.h | 43 +++++-- samples/grid/griddemo.cpp | 29 ++++- samples/grid/griddemo.h | 1 + samples/minimal/minimal.cpp | 10 ++ src/generic/grid.cpp | 203 ++++++++++++++++++++-------------- src/generic/gridctrl.cpp | 43 ++++--- 9 files changed, 291 insertions(+), 141 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 09ce2b72e1..ecd68c800d 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -199,6 +199,15 @@ Changes in behaviour which may result in compilation errors have been changed to accept "wxBitmapType bitmaptype", please use enum wxBitmapType in your code. +- wxGridCellEditor::EndEdit() signature has changed and it was split in two + functions, one still called EndEdit() and ApplyEdit(). See the documentation + of the new functions for more details about how grid editors should be + written now. + +- wxEVT_GRID_CELL_CHANGE event renamed to wxEVT_GRID_CELL_CHANGED and shouldn't + be vetoed any more, use the new wxEVT_GRID_CELL_CHANGING event to do it. + + Deprecated methods and their replacements ----------------------------------------- @@ -416,6 +425,7 @@ All (GUI): - Improved drawing of the hint during column move in wxGrid (Santo Pfingsten). - Add wxGridSelectRowsOrColumns selection mode to wxGrid. - Get/HasModifiers() of wxKeyEvent are now also available in wxMouseEvent. +- Provide new/old cell value in wxEVT_GRID_CELL_CHANGING/CHANGED events. wxGTK: diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 07d55f9d68..c9ee2e7143 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -327,13 +327,26 @@ public: // version just fills it with background colour from the attribute virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); + + // The methods called by wxGrid when a cell is edited: first BeginEdit() is + // called, then EndEdit() is and if it returns true and if the change is + // not vetoed by a user-defined event handler, finally ApplyEdit() is called + // Fetch the value from the table and prepare the edit control // to begin editing. Set the focus to the edit control. virtual void BeginEdit(int row, int col, wxGrid* grid) = 0; - // Complete the editing of the current cell. Returns true if the value has - // changed. If necessary, the control may be destroyed. - virtual bool EndEdit(int row, int col, wxGrid* grid) = 0; + // Returns false if nothing changed, otherwise returns true and return the + // new value in its string form in the newval output parameter. + // + // This should also store the new value in its real type internally so that + // it could be used by ApplyEdit(). + virtual bool EndEdit(const wxString& oldval, wxString *newval) = 0; + + // Complete the editing of the current cell by storing the value saved by + // the previous call to EndEdit() in the grid + virtual void ApplyEdit(int row, int col, wxGrid* grid) = 0; + // Reset the value in the control back to its starting value virtual void Reset() = 0; @@ -410,7 +423,8 @@ public: virtual bool IsAcceptedKey(wxKeyEvent& event); virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); virtual void Reset(); virtual void StartingKey(wxKeyEvent& event); @@ -436,7 +450,7 @@ protected: private: size_t m_maxChars; // max number of chars allowed - wxString m_startValue; + wxString m_value; DECLARE_NO_COPY_CLASS(wxGridCellTextEditor) }; @@ -455,7 +469,8 @@ public: virtual bool IsAcceptedKey(wxKeyEvent& event); virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); virtual void Reset(); virtual void StartingKey(wxKeyEvent& event); @@ -484,15 +499,15 @@ protected: #endif } - // string representation of m_valueOld + // string representation of our value wxString GetString() const - { return wxString::Format(_T("%ld"), m_valueOld); } + { return wxString::Format(_T("%ld"), m_value); } private: int m_min, m_max; - long m_valueOld; + long m_value; DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor) }; @@ -509,7 +524,8 @@ public: virtual bool IsAcceptedKey(wxKeyEvent& event); virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); virtual void Reset(); virtual void StartingKey(wxKeyEvent& event); @@ -521,13 +537,13 @@ public: virtual void SetParameters(const wxString& params); protected: - // string representation of m_valueOld + // string representation of our value wxString GetString() const; private: int m_width, m_precision; - double m_valueOld; + double m_value; DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor) }; @@ -551,7 +567,8 @@ public: virtual bool IsAcceptedKey(wxKeyEvent& event); virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); virtual void Reset(); virtual void StartingClick(); @@ -577,7 +594,7 @@ protected: wxCheckBox *CBox() const { return (wxCheckBox *)m_control; } private: - bool m_startValue; + bool m_value; static wxString ms_stringValues[2]; @@ -606,7 +623,8 @@ public: virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); virtual void Reset(); @@ -621,10 +639,7 @@ public: protected: wxComboBox *Combo() const { return (wxComboBox *)m_control; } -// DJC - (MAPTEK) you at least need access to m_choices if you -// wish to override this class -protected: - wxString m_startValue; + wxString m_value; wxArrayString m_choices; bool m_allowOthers; @@ -2233,11 +2248,15 @@ protected: const wxGridCellCoords& coords, wxMouseEvent& e) { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); } - int SendEvent(const wxEventType evtType, int row, int col); - int SendEvent(const wxEventType evtType, const wxGridCellCoords& coords) - { return SendEvent(evtType, coords.GetRow(), coords.GetCol()); } - int SendEvent(const wxEventType evtType) - { return SendEvent(evtType, m_currentCellCoords); } + int SendEvent(const wxEventType evtType, + int row, int col, + const wxString& s = wxString()); + int SendEvent(const wxEventType evtType, + const wxGridCellCoords& coords, + const wxString& s = wxString()) + { return SendEvent(evtType, coords.GetRow(), coords.GetCol(), s); } + int SendEvent(const wxEventType evtType, const wxString& s = wxString()) + { return SendEvent(evtType, m_currentCellCoords, s); } void OnPaint( wxPaintEvent& ); void OnSize( wxSizeEvent& ); @@ -2659,7 +2678,8 @@ extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_LABEL_RIGHT_DCLICK; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_ROW_SIZE; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SIZE; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_RANGE_SELECT; -extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGE; +extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGING; +extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_CHANGED; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_SELECT_CELL; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_SHOWN; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_HIDDEN; @@ -2668,7 +2688,6 @@ extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_BEGIN_DRAG; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_MOVE; extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SORT; - typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&); typedef void (wxEvtHandler::*wxGridSizeEventFunction)(wxGridSizeEvent&); typedef void (wxEvtHandler::*wxGridRangeSelectEventFunction)(wxGridRangeSelectEvent&); @@ -2711,7 +2730,8 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat #define EVT_GRID_CMD_COL_MOVE(id, fn) wx__DECLARE_GRIDEVT(COL_MOVE, id, fn) #define EVT_GRID_CMD_COL_SORT(id, fn) wx__DECLARE_GRIDEVT(COL_SORT, id, fn) #define EVT_GRID_CMD_RANGE_SELECT(id, fn) wx__DECLARE_GRIDRANGESELEVT(RANGE_SELECT, id, fn) -#define EVT_GRID_CMD_CELL_CHANGE(id, fn) wx__DECLARE_GRIDEVT(CELL_CHANGE, id, fn) +#define EVT_GRID_CMD_CELL_CHANGING(id, fn) wx__DECLARE_GRIDEVT(CELL_CHANGING, id, fn) +#define EVT_GRID_CMD_CELL_CHANGED(id, fn) wx__DECLARE_GRIDEVT(CELL_CHANGED, id, fn) #define EVT_GRID_CMD_SELECT_CELL(id, fn) wx__DECLARE_GRIDEVT(SELECT_CELL, id, fn) #define EVT_GRID_CMD_EDITOR_SHOWN(id, fn) wx__DECLARE_GRIDEVT(EDITOR_SHOWN, id, fn) #define EVT_GRID_CMD_EDITOR_HIDDEN(id, fn) wx__DECLARE_GRIDEVT(EDITOR_HIDDEN, id, fn) @@ -2733,13 +2753,25 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat #define EVT_GRID_COL_MOVE(fn) EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn) #define EVT_GRID_COL_SORT(fn) EVT_GRID_CMD_COL_SORT(wxID_ANY, fn) #define EVT_GRID_RANGE_SELECT(fn) EVT_GRID_CMD_RANGE_SELECT(wxID_ANY, fn) -#define EVT_GRID_CELL_CHANGE(fn) EVT_GRID_CMD_CELL_CHANGE(wxID_ANY, fn) +#define EVT_GRID_CELL_CHANGING(fn) EVT_GRID_CMD_CELL_CHANGING(wxID_ANY, fn) +#define EVT_GRID_CELL_CHANGED(fn) EVT_GRID_CMD_CELL_CHANGED(wxID_ANY, fn) #define EVT_GRID_SELECT_CELL(fn) EVT_GRID_CMD_SELECT_CELL(wxID_ANY, fn) #define EVT_GRID_EDITOR_SHOWN(fn) EVT_GRID_CMD_EDITOR_SHOWN(wxID_ANY, fn) #define EVT_GRID_EDITOR_HIDDEN(fn) EVT_GRID_CMD_EDITOR_HIDDEN(wxID_ANY, fn) #define EVT_GRID_EDITOR_CREATED(fn) EVT_GRID_CMD_EDITOR_CREATED(wxID_ANY, fn) #define EVT_GRID_CELL_BEGIN_DRAG(fn) EVT_GRID_CMD_CELL_BEGIN_DRAG(wxID_ANY, fn) +// we used to have a single wxEVT_GRID_CELL_CHANGE event but it was split into +// wxEVT_GRID_CELL_CHANGING and CHANGED ones in wx 2.9.0, however the CHANGED +// is basically the same as the old CHANGE event so we keep the name for +// compatibility +#if WXWIN_COMPATIBILITY_2_8 + #define wxEVT_GRID_CELL_CHANGE wxEVT_GRID_CELL_CHANGED + + #define EVT_GRID_CMD_CELL_CHANGE EVT_GRID_CMD_CELL_CHANGED + #define EVT_GRID_CELL_CHANGE EVT_GRID_CELL_CHANGED +#endif // WXWIN_COMPATIBILITY_2_8 + #if 0 // TODO: implement these ? others ? extern const int wxEVT_GRID_CREATE_CELL; diff --git a/include/wx/generic/gridctrl.h b/include/wx/generic/gridctrl.h index 2ee1c10488..748713f87b 100644 --- a/include/wx/generic/gridctrl.h +++ b/include/wx/generic/gridctrl.h @@ -100,11 +100,12 @@ public: virtual wxGridCellEditor* Clone() const; - virtual bool EndEdit(int row, int col, wxGrid* grid); 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 int m_startint; + long m_index; DECLARE_NO_COPY_CLASS(wxGridCellEnumEditor) }; diff --git a/interface/wx/grid.h b/interface/wx/grid.h index 0f4e06e2a7..83aa1b25a1 100644 --- a/interface/wx/grid.h +++ b/interface/wx/grid.h @@ -186,7 +186,13 @@ public: /** Fetch the value from the table and prepare the edit control to begin - editing. Sets the focus to the edit control. + editing. + + This function should save the original value of the grid cell at the + given @a row and @a col and show the control allowing the user to + change it. + + @see EndEdit() */ virtual void BeginEdit(int row, int col, wxGrid* grid) = 0; @@ -207,13 +213,28 @@ public: virtual void Destroy(); /** - Complete the editing of the current cell. If necessary, the control may - be destroyed. + End editing the cell. - @return @true if the value has changed. + 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. + + If the user-defined wxEVT_GRID_CELL_CHANGING event handler doesn't veto + this change, ApplyEdit() will be called next. */ virtual bool EndEdit(int row, int col, wxGrid* grid) = 0; + /** + Effectively save the changes in the grid. + + This function should save the value of the control in the grid. It is + called only after EndEdit() returns @true. + */ + virtual void ApplyEdit(int row, int col, wxGrid* grid) = 0; + /** Some types of controls on some platforms may need some help with the Return key. @@ -3330,9 +3351,17 @@ public: documented below for brevity. @beginEventTable{wxGridEvent} - @event{EVT_GRID_CELL_CHANGE(func)} - The user changed the data in a cell. Processes a - @c wxEVT_GRID_CELL_CHANGE event type. + @event{EVT_GRID_CELL_CHANGING(func)} + The user is about to change the data in a cell. The new cell value as + string is available from GetString() event object method. This event + can be vetoed if the change is not allowed. Processes a @c + wxEVT_GRID_CELL_CHANGING event type. + @event{EVT_GRID_CELL_CHANGED(func)} + The user changed the data in a cell. The old cell value as string is + available from GetString() event object method. Notice that vetoing + this event still works for backwards compatibility reasons but any new + code should only veto EVT_GRID_CELL_CHANGING event and not this one. + Processes a @c wxEVT_GRID_CELL_CHANGED event type. @event{EVT_GRID_CELL_LEFT_CLICK(func)} The user clicked a cell with the left mouse button. Processes a @c wxEVT_GRID_CELL_LEFT_CLICK event type. diff --git a/samples/grid/griddemo.cpp b/samples/grid/griddemo.cpp index d21b8a0761..6e682f597b 100644 --- a/samples/grid/griddemo.cpp +++ b/samples/grid/griddemo.cpp @@ -133,6 +133,7 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame ) EVT_GRID_COL_SIZE( GridFrame::OnColSize ) EVT_GRID_SELECT_CELL( GridFrame::OnSelectCell ) EVT_GRID_RANGE_SELECT( GridFrame::OnRangeSelected ) + EVT_GRID_CELL_CHANGING( GridFrame::OnCellValueChanging ) EVT_GRID_CELL_CHANGE( GridFrame::OnCellValueChanged ) EVT_GRID_CELL_BEGIN_DRAG( GridFrame::OnCellBeginDrag ) @@ -1059,13 +1060,36 @@ void GridFrame::OnRangeSelected( wxGridRangeSelectEvent& ev ) ev.Skip(); } +void GridFrame::OnCellValueChanging( wxGridEvent& ev ) +{ + int row = ev.GetRow(), + col = ev.GetCol(); + + wxLogMessage("Value of cell at (%d, %d): about to change " + "from \"%s\" to \"%s\"", + row, col, + grid->GetCellValue(row, col), ev.GetString()); + + // test how vetoing works + if ( ev.GetString() == "42" ) + { + wxLogMessage("Vetoing the change."); + ev.Veto(); + return; + } + + ev.Skip(); +} + void GridFrame::OnCellValueChanged( wxGridEvent& ev ) { int row = ev.GetRow(), col = ev.GetCol(); - wxLogMessage(_T("Value changed for cell at row %d, col %d: now \"%s\""), - row, col, grid->GetCellValue(row, col).c_str()); + wxLogMessage("Value of cell at (%d, %d) changed and is now \"%s\" " + "(was \"%s\")", + row, col, + grid->GetCellValue(row, col), ev.GetString()); ev.Skip(); } @@ -1969,4 +1993,3 @@ void GridFrame::OnTabularTable(wxCommandEvent&) { new TabularGridFrame; } - diff --git a/samples/grid/griddemo.h b/samples/grid/griddemo.h index 0545692a3c..fdd0a06a28 100644 --- a/samples/grid/griddemo.h +++ b/samples/grid/griddemo.h @@ -91,6 +91,7 @@ class GridFrame : public wxFrame void OnColSize( wxGridSizeEvent& ); void OnSelectCell( wxGridEvent& ); void OnRangeSelected( wxGridRangeSelectEvent& ); + void OnCellValueChanging( wxGridEvent& ); void OnCellValueChanged( wxGridEvent& ); void OnCellBeginDrag( wxGridEvent& ); diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp index 80bf766199..cd34c36f20 100644 --- a/samples/minimal/minimal.cpp +++ b/samples/minimal/minimal.cpp @@ -99,6 +99,7 @@ enum BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Minimal_Quit, MyFrame::OnQuit) EVT_MENU(Minimal_About, MyFrame::OnAbout) + EVT_BUTTON(Minimal_About, MyFrame::OnAbout) END_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create @@ -167,6 +168,11 @@ MyFrame::MyFrame(const wxString& title) SetMenuBar(menuBar); #endif // wxUSE_MENUS + wxSizer * const sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(new wxButton(this, wxID_ABOUT)); + sizer->Add(new wxButton(this, wxID_OPEN)); + SetSizer(sizer); + #if wxUSE_STATUSBAR // create a status bar just for fun (by default with 1 pane only) CreateStatusBar(2); @@ -185,6 +191,9 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { + wxGetTextFromUser("Your text?"); + +#if 0 wxMessageBox(wxString::Format ( "Welcome to %s!\n" @@ -197,4 +206,5 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) "About wxWidgets minimal sample", wxOK | wxICON_INFORMATION, this); +#endif } diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index af2d174e39..1da201ad36 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -148,7 +148,8 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SORT) DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE) +DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGING) +DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGED) DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN) DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN) @@ -1259,9 +1260,9 @@ void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid) { wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); - m_startValue = grid->GetTable()->GetValue(row, col); + m_value = grid->GetTable()->GetValue(row, col); - DoBeginEdit(m_startValue); + DoBeginEdit(m_value); } void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) @@ -1272,31 +1273,35 @@ void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) Text()->SetFocus(); } -bool wxGridCellTextEditor::EndEdit(int row, int col, wxGrid* grid) +bool wxGridCellTextEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) { - wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); + wxCHECK_MSG( m_control, false, + "wxGridCellTextEditor must be created first!" ); - bool changed = false; - wxString value = Text()->GetValue(); - if (value != m_startValue) - changed = true; + const wxString value = Text()->GetValue(); + if ( value == m_value ) + return false; - if (changed) - grid->GetTable()->SetValue(row, col, value); + m_value = value; - m_startValue = wxEmptyString; + if ( newval ) + *newval = m_value; - // No point in setting the text of the hidden control - //Text()->SetValue(m_startValue); + return true; +} - return changed; +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, wxT("The wxGridCellEditor must be created first!")); + wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" ); - DoReset(m_startValue); + DoReset(m_value); } void wxGridCellTextEditor::DoReset(const wxString& startValue) @@ -1438,13 +1443,13 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) wxGridTableBase *table = grid->GetTable(); if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) { - m_valueOld = table->GetValueAsLong(row, col); + m_value = table->GetValueAsLong(row, col); } else { - m_valueOld = 0; + m_value = 0; wxString sValue = table->GetValue(row, col); - if (! sValue.ToLong(&m_valueOld) && ! sValue.empty()) + if (! sValue.ToLong(&m_value) && ! sValue.empty()) { wxFAIL_MSG( _T("this cell doesn't have numeric value") ); return; @@ -1454,7 +1459,7 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) #if wxUSE_SPINCTRL if ( HasRange() ) { - Spin()->SetValue((int)m_valueOld); + Spin()->SetValue((int)m_value); Spin()->SetFocus(); } else @@ -1464,8 +1469,7 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) } } -bool wxGridCellNumberEditor::EndEdit(int row, int col, - wxGrid* grid) +bool wxGridCellNumberEditor::EndEdit(const wxString& oldval, wxString *newval) { long value = 0; wxString text; @@ -1474,7 +1478,7 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col, if ( HasRange() ) { value = Spin()->GetValue(); - if ( value == m_valueOld ) + if ( value == m_value ) return false; text.Printf(wxT("%ld"), value); @@ -1482,11 +1486,10 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col, else // using unconstrained input #endif // wxUSE_SPINCTRL { - const wxString textOld(grid->GetCellValue(row, col)); text = Text()->GetValue(); if ( text.empty() ) { - if ( textOld.empty() ) + if ( oldval.empty() ) return false; } else // non-empty text now (maybe 0) @@ -1494,20 +1497,28 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col, if ( !text.ToLong(&value) ) return false; - // if value == m_valueOld == 0 but old text was "" and new one is + // if value == m_value == 0 but old text was "" and new one is // "0" something still did change - if ( value == m_valueOld && (value || !textOld.empty()) ) + 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, value); + table->SetValueAsLong(row, col, m_value); else - table->SetValue(row, col, text); - - return true; + table->SetValue(row, col, wxString::Format("%ld", m_value)); } void wxGridCellNumberEditor::Reset() @@ -1515,7 +1526,7 @@ void wxGridCellNumberEditor::Reset() #if wxUSE_SPINCTRL if ( HasRange() ) { - Spin()->SetValue((int)m_valueOld); + Spin()->SetValue((int)m_value); } else #endif @@ -1643,16 +1654,16 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) wxGridTableBase * const table = grid->GetTable(); if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) { - m_valueOld = table->GetValueAsDouble(row, col); + m_value = table->GetValueAsDouble(row, col); } else { - m_valueOld = 0.0; + m_value = 0.0; const wxString value = table->GetValue(row, col); if ( !value.empty() ) { - if ( !value.ToDouble(&m_valueOld) ) + if ( !value.ToDouble(&m_value) ) { wxFAIL_MSG( _T("this cell doesn't have float value") ); return; @@ -1663,10 +1674,9 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) DoBeginEdit(GetString()); } -bool wxGridCellFloatEditor::EndEdit(int row, int col, wxGrid* grid) +bool wxGridCellFloatEditor::EndEdit(const wxString& oldval, wxString *newval) { - const wxString text(Text()->GetValue()), - textOld(grid->GetCellValue(row, col)); + const wxString text(Text()->GetValue()); double value; if ( !text.empty() ) @@ -1676,7 +1686,7 @@ bool wxGridCellFloatEditor::EndEdit(int row, int col, wxGrid* grid) } else // new value is empty string { - if ( textOld.empty() ) + if ( oldval.empty() ) return false; // nothing changed value = 0.; @@ -1684,17 +1694,25 @@ bool wxGridCellFloatEditor::EndEdit(int row, int col, wxGrid* grid) // 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_valueOld) && !text.empty() && !textOld.empty() ) + 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, value); + table->SetValueAsDouble(row, col, m_value); else - table->SetValue(row, col, text); - - return true; + table->SetValue(row, col, Text()->GetValue()); } void wxGridCellFloatEditor::Reset() @@ -1780,7 +1798,7 @@ wxString wxGridCellFloatEditor::GetString() const fmt = _T("%f"); } - return wxString::Format(fmt, m_valueOld); + return wxString::Format(fmt, m_value); } bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) @@ -1928,16 +1946,16 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid) if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL)) { - m_startValue = grid->GetTable()->GetValueAsBool(row, col); + m_value = grid->GetTable()->GetValueAsBool(row, col); } else { wxString cellval( grid->GetTable()->GetValue(row, col) ); if ( cellval == ms_stringValues[false] ) - m_startValue = false; + m_value = false; else if ( cellval == ms_stringValues[true] ) - m_startValue = true; + m_value = true; else { // do not try to be smart here and convert it to true or false @@ -1948,31 +1966,32 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid) } } - CBox()->SetValue(m_startValue); + CBox()->SetValue(m_value); CBox()->SetFocus(); } -bool wxGridCellBoolEditor::EndEdit(int row, int col, - wxGrid* grid) +bool wxGridCellBoolEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) { - wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be created first!")); - - bool changed = false; bool value = CBox()->GetValue(); - if ( value != m_startValue ) - changed = true; + if ( value == m_value ) + return false; - if ( changed ) - { - wxGridTableBase * const table = grid->GetTable(); - if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) ) - table->SetValueAsBool(row, col, value); - else - table->SetValue(row, col, GetValue()); - } + m_value = value; + + if ( newval ) + *newval = GetValue(); - return changed; + 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() @@ -1980,7 +1999,7 @@ void wxGridCellBoolEditor::Reset() wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); - CBox()->SetValue(m_startValue); + CBox()->SetValue(m_value); } void wxGridCellBoolEditor::StartingClick() @@ -2123,9 +2142,9 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) if (evtHandler) evtHandler->SetInSetFocus(true); - m_startValue = grid->GetTable()->GetValue(row, col); + m_value = grid->GetTable()->GetValue(row, col); - Reset(); // this updates combo box to correspond to m_startValue + Reset(); // this updates combo box to correspond to m_value Combo()->SetFocus(); @@ -2139,29 +2158,37 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) } } -bool wxGridCellChoiceEditor::EndEdit(int row, int col, - wxGrid* grid) +bool wxGridCellChoiceEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) { - wxString value = Combo()->GetValue(); - if ( value == m_startValue ) + const wxString value = Combo()->GetValue(); + if ( value == m_value ) return false; - grid->GetTable()->SetValue(row, col, value); + 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_startValue); + 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_startValue); + int pos = Combo()->FindString(m_value); if (pos == wxNOT_FOUND) pos = 0; Combo()->SetSelection(pos); @@ -7105,7 +7132,8 @@ wxGrid::SendEvent(const wxEventType type, // Generate a grid event of specified type, return value same as above // -int wxGrid::SendEvent(const wxEventType type, int row, int col) +int +wxGrid::SendEvent(const wxEventType type, int row, int col, const wxString& s) { bool claimed, vetoed; @@ -7121,6 +7149,7 @@ int wxGrid::SendEvent(const wxEventType type, int row, int col) else { wxGridEvent gridEvt( GetId(), type, this, row, col ); + gridEvt.SetString(s); claimed = GetEventHandler()->ProcessEvent(gridEvt); vetoed = !gridEvt.IsAllowed(); @@ -8573,7 +8602,6 @@ void wxGrid::EnableCellEditControl( bool enable ) } else { - //FIXME:add veto support SendEvent(wxEVT_GRID_EDITOR_HIDDEN); HideCellEditControl(); @@ -8806,19 +8834,26 @@ void wxGrid::SaveEditControlValue() wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellEditor* editor = attr->GetEditor(this, row, col); - bool changed = editor->EndEdit(row, col, this); - editor->DecRef(); - attr->DecRef(); + wxString newval; + bool changed = editor->EndEdit(oldval, &newval); - if (changed) + if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 ) { - if ( SendEvent(wxEVT_GRID_CELL_CHANGE) == -1 ) + editor->ApplyEdit(row, col, this); + + // for compatibility reasons dating back to wx 2.8 when this event + // was called wxEVT_GRID_CELL_CHANGE and wxEVT_GRID_CELL_CHANGING + // didn't exist we allow vetoing this one too + if ( SendEvent(wxEVT_GRID_CELL_CHANGED, oldval) == -1 ) { // Event has been vetoed, set the data back. SetCellValue(row, col, oldval); } } + + editor->DecRef(); + attr->DecRef(); } } diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index e5ec58360f..052dfbd49f 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -225,7 +225,7 @@ void wxGridCellEnumRenderer::SetParameters(const wxString& params) wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices) :wxGridCellChoiceEditor() { - m_startint = -1; + m_index = -1; if (!choices.empty()) SetParameters(choices); @@ -234,7 +234,7 @@ wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices) wxGridCellEditor *wxGridCellEnumEditor::Clone() const { wxGridCellEnumEditor *editor = new wxGridCellEnumEditor(); - editor->m_startint = m_startint; + editor->m_index = m_index; return editor; } @@ -247,40 +247,49 @@ void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid) if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) { - m_startint = table->GetValueAsLong(row, col); + m_index = table->GetValueAsLong(row, col); } else { wxString startValue = table->GetValue(row, col); if (startValue.IsNumber() && !startValue.empty()) { - startValue.ToLong(&m_startint); + startValue.ToLong(&m_index); } else { - m_startint=-1; + m_index = -1; } } - Combo()->SetSelection(m_startint); + Combo()->SetSelection(m_index); Combo()->SetInsertionPointEnd(); Combo()->SetFocus(); } -bool wxGridCellEnumEditor::EndEdit(int row, int col, wxGrid* grid) +bool wxGridCellEnumEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) { - int pos = Combo()->GetSelection(); - bool changed = (pos != m_startint); - if (changed) - { - if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER)) - grid->GetTable()->SetValueAsLong(row, col, pos); - else - grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos)); - } + long idx = Combo()->GetSelection(); + if ( idx == m_index ) + return false; + + m_index = idx; + + if ( newval ) + newval->Printf("%ld", m_index); - return changed; + 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 -- 2.45.2