From e738283be285d34f2b411575b26bceb57840e7ec Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Mon, 23 Jul 2007 12:23:15 +0000 Subject: [PATCH] Avoid a hang if we're dragging a tab to a notebook that's a child of the original tab git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@47662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/aui/auibook.cpp | 51 +++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index f92b0ae022..47e7fb1682 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -2068,13 +2068,13 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) if (m_is_dragging) { m_is_dragging = false; - + wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId); evt.SetSelection(GetIdxFromWindow(m_click_tab)); evt.SetOldSelection(evt.GetSelection()); evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); - + return; } @@ -2719,9 +2719,9 @@ bool wxAuiNotebook::DeletePage(size_t page_idx) { if (page_idx >= m_tabs.GetPageCount()) return false; - + wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx); - + // hide the window in advance, as this will // prevent flicker ShowWnd(wnd, false); @@ -2755,7 +2755,7 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) wxWindow* active_wnd = NULL; if (m_curpage >= 0) active_wnd = m_tabs.GetWindowFromIdx(m_curpage); - + // save pointer of window being deleted wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx); wxWindow* new_active = NULL; @@ -2763,7 +2763,7 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) // make sure we found the page if (!wnd) return false; - + // find out which onscreen tab ctrl owns this tab wxAuiTabCtrl* ctrl; int ctrl_idx; @@ -2784,15 +2784,15 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) if (is_active_in_split) { int ctrl_new_page_count = (int)ctrl->GetPageCount(); - + if (ctrl_idx >= ctrl_new_page_count) ctrl_idx = ctrl_new_page_count-1; - + if (ctrl_idx >= 0 && ctrl_idx < (int)ctrl->GetPageCount()) { // set new page as active in the tab split ctrl->SetActivePage(ctrl_idx); - + // if the page deleted was the current page for the // entire tab control, then record the window // pointer of the new active page for activation @@ -2808,25 +2808,25 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) new_active = active_wnd; } - + if (!new_active) { // we haven't yet found a new page to active, // so select the next page from the main tab // catalogue - + if (page_idx < m_tabs.GetPageCount()) { new_active = m_tabs.GetPage(page_idx).window; } - + if (!new_active && m_tabs.GetPageCount() > 0) { new_active = m_tabs.GetPage(0).window; } } - + RemoveEmptyTabFrames(); // set new active pane @@ -2835,7 +2835,7 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) m_curpage = -1; SetSelection(m_tabs.GetIdxFromWindow(new_active)); } - + return true; } @@ -3426,6 +3426,17 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) int src_idx = evt.GetSelection(); wxWindow* src_page = src_tabs->GetWindowFromIdx(src_idx); + // Check that it's not an impossible parent relationship + wxWindow* p = nb; + while (p && !p->IsTopLevel()) + { + if (p == src_page) + { + return; + } + p = p->GetParent(); + } + // get main index of the page int main_idx = m_tabs.GetIdxFromWindow(src_page); @@ -3628,7 +3639,7 @@ void wxAuiNotebook::RemoveEmptyTabFrames() // window closing, refreshs are pending if (!wxPendingDelete.Member(tab_frame->m_tabs)) wxPendingDelete.Append(tab_frame->m_tabs); - + tab_frame->m_tabs = NULL; delete tab_frame; @@ -3667,7 +3678,7 @@ void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt) // was hidden. In the bug, the focus would return to the notebook // child, which would then enter this handler and call // SetSelection, which is not desired turn tab dragging. - + wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); size_t i, pane_count = all_panes.GetCount(); for (i = 0; i < pane_count; ++i) @@ -3708,7 +3719,7 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt) // page selection to determine which page to close selection = GetSelection(); } - + if (selection != -1) { wxWindow* close_wnd = tabs->GetWindowFromIdx(selection); @@ -3754,7 +3765,7 @@ void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent& evt) // click should act like a tab close action. However, first // give the owner an opportunity to handle the middle up event // for custom action - + wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject(); wxWindow* wnd = tabs->GetWindowFromIdx(evt.GetSelection()); @@ -3765,11 +3776,11 @@ void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent& evt) return; if (!e.IsAllowed()) return; - + // check if we are supposed to close on middle-up if ((m_flags & wxAUI_NB_MIDDLE_CLICK_CLOSE) == 0) return; - + // simulate the user pressing the close button on the tab evt.SetInt(wxAUI_BUTTON_CLOSE); OnTabButton(evt);