diff --git a/include/wx/dvrenderers.h b/include/wx/dvrenderers.h index c1230cafcc..4cda6ba033 100644 --- a/include/wx/dvrenderers.h +++ b/include/wx/dvrenderers.h @@ -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 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(); diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index dcbc5cd101..9043cf3fd4 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -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; } diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index d1f55061f6..6ed97b47b7 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -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))