summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2010-03-15 12:33:39 -0500
committerShaun McCance <shaunm@gnome.org>2010-03-15 12:33:39 -0500
commit1d71f9cf026fc62911a9cda8989ca96e709a9dbe (patch)
tree64a395c92c8bf48448b5ad7f40ec1514b55a257b
parentb519e961e8f8c6139f0ccf70bddfbc29c3f6c9e9 (diff)
downloadyelp-1d71f9cf026fc62911a9cda8989ca96e709a9dbe.tar.gz
[yelp-window.c] Implement basic back button
-rw-r--r--src/yelp-window.c123
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);
+ }
}