]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtknotebook.c
Declare gtk_tree_row_reference_get_type(). It is already used by a macro
[~andy/gtk] / gtk / gtknotebook.c
index 8eb626ad8860ef29259b2d9f2733038641d8d4c3..ab2b2ab98bbb47e1f8edcc8a2da18a7678bf3d5b 100644 (file)
@@ -25,7 +25,6 @@
  */
 
 #include "gtknotebook.h"
-#include "gtksignal.h"
 #include "gtkmain.h"
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
@@ -180,7 +179,7 @@ static void gtk_notebook_remove              (GtkContainer     *container,
                                              GtkWidget        *widget);
 static void gtk_notebook_set_focus_child     (GtkContainer     *container,
                                              GtkWidget        *child);
-static GtkType gtk_notebook_child_type       (GtkContainer     *container);
+static GType gtk_notebook_child_type       (GtkContainer     *container);
 static void gtk_notebook_forall              (GtkContainer     *container,
                                              gboolean          include_internals,
                                              GtkCallback       callback,
@@ -189,8 +188,6 @@ static void gtk_notebook_forall              (GtkContainer     *container,
 /*** GtkNotebook Private Functions ***/
 static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
 static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
-static void gtk_notebook_focus_changed       (GtkNotebook      *notebook,
-                                             GtkNotebookPage  *old_page);
 static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
                                              GList            *list);
 static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
@@ -251,6 +248,16 @@ static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
 static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
                                              GtkMenu          *menu);
 
+/*** GtkNotebook Private Setters ***/
+static void gtk_notebook_set_homogeneous_tabs_internal (GtkNotebook *notebook,
+                                                       gboolean     homogeneous);
+static void gtk_notebook_set_tab_border_internal       (GtkNotebook *notebook,
+                                                       guint        border_width);
+static void gtk_notebook_set_tab_hborder_internal      (GtkNotebook *notebook,
+                                                       guint        tab_hborder);
+static void gtk_notebook_set_tab_vborder_internal      (GtkNotebook *notebook,
+                                                       guint        tab_vborder);
+
 static gboolean focus_tabs_in  (GtkNotebook      *notebook);
 static gboolean focus_child_in (GtkNotebook      *notebook,
                                GtkDirectionType  direction);
@@ -258,26 +265,28 @@ static gboolean focus_child_in (GtkNotebook      *notebook,
 static GtkContainerClass *parent_class = NULL;
 static guint notebook_signals[LAST_SIGNAL] = { 0 };
 
-GtkType
+GType
 gtk_notebook_get_type (void)
 {
-  static GtkType notebook_type = 0;
+  static GType notebook_type = 0;
 
   if (!notebook_type)
     {
-      static const GtkTypeInfo notebook_info =
+      static const GTypeInfo notebook_info =
       {
-       "GtkNotebook",
-       sizeof (GtkNotebook),
        sizeof (GtkNotebookClass),
-       (GtkClassInitFunc) gtk_notebook_class_init,
-       (GtkObjectInitFunc) gtk_notebook_init,
-       /* reserved_1 */ NULL,
-        /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_notebook_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkNotebook),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_notebook_init,
       };
 
-      notebook_type = gtk_type_unique (gtk_container_get_type (), &notebook_info);
+      notebook_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkNotebook",
+                                             &notebook_info, 0);
     }
 
   return notebook_type;
