[yelp] [libyelp] Show bookmarks in location entry with YelpBookmarks
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp] [libyelp] Show bookmarks in location entry with YelpBookmarks
- Date: Tue, 10 Aug 2010 16:04:24 +0000 (UTC)
commit c799c996a8a679631d45c0a08e8a7c8d73e279e5
Author: Shaun McCance <shaunm gnome org>
Date: Tue Aug 10 12:03:39 2010 -0400
[libyelp] Show bookmarks in location entry with YelpBookmarks
The bookmarks are managed by the application, not libyelp, so we need a way for
the application to tell libyelp about bookmarks. Add a YelpBookmarks interface,
which is implemented by YelpApplication. Then we can pass a YelpBookmarks to
any libyelp class that needs it.
Still need to hook up the bookmarks-changed signal and do something useful when
the bookmark-new icon is clicked.
libyelp/Makefile.am | 2 +
libyelp/yelp-bookmarks.c | 86 +++++++++
libyelp/yelp-bookmarks.h | 74 ++++++++
libyelp/yelp-location-entry.c | 390 +++++++++++++++++++++++------------------
libyelp/yelp-location-entry.h | 32 +---
libyelp/yelp-settings.c | 5 +
src/yelp-application.c | 51 +++++-
src/yelp-application.h | 3 +
src/yelp-window.c | 3 +-
9 files changed, 437 insertions(+), 209 deletions(-)
---
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 01217d1..7aa7907 100644
--- a/libyelp/Makefile.am
+++ b/libyelp/Makefile.am
@@ -1,6 +1,7 @@
lib_LTLIBRARIES = libyelp.la
libyelp_la_SOURCES = \
+ yelp-bookmarks.c \
yelp-debug.c \
yelp-error.c \
yelp-docbook-document.c \
@@ -51,6 +52,7 @@ libyelp_la_LIBADD = \
$(YELP_LIBS)
libyelp_headers = \
+ yelp-bookmarks.h \
yelp-docbook-document.h \
yelp-document.h \
yelp-info-document.h \
diff --git a/libyelp/yelp-bookmarks.c b/libyelp/yelp-bookmarks.c
new file mode 100644
index 0000000..e68d8a8
--- /dev/null
+++ b/libyelp/yelp-bookmarks.c
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "yelp-bookmarks.h"
+
+enum {
+ BOOKMARKS_CHANGED,
+ LAST_SIGNAL
+};
+
+G_DEFINE_INTERFACE (YelpBookmarks, yelp_bookmarks, G_TYPE_OBJECT)
+
+static void
+yelp_bookmarks_default_init (YelpBookmarksInterface *iface)
+{
+}
+
+void
+yelp_bookmarks_add_bookmark (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id,
+ const gchar *icon,
+ const gchar *title)
+{
+ YelpBookmarksInterface *iface;
+
+ g_return_if_fail (YELP_IS_BOOKMARKS (bookmarks));
+
+ iface = YELP_BOOKMARKS_GET_INTERFACE (bookmarks);
+
+ if (iface->add_bookmark)
+ (* iface->add_bookmark) (bookmarks,
+ doc_uri, page_id,
+ icon, title);
+}
+
+void
+yelp_bookmarks_remove_bookmark (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id)
+{
+ YelpBookmarksInterface *iface;
+
+ g_return_if_fail (YELP_IS_BOOKMARKS (bookmarks));
+
+ iface = YELP_BOOKMARKS_GET_INTERFACE (bookmarks);
+
+ if (iface->remove_bookmark)
+ (* iface->remove_bookmark) (bookmarks, doc_uri, page_id);
+}
+
+gboolean
+yelp_bookmarks_is_bookmarked (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id)
+{
+ YelpBookmarksInterface *iface;
+
+ g_return_if_fail (YELP_IS_BOOKMARKS (bookmarks));
+
+ iface = YELP_BOOKMARKS_GET_INTERFACE (bookmarks);
+
+ if (iface->is_bookmarked)
+ return (* iface->is_bookmarked) (bookmarks, doc_uri, page_id);
+ else
+ return FALSE;
+}
diff --git a/libyelp/yelp-bookmarks.h b/libyelp/yelp-bookmarks.h
new file mode 100644
index 0000000..4c02518
--- /dev/null
+++ b/libyelp/yelp-bookmarks.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_BOOKMARKS_H__
+#define __YELP_BOOKMARKS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_BOOKMARKS (yelp_bookmarks_get_type ())
+#define YELP_BOOKMARKS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YELP_TYPE_BOOKMARKS, YelpBookmarks))
+#define YELP_IS_BOOKMARKS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YELP_TYPE_BOOKMARKS))
+#define YELP_BOOKMARKS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), YELP_TYPE_BOOKMARKS, YelpBookmarksInterface))
+
+typedef struct _YelpBookmarks YelpBookmarks;
+typedef struct _YelpBookmarksInterface YelpBookmarksInterface;
+
+struct _YelpBookmarksInterface
+{
+ GTypeInterface g_iface;
+
+ /* Signals */
+ void (* bookmarks_changed) (YelpBookmarks *bookmarks);
+
+ /* Virtual Table */
+ void (* add_bookmark) (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id,
+ const gchar *icon,
+ const gchar *title);
+ void (* remove_bookmark) (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id);
+ gboolean (* is_bookmarked) (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id);
+};
+
+GType yelp_bookmarks_get_type (void);
+void yelp_bookmarks_add_bookmark (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id,
+ const gchar *icon,
+ const gchar *title);
+void yelp_bookmarks_remove_bookmark (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id);
+gboolean yelp_bookmarks_is_bookmarked (YelpBookmarks *bookmarks,
+ const gchar *doc_uri,
+ const gchar *page_id);
+
+G_END_DECLS
+
+#endif /* __YELP_BOOKMARKS_H__ */
diff --git a/libyelp/yelp-location-entry.c b/libyelp/yelp-location-entry.c
index 86e1ab1..61fd456 100644
--- a/libyelp/yelp-location-entry.c
+++ b/libyelp/yelp-location-entry.c
@@ -172,7 +172,9 @@ typedef struct _YelpLocationEntryPrivate YelpLocationEntryPrivate;
struct _YelpLocationEntryPrivate
{
YelpView *view;
+ YelpBookmarks *bookmarks;
GtkTreeRowReference *row;
+ gchar *completion_uri;
/* do not free below */
GtkWidget *text_entry;
@@ -181,7 +183,6 @@ struct _YelpLocationEntryPrivate
GtkEntryCompletion *completion;
gboolean enable_search;
- gboolean enable_bookmarks;
gboolean view_uri_selected;
@@ -190,6 +191,12 @@ struct _YelpLocationEntryPrivate
};
enum {
+ LOCATION_ENTRY_IS_LOADING = 1 << 0,
+ LOCATION_ENTRY_IS_SEPARATOR = 1 << 1,
+ LOCATION_ENTRY_IS_SEARCH = 1 << 2
+};
+
+enum {
HISTORY_COL_TITLE,
HISTORY_COL_DESC,
HISTORY_COL_ICON,
@@ -209,20 +216,19 @@ enum {
};
enum {
- LOCATION_SELECTED,
- SEARCH_ACTIVATED,
- BOOKMARK_CLICKED,
- LAST_SIGNAL
+ LOCATION_SELECTED,
+ SEARCH_ACTIVATED,
+ BOOKMARK_CLICKED,
+ LAST_SIGNAL
};
enum {
- PROP_0,
- PROP_VIEW,
- PROP_ENABLE_SEARCH,
- PROP_ENABLE_BOOKMARKS
+ PROP_0,
+ PROP_VIEW,
+ PROP_BOOKMARKS,
+ PROP_ENABLE_SEARCH
};
-static GHashTable *bookmarks;
static GHashTable *completions;
static guint location_entry_signals[LAST_SIGNAL] = {0,};
@@ -319,6 +325,22 @@ yelp_location_entry_class_init (YelpLocationEntryClass *klass)
G_PARAM_STATIC_STRINGS));
/**
+ * YelpLocationEntry:bookmarks
+ *
+ * An instance of an implementation of YelpBookmarks to provide
+ * bookmark information for this location entry.
+ **/
+ g_object_class_install_property (object_class,
+ PROP_BOOKMARKS,
+ g_param_spec_object ("bookmarks",
+ _("Bookmarks"),
+ _("A YelpBookmarks implementation instance"),
+ YELP_TYPE_BOOKMARKS,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* YelpLocationEntry:enable-search
*
* Whether the location entry can act as a search entry. If search is not
@@ -335,46 +357,30 @@ yelp_location_entry_class_init (YelpLocationEntryClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
- /**
- * YelpLocationEntry:enable-bookmarks
- *
- * Whether the location entry should show bookmark icons. If bookmarks
- * are enabled, the location entry will show an "add bookmark" icon on the
- * active location if it is not bookmarked and show bookmark flags next to
- * rows in the history and completion drop-downs for locations that are
- * bookmarked. Use yelp_location_entry_add_bookmark() and
- * yelp_location_entry_remove_bookmark() to manage bookmarks.
- **/
- g_object_class_install_property (object_class,
- PROP_ENABLE_BOOKMARKS,
- g_param_spec_boolean ("enable-bookmarks",
- N_("Enable Bookmarks"),
- N_("Whether the location entry should show bookmark icons"),
- TRUE,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
g_type_class_add_private ((GObjectClass *) klass,
sizeof (YelpLocationEntryPrivate));
- bookmarks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
completions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
static void
yelp_location_entry_init (YelpLocationEntry *entry)
{
- GtkCellRenderer *bookmark_cell;
- GList *cells;
YelpLocationEntryPrivate *priv = GET_PRIV (entry);
-
priv->search_mode = FALSE;
-
g_object_set (entry, "text-column", HISTORY_COL_TITLE, NULL);
+}
+
+static void
+location_entry_constructed (GObject *object)
+{
+ GtkCellRenderer *bookmark_cell;
+ GList *cells;
+ GtkTreeIter iter;
+ YelpLocationEntryPrivate *priv = GET_PRIV (object);
/* Set up the text entry child */
- priv->text_entry = gtk_bin_get_child (GTK_BIN (entry));
+ priv->text_entry = gtk_bin_get_child (GTK_BIN (object));
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
GTK_ENTRY_ICON_PRIMARY,
"help-browser");
@@ -384,6 +390,12 @@ yelp_location_entry_init (YelpLocationEntry *entry)
gtk_entry_set_icon_activatable (GTK_ENTRY (priv->text_entry),
GTK_ENTRY_ICON_SECONDARY,
TRUE);
+ gtk_editable_set_editable (GTK_EDITABLE (priv->text_entry),
+ priv->enable_search);
+ if (!priv->enable_search) {
+ priv->search_mode = FALSE;
+ location_entry_set_entry ((YelpLocationEntry *) object, FALSE);
+ }
/* Set up the history model */
priv->history = gtk_list_store_new (8,
@@ -398,8 +410,20 @@ yelp_location_entry_init (YelpLocationEntry *entry)
);
g_signal_connect (priv->history, "row-changed",
G_CALLBACK (history_row_changed),
- entry);
- g_object_set (entry, "model", priv->history, NULL);
+ object);
+ g_object_set (object, "model", priv->history, NULL);
+ if (priv->enable_search) {
+ gtk_list_store_append (priv->history, &iter);
+ gtk_list_store_set (priv->history, &iter,
+ HISTORY_COL_FLAGS, LOCATION_ENTRY_IS_SEPARATOR,
+ -1);
+ gtk_list_store_append (priv->history, &iter);
+ gtk_list_store_set (priv->history, &iter,
+ HISTORY_COL_ICON, "system-search",
+ HISTORY_COL_TITLE, _("Search..."),
+ HISTORY_COL_FLAGS, LOCATION_ENTRY_IS_SEARCH,
+ -1);
+ }
/* Set up the history drop-down */
/* Trying to get the text to line up with the text in the GtkEntry.
@@ -407,71 +431,56 @@ yelp_location_entry_init (YelpLocationEntry *entry)
* yet called reorder. I realize using a guesstimate pixel value
* won't be perfect all the time, but 4 looks niceish.
*/
- cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (entry));
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (object));
g_object_set (cells->data, "xpad", 4, NULL);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (object),
GTK_CELL_RENDERER (cells->data),
(GtkCellLayoutDataFunc) cell_set_text_cell,
- entry, NULL);
+ object, NULL);
g_object_set (cells->data, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
g_list_free (cells);
priv->icon_cell = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (entry), priv->icon_cell, FALSE);
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (object), priv->icon_cell, FALSE);
g_object_set (priv->icon_cell, "yalign", 0.2, NULL);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (entry),
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (object),
priv->icon_cell,
"icon-name",
HISTORY_COL_ICON,
NULL);
-
- gtk_cell_layout_reorder (GTK_CELL_LAYOUT (entry), priv->icon_cell, 0);
-
- bookmark_cell = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (entry), bookmark_cell, FALSE);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
- bookmark_cell,
- (GtkCellLayoutDataFunc) cell_set_bookmark_icon,
- entry, NULL);
+ gtk_cell_layout_reorder (GTK_CELL_LAYOUT (object), priv->icon_cell, 0);
+
+ if (priv->bookmarks) {
+ bookmark_cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (object), bookmark_cell, FALSE);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (object),
+ bookmark_cell,
+ (GtkCellLayoutDataFunc) cell_set_bookmark_icon,
+ object, NULL);
+ }
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (object),
+ (GtkTreeViewRowSeparatorFunc)
+ combo_box_row_separator_func,
+ object, NULL);
+ /* Without this, you get a warning about the popup widget
+ * being NULL the firt time you click the arrow.
+ */
+ gtk_widget_show_all (GTK_WIDGET (object));
/* Connect signals */
- g_signal_connect (entry, "changed",
+ g_signal_connect (object, "changed",
G_CALLBACK (combo_box_changed_cb), NULL);
g_signal_connect (priv->text_entry, "focus-in-event",
- G_CALLBACK (entry_focus_in_cb), entry);
+ G_CALLBACK (entry_focus_in_cb), object);
g_signal_connect (priv->text_entry, "focus-out-event",
- G_CALLBACK (entry_focus_out_cb), entry);
+ G_CALLBACK (entry_focus_out_cb), object);
g_signal_connect (priv->text_entry, "icon-press",
- G_CALLBACK (entry_icon_press_cb), entry);
+ G_CALLBACK (entry_icon_press_cb), object);
g_signal_connect (priv->text_entry, "key-press-event",
- G_CALLBACK (entry_key_press_cb), entry);
+ G_CALLBACK (entry_key_press_cb), object);
g_signal_connect (priv->text_entry, "activate",
- G_CALLBACK (entry_activate_cb), entry);
-}
-
-static void
-location_entry_constructed (GObject *object)
-{
- GtkTreeIter iter;
- YelpLocationEntryPrivate *priv = GET_PRIV (object);
-
- if (priv->enable_search) {
- gtk_list_store_append (priv->history, &iter);
- gtk_list_store_set (priv->history, &iter,
- HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEPARATOR,
- -1);
- gtk_list_store_append (priv->history, &iter);
- gtk_list_store_set (priv->history, &iter,
- HISTORY_COL_ICON, "system-search",
- HISTORY_COL_TITLE, _("Search..."),
- HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEARCH,
- -1);
- }
- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (object),
- (GtkTreeViewRowSeparatorFunc)
- combo_box_row_separator_func,
- object, NULL);
+ G_CALLBACK (entry_activate_cb), object);
g_signal_connect (priv->view, "loaded", G_CALLBACK (view_loaded), object);
g_signal_connect (priv->view, "notify::yelp-uri", G_CALLBACK (view_uri_selected), object);
@@ -490,6 +499,11 @@ location_entry_dispose (GObject *object)
priv->view = NULL;
}
+ if (priv->bookmarks) {
+ g_object_unref (priv->bookmarks);
+ priv->bookmarks = NULL;
+ }
+
if (priv->row) {
gtk_tree_row_reference_free (priv->row);
priv->row = NULL;
@@ -506,6 +520,10 @@ location_entry_dispose (GObject *object)
static void
location_entry_finalize (GObject *object)
{
+ YelpLocationEntryPrivate *priv = GET_PRIV (object);
+
+ g_free (priv->completion_uri);
+
G_OBJECT_CLASS (yelp_location_entry_parent_class)->finalize (object);
}
@@ -521,12 +539,12 @@ location_entry_get_property (GObject *object,
case PROP_VIEW:
g_value_set_object (value, priv->view);
break;
+ case PROP_BOOKMARKS:
+ g_value_set_object (value, priv->bookmarks);
+ break;
case PROP_ENABLE_SEARCH:
g_value_set_boolean (value, priv->enable_search);
break;
- case PROP_ENABLE_BOOKMARKS:
- g_value_set_boolean (value, priv->enable_bookmarks);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -545,17 +563,11 @@ location_entry_set_property (GObject *object,
case PROP_VIEW:
priv->view = g_value_dup_object (value);
break;
+ case PROP_BOOKMARKS:
+ priv->bookmarks = g_value_dup_object (value);
+ break;
case PROP_ENABLE_SEARCH:
priv->enable_search = g_value_get_boolean (value);
- gtk_editable_set_editable (GTK_EDITABLE (priv->text_entry),
- priv->enable_search);
- if (!priv->enable_search) {
- priv->search_mode = FALSE;
- location_entry_set_entry ((YelpLocationEntry *) object, FALSE);
- }
- break;
- case PROP_ENABLE_BOOKMARKS:
- priv->enable_bookmarks = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -672,14 +684,14 @@ location_entry_set_completion (YelpLocationEntry *entry,
"icon-name",
COMPLETION_COL_ICON,
NULL);
-
- bookmark_cell = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (priv->completion), bookmark_cell, FALSE);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->completion),
- bookmark_cell,
- (GtkCellLayoutDataFunc) cell_set_completion_bookmark_icon,
- entry, NULL);
-
+ if (priv->bookmarks) {
+ bookmark_cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (priv->completion), bookmark_cell, FALSE);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->completion),
+ bookmark_cell,
+ (GtkCellLayoutDataFunc) cell_set_completion_bookmark_icon,
+ entry, NULL);
+ }
gtk_entry_set_completion (GTK_ENTRY (priv->text_entry),
priv->completion);
}
@@ -710,15 +722,17 @@ location_entry_set_entry (YelpLocationEntry *entry, gboolean emit)
path = gtk_tree_row_reference_get_path (priv->row);
if (path) {
- gchar *text;
+ gchar *text, *doc_uri, *page_id;
gint flags;
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter,
HISTORY_COL_TITLE, &text,
HISTORY_COL_ICON, &icon_name,
HISTORY_COL_FLAGS, &flags,
+ HISTORY_COL_DOC, &doc_uri,
+ HISTORY_COL_PAGE, &page_id,
-1);
- if (flags & YELP_LOCATION_ENTRY_IS_LOADING) {
+ if (flags & LOCATION_ENTRY_IS_LOADING) {
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
GTK_ENTRY_ICON_PRIMARY,
"image-loading");
@@ -731,19 +745,23 @@ location_entry_set_entry (YelpLocationEntry *entry, gboolean emit)
GTK_ENTRY_ICON_PRIMARY,
icon_name);
}
- if (flags & YELP_LOCATION_ENTRY_CAN_BOOKMARK) {
- gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
- GTK_ENTRY_ICON_SECONDARY,
- "bookmark-new");
- gtk_entry_set_icon_tooltip_text (GTK_ENTRY (priv->text_entry),
- GTK_ENTRY_ICON_SECONDARY,
- "Bookmark this page");
- }
- else {
- gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
- GTK_ENTRY_ICON_SECONDARY,
- NULL);
+ if (priv->bookmarks && doc_uri && page_id) {
+ if (!yelp_bookmarks_is_bookmarked (priv->bookmarks, doc_uri, page_id)) {
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ "bookmark-new");
+ gtk_entry_set_icon_tooltip_text (GTK_ENTRY (priv->text_entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ "Bookmark this page");
+ }
+ else {
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->text_entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ NULL);
+ }
}
+ g_free (doc_uri);
+ g_free (page_id);
gtk_entry_set_text (GTK_ENTRY (priv->text_entry), text);
if (emit)
g_signal_emit (entry, location_entry_signals[LOCATION_SELECTED], 0);
@@ -779,14 +797,14 @@ location_entry_pulse (gpointer data)
gtk_tree_path_free (path);
}
- if (flags & YELP_LOCATION_ENTRY_IS_LOADING && !priv->search_mode) {
+ if (flags & LOCATION_ENTRY_IS_LOADING && !priv->search_mode) {
gtk_entry_progress_pulse (GTK_ENTRY (priv->text_entry));
}
else {
gtk_entry_set_progress_fraction (GTK_ENTRY (priv->text_entry), 0.0);
}
- return flags & YELP_LOCATION_ENTRY_IS_LOADING;
+ return flags & LOCATION_ENTRY_IS_LOADING;
}
static void
@@ -804,7 +822,7 @@ combo_box_changed_cb (GtkComboBox *widget,
gtk_tree_model_get (model, &iter,
HISTORY_COL_FLAGS, &flags,
-1);
- if (flags & YELP_LOCATION_ENTRY_IS_SEARCH) {
+ if (flags & LOCATION_ENTRY_IS_SEARCH) {
location_entry_start_search ((YelpLocationEntry *) widget, TRUE);
}
else {
@@ -838,7 +856,7 @@ combo_box_row_separator_func (GtkTreeModel *model,
gtk_tree_model_get (model, iter,
HISTORY_COL_FLAGS, &flags,
-1);
- return (flags & YELP_LOCATION_ENTRY_IS_SEPARATOR);
+ return (flags & LOCATION_ENTRY_IS_SEPARATOR);
}
static void
@@ -976,17 +994,32 @@ cell_set_bookmark_icon (GtkCellLayout *layout,
YelpLocationEntry *entry)
{
gint flags;
+ gchar *doc_uri, *page_id;
YelpLocationEntryPrivate *priv = GET_PRIV (entry);
+ if (priv->bookmarks == NULL) {
+ g_object_set (cell, "icon-name", NULL, NULL);
+ return;
+ }
+
+ gtk_tree_model_get (model, iter, HISTORY_COL_FLAGS, &flags, -1);
+ if (flags & (LOCATION_ENTRY_IS_SEPARATOR | LOCATION_ENTRY_IS_SEARCH)) {
+ g_object_set (cell, "icon-name", NULL, NULL);
+ return;
+ }
+
gtk_tree_model_get (model, iter,
- HISTORY_COL_FLAGS, &flags,
+ HISTORY_COL_DOC, &doc_uri,
+ HISTORY_COL_PAGE, &page_id,
-1);
- if (!(flags & YELP_LOCATION_ENTRY_IS_SEPARATOR) &&
- !(flags & YELP_LOCATION_ENTRY_IS_SEARCH) &&
- (flags & YELP_LOCATION_ENTRY_IS_BOOKMARKED))
+ if (doc_uri && page_id &&
+ yelp_bookmarks_is_bookmarked (priv->bookmarks, doc_uri, page_id))
g_object_set (cell, "icon-name", "bookmark", NULL);
else
g_object_set (cell, "icon-name", NULL, NULL);
+
+ g_free (doc_uri);
+ g_free (page_id);
}
static void
@@ -996,16 +1029,22 @@ cell_set_completion_bookmark_icon (GtkCellLayout *layout,
GtkTreeIter *iter,
YelpLocationEntry *entry)
{
- gint flags;
YelpLocationEntryPrivate *priv = GET_PRIV (entry);
- gtk_tree_model_get (model, iter,
- COMPLETION_COL_FLAGS, &flags,
- -1);
- if (flags & YELP_LOCATION_ENTRY_IS_BOOKMARKED)
- g_object_set (cell, "icon-name", "bookmark", NULL);
- else
- g_object_set (cell, "icon-name", NULL, NULL);
+ if (priv->completion_uri) {
+ gchar *page_id = NULL;
+ gtk_tree_model_get (model, iter,
+ COMPLETION_COL_PAGE, &page_id,
+ -1);
+
+ if (page_id && yelp_bookmarks_is_bookmarked (priv->bookmarks,
+ priv->completion_uri, page_id))
+ g_object_set (cell, "icon-name", "bookmark", NULL);
+ else
+ g_object_set (cell, "icon-name", NULL, NULL);
+
+ g_free (page_id);
+ }
}
static void
@@ -1160,8 +1199,8 @@ view_loaded (YelpView *view,
gtk_tree_model_get (GTK_TREE_MODEL (priv->history), &iter,
HISTORY_COL_FLAGS, &flags,
-1);
- if (flags & YELP_LOCATION_ENTRY_IS_LOADING) {
- flags = flags & ~YELP_LOCATION_ENTRY_IS_LOADING;
+ if (flags & LOCATION_ENTRY_IS_LOADING) {
+ flags = flags & ~LOCATION_ENTRY_IS_LOADING;
gtk_list_store_set (priv->history, &iter, HISTORY_COL_FLAGS, flags, -1);
}
@@ -1176,46 +1215,47 @@ view_loaded (YelpView *view,
-1);
g_free (page_id);
- completion = (GtkTreeModel *) g_hash_table_lookup (completions, doc_uri);
- if (completion == NULL) {
- GtkListStore *base = gtk_list_store_new (5,
- G_TYPE_STRING, /* title */
- G_TYPE_STRING, /* desc */
- G_TYPE_STRING, /* icon */
- G_TYPE_STRING, /* uri */
- G_TYPE_INT /* flags */
- );
- completion = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base));
- gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (completion),
- entry_completion_sort,
- NULL, NULL);
- g_hash_table_insert (completions, doc_uri, completion);
- ids = yelp_document_list_page_ids (document);
- for (i = 0; ids[i]; i++) {
- GtkTreeIter iter;
- gchar *title, *desc, *icon;
- gtk_list_store_insert (GTK_LIST_STORE (base), &iter, 0);
- title = yelp_document_get_page_title (document, ids[i]);
- desc = yelp_document_get_page_desc (document, ids[i]);
- icon = yelp_document_get_page_icon (document, ids[i]);
- gtk_list_store_set (base, &iter,
- COMPLETION_COL_TITLE, title,
- COMPLETION_COL_DESC, desc,
- COMPLETION_COL_ICON, icon,
- COMPLETION_COL_PAGE, ids[i],
- -1);
- g_free (icon);
- g_free (desc);
- g_free (title);
+ if ((priv->completion_uri == NULL) ||
+ !g_str_equal (doc_uri, priv->completion_uri)) {
+ completion = (GtkTreeModel *) g_hash_table_lookup (completions, doc_uri);
+ if (completion == NULL) {
+ GtkListStore *base = gtk_list_store_new (5,
+ G_TYPE_STRING, /* title */
+ G_TYPE_STRING, /* desc */
+ G_TYPE_STRING, /* icon */
+ G_TYPE_STRING, /* uri */
+ G_TYPE_INT /* flags */
+ );
+ completion = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base));
+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (completion),
+ entry_completion_sort,
+ NULL, NULL);
+ g_hash_table_insert (completions, g_strdup (doc_uri), completion);
+ ids = yelp_document_list_page_ids (document);
+ for (i = 0; ids[i]; i++) {
+ GtkTreeIter iter;
+ gchar *title, *desc, *icon;
+ gtk_list_store_insert (GTK_LIST_STORE (base), &iter, 0);
+ title = yelp_document_get_page_title (document, ids[i]);
+ desc = yelp_document_get_page_desc (document, ids[i]);
+ icon = yelp_document_get_page_icon (document, ids[i]);
+ gtk_list_store_set (base, &iter,
+ COMPLETION_COL_TITLE, title,
+ COMPLETION_COL_DESC, desc,
+ COMPLETION_COL_ICON, icon,
+ COMPLETION_COL_PAGE, ids[i],
+ -1);
+ g_free (icon);
+ g_free (desc);
+ g_free (title);
+ }
+ g_object_unref (base);
+ g_strfreev (ids);
}
- g_object_unref (base);
- g_strfreev (ids);
+ g_free (priv->completion_uri);
+ priv->completion_uri = doc_uri;
+ location_entry_set_completion (entry, completion);
}
- else {
- g_free (doc_uri);
- }
-
- location_entry_set_completion (entry, completion);
g_object_unref (uri);
}
@@ -1265,7 +1305,7 @@ view_uri_selected (YelpView *view,
HISTORY_COL_TITLE, _("Loading"),
HISTORY_COL_ICON, "help-contents",
HISTORY_COL_URI, struri,
- HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_LOADING,
+ HISTORY_COL_FLAGS, LOCATION_ENTRY_IS_LOADING,
-1);
/* Limit to 15 entries. There are two extra for the search entry and
* the separator above it.
@@ -1373,13 +1413,15 @@ view_page_icon (YelpView *view,
* Returns: A new #YelpLocationEntry.
**/
GtkWidget*
-yelp_location_entry_new (YelpView *view)
+yelp_location_entry_new (YelpView *view,
+ YelpBookmarks *bookmarks)
{
GtkWidget *ret;
g_return_val_if_fail (YELP_IS_VIEW (view), NULL);
ret = GTK_WIDGET (g_object_new (YELP_TYPE_LOCATION_ENTRY,
"view", view,
+ "bookmarks", bookmarks,
NULL));
return ret;
diff --git a/libyelp/yelp-location-entry.h b/libyelp/yelp-location-entry.h
index 34cd72c..9ba427c 100644
--- a/libyelp/yelp-location-entry.h
+++ b/libyelp/yelp-location-entry.h
@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
+#include "yelp-bookmarks.h"
#include "yelp-view.h"
G_BEGIN_DECLS
@@ -70,37 +71,10 @@ struct _YelpLocationEntryClass
void (*_gtk_reserved3) (void);
};
-/**
- * YelpLocationEntryFlags:
- * @YELP_LOCATION_ENTRY_CAN_BOOKMARK: This location can be bookmarked. When a
- * bookmarkable location is selected, the secondary icon of the embedded text
- * entry will be a clickable bookmark icon.
- * @YELP_LOCATION_ENTRY_IS_BOOKMARKED: This location is already bookmarked.
- * Bookmarked locations will have an emblem in drop-down lists.
- * @YELP_LOCATION_ENTRY_IS_LOADING: Page data for this location is still loading.
- * The #YelpLocationEntry widget will display an indeterminate progress indicator.
- * @YELP_LOCATION_ENTRY_IS_SEPARATOR: This row should be displayed as a separator.
- * @YELP_LOCATION_ENTRY_IS_SEARCH: Selecting this row initiates a search instead
- * of selecting a location.
- *
- * Flags which can be used to provide additional information about rows
- * to be displayed by a #YelpLocationEntry.
- **/
-typedef enum {
- YELP_LOCATION_ENTRY_CAN_BOOKMARK = 1 << 0,
- YELP_LOCATION_ENTRY_IS_BOOKMARKED = 1 << 1,
- YELP_LOCATION_ENTRY_IS_LOADING = 1 << 2,
- YELP_LOCATION_ENTRY_IS_SEPARATOR = 1 << 3,
- YELP_LOCATION_ENTRY_IS_SEARCH = 1 << 4
-} YelpLocationEntryFlags;
-
GType yelp_location_entry_get_type (void);
-GtkWidget * yelp_location_entry_new (YelpView *window);
+GtkWidget * yelp_location_entry_new (YelpView *window,
+ YelpBookmarks *bookmarks);
void yelp_location_entry_start_search (YelpLocationEntry *entry);
-void yelp_location_entry_add_bookmark (const gchar *doc_uri,
- const gchar *page_id);
-void yelp_location_entry_remove_bookmark (const gchar *doc_uri,
- const gchar *page_id);
G_END_DECLS
diff --git a/libyelp/yelp-settings.c b/libyelp/yelp-settings.c
index 478b378..69a474d 100644
--- a/libyelp/yelp-settings.c
+++ b/libyelp/yelp-settings.c
@@ -48,6 +48,8 @@ struct _YelpSettingsPriv {
gboolean show_text_cursor;
gboolean editor_mode;
+
+ GHashTable *bookmarks;
};
enum {
@@ -227,6 +229,9 @@ yelp_settings_init (YelpSettings *settings)
settings->priv->setfonts[i] = NULL;
settings->priv->fonts[i] = NULL;
}
+
+ settings->priv->bookmarks = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
}
static void
diff --git a/src/yelp-application.c b/src/yelp-application.c
index 9a9c621..a4635a1 100644
--- a/src/yelp-application.c
+++ b/src/yelp-application.c
@@ -32,6 +32,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
+#include "yelp-bookmarks.h"
#include "yelp-settings.h"
#include "yelp-view.h"
@@ -73,10 +74,11 @@ static const gchar introspection_xml[] =
"</node>";
GDBusNodeInfo *introspection_data;
-static void yelp_application_init (YelpApplication *app);
-static void yelp_application_class_init (YelpApplicationClass *klass);
-static void yelp_application_dispose (GObject *object);
-static void yelp_application_finalize (GObject *object);
+static void yelp_application_init (YelpApplication *app);
+static void yelp_application_class_init (YelpApplicationClass *klass);
+static void yelp_application_iface_init (YelpBookmarksInterface *iface);
+static void yelp_application_dispose (GObject *object);
+static void yelp_application_finalize (GObject *object);
static void yelp_application_method (GDBusConnection *connection,
const gchar *sender,
@@ -103,7 +105,9 @@ static void application_set_font_sensitivity (YelpApplication *a
static gboolean window_resized (YelpWindow *window,
YelpApplication *app);
-G_DEFINE_TYPE (YelpApplication, yelp_application, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE (YelpApplication, yelp_application, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (YELP_TYPE_BOOKMARKS,
+ yelp_application_iface_init))
#define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_APPLICATION, YelpApplicationPrivate))
GDBusInterfaceVTable yelp_dbus_vtable = {
@@ -174,6 +178,14 @@ yelp_application_class_init (YelpApplicationClass *klass)
}
static void
+yelp_application_iface_init (YelpBookmarksInterface *iface)
+{
+ iface->add_bookmark = yelp_application_add_bookmark;
+ iface->remove_bookmark = yelp_application_remove_bookmark;
+ iface->is_bookmarked = yelp_application_is_bookmarked;
+}
+
+static void
yelp_application_dispose (GObject *object)
{
YelpApplicationPrivate *priv = GET_PRIV (object);
@@ -678,6 +690,35 @@ yelp_application_remove_bookmark (YelpApplication *app,
}
}
+gboolean
+yelp_application_is_bookmarked (YelpApplication *app,
+ const gchar *doc_uri,
+ const gchar *page_id)
+{
+ GVariant *bookmarks;
+ GVariantIter *iter;
+ gboolean ret = FALSE;
+ gchar *this_id = NULL;
+ GSettings *settings;
+
+ settings = application_get_doc_settings (app, doc_uri);
+ if (settings == NULL)
+ return FALSE;
+
+ bookmarks = g_settings_get_value (settings, "bookmarks");
+ g_settings_get (settings, "bookmarks", "a(sss)", &iter);
+ while (g_variant_iter_loop (iter, "(&s&s&s)", &this_id, NULL, NULL)) {
+ if (g_str_equal (page_id, this_id)) {
+ ret = TRUE;
+ break;
+ }
+ }
+
+ g_variant_iter_free (iter);
+ g_variant_unref (bookmarks);
+ return ret;
+}
+
void
yelp_application_update_bookmarks (YelpApplication *app,
const gchar *doc_uri,
diff --git a/src/yelp-application.h b/src/yelp-application.h
index 1060683..98839e9 100644
--- a/src/yelp-application.h
+++ b/src/yelp-application.h
@@ -68,6 +68,9 @@ void yelp_application_add_bookmark (YelpApplication *app,
void yelp_application_remove_bookmark (YelpApplication *app,
const gchar *doc_uri,
const gchar *page_id);
+gboolean yelp_application_is_bookmarked (YelpApplication *app,
+ const gchar *doc_uri,
+ const gchar *page_id);
void yelp_application_update_bookmarks (YelpApplication *app,
const gchar *doc_uri,
const gchar *page_id,
diff --git a/src/yelp-window.c b/src/yelp-window.c
index a6c5680..a082527 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -509,7 +509,8 @@ window_construct (YelpWindow *window)
button,
FALSE, FALSE, 0);
- priv->entry = (YelpLocationEntry *) yelp_location_entry_new (priv->view);
+ priv->entry = (YelpLocationEntry *) yelp_location_entry_new (priv->view,
+ YELP_BOOKMARKS (priv->application));
g_signal_connect (gtk_bin_get_child (GTK_BIN (priv->entry)), "focus-in-event",
G_CALLBACK (entry_focus_in), window);
g_signal_connect (priv->entry, "focus-out-event",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]