From 36202885d48e85cc2012f5595ec1dfe00991e886 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 22 May 2001 14:01:02 +0000 Subject: [PATCH] fix for discrepancies between wxNotebookEvent and wxNotebook GetSelection() results git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10268 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/notebook.h | 5 ++- include/wx/gtk1/notebook.h | 5 ++- samples/controls/controls.cpp | 8 +++- src/gtk/notebook.cpp | 82 +++++++++++++++++++++++++---------- src/gtk1/notebook.cpp | 82 +++++++++++++++++++++++++---------- 5 files changed, 130 insertions(+), 52 deletions(-) diff --git a/include/wx/gtk/notebook.h b/include/wx/gtk/notebook.h index 4b297ddf32..45d6eecfbf 100644 --- a/include/wx/gtk/notebook.h +++ b/include/wx/gtk/notebook.h @@ -160,7 +160,10 @@ public: wxImageList* m_imageList; bool m_ownsImageList; wxList m_pages; - int m_lastSelection; /* hack */ + + // for reasons explained in gtk/notebook.cpp we store the current + // selection internally instead of querying the notebook for it + int m_selection; private: DECLARE_DYNAMIC_CLASS(wxNotebook) diff --git a/include/wx/gtk1/notebook.h b/include/wx/gtk1/notebook.h index 4b297ddf32..45d6eecfbf 100644 --- a/include/wx/gtk1/notebook.h +++ b/include/wx/gtk1/notebook.h @@ -160,7 +160,10 @@ public: wxImageList* m_imageList; bool m_ownsImageList; wxList m_pages; - int m_lastSelection; /* hack */ + + // for reasons explained in gtk/notebook.cpp we store the current + // selection internally instead of querying the notebook for it + int m_selection; private: DECLARE_DYNAMIC_CLASS(wxNotebook) diff --git a/samples/controls/controls.cpp b/samples/controls/controls.cpp index 8ea9cf6b99..8fe30a9a9a 100644 --- a/samples/controls/controls.cpp +++ b/samples/controls/controls.cpp @@ -869,12 +869,16 @@ void MyPanel::OnPageChanging( wxNotebookEvent &event ) } } - *m_text << "Notebook selection is being changed from " << selOld << "\n"; + *m_text << "Notebook selection is being changed from " << selOld + << " to " << event.GetSelection() + << " (current page from notebook is " + << m_notebook->GetSelection() << ")\n"; } void MyPanel::OnPageChanged( wxNotebookEvent &event ) { - *m_text << "Notebook selection is " << event.GetSelection() << "\n"; + *m_text << "Notebook selection is now " << event.GetSelection() + << " (from notebook: " << m_notebook->GetSelection() << ")\n"; } void MyPanel::OnTestButton(wxCommandEvent& event) diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp index 78f0ebc9d6..1bbcc15109 100644 --- a/src/gtk/notebook.cpp +++ b/src/gtk/notebook.cpp @@ -89,27 +89,44 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), gint page, wxNotebook *notebook ) { + static bool s_inPageChange = FALSE; + + // are you trying to call SetSelection() from a notebook event handler? + // you shouldn't! + wxCHECK_RET( !s_inPageChange, + _T("gtk_notebook_page_change_callback reentered") ); + + s_inPageChange = TRUE; if (g_isIdle) wxapp_install_idle_handler(); int old = notebook->GetSelection(); - wxNotebookEvent event1( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, - notebook->GetId(), page, old ); - event1.SetEventObject( notebook ); + wxNotebookEvent eventChanging( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, + notebook->GetId(), page, old ); + eventChanging.SetEventObject( notebook ); - if ((notebook->GetEventHandler()->ProcessEvent( event1 )) && - !event1.IsAllowed() ) + if ( (notebook->GetEventHandler()->ProcessEvent(eventChanging)) && + !eventChanging.IsAllowed() ) { /* program doesn't allow the page change */ - gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), "switch_page" ); - return; + gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), + "switch_page" ); + } + else // change allowed + { + // make wxNotebook::GetSelection() return the correct (i.e. consistent + // with wxNotebookEvent::GetSelection()) value even though the page is + // not really changed in GTK+ + notebook->m_selection = page; + + wxNotebookEvent eventChanged( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + notebook->GetId(), page, old ); + eventChanged.SetEventObject( notebook ); + notebook->GetEventHandler()->ProcessEvent( eventChanged ); } - wxNotebookEvent event2( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - notebook->GetId(), page, old ); - event2.SetEventObject( notebook ); - notebook->GetEventHandler()->ProcessEvent( event2 ); + s_inPageChange = FALSE; } //----------------------------------------------------------------------------- @@ -223,7 +240,7 @@ void wxNotebook::Init() m_imageList = (wxImageList *) NULL; m_ownsImageList = FALSE; m_pages.DeleteContents( TRUE ); - m_lastSelection = -1; + m_selection = -1; m_themeEnabled = TRUE; } @@ -305,15 +322,24 @@ int wxNotebook::GetSelection() const { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") ); - GList *pages = GTK_NOTEBOOK(m_widget)->children; - - if (g_list_length(pages) == 0) return -1; + if ( m_selection == -1 ) + { + GList *pages = GTK_NOTEBOOK(m_widget)->children; - GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); + if (g_list_length(pages) != 0) + { + GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); - if (notebook->cur_page == NULL) return m_lastSelection; + gpointer cur = notebook->cur_page; + if ( cur != NULL ) + { + wxConstCast(this, wxNotebook)->m_selection = + g_list_index( pages, cur ); + } + } + } - return g_list_index( pages, (gpointer)(notebook->cur_page) ); + return m_selection; } int wxNotebook::GetPageCount() const @@ -367,6 +393,8 @@ int wxNotebook::SetSelection( int page ) int selOld = GetSelection(); + // cache the selection + m_selection = page; gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page ); wxGtkNotebookPage* g_page = GetNotebookPage( page ); @@ -536,17 +564,23 @@ bool wxNotebook::DeleteAllPages() bool wxNotebook::DeletePage( int page ) { wxGtkNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) return FALSE; + wxCHECK_MSG( nb_page, FALSE, _T("invalid page in wxNotebook::DeletePage") ); - /* GTK sets GtkNotebook.cur_page to NULL before sending - the switch page event */ - m_lastSelection = GetSelection(); + // GTK sets GtkNotebook.cur_page to NULL before sending the switch page + // event so we have to store the selection internally + if ( m_selection == -1 ) + { + m_selection = GetSelection(); + if ( m_selection == (int)m_pages.GetCount() - 1 ) + { + // the index will become invalid after the page is deleted + m_selection = -1; + } + } nb_page->m_client->Destroy(); m_pages.DeleteObject( nb_page ); - m_lastSelection = -1; - return TRUE; } diff --git a/src/gtk1/notebook.cpp b/src/gtk1/notebook.cpp index 78f0ebc9d6..1bbcc15109 100644 --- a/src/gtk1/notebook.cpp +++ b/src/gtk1/notebook.cpp @@ -89,27 +89,44 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), gint page, wxNotebook *notebook ) { + static bool s_inPageChange = FALSE; + + // are you trying to call SetSelection() from a notebook event handler? + // you shouldn't! + wxCHECK_RET( !s_inPageChange, + _T("gtk_notebook_page_change_callback reentered") ); + + s_inPageChange = TRUE; if (g_isIdle) wxapp_install_idle_handler(); int old = notebook->GetSelection(); - wxNotebookEvent event1( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, - notebook->GetId(), page, old ); - event1.SetEventObject( notebook ); + wxNotebookEvent eventChanging( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, + notebook->GetId(), page, old ); + eventChanging.SetEventObject( notebook ); - if ((notebook->GetEventHandler()->ProcessEvent( event1 )) && - !event1.IsAllowed() ) + if ( (notebook->GetEventHandler()->ProcessEvent(eventChanging)) && + !eventChanging.IsAllowed() ) { /* program doesn't allow the page change */ - gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), "switch_page" ); - return; + gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), + "switch_page" ); + } + else // change allowed + { + // make wxNotebook::GetSelection() return the correct (i.e. consistent + // with wxNotebookEvent::GetSelection()) value even though the page is + // not really changed in GTK+ + notebook->m_selection = page; + + wxNotebookEvent eventChanged( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + notebook->GetId(), page, old ); + eventChanged.SetEventObject( notebook ); + notebook->GetEventHandler()->ProcessEvent( eventChanged ); } - wxNotebookEvent event2( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - notebook->GetId(), page, old ); - event2.SetEventObject( notebook ); - notebook->GetEventHandler()->ProcessEvent( event2 ); + s_inPageChange = FALSE; } //----------------------------------------------------------------------------- @@ -223,7 +240,7 @@ void wxNotebook::Init() m_imageList = (wxImageList *) NULL; m_ownsImageList = FALSE; m_pages.DeleteContents( TRUE ); - m_lastSelection = -1; + m_selection = -1; m_themeEnabled = TRUE; } @@ -305,15 +322,24 @@ int wxNotebook::GetSelection() const { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") ); - GList *pages = GTK_NOTEBOOK(m_widget)->children; - - if (g_list_length(pages) == 0) return -1; + if ( m_selection == -1 ) + { + GList *pages = GTK_NOTEBOOK(m_widget)->children; - GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); + if (g_list_length(pages) != 0) + { + GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); - if (notebook->cur_page == NULL) return m_lastSelection; + gpointer cur = notebook->cur_page; + if ( cur != NULL ) + { + wxConstCast(this, wxNotebook)->m_selection = + g_list_index( pages, cur ); + } + } + } - return g_list_index( pages, (gpointer)(notebook->cur_page) ); + return m_selection; } int wxNotebook::GetPageCount() const @@ -367,6 +393,8 @@ int wxNotebook::SetSelection( int page ) int selOld = GetSelection(); + // cache the selection + m_selection = page; gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page ); wxGtkNotebookPage* g_page = GetNotebookPage( page ); @@ -536,17 +564,23 @@ bool wxNotebook::DeleteAllPages() bool wxNotebook::DeletePage( int page ) { wxGtkNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) return FALSE; + wxCHECK_MSG( nb_page, FALSE, _T("invalid page in wxNotebook::DeletePage") ); - /* GTK sets GtkNotebook.cur_page to NULL before sending - the switch page event */ - m_lastSelection = GetSelection(); + // GTK sets GtkNotebook.cur_page to NULL before sending the switch page + // event so we have to store the selection internally + if ( m_selection == -1 ) + { + m_selection = GetSelection(); + if ( m_selection == (int)m_pages.GetCount() - 1 ) + { + // the index will become invalid after the page is deleted + m_selection = -1; + } + } nb_page->m_client->Destroy(); m_pages.DeleteObject( nb_page ); - m_lastSelection = -1; - return TRUE; } -- 2.45.2