[yelp/yelp-3-0] [yelp-window.c] Implement basic back button



commit 1d71f9cf026fc62911a9cda8989ca96e709a9dbe
Author: Shaun McCance <shaunm gnome org>
Date:   Mon Mar 15 12:33:39 2010 -0500

    [yelp-window.c] Implement basic back button

 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 9b07e2e..4ec84ad 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);
+    }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]