]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/mdi.cpp
Fix return value of wxCountingOutputStream::LastWrite().
[wxWidgets.git] / src / gtk / mdi.cpp
index 9511b2e22ddba44abddbaf1d8559db0188412a83..5480673b29e0d7c815ac4b3eae161bea03674af6 100644 (file)
 
 extern "C" {
 static void
-gtk_mdi_page_change_callback( GtkNotebook *WXUNUSED(widget),
-                              GtkNotebookPage *page,
-                              gint WXUNUSED(page_num),
-                              wxMDIParentFrame *parent )
+switch_page(GtkNotebook* widget, GtkNotebookPage*, guint page_num, wxMDIParentFrame* parent)
 {
     // send deactivate event to old child
 
@@ -49,6 +46,7 @@ gtk_mdi_page_change_callback( GtkNotebook *WXUNUSED(widget),
         return;
 
     child = NULL;
+    GtkWidget* page = gtk_notebook_get_nth_page(widget, page_num);
 
     wxWindowList::compatibility_iterator node = client_window->GetChildren().GetFirst();
     while ( node )
@@ -58,7 +56,7 @@ gtk_mdi_page_change_callback( GtkNotebook *WXUNUSED(widget),
         // child_frame can be NULL when this is called from dtor, probably
         // because g_signal_connect (m_widget, "switch_page", (see below)
         // isn't deleted early enough
-        if ( child_frame && child_frame->m_page == page )
+        if (child_frame && child_frame->m_widget == page)
         {
             child = child_frame;
             break;
@@ -114,7 +112,7 @@ void wxMDIParentFrame::OnInternalIdle()
     if (m_justInserted)
     {
         GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
-        gtk_notebook_set_current_page( notebook, g_list_length( notebook->children ) - 1 );
+        gtk_notebook_set_current_page(notebook, -1);
 
         /* need to set the menubar of the child */
         wxMDIChildFrame *active_child_frame = GetActiveChild();
@@ -123,7 +121,7 @@ void wxMDIParentFrame::OnInternalIdle()
             wxMenuBar *menu_bar = active_child_frame->m_menuBar;
             if (menu_bar)
             {
-                menu_bar->SetInvokingWindow(active_child_frame);
+                menu_bar->Attach(active_child_frame);
             }
         }
         m_justInserted = false;
@@ -149,7 +147,13 @@ void wxMDIParentFrame::OnInternalIdle()
                 {
                     if (menu_bar->Show(true))
                     {
-                        menu_bar->SetInvokingWindow( child_frame );
+                        // Attach() asserts if we call it for an already
+                        // attached menu bar so don't do it if we're already
+                        // associated with this frame (it would be nice to get
+                        // rid of this check and ensure that this doesn't
+                        // happen...)
+                        if ( menu_bar->GetFrame() != child_frame )
+                            menu_bar->Attach( child_frame );
                     }
                     visible_child_menu = true;
                 }
@@ -157,7 +161,7 @@ void wxMDIParentFrame::OnInternalIdle()
                 {
                     if (menu_bar->Show(false))
                     {
-                        menu_bar->UnsetInvokingWindow( child_frame );
+                        menu_bar->Detach();
                     }
                 }
             }
@@ -173,12 +177,12 @@ void wxMDIParentFrame::OnInternalIdle()
         if (visible_child_menu)
         {
             m_frameMenuBar->Show( false );
-            m_frameMenuBar->UnsetInvokingWindow( this );
+            m_frameMenuBar->Detach();
         }
         else
         {
             m_frameMenuBar->Show( true );
-            m_frameMenuBar->SetInvokingWindow( this );
+            m_frameMenuBar->Attach( this );
         }
     }
 }
@@ -187,7 +191,7 @@ void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const
 {
     wxFrame::DoGetClientSize(width, height);
 
-    if (height)
+    if (!m_useCachedClientSize && height)
     {
         wxMDIChildFrame* active_child_frame = GetActiveChild();
         if (active_child_frame)
@@ -196,7 +200,7 @@ void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const
             if (menubar && menubar->IsShown())
             {
                 GtkRequisition req;
-                gtk_widget_size_request(menubar->m_widget, &req);
+                gtk_widget_get_preferred_height(menubar->m_widget, NULL, &req.height);
                 *height -= req.height;
                 if (*height < 0) *height = 0;
             }
@@ -214,7 +218,7 @@ wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
     gint i = gtk_notebook_get_current_page( notebook );
     if (i < 0) return NULL;
 
-    GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data);
+    GtkWidget* page = gtk_notebook_get_nth_page(notebook, i);
     if (!page) return NULL;
 
     wxWindowList::compatibility_iterator node = m_clientWindow->GetChildren().GetFirst();
@@ -228,7 +232,7 @@ wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
         if (!child_frame)
             return NULL;
 
-        if (child_frame->m_page == page)
+        if (child_frame->m_widget == page)
             return child_frame;
 
         node = node->GetNext();
@@ -263,7 +267,6 @@ END_EVENT_TABLE()
 void wxMDIChildFrame::Init()
 {
     m_menuBar = NULL;
-    m_page = NULL;
 }
 
 bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
@@ -291,6 +294,12 @@ wxMDIChildFrame::~wxMDIChildFrame()
         gtk_widget_queue_draw(m_parent->m_widget);
 }
 
+void wxMDIChildFrame::GTKHandleRealized()
+{
+    // since m_widget is not a GtkWindow, must bypass wxTopLevelWindowGTK
+    wxTopLevelWindowBase::GTKHandleRealized();
+}
+
 void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
 {
     wxASSERT_MSG( m_menuBar == NULL, "Only one menubar allowed" );
@@ -307,14 +316,6 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
         m_menuBar->Show(false);
         gtk_box_pack_start(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, false, false, 0);
         gtk_box_reorder_child(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0);
-
-        gulong handler_id = g_signal_handler_find(
-            m_menuBar->m_widget,
-            GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
-            g_signal_lookup("size_request", GTK_TYPE_WIDGET),
-            0, NULL, NULL, m_menuBar);
-        if (handler_id != 0)
-            g_signal_handler_disconnect(m_menuBar->m_widget, handler_id);
         gtk_widget_set_size_request(m_menuBar->m_widget, -1, -1);
     }
 }
@@ -377,6 +378,17 @@ void wxMDIChildFrame::SetTitle( const wxString &title )
 
 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
 
+wxMDIClientWindow::~wxMDIClientWindow()
+{
+    // disconnect our handler because our ~wxWindow (which is going to be called
+    // after this dtor) will call DestroyChildren(); in turns our children
+    // ~wxWindow dtors will call wxWindow::Show(false) and this will generate
+    // a call to gtk_mdi_page_change_callback with an invalid parent
+    // (because gtk_mdi_page_change_callback expects a wxMDIClientWindow but
+    //  at that point of the dtor chain we are a simple wxWindow!)
+    g_signal_handlers_disconnect_by_func(m_widget, (void*)switch_page, GetParent());
+}
+
 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
 {
     if ( !PreCreation( parent, wxDefaultPosition, wxDefaultSize ) ||
@@ -390,8 +402,7 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
     m_widget = gtk_notebook_new();
     g_object_ref(m_widget);
 
-    g_signal_connect (m_widget, "switch_page",
-                      G_CALLBACK (gtk_mdi_page_change_callback), parent);
+    g_signal_connect(m_widget, "switch_page", G_CALLBACK(switch_page), parent);
 
     gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
 
@@ -418,8 +429,6 @@ void wxMDIClientWindow::AddChildGTK(wxWindowGTK* child)
 
     gtk_notebook_append_page( notebook, child->m_widget, label_widget );
 
-    child_frame->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
-
     wxMDIParentFrame* parent_frame = static_cast<wxMDIParentFrame*>(GetParent());
     parent_frame->m_justInserted = true;
 }