Send wxEVT_DATAVIEW_ITEM_EDITING_DONE after cancelling too

Previously this event was not sent at all if editing the item was
cancelled, e.g. by pressing Esc.

Do send it now from the generic implementation and update the sample to
show this event.

See #17835.
This commit is contained in:
Vadim Zeitlin 2018-02-04 22:40:51 +01:00
parent 7e3d28e79f
commit 1e3e5b7253
4 changed files with 46 additions and 15 deletions

View File

@ -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:

View File

@ -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();

View File

@ -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 )

View File

@ -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;