diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ephy-nautilus-view.c | 4 | ||||
-rw-r--r-- | src/ephy-notebook.c | 314 | ||||
-rw-r--r-- | src/ephy-notebook.h | 30 | ||||
-rw-r--r-- | src/ephy-tab.c | 341 | ||||
-rw-r--r-- | src/ephy-tab.h | 18 | ||||
-rw-r--r-- | src/ephy-tabs-menu.c | 4 | ||||
-rw-r--r-- | src/ephy-window.c | 821 | ||||
-rw-r--r-- | src/ephy-window.h | 12 | ||||
-rwxr-xr-x | src/toolbar.c | 6 |
9 files changed, 786 insertions, 764 deletions
diff --git a/src/ephy-nautilus-view.c b/src/ephy-nautilus-view.c index e99ef1bba..cec56630e 100644 --- a/src/ephy-nautilus-view.c +++ b/src/ephy-nautilus-view.c @@ -453,8 +453,8 @@ gnv_embed_new_window_cb (EphyEmbed *embed, EphyEmbed **new_embed, EMBED_CHROME_OPENASPOPUP); } new_tab = ephy_tab_new (); - ephy_window_add_tab (window, new_tab, FALSE, FALSE); - + ephy_window_add_tab (window, new_tab, EPHY_NOTEBOOK_INSERT_LAST, FALSE); + *new_embed = ephy_tab_get_embed (new_tab); } diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c index 1671126dd..878807e14 100644 --- a/src/ephy-notebook.c +++ b/src/ephy-notebook.c @@ -29,6 +29,7 @@ #include "ephy-embed.h" #include "ephy-window.h" #include "ephy-shell.h" +#include "ephy-debug.h" #include <gtk/gtk.h> #include <glib-object.h> @@ -45,8 +46,6 @@ struct EphyNotebookPrivate GList *focused_pages; GList *opened_tabs; - EphyNotebookPageLoadStatus current_status; - GtkTooltips *title_tips; /* Used during tab drag'n'drop */ @@ -86,13 +85,16 @@ static gboolean motion_notify_cb (EphyNotebook *notebook, /* Signals */ enum { - TAB_DROPPED, + TAB_ADDED, + TAB_REMOVED, + TABS_REORDERED, TAB_DETACHED, - TABS_CHANGED, LAST_SIGNAL }; -static guint ephy_notebook_signals[LAST_SIGNAL] = { 0 }; +static GObjectClass *parent_class = NULL; + +static guint signals[LAST_SIGNAL] = { 0 }; GType ephy_notebook_get_type (void) @@ -126,41 +128,50 @@ static void ephy_notebook_class_init (EphyNotebookClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + object_class->finalize = ephy_notebook_finalize; - /* init signals */ - ephy_notebook_signals[TAB_DROPPED] = - g_signal_new ("tab_dropped", + signals[TAB_ADDED] = + g_signal_new ("tab_added", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNotebookClass, tab_dropped), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyNotebookClass, tab_added), NULL, NULL, - ephy_marshal_VOID__OBJECT_OBJECT_INT, + ephy_marshal_VOID__OBJECT, G_TYPE_NONE, - 3, - GTK_TYPE_WIDGET, - EPHY_NOTEBOOK_TYPE, - G_TYPE_INT); - ephy_notebook_signals[TAB_DETACHED] = + 1, + GTK_TYPE_WIDGET); + signals[TAB_REMOVED] = + g_signal_new ("tab_removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyNotebookClass, tab_removed), + NULL, NULL, + ephy_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GTK_TYPE_WIDGET); + signals[TAB_DETACHED] = g_signal_new ("tab_detached", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (EphyNotebookClass, tab_detached), NULL, NULL, - ephy_marshal_VOID__INT_INT_INT, + ephy_marshal_VOID__OBJECT, G_TYPE_NONE, - 3, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - ephy_notebook_signals[TABS_CHANGED] = - g_signal_new ("tabs_changed", + 1, + GTK_TYPE_WIDGET); + signals[TABS_REORDERED] = + g_signal_new ("tabs_reordered", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyNotebookClass, tabs_changed), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyNotebookClass, tabs_reordered), NULL, NULL, ephy_marshal_VOID__VOID, - G_TYPE_NONE, 0); + G_TYPE_NONE, + 0); } static gboolean @@ -220,7 +231,6 @@ find_notebook_at_pointer (gint abs_x, gint abs_y) return NULL; } - static gint find_tab_num_at_pos (EphyNotebook *notebook, gint abs_x, gint abs_y) { @@ -277,7 +287,6 @@ find_tab_num_at_pos (EphyNotebook *notebook, gint abs_x, gint abs_y) return AFTER_ALL_TABS; } - static gint find_notebook_and_tab_at_pos (gint abs_x, gint abs_y, EphyNotebook **notebook, gint *page_num) @@ -331,31 +340,26 @@ void ephy_notebook_move_page (EphyNotebook *src, EphyNotebook *dest, GtkWidget *src_page, gint dest_page) { - GtkWidget *tab_label; - if (dest == NULL || src == dest) { gtk_notebook_reorder_child (GTK_NOTEBOOK (src), src_page, dest_page); - g_signal_emit (G_OBJECT (src), ephy_notebook_signals[TABS_CHANGED], 0); + + if (src->priv->drag_in_progress == FALSE) + { + g_signal_emit (G_OBJECT (src), signals[TABS_REORDERED], 0); + } } else { - tab_label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (src), src_page); - - /* We don't want gtk to destroy tab and src_page behind our back */ + /* make sure the tab isn't destroyed while we move its embed */ g_object_ref (G_OBJECT (src_page)); - g_object_ref (G_OBJECT (tab_label)); ephy_notebook_remove_page (EPHY_NOTEBOOK (src), src_page); ephy_notebook_insert_page (EPHY_NOTEBOOK (dest), src_page, dest_page, TRUE); - gtk_notebook_set_tab_label (GTK_NOTEBOOK (dest), src_page, tab_label); g_object_unref (G_OBJECT (src_page)); - g_object_unref (G_OBJECT (tab_label)); } } - - static void move_tab_to_another_notebook(EphyNotebook *src, EphyNotebook *dest, gint dest_page) @@ -390,7 +394,9 @@ move_tab_to_another_notebook(EphyNotebook *src, NULL); } - +/* this function is only called during dnd, we don't need to emit TABS_REORDERED + * here, instead we do it on drag_stop + */ static void move_tab (EphyNotebook *notebook, gint dest_page_num) { @@ -437,6 +443,11 @@ drag_start (EphyNotebook *notebook, static void drag_stop (EphyNotebook *notebook) { + if (notebook->priv->drag_in_progress) + { + g_signal_emit (G_OBJECT (notebook), signals[TABS_REORDERED], 0); + } + notebook->priv->drag_in_progress = FALSE; notebook->priv->src_notebook = NULL; notebook->priv->src_page = -1; @@ -466,20 +477,8 @@ button_release_cb (EphyNotebook *notebook, GdkEventButton *event, if (!is_in_notebook_window (notebook, event->x_root, event->y_root)) { /* Tab was detached */ - g_signal_emit (G_OBJECT(notebook), - ephy_notebook_signals[TAB_DETACHED], 0, - cur_page_num, (gint)event->x_root, - (gint)event->y_root); - } - else - { - /* Tab was dragged and dropped (but it may have stayed - in the same place) */ - g_signal_emit (G_OBJECT(notebook), - ephy_notebook_signals[TAB_DROPPED], 0, - cur_page, - notebook->priv->src_notebook, - notebook->priv->src_page); + g_signal_emit (G_OBJECT (notebook), + signals[TAB_DETACHED], 0, cur_page); } /* ungrab the pointer if it's grabbed */ @@ -694,8 +693,6 @@ ephy_notebook_init (EphyNotebook *notebook) { notebook->priv = g_new (EphyNotebookPrivate, 1); - notebook->priv->current_status = EPHY_NOTEBOOK_TAB_LOAD_NORMAL; - notebook->priv->title_tips = gtk_tooltips_new (); g_object_ref (G_OBJECT (notebook->priv->title_tips)); gtk_object_sink (GTK_OBJECT (notebook->priv->title_tips)); @@ -744,75 +741,84 @@ ephy_notebook_finalize (GObject *object) g_object_unref (notebook->priv->title_tips); g_free (notebook->priv); -} + LOG ("EphyNotebook finalised %p", object) +} -void -ephy_notebook_set_page_status (EphyNotebook *nb, - GtkWidget *child, - EphyNotebookPageLoadStatus status) +static void +sync_load_status (EphyTab *tab, GParamSpec *pspec, GtkWidget *proxy) { - GtkWidget *tab, *image, *icon; + GtkWidget *animation = NULL, *icon = NULL; - g_return_if_fail (nb != NULL); + animation = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "loading-image")); + icon = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "icon")); + g_return_if_fail (animation != NULL && icon != NULL); - if (status == nb->priv->current_status) + switch (ephy_tab_get_load_status (tab)) { - return; + case TRUE: + gtk_widget_hide (icon); + gtk_widget_show (animation); + break; + case FALSE: + gtk_widget_hide (animation); + gtk_widget_show (icon); + break; } +} - tab = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), child); - - g_return_if_fail (tab != NULL); - - image = g_object_get_data (G_OBJECT (tab), "loading-image"); - - g_return_if_fail (image != NULL); - - icon = g_object_get_data (G_OBJECT (tab), "icon"); +static void +sync_icon (EphyTab *tab, GParamSpec *pspec, GtkWidget *proxy) +{ + EphyFaviconCache *cache; + GdkPixbuf *pixbuf = NULL; + GtkImage *icon = NULL; + const char *address; - g_return_if_fail (icon != NULL); + cache = ephy_embed_shell_get_favicon_cache (EPHY_EMBED_SHELL (ephy_shell)); + address = ephy_tab_get_icon_address (tab); - switch (status) + if (address) { - case EPHY_NOTEBOOK_TAB_LOAD_LOADING: - gtk_widget_hide (icon); - gtk_widget_show (image); - break; + pixbuf = ephy_favicon_cache_get (cache, address); + } - case EPHY_NOTEBOOK_TAB_LOAD_COMPLETED: - case EPHY_NOTEBOOK_TAB_LOAD_NORMAL: - gtk_widget_hide (image); - gtk_widget_show (icon); - break; + icon = GTK_IMAGE (g_object_get_data (G_OBJECT (proxy), "icon")); + if (icon) + { + gtk_image_set_from_pixbuf (icon, pixbuf); } - nb->priv->current_status = status; + if (pixbuf) + { + g_object_unref (pixbuf); + } } -void -ephy_notebook_set_page_icon (EphyNotebook *nb, - GtkWidget *child, - GdkPixbuf *icon) +static void +sync_label (EphyTab *tab, GParamSpec *pspec, GtkWidget *proxy) { - GtkWidget *tab, *image; - - g_return_if_fail (nb != NULL); - - tab = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), child); + GtkWidget *label, *ebox; + GtkTooltips *tips; + const char *title; - g_return_if_fail (tab != NULL); + ebox = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "label-ebox")); + tips = GTK_TOOLTIPS (g_object_get_data (G_OBJECT (proxy), "tooltips")); + label = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "label")); - image = g_object_get_data (G_OBJECT (tab), "icon"); + g_return_if_fail (ebox != NULL && tips != NULL && label != NULL); - g_return_if_fail (image != NULL); + title = ephy_tab_get_title (tab); - gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon); + if (title) + { + gtk_label_set_label (GTK_LABEL (label), title); + gtk_tooltips_set_tip (tips, ebox, title, NULL); + } } static void -ephy_tab_close_button_clicked_cb (GtkWidget *widget, - GtkWidget *child) +close_button_clicked_cb (GtkWidget *widget, GtkWidget *child) { EphyNotebook *notebook; @@ -821,7 +827,7 @@ ephy_tab_close_button_clicked_cb (GtkWidget *widget, } static GtkWidget * -tab_build_label (EphyNotebook *nb, GtkWidget *child) +build_tab_label (EphyNotebook *nb, GtkWidget *child) { GtkWidget *label, *hbox, *close_button, *image; int h, w; @@ -850,6 +856,7 @@ tab_build_label (EphyNotebook *nb, GtkWidget *child) image); /* setup load feedback image */ + /* FIXME: make the animation themeable */ loading_pixbuf = gdk_pixbuf_animation_new_from_file (ephy_file ("epiphany-tab-loading.gif"), NULL); loading_image = gtk_image_new_from_animation (loading_pixbuf); g_object_unref (loading_pixbuf); @@ -861,7 +868,7 @@ tab_build_label (EphyNotebook *nb, GtkWidget *child) /* setup label */ label_ebox = gtk_event_box_new (); - label = gtk_label_new (_("Untitled")); + label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.5); gtk_misc_set_padding (GTK_MISC (label), 4, 0); gtk_box_pack_start (GTK_BOX (hbox), label_ebox, TRUE, TRUE, 0); @@ -883,7 +890,7 @@ tab_build_label (EphyNotebook *nb, GtkWidget *child) FALSE, FALSE, 0); g_signal_connect (G_OBJECT (close_button), "clicked", - G_CALLBACK (ephy_tab_close_button_clicked_cb), + G_CALLBACK (close_button_clicked_cb), child); gtk_widget_show (hbox); @@ -896,6 +903,7 @@ tab_build_label (EphyNotebook *nb, GtkWidget *child) g_object_set_data (G_OBJECT (hbox), "label-ebox", label_ebox); g_object_set_data (G_OBJECT (hbox), "loading-image", loading_image); g_object_set_data (G_OBJECT (hbox), "icon", icon); + g_object_set_data (G_OBJECT (hbox), "tooltips", nb->priv->title_tips); return hbox; } @@ -903,19 +911,18 @@ tab_build_label (EphyNotebook *nb, GtkWidget *child) /* * update_tabs_visibility: Hide tabs if there is only one tab * and the pref is not set. - * HACK We need to show tabs before inserting the second. Otherwise - * gtknotebook go crazy. */ static void update_tabs_visibility (EphyNotebook *nb, gboolean before_inserting) { gboolean show_tabs; - guint tabs_num = 1; + guint num; + + num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); - if (before_inserting) tabs_num--; + if (before_inserting) num++; - show_tabs = eel_gconf_get_boolean (CONF_TABS_TABBED) || - gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), tabs_num) > 0; + show_tabs = eel_gconf_get_boolean (CONF_TABS_TABBED) || num > 1; gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), show_tabs); } @@ -926,9 +933,14 @@ ephy_notebook_insert_page (EphyNotebook *nb, int position, gboolean jump_to) { - GtkWidget *tab_hbox; + EphyTab *tab; + GtkWidget *label; - tab_hbox = tab_build_label (nb, child); + g_return_if_fail (IS_EPHY_EMBED (child)); + tab = EPHY_TAB (g_object_get_data (G_OBJECT (child), "EphyTab")); + g_return_if_fail (IS_EPHY_TAB (tab)); + + label = build_tab_label (nb, child); update_tabs_visibility (nb, TRUE); @@ -954,17 +966,28 @@ ephy_notebook_insert_page (EphyNotebook *nb, g_list_append (nb->priv->opened_tabs, child); } - gtk_notebook_insert_page (GTK_NOTEBOOK (nb), - child, - tab_hbox, position); + + gtk_notebook_insert_page (GTK_NOTEBOOK (nb), child, + label, position); /* Set up drag-and-drop target */ - g_signal_connect (G_OBJECT(tab_hbox), "drag_data_received", + g_signal_connect (G_OBJECT(label), "drag_data_received", G_CALLBACK(notebook_drag_data_received_cb), child); - gtk_drag_dest_set (tab_hbox, GTK_DEST_DEFAULT_ALL, + gtk_drag_dest_set (label, GTK_DEST_DEFAULT_ALL, url_drag_types,n_url_drag_types, GDK_ACTION_MOVE | GDK_ACTION_COPY); + sync_icon (tab, NULL, label); + sync_label (tab, NULL, label); + sync_load_status (tab, NULL, label); + + g_signal_connect_object (tab, "notify::icon", + G_CALLBACK (sync_icon), label, 0); + g_signal_connect_object (tab, "notify::title", + G_CALLBACK (sync_label), label, 0); + g_signal_connect_object (tab, "notify::load-status", + G_CALLBACK (sync_load_status), label, 0); + if (jump_to) { gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), @@ -973,7 +996,7 @@ ephy_notebook_insert_page (EphyNotebook *nb, GINT_TO_POINTER (jump_to)); } - g_signal_emit (G_OBJECT (nb), ephy_notebook_signals[TABS_CHANGED], 0); + g_signal_emit (G_OBJECT (nb), signals[TAB_ADDED], 0, child); } static void @@ -1009,16 +1032,18 @@ void ephy_notebook_remove_page (EphyNotebook *nb, GtkWidget *child) { - int position, cur; - gboolean last_tab; - GtkWidget *hbox, *ebox; + int num, position, curr; + EphyTab *tab; + GtkWidget *label, *ebox; - hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), child); - ebox = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label-ebox")); - gtk_tooltips_set_tip (GTK_TOOLTIPS (nb->priv->title_tips), ebox, NULL, NULL); + g_return_if_fail (IS_EPHY_NOTEBOOK (nb)); + g_return_if_fail (IS_EPHY_EMBED (child)); + + tab = EPHY_TAB (g_object_get_data (G_OBJECT (child), "EphyTab")); + g_return_if_fail (IS_EPHY_TAB (tab)); - last_tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), 1) == NULL; - if (last_tab) + num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)); + if (num <= 1) { GtkWidget *window; window = gtk_widget_get_toplevel (GTK_WIDGET (nb)); @@ -1031,34 +1056,29 @@ ephy_notebook_remove_page (EphyNotebook *nb, child); nb->priv->opened_tabs = g_list_remove (nb->priv->opened_tabs, child); + position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), child); + curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); - position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), - child); - - cur = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)); - if (position == cur) + if (position == curr) { smart_tab_switching_on_closure (nb, child); } - gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position); - g_signal_emit (G_OBJECT (nb), ephy_notebook_signals[TABS_CHANGED], 0); + label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), child); + ebox = GTK_WIDGET (g_object_get_data (G_OBJECT (label), "label-ebox")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (nb->priv->title_tips), ebox, NULL, NULL); - update_tabs_visibility (nb, FALSE); -} + g_signal_handlers_disconnect_by_func (label, + G_CALLBACK (sync_icon), tab); + g_signal_handlers_disconnect_by_func (label, + G_CALLBACK (sync_label), tab); + g_signal_handlers_disconnect_by_func (label, + G_CALLBACK (sync_load_status), tab); -void -ephy_notebook_set_page_title (EphyNotebook *nb, - GtkWidget *child, - const char *title) -{ - GtkWidget *hbox, *ebox, *label; - hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), child); + g_signal_emit (G_OBJECT (nb), signals[TAB_REMOVED], 0, child); - label = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label")); - gtk_label_set_label (GTK_LABEL (label), title); + gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position); - ebox = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label-ebox")); - gtk_tooltips_set_tip (GTK_TOOLTIPS (nb->priv->title_tips), ebox, title, NULL); + update_tabs_visibility (nb, FALSE); } diff --git a/src/ephy-notebook.h b/src/ephy-notebook.h index 9ce55f5b3..454f8de10 100644 --- a/src/ephy-notebook.h +++ b/src/ephy-notebook.h @@ -59,15 +59,13 @@ struct EphyNotebookClass GtkNotebookClass parent_class; /* Signals */ - void (* tab_dropped) (EphyNotebook *dest, - GtkWidget *widget, - EphyNotebook *src, - gint src_page); - void (* tab_detached) (EphyNotebook *dest, - gint cur_page, - gint root_x, gint root_y); - void (* tabs_changed) (EphyNotebook *nb); - + void (* tab_added) (EphyNotebook *notebook, + GtkWidget *child); + void (* tab_removed) (EphyNotebook *notebook, + GtkWidget *child); + void (* tab_detached) (EphyNotebook *notebook, + GtkWidget *child); + void (* tabs_reordered) (EphyNotebook *notebook); }; GType ephy_notebook_get_type (void); @@ -87,18 +85,6 @@ void ephy_notebook_move_page (EphyNotebook *src, GtkWidget *src_page, gint dest_page); -void ephy_notebook_set_page_status (EphyNotebook *nb, - GtkWidget *child, - EphyNotebookPageLoadStatus status); - -void ephy_notebook_set_page_title (EphyNotebook *nb, - GtkWidget *child, - const char *title); - -void ephy_notebook_set_page_icon (EphyNotebook *nb, - GtkWidget *child, - GdkPixbuf *icon); - -G_END_DECLS; +G_END_DECLS #endif /* EPHY_NOTEBOOK_H */ diff --git a/src/ephy-tab.c b/src/ephy-tab.c index d1ccf250e..456e7f8b8 100644 --- a/src/ephy-tab.c +++ b/src/ephy-tab.c @@ -52,8 +52,6 @@ struct EphyTabPrivate EphyEmbed *embed; EphyWindow *window; EphyEmbedEvent *event; - gboolean is_active; - TabLoadStatus load_status; char *status_message; char *link_message; char *icon_address; @@ -61,6 +59,7 @@ struct EphyTabPrivate char *title; int load_percent; gboolean visibility; + gboolean load_status; int cur_requests; int total_requests; int width; @@ -68,12 +67,12 @@ struct EphyTabPrivate EggAction *action; float zoom; EmbedSecurityLevel security_level; + TabNavigationFlags nav_flags; }; static void ephy_tab_class_init (EphyTabClass *klass); static void ephy_tab_init (EphyTab *tab); static void ephy_tab_finalize (GObject *object); -static void ephy_tab_update_color (EphyTab *tab); enum { @@ -83,6 +82,7 @@ enum PROP_LOAD_PROGRESS, PROP_LOAD_STATUS, PROP_MESSAGE, + PROP_NAVIGATION, PROP_SECURITY, PROP_TITLE, PROP_WINDOW, @@ -94,19 +94,20 @@ static GObjectClass *parent_class = NULL; static gulong tab_id = 0; /* internal functions, accessible only from this file */ -void ephy_tab_set_icon_address (EphyTab *tab, +static void ephy_tab_set_icon_address (EphyTab *tab, const char *location); -void ephy_tab_set_load_status (EphyTab *tab, - TabLoadStatus status); -void ephy_tab_set_link_message (EphyTab *tab, +static void ephy_tab_set_load_status (EphyTab *tab, + gboolean status); +static void ephy_tab_set_link_message (EphyTab *tab, const char *message); -void ephy_tab_set_load_percent (EphyTab *tab, +static void ephy_tab_set_load_percent (EphyTab *tab, int percent); -void ephy_tab_set_security_level (EphyTab *tab, +static void ephy_tab_update_navigation_flags(EphyTab *tab); +static void ephy_tab_set_security_level (EphyTab *tab, EmbedSecurityLevel level); -void ephy_tab_set_title (EphyTab *tab, +static void ephy_tab_set_title (EphyTab *tab, const char *new_title); -void ephy_tab_set_zoom (EphyTab *tab, +static void ephy_tab_set_zoom (EphyTab *tab, float zoom); /* Class functions */ @@ -160,6 +161,7 @@ ephy_tab_set_property (GObject *object, case PROP_LOAD_PROGRESS: case PROP_LOAD_STATUS: case PROP_MESSAGE: + case PROP_NAVIGATION: case PROP_SECURITY: case PROP_TITLE: case PROP_ZOOM: @@ -188,11 +190,14 @@ ephy_tab_get_property (GObject *object, g_value_set_int (value, tab->priv->load_percent); break; case PROP_LOAD_STATUS: - g_value_set_int (value, tab->priv->load_status); + g_value_set_boolean (value, tab->priv->load_status); break; case PROP_MESSAGE: g_value_set_string (value, ephy_tab_get_status_message (tab)); break; + case PROP_NAVIGATION: + g_value_set_int (value, tab->priv->nav_flags); + break; case PROP_SECURITY: g_value_set_int (value, tab->priv->security_level); break; @@ -255,13 +260,11 @@ ephy_tab_class_init (EphyTabClass *class) g_object_class_install_property (object_class, PROP_LOAD_STATUS, - g_param_spec_int ("load-status", - "Load status", - "The tab's load status", - TAB_LOAD_NONE, - TAB_LOAD_COMPLETED, - TAB_LOAD_NONE, - G_PARAM_READABLE)); + g_param_spec_boolean ("load-status", + "Load status", + "The tab's load status", + FALSE, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_MESSAGE, @@ -272,6 +275,18 @@ ephy_tab_class_init (EphyTabClass *class) G_PARAM_READABLE)); g_object_class_install_property (object_class, + PROP_NAVIGATION, + g_param_spec_int ("navigation", + "Navigation flags", + "The tab's navigation flags", + 0, + TAB_NAV_UP | + TAB_NAV_BACK | + TAB_NAV_FORWARD, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_LOAD_STATUS, g_param_spec_int ("security-level", "Security Level", @@ -317,10 +332,8 @@ ephy_tab_parent_set_cb (GtkWidget *widget, GtkWidget *previous_parent, if (widget->parent == NULL) return; toplevel = gtk_widget_get_toplevel (widget); - - tab->priv->window = EPHY_WINDOW (toplevel); + ephy_tab_set_window (tab, EPHY_WINDOW (toplevel)); } - static void ephy_tab_embed_destroy_cb (GtkWidget *widget, EphyTab *tab) { @@ -376,41 +389,25 @@ ephy_tab_new (void) return tab; } -void -ephy_tab_set_load_status (EphyTab *tab, - TabLoadStatus status) +static void +ephy_tab_set_load_status (EphyTab *tab, gboolean status) { - if (status == TAB_LOAD_COMPLETED) - { - Session *s; - s = ephy_shell_get_session (ephy_shell); - session_save (s, SESSION_CRASHED); - } - - if (ephy_tab_get_is_active (tab) && - status == TAB_LOAD_COMPLETED) - { - tab->priv->load_status = TAB_LOAD_NONE; - } - else - { - tab->priv->load_status = status; - } + g_return_if_fail (IS_EPHY_TAB (tab)); - ephy_tab_update_color (tab); + tab->priv->load_status = status; g_object_notify (G_OBJECT (tab), "load-status"); } -TabLoadStatus +gboolean ephy_tab_get_load_status (EphyTab *tab) { - g_return_val_if_fail (IS_EPHY_TAB (tab), TAB_LOAD_NONE); + g_return_val_if_fail (IS_EPHY_TAB (tab), FALSE); return tab->priv->load_status; } -void +static void ephy_tab_set_link_message (EphyTab *tab, const char *message) { g_return_if_fail (IS_EPHY_TAB (tab)); @@ -443,7 +440,12 @@ ephy_tab_set_window (EphyTab *tab, EphyWindow *window) g_return_if_fail (IS_EPHY_TAB (tab)); if (window) g_return_if_fail (IS_EPHY_WINDOW (window)); - tab->priv->window = window; + if (window != tab->priv->window) + { + tab->priv->window = window; + + g_object_notify (G_OBJECT (tab), "window"); + } } EphyWindow * @@ -457,55 +459,9 @@ ephy_tab_get_window (EphyTab *tab) EphyEmbedEvent * ephy_tab_get_event (EphyTab *tab) { - return tab->priv->event; -} - -static void -ephy_tab_update_color (EphyTab *tab) -{ - TabLoadStatus status = ephy_tab_get_load_status (tab); - EphyNotebookPageLoadStatus page_status = 0; - GtkWidget *nb; - - nb = ephy_window_get_notebook (tab->priv->window); - - switch (status) - { - case TAB_LOAD_NONE: - page_status = EPHY_NOTEBOOK_TAB_LOAD_NORMAL; - break; - case TAB_LOAD_STARTED: - page_status = EPHY_NOTEBOOK_TAB_LOAD_LOADING; - break; - case TAB_LOAD_COMPLETED: - page_status = EPHY_NOTEBOOK_TAB_LOAD_COMPLETED; - break; - } - - ephy_notebook_set_page_status (EPHY_NOTEBOOK (nb), - GTK_WIDGET (tab->priv->embed), - page_status); -} - -void -ephy_tab_set_is_active (EphyTab *tab, gboolean is_active) -{ - g_return_if_fail (IS_EPHY_TAB (tab)); - - tab->priv->is_active = is_active; - - if (tab->priv->load_status == TAB_LOAD_COMPLETED) - { - ephy_tab_set_load_status (tab, TAB_LOAD_NONE); - } -} - -gboolean -ephy_tab_get_is_active (EphyTab *tab) -{ - g_return_val_if_fail (IS_EPHY_TAB (tab), FALSE); + g_return_val_if_fail (IS_EPHY_TAB (tab), NULL); - return tab->priv->is_active; + return tab->priv->event; } void @@ -536,59 +492,32 @@ ephy_tab_set_visibility (EphyTab *tab, } static void -ephy_tab_set_favicon (EphyTab *tab, - GdkPixbuf *favicon) -{ - GtkWidget *nb; - - nb = ephy_window_get_notebook (tab->priv->window); - ephy_notebook_set_page_icon (EPHY_NOTEBOOK (nb), - GTK_WIDGET (tab->priv->embed), - favicon); -} - -static void ephy_tab_icon_cache_changed_cb (EphyFaviconCache *cache, const char *address, EphyTab *tab) { - GdkPixbuf *pixbuf = NULL; + g_return_if_fail (address != NULL); /* is this for us? */ - if (tab->priv->icon_address == NULL || - strcmp (tab->priv->icon_address, address) != 0) return; - - /* notify */ - g_object_notify (G_OBJECT (tab), "icon"); - - /* set favicon */ - if (tab->priv->icon_address) + if (tab->priv->icon_address != NULL && + strcmp (tab->priv->icon_address, address) != 0) { - pixbuf = ephy_favicon_cache_get (cache, tab->priv->icon_address); - ephy_tab_set_favicon (tab, pixbuf); - - if (pixbuf) - { - g_object_unref (pixbuf); - } + /* notify */ + g_object_notify (G_OBJECT (tab), "icon"); } } -void +static void ephy_tab_set_icon_address (EphyTab *tab, const char *address) { EphyBookmarks *eb; EphyHistory *history; - EphyFaviconCache *cache; - GdkPixbuf *pixbuf = NULL; g_return_if_fail (IS_EPHY_TAB (tab)); g_free (tab->priv->icon_address); - tab->priv->icon_address = g_strdup (address); - cache = ephy_embed_shell_get_favicon_cache - (EPHY_EMBED_SHELL (ephy_shell)); + tab->priv->icon_address = g_strdup (address); if (tab->priv->icon_address) { @@ -599,31 +528,15 @@ ephy_tab_set_icon_address (EphyTab *tab, const char *address) tab->priv->icon_address); ephy_history_set_icon (history, tab->priv->address, tab->priv->icon_address); - - pixbuf = ephy_favicon_cache_get (cache, tab->priv->icon_address); - - ephy_tab_set_favicon (tab, pixbuf); - - if (pixbuf) - { - g_object_unref (pixbuf); - } - } - else - { - ephy_tab_set_favicon (tab, NULL); } - ephy_window_update_control (tab->priv->window, - FaviconControl); - g_object_notify (G_OBJECT (tab), "icon"); } const char * ephy_tab_get_icon_address (EphyTab *tab) { - g_return_val_if_fail (IS_EPHY_TAB (tab), ""); + g_return_val_if_fail (IS_EPHY_TAB (tab), NULL); return tab->priv->icon_address; } @@ -643,12 +556,7 @@ ephy_tab_link_message_cb (EphyEmbed *embed, const gchar *message, EphyTab *tab) { - if (!tab->priv->is_active) return; - ephy_tab_set_link_message (tab, message); - - ephy_window_update_control (tab->priv->window, - StatusbarMessageControl); } static void @@ -662,24 +570,13 @@ ephy_tab_address_cb (EphyEmbed *embed, EphyTab *tab) ephy_tab_set_link_message (tab, NULL); ephy_tab_set_icon_address (tab, NULL); - - if (tab->priv->is_active) - { - ephy_window_update_control (tab->priv->window, LocationControl); - ephy_window_update_control (tab->priv->window, NavControl); - ephy_window_update_control (tab->priv->window, FaviconControl); - } + ephy_tab_update_navigation_flags (tab); } static void ephy_tab_zoom_changed_cb (EphyEmbed *embed, float zoom, EphyTab *tab) { ephy_tab_set_zoom (tab, zoom); - - if (tab->priv->is_active) - { - ephy_window_update_control (tab->priv->window, ZoomControl); - } } static void @@ -815,7 +712,6 @@ ensure_address (EphyTab *tab, const char *address) if (tab->priv->address == NULL) { ephy_tab_set_location (tab, address); - ephy_window_update_control (tab->priv->window, LocationControl); } } @@ -828,43 +724,32 @@ ephy_tab_net_state_cb (EphyEmbed *embed, const char *uri, g_object_notify (G_OBJECT (tab), "message"); - ephy_window_update_control (tab->priv->window, StatusbarMessageControl); - if (state & EMBED_STATE_IS_NETWORK) { if (state & EMBED_STATE_START) { tab->priv->total_requests = 0; tab->priv->cur_requests = 0; - ephy_tab_set_load_percent (tab, 0); - ensure_address (tab, uri); - ephy_tab_set_load_status (tab, TAB_LOAD_STARTED); - - ephy_window_update_control (tab->priv->window, - NavControl); - ephy_window_update_control (tab->priv->window, - SpinnerControl); + ephy_tab_set_load_percent (tab, 0); + ephy_tab_set_load_status (tab, TRUE); + ephy_tab_update_navigation_flags (tab); } else if (state & EMBED_STATE_STOP) { - ephy_tab_set_load_percent (tab, 0); - - ephy_tab_set_load_status (tab, TAB_LOAD_COMPLETED); + /* tab load completed, save in session */ + Session *s; + s = ephy_shell_get_session (ephy_shell); + session_save (s, SESSION_CRASHED); - ephy_window_update_control (tab->priv->window, - NavControl); - ephy_window_update_control (tab->priv->window, - SpinnerControl); - ephy_tab_update_color (tab); + ephy_tab_set_load_percent (tab, 0); + ephy_tab_set_load_status (tab, FALSE); + ephy_tab_update_navigation_flags (tab); } } build_progress_from_requests (tab, state); - - ephy_window_update_control (tab->priv->window, - StatusbarProgressControl); } static void @@ -914,14 +799,10 @@ ephy_tab_visibility_cb (EphyEmbed *embed, gboolean visibility, static void ephy_tab_destroy_brsr_cb (EphyEmbed *embed, EphyTab *tab) { - EphyWindow *window; - g_return_if_fail (IS_EPHY_TAB (tab)); g_return_if_fail (tab->priv->window != NULL); - window = ephy_tab_get_window (tab); - - ephy_window_remove_tab (window, tab); + ephy_window_remove_tab (tab->priv->window, tab); ephy_embed_shell_remove_embed (EPHY_EMBED_SHELL (ephy_shell), tab->priv->embed); @@ -1113,11 +994,6 @@ ephy_tab_security_change_cb (EphyEmbed *embed, EmbedSecurityLevel level, EphyTab *tab) { ephy_tab_set_security_level (tab, level); - - if (!tab->priv->is_active) return; - - ephy_window_update_control (tab->priv->window, - StatusbarSecurityControl); } static void @@ -1137,13 +1013,20 @@ ephy_tab_init (EphyTab *tab) tab->priv->window = NULL; tab->priv->event = NULL; - tab->priv->is_active = FALSE; tab->priv->status_message = NULL; tab->priv->link_message = NULL; tab->priv->total_requests = 0; tab->priv->cur_requests = 0; tab->priv->width = -1; tab->priv->height = -1; + tab->priv->address = NULL; + tab->priv->icon_address = NULL; + tab->priv->load_percent = 0; + tab->priv->load_status = FALSE; + tab->priv->link_message = NULL; + tab->priv->security_level = STATE_IS_UNKNOWN; + tab->priv->status_message = NULL; + tab->priv->zoom = 1.0; tab->priv->embed = ephy_embed_new (G_OBJECT(single)); ephy_embed_shell_add_embed (EPHY_EMBED_SHELL (ephy_shell), @@ -1225,9 +1108,12 @@ ephy_tab_set_load_percent (EphyTab *tab, int percent) { g_return_if_fail (IS_EPHY_TAB (tab)); - tab->priv->load_percent = percent; + if (percent != tab->priv->load_percent) + { + tab->priv->load_percent = percent; - g_object_notify (G_OBJECT (tab), "load-progress"); + g_object_notify (G_OBJECT (tab), "load-progress"); + } } int @@ -1238,12 +1124,51 @@ ephy_tab_get_load_percent (EphyTab *tab) return tab->priv->load_percent; } +static void +ephy_tab_update_navigation_flags (EphyTab *tab) +{ + EphyEmbed *embed; + TabNavigationFlags flags = 0; + + embed = tab->priv->embed; + + if (ephy_embed_can_go_up (embed) == G_OK) + { + flags |= TAB_NAV_UP; + } + + if (ephy_embed_can_go_back (embed) == G_OK) + { + flags |= TAB_NAV_BACK; + } + + if (ephy_embed_can_go_forward (embed) == G_OK) + { + flags |= TAB_NAV_FORWARD; + } + + if (flags != tab->priv->nav_flags) + { + tab->priv->nav_flags = flags; + + g_object_notify (G_OBJECT (tab), "navigation"); + } +} + +TabNavigationFlags +ephy_tab_get_navigation_flags (EphyTab *tab) +{ + g_return_val_if_fail (IS_EPHY_TAB (tab), 0); + + return tab->priv->nav_flags; +} + const char * ephy_tab_get_status_message (EphyTab *tab) { g_return_val_if_fail (IS_EPHY_TAB (tab), ""); - if (tab->priv->link_message) + if (tab->priv->link_message && tab->priv->link_message[0] != '\0') { return tab->priv->link_message; } @@ -1259,10 +1184,9 @@ ephy_tab_get_status_message (EphyTab *tab) #define MAX_LABEL_LENGTH 32 -void +static void ephy_tab_set_title (EphyTab *tab, const char *new_title) { - GtkWidget *nb; GnomeVFSURI *uri; char *title_short = NULL; char *title = NULL; @@ -1310,19 +1234,6 @@ ephy_tab_set_title (EphyTab *tab, const char *new_title) g_free (title_short); - if (tab->priv->window != NULL) - { - nb = ephy_window_get_notebook (tab->priv->window); - ephy_notebook_set_page_title (EPHY_NOTEBOOK (nb), - GTK_WIDGET (tab->priv->embed), - tab->priv->title); - - if (tab->priv->is_active) - { - ephy_window_update_control (tab->priv->window, TitleControl); - } - } - g_object_notify (G_OBJECT (tab), "title"); } @@ -1354,7 +1265,7 @@ ephy_tab_set_location (EphyTab *tab, g_object_notify (G_OBJECT (tab), "address"); } -void +static void ephy_tab_set_security_level (EphyTab *tab, EmbedSecurityLevel level) { g_return_if_fail (IS_EPHY_TAB (tab)); @@ -1372,7 +1283,7 @@ ephy_tab_get_security_level (EphyTab *tab) return tab->priv->security_level; } -void +static void ephy_tab_set_zoom (EphyTab *tab, float zoom) { g_return_if_fail (IS_EPHY_TAB (tab)); diff --git a/src/ephy-tab.h b/src/ephy-tab.h index 8b38e8f6d..96b40d6ed 100644 --- a/src/ephy-tab.h +++ b/src/ephy-tab.h @@ -41,10 +41,10 @@ typedef struct EphyTabPrivate EphyTabPrivate; typedef enum { - TAB_LOAD_NONE, - TAB_LOAD_STARTED, - TAB_LOAD_COMPLETED -} TabLoadStatus; + TAB_NAV_UP = 1 << 0, + TAB_NAV_BACK = 1 << 1, + TAB_NAV_FORWARD = 1 << 2, +} TabNavigationFlags; struct EphyTab { @@ -77,13 +77,7 @@ EphyWindow * ephy_tab_get_window (EphyTab *tab); const char * ephy_tab_get_icon_address (EphyTab *tab); -void ephy_tab_set_is_active (EphyTab *tab, - gboolean is_active); - -gboolean ephy_tab_get_is_active (EphyTab *tab); - - -TabLoadStatus ephy_tab_get_load_status (EphyTab *tab); +gboolean ephy_tab_get_load_status (EphyTab *tab); const char * ephy_tab_get_link_message (EphyTab *tab); @@ -94,6 +88,8 @@ void ephy_tab_set_location (EphyTab *tab, const char *location); const char * ephy_tab_get_location (EphyTab *tab); + +TabNavigationFlags ephy_tab_get_navigation_flags (EphyTab *tab); EmbedSecurityLevel ephy_tab_get_security_level (EphyTab *tab); diff --git a/src/ephy-tabs-menu.c b/src/ephy-tabs-menu.c index 972342e41..128e69395 100644 --- a/src/ephy-tabs-menu.c +++ b/src/ephy-tabs-menu.c @@ -241,6 +241,10 @@ tab_set_action_accelerator (EggActionGroup *action_group, accel_mods, TRUE); } } + else + { + gtk_accel_map_change_entry (accel_path, 0, 0, TRUE); + } action->accel_quark = g_quark_from_string (accel_path); g_free (accel_path); diff --git a/src/ephy-window.c b/src/ephy-window.c index 20f9ce60e..6d30ad8bd 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -281,6 +281,7 @@ struct EphyWindowPrivate EphyDialog *find_dialog; EmbedChromeMask chrome_mask; gboolean closing; + guint num_tabs; }; static void @@ -297,10 +298,6 @@ ephy_window_notebook_switch_page_cb (GtkNotebook *notebook, guint page_num, EphyWindow *window); -static void -ephy_window_tab_detached_cb (EphyNotebook *notebook, gint page, - gint x, gint y, gpointer data); - static GObjectClass *parent_class = NULL; GType @@ -430,6 +427,14 @@ menu_activate_cb (GtkWidget *widget, } static void +ephy_window_destroy_cb (GtkWidget *widget, EphyWindow *window) +{ + LOG ("EphyWindow destroy %p", window) + + window->priv->closing = TRUE; +} + +static void setup_window (EphyWindow *window) { EggActionGroup *action_group; @@ -503,6 +508,376 @@ setup_window (EphyWindow *window) "selection-received", G_CALLBACK (ephy_window_selection_received_cb), window); + g_signal_connect (window, "destroy", + G_CALLBACK (ephy_window_destroy_cb), + window); +} + +static void +sync_tab_address (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + const char *address; + + if (window->priv->closing) return; + + address = ephy_tab_get_location (tab); + + if (address == NULL) + { + address = ""; + } + + toolbar_set_location (window->priv->toolbar, address); +} + +static void +sync_tab_icon (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + const char *address; + EphyFaviconCache *cache; + GdkPixbuf *pixbuf = NULL; + + if (window->priv->closing) return; + + cache = ephy_embed_shell_get_favicon_cache + (EPHY_EMBED_SHELL (ephy_shell)); + + address = ephy_tab_get_icon_address (tab); + + if (address) + { + pixbuf = ephy_favicon_cache_get (cache, address); + } + + gtk_window_set_icon (GTK_WINDOW (window), pixbuf); + + toolbar_update_favicon (window->priv->toolbar); + + if (pixbuf) + { + g_object_unref (pixbuf); + } +} + +static void +sync_tab_load_progress (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + if (window->priv->closing) return; + + statusbar_set_progress (STATUSBAR (window->priv->statusbar), + ephy_tab_get_load_percent (tab)); +} + +static void +sync_tab_load_status (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + gboolean spin = FALSE; + GList *tabs, *l; + + if (window->priv->closing) return; + + tabs = ephy_window_get_tabs (window); + for (l = tabs; l != NULL; l = l->next) + { + EphyTab *tab = EPHY_TAB(l->data); + g_return_if_fail (IS_EPHY_TAB(tab)); + + if (ephy_tab_get_load_status (tab)) + { + spin = TRUE; + break; + } + } + g_list_free (tabs); + + if (spin) + { + toolbar_spinner_start (window->priv->toolbar); + } + else + { + toolbar_spinner_stop (window->priv->toolbar); + } +} + +static void +sync_tab_message (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + if (window->priv->closing) return; + + statusbar_set_message (STATUSBAR (window->priv->statusbar), + ephy_tab_get_status_message (tab)); +} + +static void +sync_tab_navigation (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + TabNavigationFlags flags; + EggActionGroup *action_group; + EggAction *action; + gboolean up = FALSE, back = FALSE, forward = FALSE; + + if (window->priv->closing) return; + + flags = ephy_tab_get_navigation_flags (tab); + + if (flags & TAB_NAV_UP) + { + up = TRUE; + } + if (flags & TAB_NAV_BACK) + { + back = TRUE; + } + if (flags & TAB_NAV_FORWARD) + { + forward = TRUE; + } + + action_group = window->priv->action_group; + action = egg_action_group_get_action (action_group, "GoUp"); + g_object_set (action, "sensitive", up, NULL); + action = egg_action_group_get_action (action_group, "GoBack"); + g_object_set (action, "sensitive", back, NULL); + action = egg_action_group_get_action (action_group, "GoForward"); + g_object_set (action, "sensitive", forward, NULL); + + toolbar_update_navigation_actions (window->priv->toolbar, + back, forward, up); +} + +static void +sync_tab_security (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + EphyEmbed *embed; + EmbedSecurityLevel level; + char *description = NULL; + char *state = NULL; + gboolean secure; + char *tooltip; + + if (window->priv->closing) return; + + embed = ephy_tab_get_embed (tab); + + if (ephy_embed_get_security_level (embed, &level, &description) != G_OK) + { + level = STATE_IS_UNKNOWN; + description = NULL; + } + + if (level != ephy_tab_get_security_level (tab)) + { + /* something is VERY wrong here! */ + level = STATE_IS_UNKNOWN; + description = NULL; + } + + secure = FALSE; + switch (level) + { + case STATE_IS_UNKNOWN: + state = _("Unknown"); + break; + case STATE_IS_INSECURE: + state = _("Insecure"); + break; + case STATE_IS_BROKEN: + state = _("Broken"); + break; + case STATE_IS_SECURE_MED: + state = _("Medium"); + secure = TRUE; + break; + case STATE_IS_SECURE_LOW: + state = _("Low"); + secure = TRUE; + break; + case STATE_IS_SECURE_HIGH: + state = _("High"); + secure = TRUE; + break; + default: + g_assert_not_reached (); + break; + } + + if (description != NULL) + { + tooltip = g_strdup_printf (_("Security level: %s\n%s"), + state, description); + g_free (description); + } + else + { + tooltip = g_strdup_printf (_("Security level: %s"), state); + + } + + statusbar_set_security_state (STATUSBAR (window->priv->statusbar), + secure, tooltip); + g_free (tooltip); + +} + +static void +sync_tab_stop (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + EggAction *action; + + if (window->priv->closing) return; + + action = egg_action_group_get_action (window->priv->action_group, "ViewStop"); + + g_object_set (action, "sensitive", ephy_tab_get_load_status (tab), NULL); +} + +static void +sync_tab_title (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + const char *title; + + if (window->priv->closing) return; + + title = ephy_tab_get_title (tab); + + if (title) + { + gtk_window_set_title (GTK_WINDOW(window), + title); + } +} + +static void +sync_tab_zoom (EphyTab *tab, GParamSpec *pspec, EphyWindow *window) +{ + EggActionGroup *action_group; + EggAction *action; + gboolean can_zoom_in = TRUE, can_zoom_out = TRUE, can_zoom_normal = FALSE; + float zoom; + + if (window->priv->closing) return; + + zoom = ephy_tab_get_zoom (tab); + + if (zoom >= ZOOM_MAXIMAL) + { + can_zoom_in = FALSE; + } + if (zoom <= ZOOM_MINIMAL) + { + can_zoom_out = FALSE; + } + if (zoom != 1.0) + { + can_zoom_normal = TRUE; + } + + toolbar_update_zoom (window->priv->toolbar, zoom); + + action_group = window->priv->action_group; + action = egg_action_group_get_action (action_group, "ViewZoomIn"); + g_object_set (action, "sensitive", can_zoom_in, NULL); + action = egg_action_group_get_action (action_group, "ViewZoomOut"); + g_object_set (action, "sensitive", can_zoom_out, NULL); + action = egg_action_group_get_action (action_group, "ViewZoomNormal"); + g_object_set (action, "sensitive", can_zoom_normal, NULL); +} + +static void +ephy_window_set_active_tab (EphyWindow *window, EphyTab *new_tab) +{ + EphyTab *old_tab; + + g_return_if_fail (IS_EPHY_WINDOW (window)); + if (ephy_tab_get_window (new_tab) != window) return; + + old_tab = window->priv->active_tab; + + if (old_tab == new_tab) return; + + if (old_tab) + { + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_address), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_icon), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_load_progress), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_stop), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_message), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_navigation), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_security), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_title), + window); + g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab), + G_CALLBACK (sync_tab_zoom), + window); + } + + window->priv->active_tab = new_tab; + + if (new_tab) + { + sync_tab_address (new_tab, NULL, window); + sync_tab_icon (new_tab, NULL, window); + sync_tab_load_progress (new_tab, NULL, window); + sync_tab_stop (new_tab, NULL, window); + sync_tab_message (new_tab, NULL, window); + sync_tab_navigation (new_tab, NULL, window); + sync_tab_security (new_tab, NULL, window); + sync_tab_title (new_tab, NULL, window); + sync_tab_zoom (new_tab, NULL, window); + + g_signal_connect_object (G_OBJECT (new_tab), + "notify::address", + G_CALLBACK (sync_tab_address), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::icon", + G_CALLBACK (sync_tab_icon), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::load-progress", + G_CALLBACK (sync_tab_load_progress), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::load-status", + G_CALLBACK (sync_tab_stop), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::message", + G_CALLBACK (sync_tab_message), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::navigation", + G_CALLBACK (sync_tab_navigation), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::security-level", + G_CALLBACK (sync_tab_security), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::title", + G_CALLBACK (sync_tab_title), + window, 0); + g_signal_connect_object (G_OBJECT (new_tab), + "notify::zoom", + G_CALLBACK (sync_tab_zoom), + window, 0); + } } static void @@ -537,12 +912,76 @@ update_tabs_menu_sensitivity (EphyWindow *window) } static void -ephy_window_tabs_changed_cb (EphyNotebook *notebook, EphyWindow *window) +update_tabs_menu (EphyWindow *window) { update_tabs_menu_sensitivity (window); ephy_tabs_menu_update (window->priv->tabs_menu); } +static void +tab_added_cb (EphyNotebook *notebook, GtkWidget *child, EphyWindow *window) +{ + EphyTab *tab; + + g_return_if_fail (IS_EPHY_EMBED (child)); + tab = EPHY_TAB (g_object_get_data (G_OBJECT (child), "EphyTab")); + + window->priv->num_tabs++; + + update_tabs_menu (window); + + sync_tab_load_status (tab, NULL, window); + g_signal_connect_object (G_OBJECT (tab), "notify::load-status", + G_CALLBACK (sync_tab_load_status), window, 0); +} + +static void +tab_removed_cb (EphyNotebook *notebook, GtkWidget *child, EphyWindow *window) +{ + EphyTab *tab; + + g_return_if_fail (IS_EPHY_EMBED (child)); + tab = EPHY_TAB (g_object_get_data (G_OBJECT (child), "EphyTab")); + + g_signal_handlers_disconnect_by_func (G_OBJECT (tab), + G_CALLBACK (sync_tab_load_status), + window); + + window->priv->num_tabs--; + + if (window->priv->num_tabs == 0) + { + /* removed the last tab, close the window */ + gtk_widget_destroy (GTK_WIDGET (window)); + } + else + { + update_tabs_menu (window); + } +} + +static void +tab_detached_cb (EphyNotebook *notebook, GtkWidget *child, + gpointer data) +{ + EphyWindow *window; + + g_return_if_fail (IS_EPHY_NOTEBOOK (notebook)); + g_return_if_fail (IS_EPHY_EMBED (child)); + + window = ephy_window_new (); + ephy_notebook_move_page (notebook, + EPHY_NOTEBOOK (ephy_window_get_notebook (window)), + child, 0); + gtk_widget_show (GTK_WIDGET (window)); +} + +static void +tabs_reordered_cb (EphyNotebook *notebook, EphyWindow *window) +{ + update_tabs_menu (window); +} + static GtkNotebook * setup_notebook (EphyWindow *window) { @@ -558,12 +997,14 @@ setup_notebook (EphyWindow *window) ephy_window_notebook_switch_page_cb), window); + g_signal_connect (G_OBJECT (notebook), "tab_added", + G_CALLBACK (tab_added_cb), window); + g_signal_connect (G_OBJECT (notebook), "tab_removed", + G_CALLBACK (tab_removed_cb), window); g_signal_connect (G_OBJECT (notebook), "tab_detached", - G_CALLBACK (ephy_window_tab_detached_cb), - NULL); - g_signal_connect (G_OBJECT (notebook), "tabs_changed", - G_CALLBACK (ephy_window_tabs_changed_cb), - window); + G_CALLBACK (tab_detached_cb), NULL); + g_signal_connect (G_OBJECT (notebook), "tabs_reordered", + G_CALLBACK (tabs_reordered_cb), window); gtk_widget_show (GTK_WIDGET (notebook)); @@ -575,6 +1016,8 @@ ephy_window_init (EphyWindow *window) { Session *session; + LOG ("EphyWindow initialising %p", window) + session = ephy_shell_get_session (ephy_shell); window->priv = g_new0 (EphyWindowPrivate, 1); @@ -583,6 +1026,7 @@ ephy_window_init (EphyWindow *window) window->priv->closing = FALSE; window->priv->ppview_toolbar = NULL; window->priv->exit_fullscreen_popup = NULL; + window->priv->num_tabs = 0; /* Setup the window and connect verbs */ setup_window (window); @@ -936,8 +1380,6 @@ ephy_window_add_tab (EphyWindow *window, g_return_if_fail (IS_EPHY_WINDOW (window)); g_return_if_fail (IS_EPHY_TAB (tab)); - ephy_tab_set_window (tab, window); - widget = GTK_WIDGET(ephy_tab_get_embed (tab)); ephy_notebook_insert_page (EPHY_NOTEBOOK (window->priv->notebook), @@ -960,31 +1402,23 @@ ephy_window_jump_to_tab (EphyWindow *window, } static EphyTab * -get_tab_from_page_num (GtkNotebook *notebook, gint page_num) +real_get_active_tab (EphyWindow *window, int page_num) { EphyTab *tab; GtkWidget *embed_widget; - if (page_num < 0) return NULL; - - embed_widget = gtk_notebook_get_nth_page (notebook, page_num); - - g_return_val_if_fail (GTK_IS_WIDGET (embed_widget), NULL); - tab = g_object_get_data (G_OBJECT (embed_widget), "EphyTab"); - g_return_val_if_fail (IS_EPHY_TAB (G_OBJECT (tab)), NULL); - - return tab; -} - -static EphyTab * -real_get_active_tab (EphyWindow *window, int page_num) -{ if (page_num == -1) { page_num = gtk_notebook_get_current_page (window->priv->notebook); } + embed_widget = gtk_notebook_get_nth_page (window->priv->notebook, + page_num); + + g_return_val_if_fail (GTK_IS_WIDGET (embed_widget), NULL); + tab = g_object_get_data (G_OBJECT (embed_widget), "EphyTab"); + g_return_val_if_fail (IS_EPHY_TAB (tab), NULL); - return get_tab_from_page_num (window->priv->notebook, page_num); + return tab; } void @@ -996,9 +1430,7 @@ ephy_window_remove_tab (EphyWindow *window, g_return_if_fail (IS_EPHY_WINDOW (window)); g_return_if_fail (IS_EPHY_TAB (tab)); - window->priv->active_tab = NULL; - - embed = GTK_WIDGET (ephy_tab_get_embed (tab)); + embed = GTK_WIDGET (ephy_tab_get_embed (tab)); ephy_notebook_remove_page (EPHY_NOTEBOOK (window->priv->notebook), embed); @@ -1063,241 +1495,12 @@ ephy_window_show (GtkWidget *widget) } static void -update_status_message (EphyWindow *window) -{ - const char *message; - EphyTab *tab; - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - message = ephy_tab_get_status_message (tab); - g_return_if_fail (message != NULL); - - statusbar_set_message (STATUSBAR(window->priv->statusbar), - message); -} - -static void -update_progress (EphyWindow *window) -{ - EphyTab *tab; - int load_percent; - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - load_percent = ephy_tab_get_load_percent (tab); - - statusbar_set_progress (STATUSBAR(window->priv->statusbar), - load_percent); -} - -static void -update_security (EphyWindow *window) -{ - EphyEmbed *embed; - EmbedSecurityLevel level; - char *description; - char *state = NULL; - gboolean secure; - char *tooltip; - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - if (ephy_embed_get_security_level (embed, &level, &description) != G_OK) - { - level = STATE_IS_UNKNOWN; - description = NULL; - } - - secure = FALSE; - switch (level) - { - case STATE_IS_UNKNOWN: - state = _("Unknown"); - break; - case STATE_IS_INSECURE: - state = _("Insecure"); - break; - case STATE_IS_BROKEN: - state = _("Broken"); - break; - case STATE_IS_SECURE_MED: - state = _("Medium"); - secure = TRUE; - break; - case STATE_IS_SECURE_LOW: - state = _("Low"); - secure = TRUE; - break; - case STATE_IS_SECURE_HIGH: - state = _("High"); - secure = TRUE; - break; - default: - g_assert_not_reached (); - break; - } - - if (description != NULL) - { - tooltip = g_strdup_printf (_("Security level: %s\n%s"), - state, description); - g_free (description); - } - else - { - tooltip = g_strdup_printf (_("Security level: %s"), state); - - } - - statusbar_set_security_state (STATUSBAR (window->priv->statusbar), - secure, tooltip); - g_free (tooltip); -} - -static void -update_nav_control (EphyWindow *window) -{ - gresult back, forward, up, stop; - EphyEmbed *embed; - EphyTab *tab; - EggActionGroup *action_group; - EggAction *action; - - g_return_if_fail (window != NULL); - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - back = ephy_embed_can_go_back (embed); - forward = ephy_embed_can_go_forward (embed); - up = ephy_embed_can_go_up (embed); - stop = ephy_tab_get_load_status (tab) & TAB_LOAD_STARTED; - - action_group = window->priv->action_group; - action = egg_action_group_get_action (action_group, "GoBack"); - g_object_set (action, "sensitive", !back, NULL); - action = egg_action_group_get_action (action_group, "GoForward"); - g_object_set (action, "sensitive", !forward, NULL); - action = egg_action_group_get_action (action_group, "GoUp"); - g_object_set (action, "sensitive", !up, NULL); - action = egg_action_group_get_action (action_group, "ViewStop"); - g_object_set (action, "sensitive", stop, NULL); - - toolbar_update_navigation_actions (window->priv->toolbar, - back, forward, up); -} - -static void -update_zoom_control (EphyWindow *window) -{ - EphyEmbed *embed; - EggActionGroup *action_group; - EggAction *action; - gboolean can_zoom_in = TRUE, can_zoom_out = TRUE, can_zoom_normal = FALSE; - float zoom = 1.0; - gresult rv; - - g_return_if_fail (window != NULL); - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (embed != NULL); - - rv = ephy_embed_zoom_get (embed, &zoom); - if (rv == G_OK) - { - if (zoom >= ZOOM_MAXIMAL) can_zoom_in = FALSE; - if (zoom <= ZOOM_MINIMAL) can_zoom_out = FALSE; - if (zoom != 1.0) can_zoom_normal = TRUE; - } - - toolbar_update_zoom (window->priv->toolbar, zoom); - - action_group = window->priv->action_group; - action = egg_action_group_get_action (action_group, "ViewZoomIn"); - g_object_set (action, "sensitive", can_zoom_in, NULL); - action = egg_action_group_get_action (action_group, "ViewZoomOut"); - g_object_set (action, "sensitive", can_zoom_out, NULL); - action = egg_action_group_get_action (action_group, "ViewZoomNormal"); - g_object_set (action, "sensitive", can_zoom_normal, NULL); -} - -static void -update_title_control (EphyWindow *window) -{ - EphyTab *tab; - const char *title; - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - title = ephy_tab_get_title (tab); - - if (title) - { - gtk_window_set_title (GTK_WINDOW(window), - title); - } -} - -static void -update_location_control (EphyWindow *window) -{ - EphyTab *tab; - const char *location; - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - location = ephy_tab_get_location (tab); - - if (!location) location = ""; - - toolbar_set_location (window->priv->toolbar, location); -} - -static void update_favorites_control (EphyWindow *window) { ephy_favorites_menu_update (window->priv->fav_menu); } static void -update_favicon_control (EphyWindow *window) -{ - const char *location; - EphyFaviconCache *cache; - GdkPixbuf *pixbuf = NULL; - EphyTab *tab; - - tab = ephy_window_get_active_tab (window); - g_return_if_fail (tab != NULL); - - cache = ephy_embed_shell_get_favicon_cache - (EPHY_EMBED_SHELL (ephy_shell)); - - location = ephy_tab_get_icon_address (tab); - if (location) - { - pixbuf = ephy_favicon_cache_get (cache, location); - } - gtk_window_set_icon (GTK_WINDOW (window), pixbuf); - - toolbar_update_favicon (window->priv->toolbar); - - if (pixbuf) - { - g_object_unref (pixbuf); - } -} - -static void update_find_control (EphyWindow *window) { gboolean can_go_next, can_go_prev; @@ -1341,35 +1544,6 @@ update_window_visibility (EphyWindow *window) } } -static void -update_spinner_control (EphyWindow *window) -{ - GList *l, *tabs; - gboolean spin = FALSE; - - tabs = ephy_window_get_tabs (window); - for (l = tabs; l != NULL; l = l->next) - { - EphyTab *tab = EPHY_TAB(l->data); - g_return_if_fail (IS_EPHY_TAB(tab)); - - if (ephy_tab_get_load_status (tab) & TAB_LOAD_STARTED) - { - spin = TRUE; - } - } - g_list_free (tabs); - - if (spin) - { - toolbar_spinner_start (window->priv->toolbar); - } - else - { - toolbar_spinner_stop (window->priv->toolbar); - } -} - void ephy_window_update_control (EphyWindow *window, ControlID control) @@ -1378,41 +1552,12 @@ ephy_window_update_control (EphyWindow *window, switch (control) { - case StatusbarMessageControl: - update_status_message (window); - break; - case StatusbarProgressControl: - update_progress (window); - break; - case StatusbarSecurityControl: - update_security (window); - break; case FindControl: update_find_control (window); break; - case ZoomControl: - /* the zoom control is updated at the same time than the navigation - controls. This keeps it synched most of the time, but not always, - because we don't get a notification when zoom changes */ - update_zoom_control (window); - case NavControl: - update_nav_control (window); - break; - case TitleControl: - update_title_control (window); - break; case WindowVisibilityControl: update_window_visibility (window); break; - case SpinnerControl: - update_spinner_control (window); - break; - case LocationControl: - update_location_control (window); - break; - case FaviconControl: - update_favicon_control (window); - break; case FavoritesControl: update_favorites_control (window); break; @@ -1429,16 +1574,7 @@ ephy_window_update_all_controls (EphyWindow *window) if (ephy_window_get_active_tab (window) != NULL) { - update_nav_control (window); - update_title_control (window); - update_location_control (window); - update_favicon_control (window); - update_status_message (window); - update_progress (window); - update_security (window); update_find_control (window); - update_spinner_control (window); - update_zoom_control (window); } } @@ -1446,6 +1582,7 @@ EphyTab * ephy_window_get_active_tab (EphyWindow *window) { g_return_val_if_fail (IS_EPHY_WINDOW (window), NULL); + g_return_val_if_fail (window->priv->active_tab != NULL, NULL); return window->priv->active_tab; } @@ -1455,15 +1592,16 @@ ephy_window_get_active_embed (EphyWindow *window) { EphyTab *tab; + g_return_val_if_fail (IS_EPHY_WINDOW (window), NULL); + tab = ephy_window_get_active_tab (window); if (tab) { - g_return_val_if_fail (IS_EPHY_WINDOW (G_OBJECT (window)), - NULL); return ephy_tab_get_embed (tab); } - else return NULL; + + return NULL; } GList * @@ -1533,13 +1671,11 @@ ephy_window_notebook_switch_page_cb (GtkNotebook *notebook, if (old_tab && tab != old_tab) { g_return_if_fail (IS_EPHY_TAB (G_OBJECT (old_tab))); - ephy_tab_set_is_active (old_tab, FALSE); save_old_embed_status (old_tab, window); } /* update new tab */ - window->priv->active_tab = tab; - ephy_tab_set_is_active (tab, TRUE); + ephy_window_set_active_tab (window, tab); update_embed_dialogs (window, tab); @@ -1613,22 +1749,3 @@ ephy_window_get_toolbar (EphyWindow *window) { return window->priv->toolbar; } - -static void -ephy_window_tab_detached_cb (EphyNotebook *notebook, gint page, - gint x, gint y, gpointer data) -{ - EphyTab *tab; - EphyWindow *window; - GtkWidget *src_page; - - src_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page); - tab = get_tab_from_page_num (GTK_NOTEBOOK (notebook), page); - window = ephy_window_new (); - ephy_notebook_move_page (notebook, - EPHY_NOTEBOOK (ephy_window_get_notebook (window)), - src_page, 0); - ephy_tab_set_window (tab, window); - gtk_widget_show (GTK_WIDGET (window)); -} - diff --git a/src/ephy-window.h b/src/ephy-window.h index 839c7f569..abb643eaf 100644 --- a/src/ephy-window.h +++ b/src/ephy-window.h @@ -62,20 +62,8 @@ typedef enum typedef enum { - NavControl, FindControl, - ZoomControl, - EncodingsControl, - TitleControl, - LocationControl, - FaviconControl, - StatusbarSecurityControl, - StatusbarMessageControl, - StatusbarProgressControl, - SpinnerControl, WindowVisibilityControl, - BMAndHistoryControl, - TabsAppeareanceControl, FavoritesControl } ControlID; diff --git a/src/toolbar.c b/src/toolbar.c index 1601953cd..a1ca442cb 100755 --- a/src/toolbar.c +++ b/src/toolbar.c @@ -686,11 +686,11 @@ toolbar_update_navigation_actions (Toolbar *t, gboolean back, gboolean forward, action_group = t->priv->action_group; action = egg_action_group_get_action (action_group, "NavigationBack"); - g_object_set (action, "sensitive", !back, NULL); + g_object_set (action, "sensitive", back, NULL); action = egg_action_group_get_action (action_group, "NavigationForward"); - g_object_set (action, "sensitive", !forward, NULL); + g_object_set (action, "sensitive", forward, NULL); action = egg_action_group_get_action (action_group, "NavigationUp"); - g_object_set (action, "sensitive", !up, NULL); + g_object_set (action, "sensitive", up, NULL); } void |