diff options
author | Shaun McCance <shaunm@gnome.org> | 2010-03-15 12:33:39 -0500 |
---|---|---|
committer | Shaun McCance <shaunm@gnome.org> | 2010-03-15 12:33:39 -0500 |
commit | 1d71f9cf026fc62911a9cda8989ca96e709a9dbe (patch) | |
tree | 64a395c92c8bf48448b5ad7f40ec1514b55a257b | |
parent | b519e961e8f8c6139f0ccf70bddfbc29c3f6c9e9 (diff) | |
download | yelp-1d71f9cf026fc62911a9cda8989ca96e709a9dbe.tar.gz |
[yelp-window.c] Implement basic back button
-rw-r--r-- | src/yelp-window.c | 123 |
1 files changed, 117 insertions, 6 deletions
diff --git a/src/yelp-window.c b/src/yelp-window.c index 9b07e2e7..4ec84adc 100644 --- a/src/yelp-window.c +++ b/src/yelp-window.c @@ -28,6 +28,7 @@ #include <gtk/gtk.h> #include "yelp-location-entry.h" +#include "yelp-settings.h" #include "yelp-uri.h" #include "yelp-view.h" @@ -42,6 +43,9 @@ static void yelp_window_finalize (GObject *object); static void entry_location_selected (YelpLocationEntry *entry, YelpWindow *window); +static void back_button_clicked (GtkWidget *button, + YelpWindow *window); + static void view_uri_selected (YelpView *view, GParamSpec *pspec, YelpWindow *window); @@ -64,6 +68,23 @@ enum { COL_TERMS }; +typedef struct _YelpBackEntry YelpBackEntry; +struct _YelpBackEntry { + YelpUri *uri; + gchar *title; + gchar *desc; +}; +static void +back_entry_free (YelpBackEntry *back) +{ + if (back == NULL) + return; + g_object_unref (back->uri); + g_free (back->title); + g_free (back->desc); + g_free (back); +} + typedef struct _YelpWindowPrivate YelpWindowPrivate; struct _YelpWindowPrivate { GtkListStore *history; @@ -71,6 +92,10 @@ struct _YelpWindowPrivate { /* no refs on these, owned by containers */ YelpView *view; YelpLocationEntry *entry; + GtkWidget *back_button; + + GSList *back_list; + gboolean back_load; gulong entry_location_selected; }; @@ -78,7 +103,7 @@ struct _YelpWindowPrivate { static void yelp_window_init (YelpWindow *window) { - GtkWidget *vbox, *hbox, *scroll; + GtkWidget *vbox, *hbox, *scroll, *align;; YelpWindowPrivate *priv = GET_PRIV (window); gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_UTILITY); @@ -87,8 +112,12 @@ yelp_window_init (YelpWindow *window) vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), vbox); - hbox = gtk_vbox_new (FALSE, 6); + hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + priv->back_button = (GtkWidget *) gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK); + g_signal_connect (priv->back_button, "clicked", back_button_clicked, window); + gtk_box_pack_start (GTK_BOX (hbox), priv->back_button, FALSE, FALSE, 0); priv->history = gtk_list_store_new (6, G_TYPE_STRING, /* title */ @@ -106,7 +135,9 @@ yelp_window_init (YelpWindow *window) COL_FLAGS); priv->entry_location_selected = g_signal_connect (priv->entry, "location-selected", G_CALLBACK (entry_location_selected), window); - gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (priv->entry), TRUE, TRUE, 0); + align = gtk_alignment_new (0.0, 0.5, 1.0, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (align), TRUE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (priv->entry)); scroll = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), @@ -136,6 +167,18 @@ yelp_window_class_init (YelpWindowClass *klass) static void yelp_window_dispose (GObject *object) { + YelpWindowPrivate *priv = GET_PRIV (object); + + if (priv->history) { + g_object_unref (priv->history); + priv->history = NULL; + } + + while (priv->back_list) { + back_entry_free ((YelpBackEntry *) priv->back_list->data); + priv->back_list = g_slist_delete_link (priv->back_list, priv->back_list); + } + G_OBJECT_CLASS (yelp_window_parent_class)->dispose (object); } @@ -186,6 +229,25 @@ entry_location_selected (YelpLocationEntry *entry, } static void +back_button_clicked (GtkWidget *button, + YelpWindow *window) +{ + YelpWindowPrivate *priv = GET_PRIV (window); + + if (priv->back_list == NULL) + return; + + back_entry_free ((YelpBackEntry *) priv->back_list->data); + priv->back_list = g_slist_delete_link (priv->back_list, priv->back_list); + + if (priv->back_list == NULL || priv->back_list->data == NULL) + return; + + priv->back_load = TRUE; + yelp_window_load_uri (window, ((YelpBackEntry *) priv->back_list->data)->uri); +} + +static void view_uri_selected (YelpView *view, GParamSpec *pspec, YelpWindow *window) @@ -195,12 +257,39 @@ view_uri_selected (YelpView *view, gboolean cont; YelpUri *uri; gchar *struri; + YelpBackEntry *back; YelpWindowPrivate *priv = GET_PRIV (window); g_object_get (G_OBJECT (view), "yelp-uri", &uri, NULL); if (uri == NULL) return; + back = g_new0 (YelpBackEntry, 1); + back->uri = g_object_ref (uri); + if (!priv->back_load) + priv->back_list = g_slist_prepend (priv->back_list, back); + priv->back_load = FALSE; + gtk_widget_set_sensitive (priv->back_button, FALSE); + gtk_widget_set_tooltip_text (priv->back_button, ""); + if (priv->back_list->next && priv->back_list->next->data) { + gchar *tooltip = ""; + YelpBackEntry *back = priv->back_list->next->data; + + gtk_widget_set_sensitive (priv->back_button, TRUE); + if (back->title && back->desc) { + gchar *color; + color = yelp_settings_get_color (yelp_settings_get_default (), + YELP_SETTINGS_COLOR_TEXT_LIGHT); + tooltip = g_markup_printf_escaped ("<span size='larger'>%s</span>\n<span color='%s'>%s</span>", + back->title, color, back->desc); + g_free (color); + } + else if (back->title) + tooltip = g_markup_printf_escaped ("<span size='larger'>%s</span>", + back->title); + gtk_widget_set_tooltip_markup (priv->back_button, tooltip); + } + struri = yelp_uri_get_canonical_uri (uri); cont = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &iter); @@ -248,6 +337,7 @@ view_page_title (YelpView *view, GtkTreeIter first; gchar *title, *frag; YelpUri *uri; + YelpBackEntry *back = NULL; YelpWindowPrivate *priv = GET_PRIV (window); g_object_get (view, "page-title", &title, NULL); @@ -257,19 +347,32 @@ view_page_title (YelpView *view, g_object_get (view, "yelp-uri", &uri, NULL); frag = yelp_uri_get_frag_id (uri); + if (priv->back_list) + back = priv->back_list->data; + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &first); if (frag) { gchar *tmp = g_strdup_printf ("%s (#%s)", title, frag); gtk_list_store_set (priv->history, &first, COL_TITLE, tmp, -1); - g_free (tmp); + if (back) { + g_free (back->title); + back->title = tmp; + } + else { + g_free (tmp); + } g_free (frag); } else { gtk_list_store_set (priv->history, &first, COL_TITLE, title, -1); + if (back) { + g_free (back->title); + back->title = g_strdup (title); + } } g_object_unref (uri); @@ -277,19 +380,27 @@ view_page_title (YelpView *view, static void view_page_desc (YelpView *view, - GParamSpec *pspec, - YelpWindow *window) + GParamSpec *pspec, + YelpWindow *window) { GtkTreeIter first; gchar *desc; + YelpBackEntry *back = NULL; YelpWindowPrivate *priv = GET_PRIV (window); g_object_get (view, "page-desc", &desc, NULL); if (desc == NULL) return; + if (priv->back_list) + back = priv->back_list->data; + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &first); gtk_list_store_set (priv->history, &first, COL_DESC, desc, -1); + if (back) { + g_free (back->desc); + back->desc = g_strdup (desc); + } } |