X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtknotebook.c;h=b623e15ea31821fffe8f2018359806ee2b6fa7b3;hb=7f12a27249aa091f242c1a18993c2777c68e0216;hp=cb25de0e6d1187be0711ddbe08817dcce5879a92;hpb=9aca5027dd52daf3368be86a590a862644710ad5;p=~andy%2Fgtk diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index cb25de0e6..b623e15ea 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -25,19 +25,27 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -#include +#include "config.h" + +#include +#include + +#include + +#undef GTK_DISABLE_DEPRECATED + #include "gtknotebook.h" #include "gtkmain.h" #include "gtkmenu.h" #include "gtkmenuitem.h" #include "gtklabel.h" -#include -#include #include "gtkintl.h" #include "gtkmarshalers.h" #include "gtkbindings.h" #include "gtkprivate.h" #include "gtkdnd.h" +#include "gtkbuildable.h" + #include "gtkalias.h" #define SCROLL_DELAY_FACTOR 5 @@ -56,6 +64,7 @@ enum { PAGE_REORDERED, PAGE_REMOVED, PAGE_ADDED, + CREATE_WINDOW, LAST_SIGNAL }; @@ -102,6 +111,7 @@ enum { PROP_PAGE, PROP_ENABLE_POPUP, PROP_GROUP_ID, + PROP_GROUP, PROP_HOMOGENEOUS }; @@ -156,7 +166,7 @@ typedef struct _GtkNotebookPrivate GtkNotebookPrivate; struct _GtkNotebookPrivate { - gint group_id; + gpointer group; gint mouse_x; gint mouse_y; gint pressed_button; @@ -208,6 +218,8 @@ static void gtk_notebook_move_focus_out (GtkNotebook *notebook, static gboolean gtk_notebook_reorder_tab (GtkNotebook *notebook, GtkDirectionType direction_type, gboolean move_to_last); +static void gtk_notebook_remove_tab_label (GtkNotebook *notebook, + GtkNotebookPage *page); /*** GtkObject Methods ***/ static void gtk_notebook_destroy (GtkObject *object); @@ -322,6 +334,11 @@ static gint gtk_notebook_real_insert_page (GtkNotebook *notebook, GtkWidget *menu_label, gint position); +static GtkNotebook *gtk_notebook_create_window (GtkNotebook *notebook, + GtkWidget *page, + gint x, + gint y); + /*** GtkNotebook Private Functions ***/ static void gtk_notebook_redraw_tabs (GtkNotebook *notebook); static void gtk_notebook_redraw_arrows (GtkNotebook *notebook); @@ -341,6 +358,8 @@ static GList * gtk_notebook_search_page (GtkNotebook *notebook, GList *list, gint direction, gboolean find_visible); +static void gtk_notebook_child_reordered (GtkNotebook *notebook, + GtkNotebookPage *page); /*** GtkNotebook Drawing Functions ***/ static void gtk_notebook_paint (GtkWidget *widget, @@ -368,8 +387,7 @@ static void gtk_notebook_real_switch_page (GtkNotebook *notebook, /*** GtkNotebook Page Switch Functions ***/ static void gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - gint page_num); + GtkNotebookPage *page); static gint gtk_notebook_page_select (GtkNotebook *notebook, gboolean move_focus); static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook, @@ -411,6 +429,12 @@ static void do_detach_tab (GtkNotebook *from, gint x, gint y); +/* GtkBuildable */ +static void gtk_notebook_buildable_init (GtkBuildableIface *iface); +static void gtk_notebook_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type); static GtkNotebookWindowCreationFunc window_creation_hook = NULL; static gpointer window_creation_hook_data; @@ -418,7 +442,9 @@ static GDestroyNotify window_creation_hook_destroy = NULL; static guint notebook_signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (GtkNotebook, gtk_notebook, GTK_TYPE_CONTAINER) +G_DEFINE_TYPE_WITH_CODE (GtkNotebook, gtk_notebook, GTK_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_notebook_buildable_init)) static void add_tab_bindings (GtkBindingSet *binding_set, @@ -466,6 +492,22 @@ add_reorder_bindings (GtkBindingSet *binding_set, G_TYPE_BOOLEAN, move_to_last); } +static gboolean +gtk_object_handled_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + GObject *object; + + object = g_value_get_object (handler_return); + g_value_set_object (return_accu, object); + continue_emission = !object; + + return continue_emission; +} + static void gtk_notebook_class_init (GtkNotebookClass *class) { @@ -522,15 +564,16 @@ gtk_notebook_class_init (GtkNotebookClass *class) class->change_current_page = gtk_notebook_change_current_page; class->move_focus_out = gtk_notebook_move_focus_out; class->reorder_tab = gtk_notebook_reorder_tab; + class->create_window = gtk_notebook_create_window; g_object_class_install_property (gobject_class, PROP_PAGE, g_param_spec_int ("page", P_("Page"), P_("The index of the current page"), - 0, + -1, G_MAXINT, - 0, + -1, GTK_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_TAB_POS, @@ -612,6 +655,20 @@ gtk_notebook_class_init (GtkNotebookClass *class) -1, GTK_PARAM_READWRITE)); + /** + * GtkNotebook:group: + * + * Group for tabs drag and drop. + * + * Since: 2.12 + */ + g_object_class_install_property (gobject_class, + PROP_GROUP, + g_param_spec_pointer ("group", + P_("Group"), + P_("Group for tabs drag and drop"), + GTK_PARAM_READWRITE)); + gtk_container_class_install_child_property (container_class, CHILD_PROP_TAB_LABEL, g_param_spec_string ("tab-label", @@ -638,7 +695,7 @@ gtk_notebook_class_init (GtkNotebookClass *class) g_param_spec_boolean ("tab-expand", P_("Tab expand"), P_("Whether to expand the child's tab or not"), - TRUE, + FALSE, GTK_PARAM_READWRITE)); gtk_container_class_install_child_property (container_class, CHILD_PROP_TAB_FILL, @@ -767,7 +824,7 @@ gtk_notebook_class_init (GtkNotebookClass *class) /** * GtkNotebook:arrow-spacing: * - * The "arrow-size" property defines the spacing between the scroll + * The "arrow-spacing" property defines the spacing between the scroll * arrows and the tabs. * * Since: 2.10 @@ -898,6 +955,39 @@ gtk_notebook_class_init (GtkNotebookClass *class) GTK_TYPE_WIDGET, G_TYPE_UINT); + /** + * GtkNotebook::create-window: + * @notebook: the #GtkNotebook emitting the signal + * @page: the tab of @notebook that is being detached + * @x: the X coordinate where the drop happens + * @y: the Y coordinate where the drop happens + * + * The ::create-window signal is emitted when a detachable + * tab is dropped on the root window. + * + * A handler for this signal can create a window containing + * a notebook where the tab will be attached. It is also + * responsible for moving/resizing the window and adding the + * necessary properties to the notebook (e.g. the + * #GtkNotebook:group-id ). + * + * The default handler uses the global window creation hook, + * if one has been set with gtk_notebook_set_window_creation_hook(). + * + * Returns: a #GtkNotebook that @page should be added to, or %NULL. + * + * Since: 2.12 + */ + notebook_signals[CREATE_WINDOW] = + g_signal_new (I_("create_window"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkNotebookClass, create_window), + gtk_object_handled_accumulator, NULL, + _gtk_marshal_OBJECT__OBJECT_INT_INT, + GTK_TYPE_NOTEBOOK, 3, + GTK_TYPE_WIDGET, G_TYPE_INT, G_TYPE_INT); + binding_set = gtk_binding_set_by_class (class); gtk_binding_entry_add_signal (binding_set, GDK_space, 0, @@ -1000,7 +1090,7 @@ gtk_notebook_init (GtkNotebook *notebook) notebook->has_after_previous = 0; notebook->has_after_next = 1; - priv->group_id = -1; + priv->group = NULL; priv->pressed_button = -1; priv->dnd_timer = 0; priv->switch_tab_timer = 0; @@ -1011,8 +1101,7 @@ gtk_notebook_init (GtkNotebook *notebook) priv->during_detach = FALSE; priv->has_scrolled = FALSE; - gtk_drag_dest_set (GTK_WIDGET (notebook), - GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, + gtk_drag_dest_set (GTK_WIDGET (notebook), 0, notebook_targets, G_N_ELEMENTS (notebook_targets), GDK_ACTION_MOVE); @@ -1022,6 +1111,36 @@ gtk_notebook_init (GtkNotebook *notebook) gtk_drag_dest_set_track_motion (GTK_WIDGET (notebook), TRUE); } +static void +gtk_notebook_buildable_init (GtkBuildableIface *iface) +{ + iface->add_child = gtk_notebook_buildable_add_child; +} + +static void +gtk_notebook_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type) +{ + GtkNotebook *notebook = GTK_NOTEBOOK (buildable); + + if (type && strcmp (type, "tab") == 0) + { + GtkWidget * page; + + page = gtk_notebook_get_nth_page (notebook, -1); + /* To set the tab label widget, we must have already a child + * inside the tab container. */ + g_assert (page != NULL); + gtk_notebook_set_tab_label (notebook, page, GTK_WIDGET (child)); + } + else if (!type) + gtk_notebook_append_page (notebook, GTK_WIDGET (child), NULL); + else + GTK_BUILDER_WARN_INVALID_CHILD_TYPE (notebook, type); +} + static gboolean gtk_notebook_select_page (GtkNotebook *notebook, gboolean move_focus) @@ -1101,7 +1220,7 @@ gtk_notebook_change_current_page (GtkNotebook *notebook, } if (current) - gtk_notebook_switch_page (notebook, current->data, -1); + gtk_notebook_switch_page (notebook, current->data); else gtk_widget_error_bell (GTK_WIDGET (notebook)); @@ -1344,7 +1463,7 @@ gtk_notebook_destroy (GtkObject *object) { GtkNotebook *notebook = GTK_NOTEBOOK (object); GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (notebook); - + if (notebook->menu) gtk_notebook_popup_disable (notebook); @@ -1411,7 +1530,11 @@ gtk_notebook_set_property (GObject *object, case PROP_GROUP_ID: gtk_notebook_set_group_id (notebook, g_value_get_int (value)); break; + case PROP_GROUP: + gtk_notebook_set_group (notebook, g_value_get_pointer (value)); + break; default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -1458,7 +1581,10 @@ gtk_notebook_get_property (GObject *object, g_value_set_uint (value, notebook->tab_vborder); break; case PROP_GROUP_ID: - g_value_set_int (value, priv->group_id); + g_value_set_int (value, gtk_notebook_get_group_id (notebook)); + break; + case PROP_GROUP: + g_value_set_pointer (value, priv->group); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1559,8 +1685,6 @@ gtk_notebook_map (GtkWidget *widget) GtkNotebookPage *page; GList *children; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); notebook = GTK_NOTEBOOK (widget); @@ -1595,8 +1719,6 @@ gtk_notebook_map (GtkWidget *widget) static void gtk_notebook_unmap (GtkWidget *widget) { - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - stop_scrolling (GTK_NOTEBOOK (widget)); GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); @@ -1614,8 +1736,6 @@ gtk_notebook_realize (GtkWidget *widget) gint attributes_mask; GdkRectangle event_window_pos; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - notebook = GTK_NOTEBOOK (widget); GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED); @@ -1650,8 +1770,6 @@ gtk_notebook_unrealize (GtkWidget *widget) GtkNotebook *notebook; GtkNotebookPrivate *priv; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - notebook = GTK_NOTEBOOK (widget); priv = GTK_NOTEBOOK_GET_PRIVATE (widget); @@ -1913,7 +2031,7 @@ gtk_notebook_size_request (GtkWidget *widget, page = children->data; if (GTK_WIDGET_VISIBLE (page->child)) { - gtk_notebook_switch_page (notebook, page, -1); + gtk_notebook_switch_page (notebook, page); break; } } @@ -1930,7 +2048,7 @@ gtk_notebook_size_request (GtkWidget *widget, if (children) { notebook->first_tab = children; - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children),-1); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children)); } } } @@ -2023,9 +2141,6 @@ gtk_notebook_expose (GtkWidget *widget, GtkNotebook *notebook; GtkNotebookPrivate *priv; - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - notebook = GTK_NOTEBOOK (widget); priv = GTK_NOTEBOOK_GET_PRIVATE (widget); @@ -2621,7 +2736,6 @@ hide_drag_window (GtkNotebook *notebook, else gtk_widget_unparent (page->tab_label); - gtk_widget_set_parent_window (page->tab_label, widget->window); gtk_widget_set_parent (page->tab_label, widget); g_object_unref (page->tab_label); } @@ -2644,7 +2758,7 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook) else page = notebook->cur_page; - if (!page) + if (!page || !page->tab_label) return; priv->pressed_button = -1; @@ -2659,7 +2773,8 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook) element = get_drop_position (notebook, page->pack); old_page_num = g_list_position (notebook->children, notebook->focus_tab); page_num = reorder_tab (notebook, element, notebook->focus_tab); - + gtk_notebook_child_reordered (notebook, page); + if (priv->has_scrolled || old_page_num != page_num) g_signal_emit (notebook, notebook_signals[PAGE_REORDERED], 0, @@ -2690,9 +2805,6 @@ gtk_notebook_button_release (GtkWidget *widget, GtkNotebookPrivate *priv; GtkNotebookPage *page; - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - if (event->type != GDK_BUTTON_RELEASE) return FALSE; @@ -3117,7 +3229,7 @@ gtk_notebook_drag_end (GtkWidget *widget, gtk_notebook_stop_reorder (GTK_NOTEBOOK (widget)); if (priv->detached_tab) - gtk_notebook_switch_page (GTK_NOTEBOOK (widget), priv->detached_tab, -1); + gtk_notebook_switch_page (GTK_NOTEBOOK (widget), priv->detached_tab); GTK_BIN (priv->dnd_window)->child = NULL; gtk_widget_destroy (priv->dnd_window); @@ -3126,6 +3238,18 @@ gtk_notebook_drag_end (GtkWidget *widget, priv->operation = DRAG_OPERATION_NONE; } +static GtkNotebook * +gtk_notebook_create_window (GtkNotebook *notebook, + GtkWidget *page, + gint x, + gint y) +{ + if (window_creation_hook) + return (* window_creation_hook) (notebook, page, x, y, window_creation_hook_data); + + return NULL; +} + static gboolean gtk_notebook_drag_failed (GtkWidget *widget, GdkDragContext *context, @@ -3135,7 +3259,7 @@ gtk_notebook_drag_failed (GtkWidget *widget, if (result == GTK_DRAG_RESULT_NO_TARGET) { GtkNotebookPrivate *priv; - GtkNotebook *notebook, *dest_notebook; + GtkNotebook *notebook, *dest_notebook = NULL; GdkDisplay *display; gint x, y; @@ -3145,10 +3269,9 @@ gtk_notebook_drag_failed (GtkWidget *widget, display = gtk_widget_get_display (widget); gdk_display_get_pointer (display, NULL, &x, &y, NULL); - dest_notebook = (* window_creation_hook) (notebook, - priv->detached_tab->child, - x, y, - window_creation_hook_data); + g_signal_emit (notebook, notebook_signals[CREATE_WINDOW], 0, + priv->detached_tab->child, x, y, &dest_notebook); + if (dest_notebook) do_detach_tab (notebook, dest_notebook, priv->detached_tab->child, 0, 0); @@ -3218,17 +3341,16 @@ gtk_notebook_drag_motion (GtkWidget *widget, if (target == tab_target) { - gint widget_group, source_widget_group; + gpointer widget_group, source_widget_group; GtkWidget *source_widget; source_widget = gtk_drag_get_source_widget (context); g_assert (source_widget); - widget_group = gtk_notebook_get_group_id (notebook); - source_widget_group = gtk_notebook_get_group_id (GTK_NOTEBOOK (source_widget)); + widget_group = gtk_notebook_get_group (notebook); + source_widget_group = gtk_notebook_get_group (GTK_NOTEBOOK (source_widget)); - if (widget_group != -1 && - source_widget_group != -1 && + if (widget_group && source_widget_group && widget_group == source_widget_group && !(widget == GTK_NOTEBOOK (source_widget)->cur_page->child || gtk_widget_is_ancestor (widget, GTK_NOTEBOOK (source_widget)->cur_page->child))) @@ -3236,19 +3358,18 @@ gtk_notebook_drag_motion (GtkWidget *widget, gdk_drag_status (context, GDK_ACTION_MOVE, time); return TRUE; } + else + { + /* it's a tab, but doesn't share + * ID with this notebook */ + gdk_drag_status (context, 0, time); + } } priv = GTK_NOTEBOOK_GET_PRIVATE (widget); x += widget->allocation.x; y += widget->allocation.y; - if (target == tab_target) - { - /* it's a tab, but doesn't share - * ID with this notebook */ - gdk_drag_status (context, 0, time); - } - if (gtk_notebook_get_event_window_position (notebook, &position) && x >= position.x && x <= position.x + position.width && y >= position.y && y <= position.y + position.height) @@ -3275,7 +3396,7 @@ gtk_notebook_drag_motion (GtkWidget *widget, } } - return TRUE; + return (target == tab_target) ? TRUE : FALSE; } static void @@ -3303,14 +3424,18 @@ gtk_notebook_drag_drop (GtkWidget *widget, gint y, guint time) { - GdkAtom target; + GdkAtom target, tab_target; target = gtk_drag_dest_find_target (widget, context, NULL); + tab_target = gdk_atom_intern_static_string ("GTK_NOTEBOOK_TAB"); - if (target == GDK_NONE) - gtk_drag_finish (context, FALSE, FALSE, time); + if (target == tab_target) + { + gtk_drag_get_data (widget, context, target, time); + return TRUE; + } - return TRUE; + return FALSE; } static void @@ -3535,7 +3660,7 @@ gtk_notebook_get_child_property (GtkContainer *container, case CHILD_PROP_TAB_LABEL: label = gtk_notebook_get_tab_label (notebook, child); - if (label && GTK_IS_LABEL (label)) + if (GTK_IS_LABEL (label)) g_value_set_string (value, GTK_LABEL (label)->label); else g_value_set_string (value, NULL); @@ -3543,7 +3668,7 @@ gtk_notebook_get_child_property (GtkContainer *container, case CHILD_PROP_MENU_LABEL: label = gtk_notebook_get_menu_label (notebook, child); - if (label && GTK_IS_LABEL (label)) + if (GTK_IS_LABEL (label)) g_value_set_string (value, GTK_LABEL (label)->label); else g_value_set_string (value, NULL); @@ -3584,8 +3709,6 @@ static void gtk_notebook_add (GtkContainer *container, GtkWidget *widget) { - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget, NULL, NULL, -1); } @@ -3599,9 +3722,6 @@ gtk_notebook_remove (GtkContainer *container, GList *children; gint page_num = 0; - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (widget != NULL); - notebook = GTK_NOTEBOOK (container); children = notebook->children; @@ -3703,8 +3823,6 @@ gtk_notebook_focus (GtkWidget *widget, gboolean widget_is_focus; GtkContainer *container; - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - container = GTK_CONTAINER (widget); notebook = GTK_NOTEBOOK (container); @@ -3858,9 +3976,6 @@ gtk_notebook_forall (GtkContainer *container, GtkNotebook *notebook; GList *children; - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (callback != NULL); - notebook = GTK_NOTEBOOK (container); children = notebook->children; @@ -3912,7 +4027,7 @@ page_visible_cb (GtkWidget *page, } if (next) - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next), -1); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next)); } } @@ -3926,28 +4041,11 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, GtkNotebookPage *page; gint nchildren; - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); - g_return_val_if_fail (GTK_IS_WIDGET (child), -1); - g_return_val_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label), -1); - g_return_val_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label), -1); - gtk_widget_freeze_child_notify (child); - - page = g_new (GtkNotebookPage, 1); + + page = g_slice_new0 (GtkNotebookPage); page->child = child; - page->last_focus_child = NULL; - page->requisition.width = 0; - page->requisition.height = 0; - page->allocation.x = 0; - page->allocation.y = 0; - page->allocation.width = 0; - page->allocation.height = 0; - page->default_menu = FALSE; - page->default_tab = FALSE; - page->mnemonic_activate_signal = 0; - page->reorderable = FALSE; - page->detachable = FALSE; - + nchildren = g_list_length (notebook->children); if ((position < 0) || (position > nchildren)) position = nchildren; @@ -3958,7 +4056,7 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, { page->default_tab = TRUE; if (notebook->show_tabs) - tab_label = gtk_label_new (""); + tab_label = gtk_label_new (NULL); } page->tab_label = tab_label; page->menu_label = menu_label; @@ -3971,9 +4069,6 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, else g_object_ref_sink (page->menu_label); - /* child visible will be turned on by switch_page below */ - gtk_widget_set_child_visible (child, FALSE); - if (notebook->menu) gtk_notebook_menu_item_create (notebook, g_list_find (notebook->children, page)); @@ -3987,6 +4082,10 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, if (!notebook->first_tab) notebook->first_tab = notebook->children; + /* child visible will be turned on by switch_page below */ + if (notebook->cur_page != page) + gtk_widget_set_child_visible (child, FALSE); + if (tab_label) { if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child)) @@ -4012,8 +4111,9 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, if (!notebook->cur_page) { - gtk_notebook_switch_page (notebook, page, 0); - gtk_notebook_switch_focus_tab (notebook, NULL); + gtk_notebook_switch_page (notebook, page); + /* focus_tab is set in the switch_page method */ + gtk_notebook_switch_focus_tab (notebook, notebook->focus_tab); } gtk_notebook_update_tab_states (notebook); @@ -4222,21 +4322,24 @@ gtk_notebook_real_remove (GtkNotebook *notebook, GtkNotebookPage *page; GList * next_list; gint need_resize = FALSE; + GtkWidget *tab_label; gboolean destroying; priv = GTK_NOTEBOOK_GET_PRIVATE (notebook); destroying = GTK_OBJECT_FLAGS (notebook) & GTK_IN_DESTRUCTION; - next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); if (!next_list) - next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); + next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + + notebook->children = g_list_remove_link (notebook->children, list); if (notebook->cur_page == list->data) { notebook->cur_page = NULL; if (next_list && !destroying) - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list)); } if (priv->detached_tab == list->data) @@ -4256,8 +4359,16 @@ gtk_notebook_real_remove (GtkNotebook *notebook, gtk_widget_unparent (page->child); - gtk_notebook_remove_tab_label (notebook, page); - + tab_label = page->tab_label; + if (tab_label) + { + g_object_ref (tab_label); + gtk_notebook_remove_tab_label (notebook, page); + if (destroying) + gtk_widget_destroy (tab_label); + g_object_unref (tab_label); + } + if (notebook->menu) { gtk_container_remove (GTK_CONTAINER (notebook->menu), @@ -4267,7 +4378,6 @@ gtk_notebook_real_remove (GtkNotebook *notebook, if (!page->default_menu) g_object_unref (page->menu_label); - notebook->children = g_list_remove_link (notebook->children, list); g_list_free (list); if (page->last_focus_child) @@ -4276,7 +4386,7 @@ gtk_notebook_real_remove (GtkNotebook *notebook, page->last_focus_child = NULL; } - g_free (page); + g_slice_free (GtkNotebookPage, page); gtk_notebook_update_labels (notebook); if (need_resize) @@ -4291,6 +4401,9 @@ gtk_notebook_update_labels (GtkNotebook *notebook) gchar string[32]; gint page_num = 1; + if (!notebook->show_tabs && !notebook->menu) + return; + for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE); list; list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE)) @@ -4320,9 +4433,9 @@ gtk_notebook_update_labels (GtkNotebook *notebook) } if (notebook->menu && page->default_menu) { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) + if (GTK_IS_LABEL (page->tab_label)) gtk_label_set_text (GTK_LABEL (page->menu_label), - GTK_LABEL (page->tab_label)->label); + GTK_LABEL (page->tab_label)->label); else gtk_label_set_text (GTK_LABEL (page->menu_label), string); } @@ -4336,9 +4449,6 @@ gtk_notebook_real_page_position (GtkNotebook *notebook, GList *work; gint count_start; - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); - g_return_val_if_fail (list != NULL, -1); - for (work = notebook->children, count_start = 0; work && work != list; work = work->next) if (GTK_NOTEBOOK_PAGE (work)->pack == GTK_PACK_START) @@ -4363,8 +4473,6 @@ gtk_notebook_search_page (GtkNotebook *notebook, GList *old_list = NULL; gint flag = 0; - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); - switch (direction) { case STEP_PREV: @@ -4443,9 +4551,6 @@ gtk_notebook_paint (GtkWidget *widget, gboolean is_rtl; gint tab_pos; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (area != NULL); - if (!GTK_WIDGET_DRAWABLE (widget)) return; @@ -4576,10 +4681,6 @@ gtk_notebook_draw_tab (GtkNotebook *notebook, GdkWindow *window; GtkWidget *widget; - g_return_if_fail (notebook != NULL); - g_return_if_fail (page != NULL); - g_return_if_fail (area != NULL); - if (!NOTEBOOK_IS_TAB_LABEL_PARENT (notebook, page) || !GTK_WIDGET_MAPPED (page->tab_label) || (page->allocation.width == 0) || (page->allocation.height == 0)) @@ -4663,7 +4764,7 @@ gtk_notebook_draw_arrow (GtkNotebook *notebook, if (notebook->focus_tab && !gtk_notebook_search_page (notebook, notebook->focus_tab, - left? STEP_PREV : STEP_NEXT, TRUE)) + left ? STEP_PREV : STEP_NEXT, TRUE)) { shadow_type = GTK_SHADOW_ETCHED_IN; state_type = GTK_STATE_INSENSITIVE; @@ -5664,9 +5765,6 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num) { - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); - if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child)) return; @@ -5710,17 +5808,14 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook, */ static void gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - gint page_num) + GtkNotebookPage *page) { - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); - + guint page_num; + if (notebook->cur_page == page) return; - if (page_num < 0) - page_num = g_list_index (notebook->children, page); + page_num = g_list_index (notebook->children, page); g_signal_emit (notebook, notebook_signals[SWITCH_PAGE], @@ -5737,13 +5832,11 @@ gtk_notebook_page_select (GtkNotebook *notebook, GtkDirectionType dir = GTK_DIR_DOWN; /* Quiet GCC */ gint tab_pos = get_effective_tab_pos (notebook); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); - if (!notebook->focus_tab) return FALSE; page = notebook->focus_tab->data; - gtk_notebook_switch_page (notebook, page, -1); + gtk_notebook_switch_page (notebook, page); if (move_focus) { @@ -5776,8 +5869,6 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook, GList *old_child; GtkNotebookPage *page; - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (notebook->focus_tab == new_child) return; @@ -5796,8 +5887,7 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook, else gtk_notebook_pages_allocate (notebook); - gtk_notebook_switch_page (notebook, page, - g_list_index (notebook->children, page)); + gtk_notebook_switch_page (notebook, page); } static void @@ -5808,9 +5898,6 @@ gtk_notebook_menu_switch_page (GtkWidget *widget, GList *children; guint page_num; - g_return_if_fail (widget != NULL); - g_return_if_fail (page != NULL); - notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget (GTK_MENU (widget->parent))); @@ -5848,7 +5935,7 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook, page = list->data; if (page->default_menu) { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) + if (GTK_IS_LABEL (page->tab_label)) page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label); else page->menu_label = gtk_label_new (""); @@ -5880,8 +5967,6 @@ gtk_notebook_menu_detacher (GtkWidget *widget, { GtkNotebook *notebook; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - notebook = GTK_NOTEBOOK (widget); g_return_if_fail (notebook->menu == (GtkWidget*) menu); @@ -5899,8 +5984,6 @@ 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; @@ -5914,8 +5997,6 @@ 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; @@ -5932,8 +6013,6 @@ 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; @@ -5949,8 +6028,6 @@ 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; @@ -6136,7 +6213,7 @@ gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child, GtkNotebookPage *page = list->data; gtk_widget_grab_focus (GTK_WIDGET (notebook)); /* Do this first to avoid focusing new page */ - gtk_notebook_switch_page (notebook, page, -1); + gtk_notebook_switch_page (notebook, page); focus_tabs_in (notebook); } @@ -6242,7 +6319,7 @@ 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, or -1 + * @page_num: the index of a page in the notebook, or -1 * to get the last page. * * Returns the child widget contained in page number @page_num. @@ -6350,15 +6427,12 @@ gtk_notebook_set_current_page (GtkNotebook *notebook, g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (page_num >= 0) - list = g_list_nth (notebook->children, page_num); - else - list = g_list_last (notebook->children); - - page_num = g_list_index (notebook->children, list); + if (page_num < 0) + page_num = g_list_length (notebook->children) - 1; + list = g_list_nth (notebook->children, page_num); if (list) - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list)); } /** @@ -6383,7 +6457,7 @@ gtk_notebook_next_page (GtkNotebook *notebook) if (!list) return; - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list)); } /** @@ -6408,7 +6482,7 @@ gtk_notebook_prev_page (GtkNotebook *notebook) if (!list) return; - gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list)); } /* Public GtkNotebook/Tab Style Functions @@ -6897,10 +6971,10 @@ gtk_notebook_set_tab_label_text (GtkNotebook *notebook, * Retrieves the text of the tab label for the page containing * @child. * - * Returns value: the text of the tab label, or %NULL if the - * tab label widget is not a #GtkLabel. The - * string is owned by the widget and must not - * be freed. + * Return value: the text of the tab label, or %NULL if the + * tab label widget is not a #GtkLabel. The + * string is owned by the widget and must not + * be freed. **/ G_CONST_RETURN gchar * gtk_notebook_get_tab_label_text (GtkNotebook *notebook, @@ -6913,7 +6987,7 @@ gtk_notebook_get_tab_label_text (GtkNotebook *notebook, tab_label = gtk_notebook_get_tab_label (notebook, child); - if (tab_label && GTK_IS_LABEL (tab_label)) + if (GTK_IS_LABEL (tab_label)) return gtk_label_get_text (GTK_LABEL (tab_label)); else return NULL; @@ -7031,11 +7105,11 @@ gtk_notebook_set_menu_label_text (GtkNotebook *notebook, * Retrieves the text of the menu label for the page containing * @child. * - * Returns value: the text of the tab label, or %NULL if the - * widget does not have a menu label other than - * the default menu label, or the menu label widget - * is not a #GtkLabel. The string is owned by - * the widget and must not be freed. + * Return value: the text of the tab label, or %NULL if the + * widget does not have a menu label other than + * the default menu label, or the menu label widget + * is not a #GtkLabel. The string is owned by + * the widget and must not be freed. **/ G_CONST_RETURN gchar * gtk_notebook_get_menu_label_text (GtkNotebook *notebook, @@ -7048,7 +7122,7 @@ gtk_notebook_get_menu_label_text (GtkNotebook *notebook, menu_label = gtk_notebook_get_menu_label (notebook, child); - if (menu_label && GTK_IS_LABEL (menu_label)) + if (GTK_IS_LABEL (menu_label)) return gtk_label_get_text (GTK_LABEL (menu_label)); else return NULL; @@ -7264,10 +7338,36 @@ gtk_notebook_set_window_creation_hook (GtkNotebookWindowCreationFunc func, * not be able to exchange tabs with any other notebook. * * Since: 2.10 - **/ + * Deprecated: 2.12: use gtk_notebook_set_group() instead. + */ void gtk_notebook_set_group_id (GtkNotebook *notebook, gint group_id) +{ + gpointer group; + + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + /* add 1 to get rid of the -1/NULL difference */ + group = GINT_TO_POINTER (group_id + 1); + gtk_notebook_set_group (notebook, group); +} + +/** + * gtk_notebook_set_group: + * @notebook: a #GtkNotebook + * @group: a pointer to identify the notebook group, or %NULL to unset it + * + * Sets a group identificator pointer for @notebook, notebooks sharing + * the same group identificator pointer will be able to exchange tabs + * via drag and drop. A notebook with a %NULL group identificator will + * not be able to exchange tabs with any other notebook. + * + * Since: 2.12 + */ +void +gtk_notebook_set_group (GtkNotebook *notebook, + gpointer group) { GtkNotebookPrivate *priv; @@ -7275,10 +7375,11 @@ gtk_notebook_set_group_id (GtkNotebook *notebook, priv = GTK_NOTEBOOK_GET_PRIVATE (notebook); - if (priv->group_id != group_id) + if (priv->group != group) { - priv->group_id = group_id; + priv->group = group; g_object_notify (G_OBJECT (notebook), "group-id"); + g_object_notify (G_OBJECT (notebook), "group"); } } @@ -7291,7 +7392,8 @@ gtk_notebook_set_group_id (GtkNotebook *notebook, * Return Value: the group identificator, or -1 if none is set. * * Since: 2.10 - **/ + * Deprecated: 2.12: use gtk_notebook_get_group() instead. + */ gint gtk_notebook_get_group_id (GtkNotebook *notebook) { @@ -7300,7 +7402,30 @@ gtk_notebook_get_group_id (GtkNotebook *notebook) g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); priv = GTK_NOTEBOOK_GET_PRIVATE (notebook); - return priv->group_id; + + /* substract 1 to get rid of the -1/NULL difference */ + return GPOINTER_TO_INT (priv->group) - 1; +} + +/** + * gtk_notebook_get_group: + * @notebook: a #GtkNotebook + * + * Gets the current group identificator pointer for @notebook. + * + * Return Value: the group identificator, or %NULL if none is set. + * + * Since: 2.12 + **/ +gpointer +gtk_notebook_get_group (GtkNotebook *notebook) +{ + GtkNotebookPrivate *priv; + + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + + priv = GTK_NOTEBOOK_GET_PRIVATE (notebook); + return priv->group; } /** @@ -7407,8 +7532,7 @@ gtk_notebook_get_tab_detachable (GtkNotebook *notebook, * destination and accept the target "GTK_NOTEBOOK_TAB". The notebook * will fill the selection with a GtkWidget** pointing to the child * widget that corresponds to the dropped tab. - * - * + * |[ * static void * on_drop_zone_drag_data_received (GtkWidget *widget, * GdkDragContext *context, @@ -7428,7 +7552,7 @@ gtk_notebook_get_tab_detachable (GtkNotebook *notebook, * process_widget (*child); * gtk_container_remove (GTK_CONTAINER (notebook), *child); * } - * + * ]| * * If you want a notebook to accept drags from other widgets, * you will have to set your own DnD code to do it.