From 93f6e00d7b98869ef38f05113550ac0c11bf0102 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 5 Oct 2010 13:38:05 +0000 Subject: [PATCH] Destroy the in-place edit control in wxGenericListCtrl dtor. If the in-place text control was still alive when wxGenericListCtrl was destroyed, it resulted in asserts from wxWindow dtor about child windows still being alive, so explicitly destroy it from wxListMainWindow dtor. As this required a slightly different behaviour from wxListTextCtrlWrapper:: EndEdit(), replace its bool argument with an enum one which can take more than 2 values. Not using bool values when calling it also made the code more clear. Finally, added a unit test verifying that the in-place control is indeed destroyed correctly. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65769 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/private/listctrl.h | 12 ++++++++- src/generic/listctrl.cpp | 39 +++++++++++++++++---------- tests/controls/listctrltest.cpp | 9 +++++++ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h index 4965aafbfb..52ef5aa075 100644 --- a/include/wx/generic/private/listctrl.h +++ b/include/wx/generic/private/listctrl.h @@ -402,7 +402,17 @@ public: wxTextCtrl *GetText() const { return m_text; } - void EndEdit( bool discardChanges ); + // Different reasons for calling EndEdit(): + // + // It was called because: + enum EndReason + { + End_Accept, // user has accepted the changes. + End_Discard, // user has cancelled editing. + End_Destroy // the entire control is being destroyed. + }; + + void EndEdit(EndReason reason); protected: void OnChar( wxKeyEvent &event ); diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 4ce0960f73..eddc8e4108 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -1407,23 +1407,31 @@ wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner, m_text->PushEventHandler(this); } -void wxListTextCtrlWrapper::EndEdit(bool discardChanges) +void wxListTextCtrlWrapper::EndEdit(EndReason reason) { m_aboutToFinish = true; - if ( discardChanges ) + switch ( reason ) { - m_owner->OnRenameCancelled(m_itemEdited); + case End_Accept: + // Notify the owner about the changes + AcceptChanges(); - Finish( true ); - } - else - { - // Notify the owner about the changes - AcceptChanges(); + // Even if vetoed, close the control (consistent with MSW) + Finish( true ); + break; + + case End_Discard: + m_owner->OnRenameCancelled(m_itemEdited); - // Even if vetoed, close the control (consistent with MSW) - Finish( true ); + Finish( true ); + break; + + case End_Destroy: + // Don't generate any notifications for the control being destroyed + // and don't set focus to it neither. + Finish(false); + break; } } @@ -1462,11 +1470,11 @@ void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event ) switch ( event.m_keyCode ) { case WXK_RETURN: - EndEdit( false ); + EndEdit( End_Accept ); break; case WXK_ESCAPE: - EndEdit( true ); + EndEdit( End_Discard ); break; default: @@ -1600,6 +1608,9 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, wxListMainWindow::~wxListMainWindow() { + if ( m_textctrlWrapper ) + m_textctrlWrapper->EndEdit(wxListTextCtrlWrapper::End_Destroy); + DoDeleteAllItems(); WX_CLEAR_LIST(wxListHeaderDataList, m_columns); WX_CLEAR_ARRAY(m_aColWidths); @@ -2273,7 +2284,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) // listctrl because the order of events is different (or something like // that), so explicitly end the edit if it is active. if ( event.LeftDown() && m_textctrlWrapper ) - m_textctrlWrapper->EndEdit( false ); + m_textctrlWrapper->EndEdit(wxListTextCtrlWrapper::End_Accept); #endif // __WXMAC__ if ( event.LeftDown() ) diff --git a/tests/controls/listctrltest.cpp b/tests/controls/listctrltest.cpp index cb61633002..108d1935c7 100644 --- a/tests/controls/listctrltest.cpp +++ b/tests/controls/listctrltest.cpp @@ -46,10 +46,12 @@ public: private: CPPUNIT_TEST_SUITE( ListCtrlTestCase ); wxLIST_BASE_TESTS(); + CPPUNIT_TEST( EditLabel ); WXUISIM_TEST( ColumnClick ); WXUISIM_TEST( ColumnDrag ); CPPUNIT_TEST_SUITE_END(); + void EditLabel(); #if wxUSE_UIACTIONSIMULATOR // Column events are only supported in wxListCtrl currently so we test them // here rather than in ListBaseTest @@ -85,6 +87,13 @@ void ListCtrlTestCase::tearDown() m_list = NULL; } +void ListCtrlTestCase::EditLabel() +{ + m_list->InsertColumn(0, "Column 0"); + m_list->InsertItem(0, "foo"); + m_list->EditLabel(0); +} + #if wxUSE_UIACTIONSIMULATOR void ListCtrlTestCase::ColumnDrag() { -- 2.45.2