@@ -418,7 +427,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                                   PROP_SCROLLABLE,
                                   g_param_spec_boolean ("scrollable",
                                                         _("Scrollable"),
-                                                        _("If TRUE, scroll arrows are added if there are to many tabs to fit"),
+                                                        _("If TRUE, scroll arrows are added if there are too many tabs to fit"),
                                                         FALSE,
                                                         G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
@@ -438,47 +447,60 @@ gtk_notebook_class_init (GtkNotebookClass *class)
 
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_LABEL,
-                                             g_param_spec_string ("tab_label", NULL, NULL,
+                                             g_param_spec_string ("tab_label", 
+                                                                  _("Tab label"),
+                                                                  _("The string displayed on the childs tab label"),
                                                                   NULL,
                                                                   G_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_MENU_LABEL,
-                                             g_param_spec_string ("menu_label", NULL, NULL,
+                                             g_param_spec_string ("menu_label", 
+                                                                  _("Menu label"), 
+                                                                  _("The string displayed in the childs menu entry"),
                                                                   NULL,
                                                                   G_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_POSITION,
-                                             g_param_spec_int ("position", NULL, NULL,
+                                             g_param_spec_int ("position", 
+                                                               _("Position"), 
+                                                               _("The index of the child in the parent"),
                                                                -1, G_MAXINT, 0,
                                                                G_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_EXPAND,
-                                             g_param_spec_boolean ("tab_expand", NULL, NULL,
+                                             g_param_spec_boolean ("tab_expand", 
+                                                                   _("Tab expand"), 
+                                                                   _("Whether to expand the childs tab or not"),
                                                                    TRUE,
                                                                    G_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_FILL,
-                                             g_param_spec_boolean ("tab_fill", NULL, NULL,
+                                             g_param_spec_boolean ("tab_fill", 
+                                                                   _("Tab fill"), 
+                                                                   _("Wheather the childs tab should fill the allocated area or not"),
                                                                    TRUE,
                                                                    G_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TAB_PACK,
-                                             g_param_spec_enum ("tab_pack", NULL, NULL,
+                                             g_param_spec_enum ("tab_pack", 
+                                                                _("Tab pack type"),
+                                                                _("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
                                                                 GTK_TYPE_PACK_TYPE, GTK_PACK_START,
                                                                 G_PARAM_READWRITE));
   
   notebook_signals[SWITCH_PAGE] =
-    gtk_signal_new ("switch_page",
-                   GTK_RUN_LAST,
-                   GTK_CLASS_TYPE (object_class),
-                   GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page),
-                   _gtk_marshal_VOID__POINTER_UINT,
-                   GTK_TYPE_NONE, 2,
-                   GTK_TYPE_POINTER,
-                   GTK_TYPE_UINT);
+    g_signal_new ("switch_page",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkNotebookClass, switch_page),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__POINTER_UINT,
+                 G_TYPE_NONE, 2,
+                 G_TYPE_POINTER,
+                 G_TYPE_UINT);
   notebook_signals[FOCUS_TAB] = 
     g_signal_new ("focus_tab",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                   NULL, NULL,
@@ -487,7 +509,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   GTK_TYPE_NOTEBOOK_TAB);
   notebook_signals[SELECT_PAGE] = 
     g_signal_new ("select_page",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                   NULL, NULL,
@@ -496,7 +518,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   G_TYPE_BOOLEAN);
   notebook_signals[CHANGE_CURRENT_PAGE] = 
     g_signal_new ("change_current_page",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                   NULL, NULL,
@@ -505,7 +527,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   G_TYPE_INT);
   notebook_signals[MOVE_FOCUS_OUT] =
     g_signal_new ("move_focus_out",
-                  G_TYPE_FROM_CLASS (object_class),
+                  G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                   G_STRUCT_OFFSET (GtkNotebookClass, move_focus_out),
                   NULL, NULL,
@@ -514,7 +536,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
                   GTK_TYPE_DIRECTION_TYPE);
   
   
-  binding_set = gtk_binding_set_by_class (object_class);
+  binding_set = gtk_binding_set_by_class (class);
   gtk_binding_entry_add_signal (binding_set,
                                 GDK_space, 0,
                                 "select_page", 1, 
@@ -562,7 +584,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
 static void
 gtk_notebook_init (GtkNotebook *notebook)
 {
-  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
+  GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
   GTK_WIDGET_SET_FLAGS (notebook, GTK_NO_WINDOW);
 
   notebook->cur_page = NULL;
@@ -647,7 +669,7 @@ gtk_notebook_change_current_page (GtkNotebook *notebook,
   if (current)
     gtk_notebook_switch_page (notebook, current->data, -1);
   else
-    gdk_beep ();
+    gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook)));
 }
 
 static GtkDirectionType
@@ -696,7 +718,7 @@ gtk_notebook_move_focus_out (GtkNotebook      *notebook,
   g_object_ref (notebook);
   
   notebook->focus_out = TRUE;
-  g_signal_emit_by_name (G_OBJECT (toplevel), "move_focus", direction_type);
+  g_signal_emit_by_name (toplevel, "move_focus", direction_type);
   notebook->focus_out = FALSE;
   
   g_object_unref (notebook);
@@ -713,7 +735,7 @@ gtk_notebook_move_focus_out (GtkNotebook      *notebook,
 GtkWidget*
 gtk_notebook_new (void)
 {
-  return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ()));
+  return g_object_new (GTK_TYPE_NOTEBOOK, NULL);
 }
 
 /* Private GtkObject Methods :
@@ -761,7 +783,7 @@ gtk_notebook_set_property (GObject         *object,
        gtk_notebook_popup_disable (notebook);
       break;
     case PROP_HOMOGENEOUS:
-      gtk_notebook_set_homogeneous_tabs (notebook, g_value_get_boolean (value));
+      gtk_notebook_set_homogeneous_tabs_internal (notebook, g_value_get_boolean (value));
       break;  
     case PROP_PAGE:
       gtk_notebook_set_current_page (notebook, g_value_get_int (value));
@@ -770,13 +792,13 @@ gtk_notebook_set_property (GObject         *object,
       gtk_notebook_set_tab_pos (notebook, g_value_get_enum (value));
       break;
     case PROP_TAB_BORDER:
-      gtk_notebook_set_tab_border (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_border_internal (notebook, g_value_get_uint (value));
       break;
     case PROP_TAB_HBORDER:
-      gtk_notebook_set_tab_hborder (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_hborder_internal (notebook, g_value_get_uint (value));
       break;
     case PROP_TAB_VBORDER:
-      gtk_notebook_set_tab_vborder (notebook, g_value_get_uint (value));
+      gtk_notebook_set_tab_vborder_internal (notebook, g_value_get_uint (value));
       break;
     default:
       break;
@@ -852,13 +874,23 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
 {
   GtkWidget *widget = GTK_WIDGET (notebook);
   gint border_width = GTK_CONTAINER (notebook)->border_width;
+  GtkNotebookPage *visible_page = NULL;
+  GList *tmp_list;
 
-  if (notebook->show_tabs && notebook->children)
+  for (tmp_list = notebook->children; tmp_list; tmp_list = tmp_list->next)
     {
-      if (rectangle)
+      GtkNotebookPage *page = tmp_list->data;
+      if (GTK_WIDGET_VISIBLE (page->child))
        {
-         GtkNotebookPage *page = notebook->children->data;
+         visible_page = page;
+         break;
+       }
+    }
 
+  if (notebook->show_tabs && visible_page)
+    {
+      if (rectangle)
+       {
          rectangle->x = widget->allocation.x + border_width;
          rectangle->y = widget->allocation.y + border_width;
          
@@ -867,13 +899,13 @@ gtk_notebook_get_event_window_position (GtkNotebook  *notebook,
            case GTK_POS_TOP:
            case GTK_POS_BOTTOM:
              rectangle->width = widget->allocation.width - 2 * border_width;
-             rectangle->height = page->requisition.height;
+             rectangle->height = visible_page->requisition.height;
              if (notebook->tab_pos == GTK_POS_BOTTOM)
                rectangle->y += widget->allocation.height - 2 * border_width - rectangle->height;
              break;
            case GTK_POS_LEFT:
            case GTK_POS_RIGHT:
-             rectangle->width = page->requisition.width;
+             rectangle->width = visible_page->requisition.width;
              rectangle->height = widget->allocation.height - 2 * border_width;
              if (notebook->tab_pos == GTK_POS_RIGHT)
                rectangle->x += widget->allocation.width - 2 * border_width - rectangle->width;
@@ -963,7 +995,7 @@ gtk_notebook_realize (GtkWidget *widget)
   gtk_notebook_get_event_window_position (notebook, &event_window_pos);
   
   widget->window = gtk_widget_get_parent_window (widget);
-  gdk_window_ref (widget->window);
+  g_object_ref (widget->window);
   
   attributes.window_type = GDK_WINDOW_CHILD;
   attributes.x = event_window_pos.x;
@@ -1449,6 +1481,27 @@ gtk_notebook_get_arrow (GtkNotebook *notebook,
   return 0;
 }
 
+static void
+gtk_notebook_do_arrow (GtkNotebook    *notebook,
+                      GtkArrowType    arrow)
+{
+  GtkWidget *widget = GTK_WIDGET (notebook);
+  GtkDirectionType dir;
+  
+  if (!notebook->focus_tab ||
+      gtk_notebook_search_page (notebook, notebook->focus_tab,
+                               arrow == GTK_ARROW_LEFT ? STEP_PREV : STEP_NEXT,
+                               TRUE))
+    {
+      if (notebook->tab_pos == GTK_POS_LEFT ||
+         notebook->tab_pos == GTK_POS_RIGHT)
+       dir = (arrow == GTK_ARROW_LEFT) ? GTK_DIR_UP : GTK_DIR_DOWN;
+      else
+       dir = (arrow == GTK_ARROW_LEFT) ? GTK_DIR_LEFT : GTK_DIR_RIGHT;
+      gtk_widget_child_focus (widget, dir);
+    }
+}
+
 static gboolean
 gtk_notebook_arrow_button_press (GtkNotebook    *notebook,
                                 GtkArrowType    arrow,
@@ -1464,19 +1517,7 @@ gtk_notebook_arrow_button_press (GtkNotebook    *notebook,
   
   if (event->button == 1)
     {
-      GtkDirectionType dir;
-      if (!notebook->focus_tab ||
-         gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                   arrow == GTK_ARROW_LEFT ? STEP_PREV : STEP_NEXT,
-                                   TRUE))
-       {
-         if (notebook->tab_pos == GTK_POS_LEFT ||
-             notebook->tab_pos == GTK_POS_RIGHT)
-           dir = (arrow == GTK_ARROW_LEFT) ? GTK_DIR_UP : GTK_DIR_DOWN;
-         else
-           dir = (arrow == GTK_ARROW_LEFT) ? GTK_DIR_LEFT : GTK_DIR_RIGHT;
-         gtk_widget_child_focus (widget, dir);
-       }
+      gtk_notebook_do_arrow (notebook, arrow);
       
       if (!notebook->timer)
        {
@@ -1562,6 +1603,9 @@ gtk_notebook_button_press (GtkWidget      *widget,
       return TRUE;
     }
 
+  if (event->button != 1)
+    return FALSE;
+  
   num = 0;
   children = notebook->children;
   while (children)
@@ -1575,24 +1619,15 @@ gtk_notebook_button_press (GtkWidget      *widget,
          (x <= (page->allocation.x + page->allocation.width)) &&
          (y <= (page->allocation.y + page->allocation.height)))
        {
-         if (page == notebook->cur_page && notebook->focus_tab &&
-             notebook->focus_tab != children &&
-             GTK_WIDGET_HAS_FOCUS (notebook))
-           {
-             GtkNotebookPage *old_page;
-             
-             notebook->child_has_focus = FALSE;
-             old_page = (GtkNotebookPage *)
-               (notebook->focus_tab->data);
-             gtk_notebook_switch_focus_tab (notebook, children);
-             gtk_notebook_focus_changed (notebook, old_page);
-           }
-         else
-           {
-             gtk_notebook_switch_focus_tab (notebook, children);
-             gtk_widget_grab_focus (widget);
-             gtk_notebook_switch_page (notebook, page, num);
-           }
+         gboolean page_changed = page != notebook->cur_page;
+         gboolean was_focus = gtk_widget_is_focus (widget);
+         
+         gtk_notebook_switch_focus_tab (notebook, children);
+         gtk_widget_grab_focus (widget);
+         
+         if (page_changed && !was_focus)
+           gtk_widget_child_focus (page->child, GTK_DIR_TAB_FORWARD);
+         
          break;
        }
       children = children->next;
@@ -1955,7 +1990,7 @@ focus_tabs_move (GtkNotebook     *notebook,
   if (new_page)
     gtk_notebook_switch_focus_tab (notebook, new_page);
   else
-    gdk_beep ();
+    gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook)));
   
   return TRUE;
 }
@@ -2162,7 +2197,7 @@ gtk_notebook_forall (GtkContainer *container,
     }
 }
 
-static GtkType
+static GType
 gtk_notebook_child_type (GtkContainer     *container)
 {
   return GTK_TYPE_WIDGET;
@@ -2171,7 +2206,6 @@ gtk_notebook_child_type (GtkContainer     *container)
 /* Private GtkNotebook Functions:
  *
  * gtk_notebook_redraw_tabs
- * gtk_notebook_focus_changed
  * gtk_notebook_real_remove
  * gtk_notebook_update_labels
  * gtk_notebook_timer
@@ -2248,68 +2282,17 @@ gtk_notebook_redraw_arrows (GtkNotebook *notebook)
     }
 }
 
-static void
-gtk_notebook_focus_changed (GtkNotebook     *notebook,
-                            GtkNotebookPage *old_page)
-{
-  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-
-  if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs) 
-    {
-      GdkRectangle area;
-      gint focus_width;
-
-      gtk_widget_style_get (GTK_WIDGET (notebook), "focus-line-width", &focus_width, NULL);
-
-      if (notebook->focus_tab)
-       {
-         GtkNotebookPage *page;
-
-         page = notebook->focus_tab->data;
-
-         area.x = page->tab_label->allocation.x - focus_width;
-         area.y = page->tab_label->allocation.y - focus_width;
-         area.width = page->tab_label->allocation.width + 2 * focus_width;
-         area.height = page->tab_label->allocation.height + 2 * focus_width;
-
-         gtk_notebook_draw_tab (notebook, page, &area);
-       }
-
-      if (old_page)
-       {
-         area.x = old_page->tab_label->allocation.x - focus_width;
-         area.y = old_page->tab_label->allocation.y - focus_width;
-         area.width = old_page->tab_label->allocation.width + 2 * focus_width;
-         area.height = old_page->tab_label->allocation.height + 2 * focus_width;
-
-         gtk_notebook_draw_tab (notebook, old_page, &area);
-       }
-    }
-}
-
 static gint
 gtk_notebook_timer (GtkNotebook *notebook)
 {
   gboolean retval = FALSE;
 
   GDK_THREADS_ENTER ();
-  
+
   if (notebook->timer)
     {
-      if (notebook->click_child == GTK_ARROW_LEFT)
-       {
-         if (!notebook->focus_tab ||
-             gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                       STEP_PREV, TRUE))
-           gtk_widget_child_focus (GTK_WIDGET (notebook), GTK_DIR_LEFT);
-       }
-      else if (notebook->click_child == GTK_ARROW_RIGHT)
-       {
-         if (!notebook->focus_tab ||
-             gtk_notebook_search_page (notebook, notebook->focus_tab,
-                                       STEP_NEXT, TRUE))
-           gtk_widget_child_focus (GTK_WIDGET (notebook), GTK_DIR_RIGHT);
-       }
+      gtk_notebook_do_arrow (notebook, notebook->click_child);
+
       if (notebook->need_timer) 
        {
          notebook->need_timer = FALSE;
@@ -2357,8 +2340,8 @@ gtk_notebook_remove_tab_label (GtkNotebook     *notebook,
   if (page->tab_label)
     {
       if (page->mnemonic_activate_signal)
-       gtk_signal_disconnect (page->tab_label,
-                              page->mnemonic_activate_signal);
+       g_signal_handler_disconnect (page->tab_label,
+                                    page->mnemonic_activate_signal);
       page->mnemonic_activate_signal = 0;
 
       gtk_widget_unparent (page->tab_label);
@@ -2390,9 +2373,6 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
     gtk_notebook_switch_focus_tab (notebook, next_list);
 
   page = list->data;
-
-  if (page->last_focus_child)
-    g_object_remove_weak_pointer (G_OBJECT (page->last_focus_child), (gpointer *)&page->last_focus_child);
   
   if (GTK_WIDGET_VISIBLE (page->child) && GTK_WIDGET_VISIBLE (notebook))
     need_resize = TRUE;
@@ -2408,10 +2388,17 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
       gtk_widget_queue_resize (notebook->menu);
     }
   if (!page->default_menu)
-    gtk_widget_unref (page->menu_label);
+    g_object_unref (page->menu_label);
   
   notebook->children = g_list_remove_link (notebook->children, list);
   g_list_free (list);
+
+  if (page->last_focus_child)
+    {
+      g_object_remove_weak_pointer (G_OBJECT (page->last_focus_child), (gpointer *)&page->last_focus_child);
+      page->last_focus_child = NULL;
+    }
+  
   g_free (page);
 
   if (!notebook->children && notebook->show_tabs &&
@@ -2756,20 +2743,19 @@ gtk_notebook_draw_tab (GtkNotebook     *notebook,
       if (gtk_widget_intersect (page->tab_label, area, &child_area) &&
           GTK_WIDGET_DRAWABLE (page->tab_label))
         {
-          GdkEventExpose expose_event;
+          GdkEvent *expose_event = gdk_event_new (GDK_EXPOSE);
 
           /* This is a lame hack since all this code needs rewriting anyhow */
           
-          expose_event.window = page->tab_label->window;
-          expose_event.area = child_area;
-          expose_event.region = gdk_region_rectangle (&child_area);
-          expose_event.send_event = TRUE;
-          expose_event.type = GDK_EXPOSE;
-          expose_event.count = 0;
+          expose_event->expose.window = g_object_ref (page->tab_label->window);
+          expose_event->expose.area = child_area;
+          expose_event->expose.region = gdk_region_rectangle (&child_area);
+          expose_event->expose.send_event = TRUE;
+          expose_event->expose.count = 0;
 
-         gtk_container_propagate_expose (GTK_CONTAINER (notebook), page->tab_label, &expose_event);
+         gtk_container_propagate_expose (GTK_CONTAINER (notebook), page->tab_label, (GdkEventExpose *)expose_event);
 
-         gdk_region_destroy (expose_event.region);
+         gdk_event_free (expose_event);
         }
     }
 }
@@ -3341,7 +3327,7 @@ gtk_notebook_page_allocate (GtkNotebook     *notebook,
          break;
        }
 
-      gtk_widget_queue_clear_area (widget, x, y, width, height);
+      gtk_widget_queue_draw_area (widget, x, y, width, height);
     }
 
   page->allocation = *allocation;
@@ -3578,10 +3564,11 @@ gtk_notebook_switch_page (GtkNotebook     *notebook,
   if (page_num < 0)
     page_num = g_list_index (notebook->children, page);
 
-  gtk_signal_emit (GTK_OBJECT (notebook), 
-                  notebook_signals[SWITCH_PAGE], 
-                  page,
-                  page_num);
+  g_signal_emit (notebook,
+                notebook_signals[SWITCH_PAGE],
+                0,
+                page,
+                page_num);
 }
 
 static gint
@@ -3650,9 +3637,12 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
 
   page = notebook->focus_tab->data;
   if (GTK_WIDGET_MAPPED (page->tab_label))
-    gtk_notebook_focus_changed (notebook, old_page);
+    gtk_notebook_redraw_tabs (notebook);
   else
     gtk_notebook_pages_allocate (notebook);
+  
+  gtk_notebook_switch_page (notebook, page,
+                           g_list_index (notebook->children, page));
 }
 
 static void
@@ -3680,10 +3670,11 @@ gtk_notebook_menu_switch_page (GtkWidget       *widget,
       page_num++;
     }
 
-  gtk_signal_emit (GTK_OBJECT (notebook), 
-                  notebook_signals[SWITCH_PAGE], 
-                  page,
-                  page_num);
+  g_signal_emit (notebook,
+                notebook_signals[SWITCH_PAGE],
+                0,
+                page,
+                page_num);
 }
 
 /* Private GtkNotebook Menu Functions:
@@ -3714,8 +3705,8 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook,
   gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
   gtk_menu_shell_insert (GTK_MENU_SHELL (notebook->menu), menu_item,
                         gtk_notebook_real_page_position (notebook, list));
-  gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
-                     GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page);
+  g_signal_connect (menu_item, "activate",
+                   G_CALLBACK (gtk_notebook_menu_switch_page), page);
   if (GTK_WIDGET_VISIBLE (page->child))
     gtk_widget_show (menu_item);
 }
@@ -3742,6 +3733,80 @@ gtk_notebook_menu_detacher (GtkWidget *widget,
   notebook->menu = NULL;
 }
 
+/* Private GtkNotebook Setter Functions:
+ *
+ * gtk_notebook_set_homogeneous_tabs_internal
+ * gtk_notebook_set_tab_border_internal
+ * gtk_notebook_set_tab_hborder_internal
+ * gtk_notebook_set_tab_vborder_internal
+ */
+static void
+gtk_notebook_set_homogeneous_tabs_internal (GtkNotebook *notebook,
+                                           gboolean     homogeneous)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (homogeneous == notebook->homogeneous)
+    return;
+
+  notebook->homogeneous = homogeneous;
+  gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "homogeneous");
+}
+
+static void
+gtk_notebook_set_tab_border_internal (GtkNotebook *notebook,
+                                     guint        border_width)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  notebook->tab_hborder = border_width;
+  notebook->tab_vborder = border_width;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_freeze_notify (G_OBJECT (notebook));
+  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+  g_object_thaw_notify (G_OBJECT (notebook));
+}
+
+static void
+gtk_notebook_set_tab_hborder_internal (GtkNotebook *notebook,
+                                      guint        tab_hborder)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->tab_hborder == tab_hborder)
+    return;
+
+  notebook->tab_hborder = tab_hborder;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+}
+
+static void
+gtk_notebook_set_tab_vborder_internal (GtkNotebook *notebook,
+                                      guint        tab_vborder)
+{
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->tab_vborder == tab_vborder)
+    return;
+
+  notebook->tab_vborder = tab_vborder;
+
+  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
+    gtk_widget_queue_resize (GTK_WIDGET (notebook));
+
+  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+}
+
 /* Public GtkNotebook Page Insert/Remove Methods :
  *
  * gtk_notebook_append_page
@@ -3978,7 +4043,7 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
     page->default_menu = TRUE;
   else  
     {
-      gtk_widget_ref (page->menu_label);
+      g_object_ref (page->menu_label);
       gtk_object_sink (GTK_OBJECT (page->menu_label));
     }
 
@@ -4016,10 +4081,10 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
 
   if (tab_label)
     page->mnemonic_activate_signal =
-      gtk_signal_connect (GTK_OBJECT (tab_label),
-                         "mnemonic_activate",
-                         (GtkSignalFunc) gtk_notebook_mnemonic_activate_switch_page,
-                         notebook);
+      g_signal_connect (tab_label,
+                       "mnemonic_activate",
+                       G_CALLBACK (gtk_notebook_mnemonic_activate_switch_page),
+                       notebook);
 
   if (notebook->show_tabs && GTK_WIDGET_MAPPED (notebook))
     gdk_window_show_unraised (notebook->event_window);
@@ -4096,7 +4161,8 @@ gtk_notebook_get_current_page (GtkNotebook *notebook)
 /**
  * gtk_notebook_get_nth_page:
  * @notebook: a #GtkNotebook
- * @page_num: the index of a page in the noteobok
+ * @page_num: the index of a page in the noteobok, or -1
+ *            to get the last page.
  * 
  * Returns the child widget contained in page number @page_num.
  * 
@@ -4108,17 +4174,42 @@ gtk_notebook_get_nth_page (GtkNotebook *notebook,
                           gint         page_num)
 {
   GtkNotebookPage *page;
+  GList *list;
 
   g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
 
-  page = g_list_nth_data (notebook->children, page_num);
+  if (page_num >= 0)
+    list = g_list_nth (notebook->children, page_num);
+  else
+    list = g_list_last (notebook->children);
 
-  if (page)
-    return page->child;
+  if (list)
+    {
+      page = list->data;
+      return page->child;
+    }
 
   return NULL;
 }
 
+/**
+ * gtk_notebook_get_n_pages:
+ * @notebook: a #GtkNotebook
+ * 
+ * Gets the number of pages in a notebook.
+ * 
+ * Return value: the number of pages in the notebook.
+ *
+ * Since: 2.2
+ **/
+gint
+gtk_notebook_get_n_pages (GtkNotebook *notebook)
+{
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), 0);
+
+  return g_list_length (notebook->children);
+}
+
 /**
  * gtk_notebook_page_num:
  * @notebook: a #GtkNotebook
@@ -4251,7 +4342,7 @@ gtk_notebook_prev_page (GtkNotebook *notebook)
  * @show_border: %TRUE if a bevel should be drawn around the notebook.
  * 
  * Sets whether a bevel will be drawn around the notebook pages.
- * This is only has an effect when the tabs are not shown.
+ * This only has a visual effect when the tabs are not shown.
  * See gtk_notebook_set_show_tabs().
  **/
 void
