summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2010-05-07 17:51:21 -0500
committerShaun McCance <shaunm@gnome.org>2010-05-07 17:51:21 -0500
commita8930a9f0d5db994a4582851f697e37c058ad169 (patch)
tree859fbce3127913ddf5111167b227916920206b41
parent027e005774f458bfa9599c30edb50d0ba4e8ef88 (diff)
downloadyelp-a8930a9f0d5db994a4582851f697e37c058ad169.tar.gz
[yelp-location-entry] Enable location entry bookmarks + markers in history
-rw-r--r--data/icons/hicolor/16x16/status/Makefile.am1
-rw-r--r--data/icons/hicolor/16x16/status/bookmark.pngbin0 -> 576 bytes
-rw-r--r--libyelp/yelp-location-entry.c53
-rw-r--r--libyelp/yelp-location-entry.h9
-rw-r--r--src/yelp-window.c176
5 files changed, 193 insertions, 46 deletions
diff --git a/data/icons/hicolor/16x16/status/Makefile.am b/data/icons/hicolor/16x16/status/Makefile.am
index 8c0f341d..1b40ddd7 100644
--- a/data/icons/hicolor/16x16/status/Makefile.am
+++ b/data/icons/hicolor/16x16/status/Makefile.am
@@ -1,6 +1,7 @@
icondir = $(datadir)/yelp/icons/hicolor/16x16/status
icon_DATA = \
+ bookmark.png \
yelp-page-task.png \
yelp-page-tip.png \
yelp-page-ui.png \
diff --git a/data/icons/hicolor/16x16/status/bookmark.png b/data/icons/hicolor/16x16/status/bookmark.png
new file mode 100644
index 00000000..627f7ade
--- /dev/null
+++ b/data/icons/hicolor/16x16/status/bookmark.png
Binary files differ
diff --git a/libyelp/yelp-location-entry.c b/libyelp/yelp-location-entry.c
index d76e829f..8a63adcb 100644
--- a/libyelp/yelp-location-entry.c
+++ b/libyelp/yelp-location-entry.c
@@ -114,6 +114,11 @@ static void cell_set_text_cell (GtkCellLayout *layout,
GtkTreeModel *model,
GtkTreeIter *iter,
YelpLocationEntry *entry);
+static void cell_set_bookmark_icon (GtkCellLayout *layout,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ YelpLocationEntry *entry);
/* GtkEntryCompletion callbacks */
static void cell_set_completion_text_cell (GtkCellLayout *layout,
@@ -145,6 +150,7 @@ struct _YelpLocationEntryPrivate
guint pulse;
GtkCellRenderer *icon_cell;
+ GtkCellRenderer *bookmark_cell;
GtkEntryCompletion *completion;
gint completion_desc_column;
@@ -157,6 +163,7 @@ enum {
LOCATION_SELECTED,
COMPLETION_SELECTED,
SEARCH_ACTIVATED,
+ BOOKMARK_CLICKED,
LAST_SIGNAL
};
@@ -241,6 +248,22 @@ yelp_location_entry_class_init (YelpLocationEntryClass *klass)
G_TYPE_STRING);
/**
+ * YelpLocationEntry::bookmark-clicked
+ * @widget: The #YelpLocationEntry for which the signal was emitted.
+ * @user_data: User data set when the handler was connected.
+ *
+ * This signal will be emitted whenever a user clicks the bookmark icon
+ * embedded in the location entry.
+ **/
+ location_entry_signals[BOOKMARK_CLICKED] =
+ g_signal_new ("bookmark-clicked",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
* YelpLocationEntry:desc-column
*
* The column in the #GtkTreeModel containing a description for each row.
@@ -347,6 +370,13 @@ yelp_location_entry_init (YelpLocationEntry *entry)
gtk_cell_layout_reorder (GTK_CELL_LAYOUT (entry), priv->icon_cell, 0);
+ priv->bookmark_cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (entry), priv->bookmark_cell, FALSE);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
+ priv->bookmark_cell,
+ cell_set_bookmark_icon,
+ entry, NULL);
+
g_signal_connect (entry, "changed",
G_CALLBACK (combo_box_changed_cb), NULL);
@@ -769,7 +799,7 @@ entry_icon_press_cb (GtkEntry *gtkentry,
location_entry_cancel_search (entry);
}
else if (g_str_equal (name, "bookmark-new")) {
- /* FIXME: emit bookmark signal */
+ g_signal_emit (entry, location_entry_signals[BOOKMARK_CLICKED], 0);
}
}
}
@@ -827,6 +857,27 @@ cell_set_text_cell (GtkCellLayout *layout,
}
static void
+cell_set_bookmark_icon (GtkCellLayout *layout,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ YelpLocationEntry *entry)
+{
+ gint flags;
+ YelpLocationEntryPrivate *priv = GET_PRIV (entry);
+
+ gtk_tree_model_get (model, iter,
+ priv->flags_column, &flags,
+ -1);
+ if (!(flags & YELP_LOCATION_ENTRY_IS_SEPARATOR) &&
+ !(flags & YELP_LOCATION_ENTRY_IS_SEARCH) &&
+ (flags & YELP_LOCATION_ENTRY_IS_BOOKMARKED))
+ g_object_set (cell, "icon-name", "bookmark", NULL);
+ else
+ g_object_set (cell, "icon-name", NULL, NULL);
+}
+
+static void
cell_set_completion_text_cell (GtkCellLayout *layout,
GtkCellRenderer *cell,
GtkTreeModel *model,
diff --git a/libyelp/yelp-location-entry.h b/libyelp/yelp-location-entry.h
index 08db5c99..2ad5b07b 100644
--- a/libyelp/yelp-location-entry.h
+++ b/libyelp/yelp-location-entry.h
@@ -73,10 +73,11 @@ struct _YelpLocationEntryClass
* to be displayed by a #YelpLocationEntry.
**/
typedef enum {
- YELP_LOCATION_ENTRY_CAN_BOOKMARK = 1 << 0,
- YELP_LOCATION_ENTRY_IS_LOADING = 1 << 1,
- YELP_LOCATION_ENTRY_IS_SEPARATOR = 1 << 2,
- YELP_LOCATION_ENTRY_IS_SEARCH = 1 << 3
+ 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);
diff --git a/src/yelp-window.c b/src/yelp-window.c
index 0cc2364e..faeccd8f 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -76,6 +76,7 @@ static void app_bookmarks_changed (YelpApplication *app,
YelpWindow *window);
static void window_set_bookmarks (YelpWindow *window,
const gchar *doc_uri);
+static void window_set_bookmark_icons (YelpWindow *window);
static gboolean find_animate_open (YelpWindow *window);
static gboolean find_animate_close (YelpWindow *window);
static gboolean find_entry_focus_out (GtkEntry *entry,
@@ -87,6 +88,8 @@ static gboolean find_entry_key_press (GtkEntry *entry,
static void find_entry_changed (GtkEntry *entry,
YelpWindow *window);
+static void entry_bookmark_clicked (YelpLocationEntry *entry,
+ YelpWindow *window);
static void entry_location_selected (YelpLocationEntry *entry,
YelpWindow *window);
static gint entry_completion_sort (GtkTreeModel *model,
@@ -153,12 +156,21 @@ G_DEFINE_TYPE (YelpWindow, yelp_window, GTK_TYPE_WINDOW);
static GHashTable *completions;
enum {
- COL_TITLE,
- COL_DESC,
- COL_ICON,
- COL_URI,
- COL_FLAGS,
- COL_TERMS
+ HISTORY_COL_TITLE,
+ HISTORY_COL_DESC,
+ HISTORY_COL_ICON,
+ HISTORY_COL_URI,
+ HISTORY_COL_DOC,
+ HISTORY_COL_PAGE,
+ HISTORY_COL_FLAGS,
+ HISTORY_COL_TERMS
+};
+
+enum {
+ COMPLETION_COL_TITLE,
+ COMPLETION_COL_DESC,
+ COMPLETION_COL_ICON,
+ COMPLETION_COL_PAGE
};
static const gchar *YELP_UI =
@@ -464,31 +476,33 @@ window_construct (YelpWindow *window)
button,
FALSE, FALSE, 0);
- priv->history = gtk_list_store_new (6,
+ priv->history = gtk_list_store_new (8,
G_TYPE_STRING, /* title */
G_TYPE_STRING, /* desc */
G_TYPE_STRING, /* icon */
G_TYPE_STRING, /* uri */
+ G_TYPE_STRING, /* doc */
+ G_TYPE_STRING, /* page */
G_TYPE_INT, /* flags */
G_TYPE_STRING /* search terms */
);
gtk_list_store_append (priv->history, &iter);
gtk_list_store_set (priv->history, &iter,
- COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEPARATOR,
+ HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEPARATOR,
-1);
gtk_list_store_append (priv->history, &iter);
gtk_list_store_set (priv->history, &iter,
- COL_ICON, "system-search",
- COL_TITLE, _("Search..."),
- COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEARCH,
+ HISTORY_COL_ICON, "system-search",
+ HISTORY_COL_TITLE, _("Search..."),
+ HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_SEARCH,
-1);
priv->entry = (YelpLocationEntry *)
yelp_location_entry_new_with_model (GTK_TREE_MODEL (priv->history),
- COL_TITLE,
- COL_DESC,
- COL_ICON,
- COL_FLAGS);
+ HISTORY_COL_TITLE,
+ HISTORY_COL_DESC,
+ HISTORY_COL_ICON,
+ HISTORY_COL_FLAGS);
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",
@@ -496,6 +510,8 @@ window_construct (YelpWindow *window)
g_signal_connect (priv->entry, "completion-selected",
G_CALLBACK (entry_completion_selected), window);
+ g_signal_connect (priv->entry, "bookmark-clicked",
+ G_CALLBACK (entry_bookmark_clicked), window);
priv->entry_location_selected = g_signal_connect (priv->entry, "location-selected",
G_CALLBACK (entry_location_selected), window);
@@ -784,11 +800,70 @@ window_set_bookmarks (YelpWindow *window,
g_free (entry);
}
+ window_set_bookmark_icons (window);
+
g_variant_iter_free (iter);
g_variant_unref (value);
}
static void
+window_set_bookmark_icons (YelpWindow *window)
+{
+ YelpUri *uri;
+ gchar *doc_uri;
+ GVariant *value;
+ GVariantIter *viter;
+ gboolean cont;
+ GtkTreeIter iter;
+ gchar *page_id;
+ GHashTable *bookmarks;
+ YelpWindowPrivate *priv = GET_PRIV (window);
+
+ g_object_get (priv->view, "yelp-uri", &uri, NULL);
+ doc_uri = yelp_uri_get_document_uri (uri);
+
+ bookmarks = g_hash_table_new (g_str_hash, g_str_equal);
+ value = yelp_application_get_bookmarks (priv->application, doc_uri);
+ g_variant_get (value, "a(sss)", &viter);
+ while (g_variant_iter_loop (viter, "(&s&s&s)", &page_id, NULL, NULL))
+ g_hash_table_insert (bookmarks, page_id, page_id);
+ g_variant_iter_free (viter);
+ g_variant_unref (value);
+
+ cont = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &iter);
+ while (cont) {
+ gchar *iter_doc, *iter_page;
+ gint iter_flags;
+ gtk_tree_model_get (GTK_TREE_MODEL (priv->history), &iter,
+ HISTORY_COL_DOC, &iter_doc,
+ HISTORY_COL_PAGE, &iter_page,
+ HISTORY_COL_FLAGS, &iter_flags,
+ -1);
+ iter_flags &= ~YELP_LOCATION_ENTRY_CAN_BOOKMARK;
+ iter_flags &= ~YELP_LOCATION_ENTRY_IS_BOOKMARKED;
+
+ if (iter_flags & (YELP_LOCATION_ENTRY_IS_SEPARATOR | YELP_LOCATION_ENTRY_IS_SEARCH)) {
+ }
+ else if (iter_doc && g_str_equal (iter_doc, doc_uri)) {
+ if (iter_page && g_hash_table_lookup (bookmarks, iter_page))
+ iter_flags |= YELP_LOCATION_ENTRY_IS_BOOKMARKED;
+ else if (iter_page)
+ iter_flags |= YELP_LOCATION_ENTRY_CAN_BOOKMARK;
+ }
+
+ g_free (iter_doc);
+ g_free (iter_page);
+ gtk_list_store_set (priv->history, &iter, HISTORY_COL_FLAGS, iter_flags, -1);
+ cont = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->history), &iter);
+ }
+
+ g_hash_table_destroy (bookmarks);
+ g_free (doc_uri);
+ g_object_unref (uri);
+}
+
+
+static void
window_start_search (GtkAction *action, YelpWindow *window)
{
YelpWindowPrivate *priv = GET_PRIV (window);
@@ -1024,6 +1099,13 @@ find_entry_changed (GtkEntry *entry,
}
static void
+entry_bookmark_clicked (YelpLocationEntry *entry,
+ YelpWindow *window)
+{
+ window_add_bookmark (NULL, window);
+}
+
+static void
entry_location_selected (YelpLocationEntry *entry,
YelpWindow *window)
{
@@ -1033,7 +1115,7 @@ entry_location_selected (YelpLocationEntry *entry,
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->entry), &iter);
gtk_tree_model_get (GTK_TREE_MODEL (priv->history), &iter,
- COL_URI, &uri,
+ HISTORY_COL_URI, &uri,
-1);
yelp_view_load (priv->view, uri);
g_free (uri);
@@ -1048,8 +1130,8 @@ entry_completion_sort (GtkTreeModel *model,
gint ret = 0;
gchar *key1, *key2;
- gtk_tree_model_get (model, iter1, COL_ICON, &key1, -1);
- gtk_tree_model_get (model, iter2, COL_ICON, &key2, -1);
+ gtk_tree_model_get (model, iter1, COMPLETION_COL_ICON, &key1, -1);
+ gtk_tree_model_get (model, iter2, COMPLETION_COL_ICON, &key2, -1);
ret = yelp_settings_cmp_icons (key1, key2);
g_free (key1);
g_free (key2);
@@ -1057,8 +1139,8 @@ entry_completion_sort (GtkTreeModel *model,
if (ret)
return ret;
- gtk_tree_model_get (model, iter1, COL_TITLE, &key1, -1);
- gtk_tree_model_get (model, iter2, COL_TITLE, &key2, -1);
+ gtk_tree_model_get (model, iter1, COMPLETION_COL_TITLE, &key1, -1);
+ gtk_tree_model_get (model, iter2, COMPLETION_COL_TITLE, &key2, -1);
if (key1 && key2)
ret = g_utf8_collate (key1, key2);
else if (key2 == NULL)
@@ -1082,7 +1164,7 @@ entry_completion_selected (YelpLocationEntry *entry,
YelpWindowPrivate *priv = GET_PRIV (window);
g_object_get (priv->view, "yelp-uri", &base, NULL);
- gtk_tree_model_get (model, iter, COL_URI, &page, -1);
+ gtk_tree_model_get (model, iter, COMPLETION_COL_PAGE, &page, -1);
xref = g_strconcat ("xref:", page, NULL);
uri = yelp_uri_new_relative (base, xref);
@@ -1181,20 +1263,29 @@ view_loaded (YelpView *view,
GtkTreeIter iter;
gint flags;
YelpUri *uri;
- gchar *doc_uri;
+ gchar *doc_uri, *page_id;
GtkTreeModel *completion;
YelpWindowPrivate *priv = GET_PRIV (window);
YelpDocument *document = yelp_view_get_document (view);
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &iter);
- gtk_tree_model_get (GTK_TREE_MODEL (priv->history), &iter, COL_FLAGS, &flags, -1);
+ 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;
- gtk_list_store_set (priv->history, &iter, COL_FLAGS, flags, -1);
+ flags = flags & ~YELP_LOCATION_ENTRY_IS_LOADING;
+ gtk_list_store_set (priv->history, &iter, HISTORY_COL_FLAGS, flags, -1);
}
g_object_get (view, "yelp-uri", &uri, NULL);
doc_uri = yelp_uri_get_document_uri (uri);
+ g_object_get (priv->view, "page-id", &page_id, NULL);
+ gtk_list_store_set (priv->history, &iter,
+ HISTORY_COL_DOC, doc_uri,
+ HISTORY_COL_PAGE, page_id,
+ -1);
+ g_free (page_id);
+
completion = (GtkTreeModel *) g_hash_table_lookup (completions, doc_uri);
if (completion == NULL) {
GtkListStore *base = gtk_list_store_new (4,
@@ -1217,10 +1308,10 @@ view_loaded (YelpView *view,
desc = yelp_document_get_page_desc (document, ids[i]);
icon = yelp_document_get_page_icon (document, ids[i]);
gtk_list_store_set (base, &iter,
- COL_TITLE, title,
- COL_DESC, desc,
- COL_ICON, icon,
- COL_URI, ids[i],
+ COMPLETION_COL_TITLE, title,
+ COMPLETION_COL_DESC, desc,
+ COMPLETION_COL_ICON, icon,
+ COMPLETION_COL_PAGE, ids[i],
-1);
g_free (icon);
g_free (desc);
@@ -1235,9 +1326,11 @@ view_loaded (YelpView *view,
yelp_location_entry_set_completion_model (YELP_LOCATION_ENTRY (priv->entry),
GTK_TREE_MODEL (completion),
- COL_TITLE,
- COL_DESC,
- COL_ICON);
+ COMPLETION_COL_TITLE,
+ COMPLETION_COL_DESC,
+ COMPLETION_COL_ICON);
+
+ window_set_bookmark_icons (window);
g_object_unref (uri);
}
@@ -1273,7 +1366,7 @@ view_uri_selected (YelpView *view,
cont = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &iter);
while (cont) {
gtk_tree_model_get (GTK_TREE_MODEL (priv->history), &iter,
- COL_URI, &iter_uri,
+ HISTORY_COL_URI, &iter_uri,
-1);
if (iter_uri && g_str_equal (struri, iter_uri)) {
g_free (iter_uri);
@@ -1294,10 +1387,10 @@ view_uri_selected (YelpView *view,
GtkTreeIter last;
gtk_list_store_prepend (priv->history, &iter);
gtk_list_store_set (priv->history, &iter,
- COL_TITLE, _("Loading"),
- COL_ICON, "help-contents",
- COL_URI, struri,
- COL_FLAGS, YELP_LOCATION_ENTRY_IS_LOADING,
+ HISTORY_COL_TITLE, _("Loading"),
+ HISTORY_COL_ICON, "help-contents",
+ HISTORY_COL_URI, struri,
+ HISTORY_COL_FLAGS, YELP_LOCATION_ENTRY_IS_LOADING,
-1);
/* Limit to 15 entries. There are two extra for the search entry and
* the separator above it.
@@ -1310,6 +1403,7 @@ view_uri_selected (YelpView *view,
gtk_list_store_remove (priv->history, &last);
}
}
+ window_set_bookmark_icons (window);
}
g_signal_handler_block (priv->entry,
priv->entry_location_selected);
@@ -1375,14 +1469,14 @@ view_page_title (YelpView *view,
if (frag) {
gchar *tmp = g_strdup_printf ("%s (#%s)", title, frag);
gtk_list_store_set (priv->history, &first,
- COL_TITLE, tmp,
+ HISTORY_COL_TITLE, tmp,
-1);
g_free (tmp);
g_free (frag);
}
else {
gtk_list_store_set (priv->history, &first,
- COL_TITLE, title,
+ HISTORY_COL_TITLE, title,
-1);
}
@@ -1405,7 +1499,7 @@ view_page_desc (YelpView *view,
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &first);
gtk_list_store_set (priv->history, &first,
- COL_DESC, desc,
+ HISTORY_COL_DESC, desc,
-1);
g_free (desc);
}
@@ -1425,7 +1519,7 @@ view_page_icon (YelpView *view,
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->history), &first);
gtk_list_store_set (priv->history, &first,
- COL_ICON, icon,
+ HISTORY_COL_ICON, icon,
-1);
g_free (icon);
}