diff --git a/docs/changes.txt b/docs/changes.txt index 6ad30469d8..8520be4207 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -182,6 +182,7 @@ All (GUI): - Generate wxEVT_SEARCH on Enter under all platforms. - Extend wxRendererNative::DrawGauge() to work for vertical gauges too. - Add wxHD_BITMAP_ON_RIGHT style to wxHeaderCtrl. +- Send wxEVT_DATAVIEW_ITEM_EDITING_DONE when editing was cancelled too. wxGTK: diff --git a/include/wx/dvrenderers.h b/include/wx/dvrenderers.h index 0d2615b659..c1230cafcc 100644 --- a/include/wx/dvrenderers.h +++ b/include/wx/dvrenderers.h @@ -259,6 +259,9 @@ protected: wxDataViewCtrl* GetView() const; private: + // Common part of {Cancel,Finish}Editing(). + bool DoFinishOrCancelEditing(bool cancelled); + // Called from {Called,Finish}Editing() and dtor to cleanup m_editorCtrl void DestroyEditControl(); diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index 64e89e7b71..240fc74d40 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -1227,7 +1227,11 @@ void MyFrame::OnEditingStarted( wxDataViewEvent &event ) void MyFrame::OnEditingDone( wxDataViewEvent &event ) { wxString title = m_music_model->GetTitle( event.GetItem() ); - wxLogMessage( "wxEVT_DATAVIEW_ITEM_EDITING_DONE, Item: %s", title ); + wxLogMessage("wxEVT_DATAVIEW_ITEM_EDITING_DONE, Item: %s, new value %s", + title, + event.IsEditCancelled() + ? wxString("unavailable because editing was cancelled") + : event.GetValue().GetString()); } void MyFrame::OnExpanded( wxDataViewEvent &event ) diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index a7d7597fff..dcbc5cd101 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -766,44 +766,67 @@ void wxDataViewRendererBase::DestroyEditControl() void wxDataViewRendererBase::CancelEditing() { - if (!m_editorCtrl) - return; - - DestroyEditControl(); + DoFinishOrCancelEditing(true); } bool wxDataViewRendererBase::FinishEditing() +{ + return DoFinishOrCancelEditing(false); +} + +bool wxDataViewRendererBase::DoFinishOrCancelEditing(bool cancelled) { if (!m_editorCtrl) return true; - // Try to get the value, normally we should succeed but if we fail, don't - // return immediately, we still need to destroy the edit control. + bool gotValue = false; + wxVariant value; - const bool gotValue = GetValueFromEditorCtrl(m_editorCtrl, value); + if ( !cancelled ) + { + if ( GetValueFromEditorCtrl(m_editorCtrl, value) ) + { + // This is the normal case and we will use this value below (if it + // passes validation). + gotValue = true; + } + //else: Not really supposed to happen, but still proceed with + // destroying the edit control if it does. + } wxDataViewColumn* const column = GetOwner(); wxDataViewCtrl* const dv_ctrl = column->GetOwner(); DestroyEditControl(); - dv_ctrl->GetMainWindow()->SetFocus(); + // If we're cancelled, it can be because focus was switched elsewhere, + // don't bring it back here. + if ( !cancelled ) + dv_ctrl->GetMainWindow()->SetFocus(); - if ( !gotValue ) - return false; + if ( gotValue ) + { + if ( !Validate(value) ) + { + // Invalid value can't be used, so if it's the same as if we hadn't + // got it in the first place. + gotValue = false; + } + } - bool isValid = Validate(value); unsigned int col = GetOwner()->GetModelColumn(); // Now we should send Editing Done event wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_EDITING_DONE, dv_ctrl, column, m_item); - event.SetValue( value ); - if ( !isValid ) + if ( gotValue ) + event.SetValue(value); + else event.SetEditCancelled(); + dv_ctrl->GetEventHandler()->ProcessEvent( event ); bool accepted = false; - if ( isValid && event.IsAllowed() ) + if ( gotValue && event.IsAllowed() ) { dv_ctrl->GetModel()->ChangeValue(value, m_item, col); accepted = true;