@@ -4410,13 +4501,7 @@ gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (homogeneous == notebook->homogeneous)
-    return;
-
-  notebook->homogeneous = homogeneous;
-  gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "homogeneous");
+  gtk_notebook_set_homogeneous_tabs_internal (notebook, homogeneous);
 }
 
 /**
@@ -4435,17 +4520,7 @@ gtk_notebook_set_tab_border (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  notebook->tab_hborder = border_width;
-  notebook->tab_vborder = border_width;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_freeze_notify (G_OBJECT (notebook));
-  g_object_notify (G_OBJECT (notebook), "tab_hborder");
-  g_object_notify (G_OBJECT (notebook), "tab_vborder");
-  g_object_thaw_notify (G_OBJECT (notebook));
-
+  gtk_notebook_set_tab_border_internal (notebook, border_width);
 }
 
 /**
@@ -4461,15 +4536,7 @@ gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (notebook->tab_hborder == tab_hborder)
-    return;
-
-  notebook->tab_hborder = tab_hborder;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "tab_hborder");
+  gtk_notebook_set_tab_hborder_internal (notebook, tab_hborder);
 }
 
 /**
@@ -4485,15 +4552,7 @@ gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
 {
   g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
 
-  if (notebook->tab_vborder == tab_vborder)
-    return;
-
-  notebook->tab_vborder = tab_vborder;
-
-  if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs)
-    gtk_widget_queue_resize (GTK_WIDGET (notebook));
-
-  g_object_notify (G_OBJECT (notebook), "tab_vborder");
+  gtk_notebook_set_tab_vborder_internal (notebook, tab_vborder);
 }
 
 /**
@@ -4701,10 +4760,10 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
 
   if (page->tab_label)
     page->mnemonic_activate_signal =
-      gtk_signal_connect (GTK_OBJECT (page->tab_label),
-                         "mnemonic_activate",
-                         (GtkSignalFunc) gtk_notebook_mnemonic_activate_switch_page,
-                         notebook);
+      g_signal_connect (page->tab_label,
+                       "mnemonic_activate",
+                       G_CALLBACK (gtk_notebook_mnemonic_activate_switch_page),
+                       notebook);
 
   if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child))
     {
@@ -4829,13 +4888,13 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
                              page->menu_label->parent);
 
       if (!page->default_menu)
-       gtk_widget_unref (page->menu_label);
+       g_object_unref (page->menu_label);
     }
 
   if (menu_label)
     {
       page->menu_label = menu_label;
-      gtk_widget_ref (page->menu_label);
+      g_object_ref (page->menu_label);
       gtk_object_sink (GTK_OBJECT(page->menu_label));
       page->default_menu = FALSE;
     }