From edb8f2985fc838f92c60d9efd42462441f3caea9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 8 Jul 2002 16:38:46 +0000 Subject: [PATCH] fix crash when the user code refuses to validate the new text when editing the item and a generic label editing code cleanup git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16083 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/treectlg.h | 7 +- src/generic/treectlg.cpp | 247 +++++++++++++++++----------------- 2 files changed, 122 insertions(+), 132 deletions(-) diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index da193415ce..87351c4865 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -353,8 +353,7 @@ protected: wxGenericTreeItem *m_anchor; wxGenericTreeItem *m_current, - *m_key_current, - *m_currentEdit; + *m_key_current; unsigned short m_indent; unsigned short m_spacing; int m_lineHeight; @@ -367,7 +366,6 @@ protected: m_ownsImageListState, m_ownsImageListButtons; bool m_isDragging; // true between BEGIN/END drag events - bool m_renameAccept; bool m_lastOnSame; // last click on the same item as prev wxImageList *m_imageListNormal, *m_imageListState, @@ -380,7 +378,6 @@ protected: wxGenericTreeItem *m_oldSelection; wxTimer *m_renameTimer; - wxString m_renameRes; wxBitmap *m_arrowRight, *m_arrowDown; @@ -431,7 +428,7 @@ protected: void RefreshSelectedUnder(wxGenericTreeItem *item); void OnRenameTimer(); - void OnRenameAccept(); + bool OnRenameAccept(wxGenericTreeItem *item, const wxString& value); void FillArray(wxGenericTreeItem*, wxArrayTreeItemIds&) const; void SelectItemRange( wxGenericTreeItem *item1, wxGenericTreeItem *item2 ); diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 35f2d96708..05cfdf1187 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -126,26 +126,19 @@ private: class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl { public: - wxTreeTextCtrl( wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxGenericTreeCtrl *owner, - const wxString &value = wxEmptyString, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - int style = wxSIMPLE_BORDER, - const wxValidator& validator = wxDefaultValidator, - const wxString &name = wxTextCtrlNameStr ); + wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item); +protected: void OnChar( wxKeyEvent &event ); void OnKeyUp( wxKeyEvent &event ); void OnKillFocus( wxFocusEvent &event ); + bool AcceptChanges(); + void Finish(); + private: - bool *m_accept; - wxString *m_res; wxGenericTreeCtrl *m_owner; + wxGenericTreeItem *m_itemEdited; wxString m_startValue; bool m_finished; @@ -353,99 +346,131 @@ BEGIN_EVENT_TABLE(wxTreeTextCtrl,wxTextCtrl) EVT_KILL_FOCUS (wxTreeTextCtrl::OnKillFocus) END_EVENT_TABLE() -wxTreeTextCtrl::wxTreeTextCtrl( wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxGenericTreeCtrl *owner, - const wxString &value, - const wxPoint &pos, - const wxSize &size, - int style, - const wxValidator& validator, - const wxString &name ) - : wxTextCtrl( parent, id, value, pos, size, style, validator, name ) -{ - m_res = res; - m_accept = accept; +wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, + wxGenericTreeItem *item) + : m_itemEdited(item), m_startValue(item->GetText()) +{ m_owner = owner; - (*m_accept) = FALSE; - (*m_res) = wxEmptyString; - m_startValue = value; m_finished = FALSE; -} -void wxTreeTextCtrl::OnChar( wxKeyEvent &event ) -{ - if (event.m_keyCode == WXK_RETURN) + int w = m_itemEdited->GetWidth(), + h = m_itemEdited->GetHeight(); + + int x, y; + m_owner->CalcScrolledPosition(item->GetX(), item->GetY(), &x, &y); + + int image_h = 0, + image_w = 0; + + int image = item->GetCurrentImage(); + if ( image != NO_IMAGE ) { - (*m_accept) = TRUE; - (*m_res) = GetValue(); + if ( m_owner->m_imageListNormal ) + { + m_owner->m_imageListNormal->GetSize( image, image_w, image_h ); + image_w += 4; + } + else + { + wxFAIL_MSG(_T("you must create an image list to use images!")); + } + } - if ((*m_res) != m_startValue) - m_owner->OnRenameAccept(); + // FIXME: what are all these hardcoded 4, 8 and 11s really? + x += image_w; + w -= image_w + 4; - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); + (void)Create(m_owner, wxID_ANY, m_startValue, + wxPoint(x - 4, y - 4), wxSize(w + 11, h + 8)); +} - m_finished = TRUE; - m_owner->SetFocus(); // This doesn't work. TODO. +bool wxTreeTextCtrl::AcceptChanges() +{ + const wxString value = GetValue(); - return; + if ( value == m_startValue ) + { + // nothing changed, always accept + return TRUE; } - if (event.m_keyCode == WXK_ESCAPE) + + if ( !m_owner->OnRenameAccept(m_itemEdited, value) ) { - (*m_accept) = FALSE; - (*m_res) = ""; + // vetoed by the user + return FALSE; + } - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); + // accepted, do rename the item + m_owner->SetItemText(m_itemEdited, value); + + return TRUE; +} + +void wxTreeTextCtrl::Finish() +{ + if ( !m_finished ) + { + wxPendingDelete.Append(this); m_finished = TRUE; + m_owner->SetFocus(); // This doesn't work. TODO. + } +} - return; +void wxTreeTextCtrl::OnChar( wxKeyEvent &event ) +{ + switch ( event.m_keyCode ) + { + case WXK_RETURN: + if ( !AcceptChanges() ) + { + // vetoed by the user, don't disappear + break; + } + //else: fall through + + case WXK_ESCAPE: + Finish(); + break; + + default: + event.Skip(); } - event.Skip(); } void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event ) { - if (m_finished) + if ( !m_finished ) { - event.Skip(); - return; + // auto-grow the textctrl: + wxSize parentSize = m_owner->GetSize(); + wxPoint myPos = GetPosition(); + wxSize mySize = GetSize(); + int sx, sy; + GetTextExtent(GetValue() + _T("M"), &sx, &sy); + if (myPos.x + sx > parentSize.x) + sx = parentSize.x - myPos.x; + if (mySize.x > sx) + sx = mySize.x; + SetSize(sx, -1); } - // auto-grow the textctrl: - wxSize parentSize = m_owner->GetSize(); - wxPoint myPos = GetPosition(); - wxSize mySize = GetSize(); - int sx, sy; - GetTextExtent(GetValue() + _T("M"), &sx, &sy); - if (myPos.x + sx > parentSize.x) sx = parentSize.x - myPos.x; - if (mySize.x > sx) sx = mySize.x; - SetSize(sx, -1); - event.Skip(); } void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event ) { - if (m_finished) + if ( m_finished ) { event.Skip(); return; } - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); - - (*m_accept) = TRUE; - (*m_res) = GetValue(); - - if ((*m_res) != m_startValue) - m_owner->OnRenameAccept(); + if ( AcceptChanges() ) + { + Finish(); + } } // ----------------------------------------------------------------------------- @@ -2692,8 +2717,8 @@ wxTreeItemId wxGenericTreeCtrl::HitTest(const wxPoint& point, int& flags) // get the bounding rectangle of the item (or of its label only) bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, - wxRect& rect, - bool WXUNUSED(textOnly)) const + wxRect& rect, + bool WXUNUSED(textOnly)) const { wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") ); @@ -2711,78 +2736,46 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, return TRUE; } -/* **** */ - void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) { - if (!item.IsOk()) return; + wxCHECK_RET( item.IsOk(), _T("can't edit an invalid item") ); - m_currentEdit = (wxGenericTreeItem*) item.m_pItem; + wxGenericTreeItem *itemEdit = (wxGenericTreeItem *)item.m_pItem; wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, GetId() ); - te.m_item = (long) m_currentEdit; + te.m_item = (long) itemEdit; te.SetEventObject( this ); - GetEventHandler()->ProcessEvent( te ); - - if (!te.IsAllowed()) return; + if ( GetEventHandler()->ProcessEvent( te ) && !te.IsAllowed() ) + { + // vetoed by user + return; + } // We have to call this here because the label in // question might just have been added and no screen // update taken place. - if (m_dirty) wxYieldIfNeeded(); + if ( m_dirty ) + wxYieldIfNeeded(); - wxString s = m_currentEdit->GetText(); - int w = m_currentEdit->GetWidth(); - int h = m_currentEdit->GetHeight(); - int x, y; - CalcScrolledPosition(m_currentEdit->GetX(), m_currentEdit->GetY(), &x, &y); + wxTreeTextCtrl *text = new wxTreeTextCtrl(this, itemEdit); - int image_h = 0; - int image_w = 0; - - int image = m_currentEdit->GetCurrentImage(); - if ( image != NO_IMAGE ) - { - if ( m_imageListNormal ) - { - m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += 4; - } - else - { - wxFAIL_MSG(_T("you must create an image list to use images!")); - } - } - x += image_w; - w -= image_w + 4; // I don't know why +4 is needed - - wxTreeTextCtrl *text = new wxTreeTextCtrl(this, -1, - &m_renameAccept, - &m_renameRes, - this, - s, - wxPoint(x-4,y-4), - wxSize(w+11,h+8)); text->SetFocus(); } -void wxGenericTreeCtrl::OnRenameTimer() +bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, + const wxString& value) { - Edit( m_current ); -} - -void wxGenericTreeCtrl::OnRenameAccept() -{ - // TODO if the validator fails this causes a crash wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, GetId() ); - le.m_item = (long) m_currentEdit; + le.m_item = (long) item; le.SetEventObject( this ); - le.m_label = m_renameRes; - GetEventHandler()->ProcessEvent( le ); + le.m_label = value; - if (!le.IsAllowed()) return; + return !GetEventHandler()->ProcessEvent( le ) || le.IsAllowed(); +} - SetItemText( m_currentEdit, m_renameRes ); +void wxGenericTreeCtrl::OnRenameTimer() +{ + Edit( m_current ); } void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) -- 2.45.2