Send wxEVT_DATAVIEW_ITEM_EDITING_DONE for all renderers in wxGTK
Previously this event was not sent for the standard renderers, such as wxDataViewTextRenderer, at all in wxGTK because the base class FinishEditing() class didn't do anything if m_editorCtrl was null, as it was always the case for non-custom renderers. Fix this by refactoring the base class code in yet another way and extracting the part which can be reused by both the generic and GTK implementation in a new DoHandleEditingDone() function and call it from wxGTK code. Finally, check "editing-canceled" property to also correctly generate the event with IsEditCancelled() returning true when editing is canceled by e.g. pressing Esc in a standard renderer too. And, as a final bonus, this makes the (just introduced) slightly artificial DoFinishOrCancelEditing() unnecessary, so it can be removed, without reintroducing any code duplication. See #17835.
This commit is contained in:
@@ -247,6 +247,12 @@ protected:
|
||||
const wxDataViewItem& item,
|
||||
unsigned column) const;
|
||||
|
||||
// Validates the given value (if it is non-null) and sends (in any case)
|
||||
// ITEM_EDITING_DONE event and, finally, updates the model with the value
|
||||
// (f it is valid, of course) if the event wasn't vetoed.
|
||||
bool DoHandleEditingDone(wxVariant* value);
|
||||
|
||||
|
||||
wxString m_variantType;
|
||||
wxDataViewColumn *m_owner;
|
||||
wxWeakRef<wxWindow> m_editorCtrl;
|
||||
@@ -259,9 +265,6 @@ 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();
|
||||
|
||||
|
@@ -766,15 +766,13 @@ void wxDataViewRendererBase::DestroyEditControl()
|
||||
|
||||
void wxDataViewRendererBase::CancelEditing()
|
||||
{
|
||||
DoFinishOrCancelEditing(true);
|
||||
if ( m_editorCtrl )
|
||||
DestroyEditControl();
|
||||
|
||||
DoHandleEditingDone(NULL);
|
||||
}
|
||||
|
||||
bool wxDataViewRendererBase::FinishEditing()
|
||||
{
|
||||
return DoFinishOrCancelEditing(false);
|
||||
}
|
||||
|
||||
bool wxDataViewRendererBase::DoFinishOrCancelEditing(bool cancelled)
|
||||
{
|
||||
if (!m_editorCtrl)
|
||||
return true;
|
||||
@@ -782,53 +780,52 @@ bool wxDataViewRendererBase::DoFinishOrCancelEditing(bool cancelled)
|
||||
bool gotValue = false;
|
||||
|
||||
wxVariant value;
|
||||
if ( !cancelled )
|
||||
if ( GetValueFromEditorCtrl(m_editorCtrl, value) )
|
||||
{
|
||||
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.
|
||||
|
||||
DestroyEditControl();
|
||||
|
||||
GetView()->GetMainWindow()->SetFocus();
|
||||
|
||||
return DoHandleEditingDone(gotValue ? &value : NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
wxDataViewRendererBase::DoHandleEditingDone(wxVariant* value)
|
||||
{
|
||||
if ( value )
|
||||
{
|
||||
if ( !Validate(*value) )
|
||||
{
|
||||
// This is the normal case and we will use this value below (if it
|
||||
// passes validation).
|
||||
gotValue = true;
|
||||
// Invalid value can't be used, so if it's the same as if we hadn't
|
||||
// got it in the first place.
|
||||
value = NULL;
|
||||
}
|
||||
//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();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int col = GetOwner()->GetModelColumn();
|
||||
unsigned int col = column->GetModelColumn();
|
||||
|
||||
// Now we should send Editing Done event
|
||||
wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_EDITING_DONE, dv_ctrl, column, m_item);
|
||||
if ( gotValue )
|
||||
event.SetValue(value);
|
||||
if ( value )
|
||||
event.SetValue(*value);
|
||||
else
|
||||
event.SetEditCancelled();
|
||||
|
||||
dv_ctrl->GetEventHandler()->ProcessEvent( event );
|
||||
|
||||
bool accepted = false;
|
||||
if ( gotValue && event.IsAllowed() )
|
||||
if ( value && event.IsAllowed() )
|
||||
{
|
||||
dv_ctrl->GetModel()->ChangeValue(value, m_item, col);
|
||||
dv_ctrl->GetModel()->ChangeValue(*value, m_item, col);
|
||||
accepted = true;
|
||||
}
|
||||
|
||||
|
@@ -1932,9 +1932,24 @@ bool wxGtkDataViewModelNotifier::Cleared()
|
||||
// ---------------------------------------------------------
|
||||
|
||||
static void
|
||||
wxgtk_cell_editable_editing_done( GtkCellEditable *WXUNUSED(editable),
|
||||
wxgtk_cell_editable_editing_done( GtkCellEditable *editable,
|
||||
wxDataViewRenderer *wxrenderer )
|
||||
{
|
||||
// "editing-cancelled" property is documented as being new since 2.20 in
|
||||
// GtkCellEditable, but seems to have existed basically forever (since GTK+
|
||||
// 1.3 days) in GtkCellRendererText, so try to use it in any case.
|
||||
if ( g_object_class_find_property(G_OBJECT_GET_CLASS(editable),
|
||||
"editing-canceled") )
|
||||
{
|
||||
gboolean wasCancelled;
|
||||
g_object_get(editable, "editing-canceled", &wasCancelled, NULL);
|
||||
if ( wasCancelled )
|
||||
{
|
||||
wxrenderer->CancelEditing();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wxrenderer->FinishEditing();
|
||||
}
|
||||
|
||||
@@ -2164,15 +2179,10 @@ wxDataViewRenderer::GtkGetValueFromString(const wxString& str) const
|
||||
void
|
||||
wxDataViewRenderer::GtkOnTextEdited(const char *itempath, const wxString& str)
|
||||
{
|
||||
m_item = wxDataViewItem(GetView()->GTKPathToItem(wxGtkTreePath(itempath)));
|
||||
|
||||
wxVariant value(GtkGetValueFromString(str));
|
||||
if (!Validate( value ))
|
||||
return;
|
||||
|
||||
wxDataViewItem
|
||||
item(GetOwner()->GetOwner()->GTKPathToItem(wxGtkTreePath(itempath)));
|
||||
|
||||
wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
|
||||
model->ChangeValue( value, item, GetOwner()->GetModelColumn() );
|
||||
DoHandleEditingDone(&value);
|
||||
}
|
||||
|
||||
void wxDataViewRenderer::SetAttr(const wxDataViewItemAttr& WXUNUSED(attr))
|
||||
|
Reference in New Issue
Block a user