diff options
author | Shaun McCance <shaunm@gnome.org> | 2014-02-22 15:17:10 -0500 |
---|---|---|
committer | Shaun McCance <shaunm@gnome.org> | 2014-02-22 15:17:10 -0500 |
commit | 8bafa65569937e1aab9649866bee57caa4472f29 (patch) | |
tree | 93d6391bfd476b5931cfa66972e2708a497d0352 | |
parent | 9c3f2e251e4b91d0f191cfe84edff99d56a5ad34 (diff) | |
download | yelp-8bafa65569937e1aab9649866bee57caa4472f29.tar.gz |
Initial work on implementing aday's new yelp designs
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | libyelp/Makefile.am | 3 | ||||
-rw-r--r-- | libyelp/yelp-search-entry.c | 673 | ||||
-rw-r--r-- | libyelp/yelp-search-entry.h | 77 | ||||
-rw-r--r-- | libyelp/yelp-view.c | 82 | ||||
-rw-r--r-- | libyelp/yelp-view.h | 11 | ||||
-rw-r--r-- | src/yelp-application.c | 16 | ||||
-rw-r--r-- | src/yelp-window.c | 717 | ||||
-rw-r--r-- | src/yelp-window.h | 4 |
9 files changed, 1178 insertions, 407 deletions
diff --git a/configure.ac b/configure.ac index bed70067..ac12a13c 100644 --- a/configure.ac +++ b/configure.ac @@ -27,7 +27,7 @@ GLIB_GSETTINGS # Library dependecies PKG_CHECK_MODULES(YELP, [ - gio-2.0 >= 2.25.11 + gio-2.0 >= 2.32.0 gio-unix-2.0 gtk+-unix-print-3.0 gtk+-3.0 >= 3.8.0 diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am index a4dd68bd..1314060e 100644 --- a/libyelp/Makefile.am +++ b/libyelp/Makefile.am @@ -9,12 +9,12 @@ libyelp_la_SOURCES = \ yelp-help-list.c \ yelp-info-document.c \ yelp-info-parser.c \ - yelp-location-entry.c \ yelp-magic-decompressor.c \ yelp-mallard-document.c \ yelp-man-document.c \ yelp-man-parser.c \ yelp-marshal.c \ + yelp-search-entry.c \ yelp-settings.c \ yelp-simple-document.c \ yelp-sqlite-storage.c \ @@ -48,6 +48,7 @@ endif libyelp_la_CFLAGS = \ $(YELP_CFLAGS) \ + -Wno-deprecated-declarations \ -DDATADIR=\""$(datadir)"\" \ -DYELP_ICON_PATH=\"$(YELP_ICON_PATH)\" diff --git a/libyelp/yelp-search-entry.c b/libyelp/yelp-search-entry.c new file mode 100644 index 00000000..d8908e60 --- /dev/null +++ b/libyelp/yelp-search-entry.c @@ -0,0 +1,673 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2009-2014 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, see <http://www.gnu.org/licenses/>. + * + * Author: Shaun McCance <shaunm@gnome.org> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include "yelp-search-entry.h" +#include "yelp-marshal.h" +#include "yelp-settings.h" + +static void search_entry_constructed (GObject *object); +static void search_entry_dispose (GObject *object); +static void search_entry_finalize (GObject *object); +static void search_entry_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void search_entry_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +/* Signals */ +static void search_entry_location_selected (YelpSearchEntry *entry); +static void search_entry_search_activated (YelpSearchEntry *entry); +static void search_entry_bookmark_clicked (YelpSearchEntry *entry); + + +/* Utilities */ +static void search_entry_set_completion (YelpSearchEntry *entry, + GtkTreeModel *model); + + +/* GtkEntry callbacks */ +static void entry_activate_cb (GtkEntry *text_entry, + gpointer user_data); + +/* GtkEntryCompletion callbacks */ +static void cell_set_completion_bookmark_icon (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry); +static void cell_set_completion_text_cell (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry); +static gboolean entry_match_func (GtkEntryCompletion *completion, + const gchar *key, + GtkTreeIter *iter, + YelpSearchEntry *entry); +static gint entry_completion_sort (GtkTreeModel *model, + GtkTreeIter *iter1, + GtkTreeIter *iter2, + gpointer user_data); +static gboolean entry_match_selected (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry); +/* YelpView callbacks */ +static void view_loaded (YelpView *view, + YelpSearchEntry *entry); + + +typedef struct _YelpSearchEntryPrivate YelpSearchEntryPrivate; +struct _YelpSearchEntryPrivate +{ + YelpView *view; + YelpBookmarks *bookmarks; + gchar *completion_uri; + + /* do not free below */ + GtkCellRenderer *icon_cell; + GtkEntryCompletion *completion; +}; + +enum { + COMPLETION_COL_TITLE, + COMPLETION_COL_DESC, + COMPLETION_COL_ICON, + COMPLETION_COL_PAGE, + COMPLETION_COL_FLAGS +}; + +enum { + COMPLETION_FLAG_ACTIVATE_SEARCH = 1<<0 +}; + +enum { + SEARCH_ACTIVATED, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_VIEW, + PROP_BOOKMARKS +}; + +static GHashTable *completions; + +static guint search_entry_signals[LAST_SIGNAL] = {0,}; + +G_DEFINE_TYPE (YelpSearchEntry, yelp_search_entry, GTK_TYPE_SEARCH_ENTRY) +#define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE((object), YELP_TYPE_SEARCH_ENTRY, YelpSearchEntryPrivate)) + +static void +yelp_search_entry_class_init (YelpSearchEntryClass *klass) +{ + GObjectClass *object_class; + + klass->search_activated = search_entry_search_activated; + klass->bookmark_clicked = search_entry_bookmark_clicked; + + object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = search_entry_constructed; + object_class->dispose = search_entry_dispose; + object_class->finalize = search_entry_finalize; + object_class->get_property = search_entry_get_property; + object_class->set_property = search_entry_set_property; + + /** + * YelpSearchEntry::search-activated + * @widget: The #YelpLocationEntry for which the signal was emitted. + * @text: The search text. + * @user_data: User data set when the handler was connected. + * + * This signal will be emitted whenever the user activates a search, generally + * by pressing <keycap>Enter</keycap> in the embedded text entry while @widget + * is in search mode. + **/ + search_entry_signals[SEARCH_ACTIVATED] = + g_signal_new ("search-activated", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (YelpSearchEntryClass, search_activated), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + /** + * YelpLocationEntry:view + * + * The YelpView instance that this location entry controls. + **/ + g_object_class_install_property (object_class, + PROP_VIEW, + g_param_spec_object ("view", + _("View"), + _("A YelpView instance to control"), + YELP_TYPE_VIEW, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + 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)); + + g_type_class_add_private ((GObjectClass *) klass, + sizeof (YelpSearchEntryPrivate)); + + completions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +} + +static void +yelp_search_entry_init (YelpSearchEntry *entry) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (entry); +} + +static void +search_entry_constructed (GObject *object) +{ + GtkCellRenderer *bookmark_cell; + GList *cells; + GtkTreeIter iter; + YelpSearchEntryPrivate *priv = GET_PRIV (object); + + g_signal_connect (object, "activate", + G_CALLBACK (entry_activate_cb), object); + + g_signal_connect (priv->view, "loaded", G_CALLBACK (view_loaded), object); +} + +static void +search_entry_dispose (GObject *object) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (object); + + if (priv->view) { + g_object_unref (priv->view); + priv->view = NULL; + } + + if (priv->bookmarks) { + g_object_unref (priv->bookmarks); + priv->bookmarks = NULL; + } + + G_OBJECT_CLASS (yelp_search_entry_parent_class)->dispose (object); +} + +static void +search_entry_finalize (GObject *object) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (object); + + g_free (priv->completion_uri); + + G_OBJECT_CLASS (yelp_search_entry_parent_class)->finalize (object); +} + +static void +search_entry_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (object); + + switch (prop_id) { + case PROP_VIEW: + g_value_set_object (value, priv->view); + break; + case PROP_BOOKMARKS: + g_value_set_object (value, priv->bookmarks); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +search_entry_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (object); + + switch (prop_id) { + case PROP_VIEW: + priv->view = g_value_dup_object (value); + break; + case PROP_BOOKMARKS: + priv->bookmarks = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +search_entry_search_activated (YelpSearchEntry *entry) +{ + YelpUri *base, *uri; + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + + g_object_get (priv->view, "yelp-uri", &base, NULL); + if (base == NULL) + return; + uri = yelp_uri_new_search (base, + gtk_entry_get_text (GTK_ENTRY (entry))); + g_object_unref (base); + yelp_view_load_uri (priv->view, uri); + gtk_widget_grab_focus (GTK_WIDGET (priv->view)); +} + +static void +search_entry_bookmark_clicked (YelpSearchEntry *entry) +{ + YelpUri *uri; + gchar *doc_uri, *page_id; + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + + g_object_get (priv->view, + "yelp-uri", &uri, + "page-id", &page_id, + NULL); + doc_uri = yelp_uri_get_document_uri (uri); + if (priv->bookmarks && doc_uri && page_id) { + if (!yelp_bookmarks_is_bookmarked (priv->bookmarks, doc_uri, page_id)) { + gchar *icon, *title; + g_object_get (priv->view, + "page-icon", &icon, + "page-title", &title, + NULL); + yelp_bookmarks_add_bookmark (priv->bookmarks, doc_uri, page_id, icon, title); + g_free (icon); + g_free (title); + } + else { + yelp_bookmarks_remove_bookmark (priv->bookmarks, doc_uri, page_id); + } + } + g_free (doc_uri); + g_free (page_id); + g_object_unref (uri); +} + +static void +search_entry_set_completion (YelpSearchEntry *entry, + GtkTreeModel *model) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + GList *cells; + GtkCellRenderer *icon_cell, *bookmark_cell; + + priv->completion = gtk_entry_completion_new (); + gtk_entry_completion_set_minimum_key_length (priv->completion, 3); + gtk_entry_completion_set_model (priv->completion, model); + gtk_entry_completion_set_text_column (priv->completion, COMPLETION_COL_TITLE); + gtk_entry_completion_set_match_func (priv->completion, + (GtkEntryCompletionMatchFunc) entry_match_func, + entry, NULL); + g_signal_connect (priv->completion, "match-selected", + G_CALLBACK (entry_match_selected), entry); + + cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->completion)); + g_object_set (cells->data, "xpad", 4, NULL); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->completion), + GTK_CELL_RENDERER (cells->data), + (GtkCellLayoutDataFunc) cell_set_completion_text_cell, + entry, NULL); + g_object_set (cells->data, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_list_free (cells); + + icon_cell = gtk_cell_renderer_pixbuf_new (); + g_object_set (priv->icon_cell, "yalign", 0.2, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->completion), icon_cell, FALSE); + gtk_cell_layout_reorder (GTK_CELL_LAYOUT (priv->completion), icon_cell, 0); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->completion), + icon_cell, + "icon-name", + COMPLETION_COL_ICON, + 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 (entry), priv->completion); +} + +static void +entry_activate_cb (GtkEntry *text_entry, + gpointer user_data) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (user_data); + gchar *text = g_strdup (gtk_entry_get_text (text_entry)); + + if (text == NULL || strlen(text) == 0) + return; + + g_signal_emit (user_data, search_entry_signals[SEARCH_ACTIVATED], 0, text); + + g_free (text); +} + +static void +cell_set_completion_bookmark_icon (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry) +{ + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + + 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", "yelp-bookmark-remove-symbolic", NULL); + else + g_object_set (cell, "icon-name", NULL, NULL); + + g_free (page_id); + } +} + +static void +cell_set_completion_text_cell (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry) +{ + gchar *title; + gint flags; + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + + gtk_tree_model_get (model, iter, COMPLETION_COL_FLAGS, &flags, -1); + if (flags & COMPLETION_FLAG_ACTIVATE_SEARCH) { + title = g_strdup_printf (_("Search for ā%sā"), + gtk_entry_get_text (GTK_ENTRY (entry))); + g_object_set (cell, "text", title, NULL); + g_free (title); + return; + } + + gtk_tree_model_get (model, iter, + COMPLETION_COL_TITLE, &title, + -1); + g_object_set (cell, "text", title, NULL); + g_free (title); +} + +static gboolean +entry_match_func (GtkEntryCompletion *completion, + const gchar *key, + GtkTreeIter *iter, + YelpSearchEntry *entry) +{ + gint stri; + gchar *title, *desc, *titlecase = NULL, *desccase = NULL; + gboolean ret = FALSE; + gchar **strs; + gint flags; + GtkTreeModel *model = gtk_entry_completion_get_model (completion); + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + static GRegex *nonword = NULL; + + if (nonword == NULL) + nonword = g_regex_new ("\\W", 0, 0, NULL); + if (nonword == NULL) + return FALSE; + + gtk_tree_model_get (model, iter, COMPLETION_COL_FLAGS, &flags, -1); + if (flags & COMPLETION_FLAG_ACTIVATE_SEARCH) + return TRUE; + + gtk_tree_model_get (model, iter, + COMPLETION_COL_TITLE, &title, + COMPLETION_COL_DESC, &desc, + -1); + if (title) { + titlecase = g_utf8_casefold (title, -1); + g_free (title); + } + if (desc) { + desccase = g_utf8_casefold (desc, -1); + g_free (desc); + } + + strs = g_regex_split (nonword, key, 0); + ret = TRUE; + for (stri = 0; strs[stri]; stri++) { + if (!titlecase || !strstr (titlecase, strs[stri])) { + if (!desccase || !strstr (desccase, strs[stri])) { + ret = FALSE; + break; + } + } + } + + g_free (titlecase); + g_free (desccase); + g_strfreev (strs); + + return ret; +} + +static gint +entry_completion_sort (GtkTreeModel *model, + GtkTreeIter *iter1, + GtkTreeIter *iter2, + gpointer user_data) +{ + gint ret = 0; + gint flags1, flags2; + gchar *key1, *key2; + + gtk_tree_model_get (model, iter1, COMPLETION_COL_FLAGS, &flags1, -1); + gtk_tree_model_get (model, iter2, COMPLETION_COL_FLAGS, &flags2, -1); + if (flags1 & COMPLETION_FLAG_ACTIVATE_SEARCH) + return 1; + else if (flags2 & COMPLETION_FLAG_ACTIVATE_SEARCH) + return -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); + + if (ret) + return ret; + + 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) + return -1; + else if (key1 == NULL) + return 1; + g_free (key1); + g_free (key2); + + return ret; +} + +static gboolean +entry_match_selected (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter, + YelpSearchEntry *entry) +{ + YelpUri *base, *uri; + gchar *page, *xref; + gint flags; + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + + gtk_tree_model_get (model, iter, COMPLETION_COL_FLAGS, &flags, -1); + if (flags & COMPLETION_FLAG_ACTIVATE_SEARCH) { + entry_activate_cb (GTK_ENTRY (entry), entry); + return TRUE; + } + + g_object_get (priv->view, "yelp-uri", &base, NULL); + gtk_tree_model_get (model, iter, COMPLETION_COL_PAGE, &page, -1); + + xref = g_strconcat ("xref:", page, NULL); + uri = yelp_uri_new_relative (base, xref); + + yelp_view_load_uri (priv->view, uri); + + g_free (page); + g_free (xref); + g_object_unref (uri); + g_object_unref (base); + + gtk_widget_grab_focus (GTK_WIDGET (priv->view)); + return TRUE; +} + +static void +view_loaded (YelpView *view, + YelpSearchEntry *entry) +{ + gchar **ids; + gint i; + GtkTreeIter iter; + gint flags; + YelpUri *uri; + gchar *doc_uri; + GtkTreeModel *completion; + YelpSearchEntryPrivate *priv = GET_PRIV (entry); + YelpDocument *document = yelp_view_get_document (view); + + g_object_get (view, "yelp-uri", &uri, NULL); + doc_uri = yelp_uri_get_document_uri (uri); + + 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); + if (document != NULL) { + ids = yelp_document_list_page_ids (document); + for (i = 0; ids[i]; i++) { + 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_strfreev (ids); + gtk_list_store_insert (GTK_LIST_STORE (base), &iter, 0); + gtk_list_store_set (base, &iter, + COMPLETION_COL_ICON, "edit-find-symbolic", + COMPLETION_COL_FLAGS, COMPLETION_FLAG_ACTIVATE_SEARCH, + -1); + } + g_object_unref (base); + } + g_free (priv->completion_uri); + priv->completion_uri = doc_uri; + search_entry_set_completion (entry, completion); + } + + g_object_unref (uri); +} + +/** + * yelp_search_entry_new: + * @view: A #YelpView. + * + * Creates a new #YelpSearchEntry widget to control @view. + * + * Returns: A new #YelpSearchEntry. + **/ +GtkWidget* +yelp_search_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_SEARCH_ENTRY, + "view", view, + "bookmarks", bookmarks, + NULL)); + + return ret; +} diff --git a/libyelp/yelp-search-entry.h b/libyelp/yelp-search-entry.h new file mode 100644 index 00000000..df7e3feb --- /dev/null +++ b/libyelp/yelp-search-entry.h @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2009-2014 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, see <http://www.gnu.org/licenses/>. + * + * Author: Shaun McCance <shaunm@gnome.org> + */ + +#ifndef __YELP_SEARCH_ENTRY_H__ +#define __YELP_SEARCH_ENTRY_H__ + +#include <gtk/gtk.h> + +#include "yelp-bookmarks.h" +#include "yelp-view.h" + +G_BEGIN_DECLS + +#define YELP_TYPE_SEARCH_ENTRY (yelp_search_entry_get_type ()) +#define YELP_SEARCH_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), YELP_TYPE_SEARCH_ENTRY, \ + YelpSearchEntry)) +#define YELP_SEARCH_ENTRY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), YELP_TYPE_SEARCH_ENTRY, \ + YelpSearchEntryClass)) +#define YELP_IS_SEARCH_ENTRY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), YELP_TYPE_SEARCH_ENTRY)) +#define YELP_IS_SEARCH_ENTRY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), YELP_TYPE_SEARCH_ENTRY)) +#define YELP_SEARCH_ENTRY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), YELP_TYPE_SEARCH_ENTRY, \ + YelpSearchEntryClass)) + +/** + * YelpSearchEntry: + **/ +typedef struct _YelpSearchEntry YelpSearchEntry; +typedef struct _YelpSearchEntryClass YelpSearchEntryClass; + +struct _YelpSearchEntry +{ + GtkSearchEntry parent; +}; + +struct _YelpSearchEntryClass +{ + GtkSearchEntryClass parent; + + void (* search_activated) (YelpSearchEntry *entry); + void (* bookmark_clicked) (YelpSearchEntry *entry); + + /* Padding for future expansion */ + void (*_gtk_reserved0) (void); + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); +}; + +GType yelp_search_entry_get_type (void); +GtkWidget * yelp_search_entry_new (YelpView *window, + YelpBookmarks *bookmarks); + +G_END_DECLS + +#endif /* __YELP_SEARCH_ENTRY_H__ */ diff --git a/libyelp/yelp-view.c b/libyelp/yelp-view.c index 1529137b..4764cf27 100644 --- a/libyelp/yelp-view.c +++ b/libyelp/yelp-view.c @@ -104,7 +104,8 @@ static void view_document_loaded (WebKitWebView *vi static void view_print (GtkAction *action, YelpView *view); -static void view_history_action (GtkAction *action, +static void view_history_action (GAction *action, + GVariant *parameter, YelpView *view); static void view_navigation_action (GtkAction *action, YelpView *view); @@ -130,6 +131,7 @@ static const GtkActionEntry entries[] = { "<Control>P", NULL, G_CALLBACK (view_print) }, +#if 0 {"YelpViewGoBack", GTK_STOCK_GO_BACK, N_("_Back"), "<Alt>Left", @@ -140,6 +142,7 @@ static const GtkActionEntry entries[] = { "<Alt>Right", NULL, G_CALLBACK (view_history_action) }, +#endif {"YelpViewGoPrevious", NULL, N_("_Previous Page"), "<Control>Page_Up", @@ -247,7 +250,12 @@ struct _YelpViewPrivate { GList *back_cur; gboolean back_load; + GSimpleAction *back_action; + GSimpleAction *forward_action; + +#if 0 GtkActionGroup *action_group; +#endif GSList *link_actions; @@ -287,6 +295,7 @@ yelp_view_init (YelpView *view) g_signal_connect (view, "script-alert", G_CALLBACK (view_script_alert), NULL); +#if 0 priv->action_group = gtk_action_group_new ("YelpView"); gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE); gtk_action_group_add_actions (priv->action_group, @@ -296,6 +305,21 @@ yelp_view_init (YelpView *view) gtk_action_set_sensitive (action, FALSE); action = gtk_action_group_get_action (priv->action_group, "YelpViewGoForward"); gtk_action_set_sensitive (action, FALSE); +#endif + + priv->back_action = g_simple_action_new ("yelp-view-go-back", NULL); + g_simple_action_set_enabled (priv->back_action, FALSE); + g_signal_connect (priv->back_action, + "activate", + G_CALLBACK (view_history_action), + view); + + priv->forward_action = g_simple_action_new ("yelp-view-go-forward", NULL); + g_simple_action_set_enabled (priv->forward_action, FALSE); + g_signal_connect (priv->forward_action, + "activate", + G_CALLBACK (view_history_action), + view); } static void @@ -315,10 +339,22 @@ yelp_view_dispose (GObject *object) priv->hadjuster = 0; } +#if 0 if (priv->action_group) { g_object_unref (priv->action_group); priv->action_group = NULL; } +#endif + + if (priv->back_action) { + g_object_unref (priv->back_action); + priv->back_action = NULL; + } + + if (priv->forward_action) { + g_object_unref (priv->forward_action); + priv->forward_action = NULL; + } if (priv->document) { g_object_unref (priv->document); @@ -571,12 +607,14 @@ yelp_view_load_uri (YelpView *view, g_object_set (view, "state", YELP_VIEW_STATE_LOADING, NULL); +#if 0 gtk_action_set_sensitive (gtk_action_group_get_action (priv->action_group, "YelpViewGoPrevious"), FALSE); gtk_action_set_sensitive (gtk_action_group_get_action (priv->action_group, "YelpViewGoNext"), FALSE); +#endif if (!yelp_uri_is_resolved (uri)) { if (priv->resolve_uri != NULL) { @@ -630,6 +668,17 @@ yelp_view_get_document (YelpView *view) return priv->document; } +void +yelp_view_register_actions (YelpView *view, + GActionMap *map) +{ + YelpViewPrivate *priv = GET_PRIV (view); + g_action_map_add_action (map, priv->back_action); + g_action_map_add_action (map, priv->forward_action); +} + + +#if 0 GtkActionGroup * yelp_view_get_action_group (YelpView *view) { @@ -637,6 +686,22 @@ yelp_view_get_action_group (YelpView *view) return priv->action_group; } +GAction * +yelp_view_get_back_action (YelpView *view) +{ + YelpViewPrivate *priv = GET_PRIV (view); + return G_ACTION (priv->back_action); +} + +GAction * +yelp_view_get_forward_action (YelpView *view) +{ + YelpViewPrivate *priv = GET_PRIV (view); + return G_ACTION (priv->forward_action); +} +#endif + + /******************************************************************************/ void @@ -1326,12 +1391,14 @@ view_populate_popup (YelpView *view, } } else { +#if 0 item = gtk_action_create_menu_item (gtk_action_group_get_action (priv->action_group, "YelpViewGoBack")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_action_create_menu_item (gtk_action_group_get_action (priv->action_group, "YelpViewGoForward")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); +#endif } if ((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) || @@ -1522,7 +1589,8 @@ view_print (GtkAction *action, YelpView *view) } static void -view_history_action (GtkAction *action, +view_history_action (GAction *action, + GVariant *parameter, YelpView *view) { GList *newcur; @@ -1531,7 +1599,7 @@ view_history_action (GtkAction *action, if (priv->back_cur == NULL) return; - if (g_str_equal (gtk_action_get_name (action), "YelpViewGoBack")) + if (g_str_equal (g_action_get_name (action), "yelp-view-go-back")) newcur = priv->back_cur->next; else newcur = priv->back_cur->prev; @@ -1932,6 +2000,7 @@ uri_resolved (YelpUri *uri, } priv->back_load = FALSE; +#if 0 action = gtk_action_group_get_action (priv->action_group, "YelpViewGoBack"); gtk_action_set_sensitive (action, FALSE); proxies = gtk_action_get_proxies (action); @@ -1959,7 +2028,10 @@ uri_resolved (YelpUri *uri, for (cur = proxies; cur != NULL; cur = cur->next) gtk_widget_set_tooltip_text (GTK_WIDGET (cur->data), ""); } +#endif + g_simple_action_set_enabled (priv->back_action, (priv->back_cur->next && priv->back_cur->next->data)); +#if 0 action = gtk_action_group_get_action (priv->action_group, "YelpViewGoForward"); gtk_action_set_sensitive (action, FALSE); proxies = gtk_action_get_proxies (action); @@ -1987,6 +2059,8 @@ uri_resolved (YelpUri *uri, for (cur = proxies; cur != NULL; cur = cur->next) gtk_widget_set_tooltip_text (GTK_WIDGET (cur->data), ""); } +#endif + g_simple_action_set_enabled (priv->forward_action, (priv->back_cur->prev && priv->back_cur->prev->data)); spec = g_object_class_find_property ((GObjectClass *) YELP_VIEW_GET_CLASS (view), "yelp-uri"); @@ -2081,6 +2155,7 @@ document_callback (YelpDocument *document, back->desc = g_strdup (priv->page_desc); } +#if 0 prev_id = yelp_document_get_prev_id (document, priv->page_id); action = gtk_action_group_get_action (priv->action_group, "YelpViewGoPrevious"); gtk_action_set_sensitive (action, prev_id != NULL); @@ -2090,6 +2165,7 @@ document_callback (YelpDocument *document, action = gtk_action_group_get_action (priv->action_group, "YelpViewGoNext"); gtk_action_set_sensitive (action, next_id != NULL); g_free (next_id); +#endif spec = g_object_class_find_property ((GObjectClass *) YELP_VIEW_GET_CLASS (view), "root-title"); diff --git a/libyelp/yelp-view.h b/libyelp/yelp-view.h index 53fe511d..a0c19950 100644 --- a/libyelp/yelp-view.h +++ b/libyelp/yelp-view.h @@ -72,7 +72,18 @@ void yelp_view_load_document (YelpView *view YelpUri *uri, YelpDocument *document); YelpDocument * yelp_view_get_document (YelpView *view); + +#if 0 GtkActionGroup * yelp_view_get_action_group (YelpView *view); +#endif + +void yelp_view_register_actions (YelpView *view, + GActionMap *map); + +#if 0 +GAction * yelp_view_get_back_action (YelpView *view); +GAction * yelp_view_get_forward_action (YelpView *view); +#endif void yelp_view_add_link_action (YelpView *view, GtkAction *action, diff --git a/src/yelp-application.c b/src/yelp-application.c index 2ac1f998..0b810cc7 100644 --- a/src/yelp-application.c +++ b/src/yelp-application.c @@ -141,6 +141,22 @@ yelp_application_init (YelpApplication *app) priv->docsettings = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); + gtk_application_add_accelerator (GTK_APPLICATION (app), + "<Control>f", + "win.find", + NULL); + gtk_application_add_accelerator (GTK_APPLICATION (app), + "<Control>s", + "win.search", + NULL); + gtk_application_add_accelerator (GTK_APPLICATION (app), + "<Alt>Left", + "win.yelp-view-go-back", + NULL); + gtk_application_add_accelerator (GTK_APPLICATION (app), + "<Alt>Right", + "win.yelp-view-go-forward", + NULL); } static void diff --git a/src/yelp-window.c b/src/yelp-window.c index d36c8fee..9ce10dac 100644 --- a/src/yelp-window.c +++ b/src/yelp-window.c @@ -26,9 +26,10 @@ #include <gdk/gdkkeysyms.h> #include <glib/gi18n.h> +#include <gio/gio.h> #include <gtk/gtk.h> -#include "yelp-location-entry.h" +#include "yelp-search-entry.h" #include "yelp-settings.h" #include "yelp-uri.h" #include "yelp-view.h" @@ -50,8 +51,7 @@ static void yelp_window_set_property (GObject *object, GParamSpec *pspec); static void window_construct (YelpWindow *window); -static void window_new (GtkAction *action, - YelpWindow *window); + static gboolean window_map_event (YelpWindow *window, GdkEvent *event, gpointer user_data); @@ -67,19 +67,18 @@ static void window_drag_received (YelpWindow *window, guint time, gpointer userdata); static gboolean window_resize_signal (YelpWindow *window); -static void window_close (GtkAction *action, - YelpWindow *window); -static void window_go_all (GtkAction *action, - YelpWindow *window); -static void window_add_bookmark (GtkAction *action, - YelpWindow *window); -static void window_remove_bookmark (GtkAction *action, + +static void bookmark_activated (GtkListBox *box, + GtkListBoxRow *row, YelpWindow *window); -static void window_load_bookmark (GtkAction *action, +static void bookmark_removed (GtkButton *button, YelpWindow *window); -static void window_find_in_page (GtkAction *action, +static void bookmark_added (GtkButton *button, YelpWindow *window); -static void window_start_search (GtkAction *action, + + +/* FIXME: all below */ +static void window_go_all (GtkAction *action, YelpWindow *window); static void window_open_location (GtkAction *action, YelpWindow *window); @@ -95,23 +94,28 @@ 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_action (YelpWindow *window); -static gboolean find_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - YelpWindow *window); +static void window_set_bookmark_buttons (YelpWindow *window); + +static void action_new_window (GSimpleAction *action, + GVariant *parameter, + gpointer userdata); +static void action_print (GSimpleAction *action, + GVariant *parameter, + gpointer userdata); +static void action_search (GSimpleAction *action, + GVariant *parameter, + gpointer userdata); +static void action_find (GSimpleAction *action, + GVariant *parameter, + gpointer userdata); + + static gboolean find_entry_key_press (GtkEntry *entry, GdkEventKey *event, YelpWindow *window); static void find_entry_changed (GtkEntry *entry, YelpWindow *window); -static gboolean entry_focus_in (GtkEntry *entry, - GdkEventFocus *event, - YelpWindow *window); -static gboolean entry_focus_out (YelpLocationEntry *entry, - GdkEventFocus *event, - YelpWindow *window); - static void view_new_window (YelpView *view, YelpUri *uri, YelpWindow *window); @@ -147,9 +151,10 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (YelpWindow, yelp_window, GTK_TYPE_WINDOW); +G_DEFINE_TYPE (YelpWindow, yelp_window, GTK_TYPE_APPLICATION_WINDOW); #define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_WINDOW, YelpWindowPrivate)) +#if 0 static const gchar *YELP_UI = "<ui>" "<menubar>" @@ -187,88 +192,51 @@ static const gchar *YELP_UI = "<accelerator action='Search'/>" "<accelerator action='OpenLocation'/>" "</ui>"; +#endif typedef struct _YelpWindowPrivate YelpWindowPrivate; struct _YelpWindowPrivate { - GtkListStore *history; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; YelpApplication *application; gulong bookmarks_changed; gulong read_later_changed; /* no refs on these, owned by containers */ - YelpView *view; + GtkWidget *header; GtkWidget *vbox_view; GtkWidget *vbox_full; - GtkWidget *hbox; - YelpLocationEntry *entry; - GtkWidget *hidden_entry; + GtkWidget *search_bar; + GtkWidget *search_entry; + GtkWidget *find_bar; GtkWidget *find_entry; - GtkWidget *find_label; + GtkWidget *bookmark_menu; + GtkWidget *bookmark_list; + GtkWidget *bookmark_add; + GtkWidget *bookmark_remove; + YelpView *view; + + GtkWidget *hidden_entry; GtkWidget *read_later_vbox; /* refs because we dynamically add & remove */ - GtkWidget *find_bar; GtkWidget *align_location; GtkWidget *align_hidden; GtkWidget *read_later; gchar *doc_uri; - GtkActionGroup *bookmark_actions; - guint bookmarks_merge_id; - guint resize_signal; gint width; gint height; - guint entry_color_animate; - gfloat entry_color_step; - gboolean configured; }; -static const GtkActionEntry entries[] = { - { "PageMenu", NULL, N_("_Page") }, - { "ViewMenu", NULL, N_("_View") }, - { "GoMenu", NULL, N_("_Go") }, - { "BookmarksMenu", NULL, N_("_Bookmarks") }, - - { "NewWindow", NULL, - N_("_New Window"), - "<Control>N", - NULL, - G_CALLBACK (window_new) }, - { "CloseWindow", NULL, - N_("_Close"), - "<Control>W", - NULL, - G_CALLBACK (window_close) }, +static const GtkActionEntry gtkentries[] = { { "GoAll", NULL, N_("_All Documents"), NULL, NULL, G_CALLBACK (window_go_all) }, - { "AddBookmark", NULL, - N_("_Add Bookmark"), - "<Control>D", - NULL, - G_CALLBACK (window_add_bookmark) }, - { "RemoveBookmark", NULL, - N_("_Remove Bookmark"), - NULL, NULL, - G_CALLBACK (window_remove_bookmark) }, - { "Find", NULL, - N_("Find in Page..."), - "<Control>F", - NULL, - G_CALLBACK (window_find_in_page) }, - { "Search", NULL, - N_("Search..."), - "<Control>S", - NULL, - G_CALLBACK (window_start_search) }, { "OpenLocation", NULL, N_("Open Location"), "<Control>L", @@ -319,21 +287,6 @@ yelp_window_dispose (GObject *object) { YelpWindowPrivate *priv = GET_PRIV (object); - if (priv->history) { - g_object_unref (priv->history); - priv->history = NULL; - } - - if (priv->action_group) { - g_object_unref (priv->action_group); - priv->action_group = NULL; - } - - if (priv->bookmark_actions) { - g_object_unref (priv->bookmark_actions); - priv->bookmark_actions = NULL; - } - if (priv->read_later_changed) { g_source_remove (priv->read_later_changed); priv->read_later_changed = 0; @@ -354,16 +307,6 @@ yelp_window_dispose (GObject *object) priv->align_hidden = NULL; } - if (priv->find_bar) { - g_object_unref (priv->find_bar); - priv->find_bar = NULL; - } - - if (priv->entry_color_animate != 0) { - g_source_remove (priv->entry_color_animate); - priv->entry_color_animate = 0; - } - G_OBJECT_CLASS (yelp_window_parent_class)->dispose (object); } @@ -416,14 +359,24 @@ window_construct (YelpWindow *window) GtkWidget *scroll; GtkActionGroup *view_actions; GtkAction *action; - GtkWidget *vbox, *button, *label; + GtkWidget *box, *button, *sw; gchar *color, *text; YelpWindowPrivate *priv = GET_PRIV (window); - gtk_window_set_icon_name (GTK_WINDOW (window), "help-browser"); + const GActionEntry entries[] = { + { "new-window", action_new_window, NULL, NULL, NULL }, + { "print", action_print, NULL, NULL, NULL }, + { "search", action_search, NULL, NULL, NULL }, + { "find", action_find, NULL, NULL, NULL }, + }; + gtk_window_set_icon_name (GTK_WINDOW (window), "help-browser"); priv->view = (YelpView *) yelp_view_new (); + g_action_map_add_action_entries (G_ACTION_MAP (window), + entries, G_N_ELEMENTS (entries), window); + yelp_view_register_actions (priv->view, G_ACTION_MAP (window)); + action = gtk_action_new ("ReadLinkLater", _("Read Link _Later"), NULL, NULL); g_signal_connect (action, "activate", G_CALLBACK (window_read_later), window); yelp_view_add_link_action (priv->view, action, @@ -436,110 +389,139 @@ window_construct (YelpWindow *window) priv->vbox_full = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); gtk_container_add (GTK_CONTAINER (window), priv->vbox_full); + priv->header = gtk_header_bar_new (); + gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (priv->header), TRUE); + gtk_window_set_titlebar (GTK_WINDOW (window), priv->header); + + /** Back/Forward **/ + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked"); + gtk_header_bar_pack_start (GTK_HEADER_BAR (priv->header), box); + + button = gtk_button_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button"); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); + g_object_set (button, "action-name", "win.yelp-view-go-back", NULL); + + button = gtk_button_new_from_icon_name ("go-next-symbolic", GTK_ICON_SIZE_MENU); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button"); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); + g_object_set (button, "action-name", "win.yelp-view-go-forward", NULL); + + /** Menu **/ + button = gtk_menu_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button"); + gtk_button_set_image (GTK_BUTTON (button), + gtk_image_new_from_icon_name ("emblem-system-symbolic", + GTK_ICON_SIZE_MENU)); + gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->header), button); + + /** Search **/ priv->vbox_view = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (priv->vbox_full), priv->vbox_view, TRUE, TRUE, 0); - priv->action_group = gtk_action_group_new ("YelpWindowActions"); - gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (priv->action_group, - entries, G_N_ELEMENTS (entries), - window); - + priv->search_bar = gtk_search_bar_new (); + gtk_box_pack_start (GTK_BOX (priv->vbox_view), priv->search_bar, FALSE, FALSE, 0); + priv->search_entry = yelp_search_entry_new (priv->view, + YELP_BOOKMARKS (priv->application)); + g_object_set (priv->search_entry, "width-request", 400, NULL); + gtk_container_add (GTK_CONTAINER (priv->search_bar), priv->search_entry); + button = gtk_toggle_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button"); + gtk_button_set_image (GTK_BUTTON (button), + gtk_image_new_from_icon_name ("edit-find-symbolic", + GTK_ICON_SIZE_MENU)); + g_object_bind_property (button, "active", + priv->search_bar, "search-mode-enabled", + G_BINDING_BIDIRECTIONAL); + gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->header), button); + + /** Bookmarks **/ + button = gtk_menu_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button"); + gtk_button_set_image (GTK_BUTTON (button), + gtk_image_new_from_icon_name ("yelp-bookmark-remove-symbolic", + GTK_ICON_SIZE_MENU)); + gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->header), button); + + priv->bookmark_menu = gtk_popover_new (button); + g_object_set (priv->bookmark_menu, "border-width", 12, NULL); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), priv->bookmark_menu); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_add (GTK_CONTAINER (priv->bookmark_menu), box); + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0); + priv->bookmark_list = gtk_list_box_new (); + g_object_set (priv->bookmark_list, "selection-mode", GTK_SELECTION_NONE, NULL); + g_signal_connect (priv->bookmark_list, "row-activated", + G_CALLBACK (bookmark_activated), window); + gtk_container_add (GTK_CONTAINER (box), priv->bookmark_list); + + priv->bookmark_add = gtk_button_new_with_label (_("Add Bookmark")); + g_signal_connect (priv->bookmark_add, "clicked", + G_CALLBACK (bookmark_added), window); + gtk_box_pack_end (GTK_BOX (box), priv->bookmark_add, FALSE, FALSE, 0); + gtk_widget_show_all (box); + + priv->bookmark_remove = gtk_button_new_with_label (_("Remove Bookmark")); + g_signal_connect (priv->bookmark_remove, "clicked", + G_CALLBACK (bookmark_removed), window); + gtk_box_pack_end (GTK_BOX (box), priv->bookmark_remove, FALSE, FALSE, 0); + gtk_widget_show_all (box); + +#if 0 priv->bookmark_actions = gtk_action_group_new ("BookmarkActions"); gtk_action_group_set_translate_func (priv->bookmark_actions, NULL, NULL, NULL); +#endif - priv->ui_manager = gtk_ui_manager_new (); - gtk_ui_manager_insert_action_group (priv->ui_manager, priv->action_group, 0); - gtk_ui_manager_insert_action_group (priv->ui_manager, priv->bookmark_actions, 1); - gtk_ui_manager_insert_action_group (priv->ui_manager, - yelp_application_get_action_group (priv->application), - 2); - view_actions = yelp_view_get_action_group (priv->view); - gtk_ui_manager_insert_action_group (priv->ui_manager, view_actions, 3); - gtk_window_add_accel_group (GTK_WINDOW (window), - gtk_ui_manager_get_accel_group (priv->ui_manager)); - gtk_ui_manager_add_ui_from_string (priv->ui_manager, YELP_UI, -1, NULL); - gtk_box_pack_start (GTK_BOX (priv->vbox_view), - gtk_ui_manager_get_widget (priv->ui_manager, "/ui/menubar"), - FALSE, FALSE, 0); - - priv->bookmarks_merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager); priv->bookmarks_changed = g_signal_connect (priv->application, "bookmarks-changed", G_CALLBACK (app_bookmarks_changed), window); - priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - g_object_set (priv->hbox, "border-width", 2, NULL); - gtk_box_pack_start (GTK_BOX (priv->vbox_view), priv->hbox, FALSE, FALSE, 0); + /** Find **/ + priv->find_bar = gtk_search_bar_new (); + gtk_search_bar_set_show_close_button (GTK_SEARCH_BAR (priv->find_bar), TRUE); + gtk_box_pack_start (GTK_BOX (priv->vbox_view), priv->find_bar, FALSE, FALSE, 0); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + g_object_set (box, "width-request", 300, NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked"); + gtk_container_add (GTK_CONTAINER (priv->find_bar), box); + + priv->find_entry = gtk_search_entry_new (); + gtk_box_pack_start (GTK_BOX (box), priv->find_entry, TRUE, TRUE, 0); + gtk_search_bar_connect_entry (GTK_SEARCH_BAR (priv->find_bar), GTK_ENTRY (priv->find_entry)); + g_signal_connect (priv->find_entry, "changed", + G_CALLBACK (find_entry_changed), window); + g_signal_connect (priv->find_entry, "key-press-event", + G_CALLBACK (find_entry_key_press), window); - action = gtk_action_group_get_action (view_actions, "YelpViewGoBack"); - button = gtk_action_create_tool_item (action); - gtk_box_pack_start (GTK_BOX (priv->hbox), - button, - FALSE, FALSE, 0); - action = gtk_action_group_get_action (view_actions, "YelpViewGoForward"); - button = gtk_action_create_tool_item (action); - gtk_box_pack_start (GTK_BOX (priv->hbox), - button, - FALSE, FALSE, 0); + button = gtk_button_new_from_icon_name ("go-up-symbolic", GTK_ICON_SIZE_MENU); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "raised"); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); + /* FIXME: signal_connect */ - 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", - G_CALLBACK (entry_focus_out), window); - - priv->align_location = g_object_ref_sink (gtk_alignment_new (0.0, 0.5, 1.0, 0.0)); - gtk_box_pack_start (GTK_BOX (priv->hbox), - GTK_WIDGET (priv->align_location), - TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (priv->align_location), GTK_WIDGET (priv->entry)); - - priv->hidden_entry = gtk_entry_new (); - priv->align_hidden = g_object_ref_sink (gtk_alignment_new (0.0, 0.5, 1.0, 0.0)); - gtk_container_add (GTK_CONTAINER (priv->align_hidden), GTK_WIDGET (priv->hidden_entry)); - - g_signal_connect (priv->hidden_entry, "activate", - G_CALLBACK (hidden_entry_activate), window); - g_signal_connect_swapped (priv->hidden_entry, "focus-out-event", - G_CALLBACK (hidden_entry_hide), window); - g_signal_connect (priv->hidden_entry, "key-press-event", - G_CALLBACK (hidden_key_press), window); + button = gtk_button_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_MENU); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "raised"); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); + /* FIXME: signal_connect */ + + gtk_widget_show_all (priv->find_bar); + /** View **/ scroll = gtk_scrolled_window_new (NULL, NULL); + g_object_set (scroll, "width-request", 420, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), - GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (priv->vbox_view), scroll, TRUE, TRUE, 0); - priv->find_bar = g_object_ref_sink (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6)); - g_object_set (priv->find_bar, - "border-width", 2, - "margin-right", 16, - NULL); - - label = gtk_label_new (_("Find:")); - gtk_box_pack_start (GTK_BOX (priv->find_bar), label, FALSE, FALSE, 6); - - priv->find_entry = gtk_entry_new (); - g_signal_connect (priv->find_entry, "changed", - G_CALLBACK (find_entry_changed), window); - g_signal_connect (priv->find_entry, "key-press-event", - G_CALLBACK (find_entry_key_press), window); - g_signal_connect (priv->find_entry, "focus-out-event", - G_CALLBACK (find_entry_focus_out), window); - g_object_set (priv->find_entry, "width-request", 300, NULL); - gtk_box_pack_start (GTK_BOX (priv->find_bar), priv->find_entry, FALSE, FALSE, 0); - - priv->find_label = gtk_label_new (""); - g_object_set (priv->find_label, "xalign", 0.0, NULL); - gtk_box_pack_start (GTK_BOX (priv->find_bar), priv->find_label, FALSE, FALSE, 0); - + /** Read Later **/ priv->read_later = g_object_ref_sink (gtk_info_bar_new ()); - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); color = yelp_settings_get_color (yelp_settings_get_default (), YELP_SETTINGS_COLOR_TEXT_LIGHT); text = g_markup_printf_escaped ("<span weight='bold' color='%s'>%s</span>", @@ -548,19 +530,19 @@ window_construct (YelpWindow *window) g_object_set (button, "use-markup", TRUE, "xalign", 0.0, NULL); g_free (color); g_free (text); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (priv->read_later))), - vbox, + box, FALSE, FALSE, 0); priv->read_later_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_box_pack_start (GTK_BOX (vbox), priv->read_later_vbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (box), priv->read_later_vbox, FALSE, FALSE, 0); g_signal_connect (priv->view, "new-view-requested", G_CALLBACK (view_new_window), window); g_signal_connect (priv->view, "loaded", G_CALLBACK (view_loaded), window); g_signal_connect (priv->view, "notify::yelp-uri", G_CALLBACK (view_uri_selected), window); g_signal_connect_swapped (priv->view, "notify::page-id", - G_CALLBACK (window_set_bookmark_action), window); - window_set_bookmark_action (window); + G_CALLBACK (window_set_bookmark_buttons), window); + window_set_bookmark_buttons (window); g_signal_connect (priv->view, "notify::root-title", G_CALLBACK (view_root_title), window); gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (priv->view)); gtk_widget_grab_focus (GTK_WIDGET (priv->view)); @@ -617,10 +599,13 @@ yelp_window_get_geometry (YelpWindow *window, /******************************************************************************/ static void -window_new (GtkAction *action, YelpWindow *window) +action_new_window (GSimpleAction *action, + GVariant *parameter, + gpointer userdata) { YelpUri *yuri; gchar *uri = NULL; + YelpWindow *window = YELP_WINDOW (userdata); YelpWindowPrivate *priv = GET_PRIV (window); g_object_get (priv->view, "yelp-uri", &yuri, NULL); @@ -633,6 +618,40 @@ window_new (GtkAction *action, YelpWindow *window) } static void +action_print (GSimpleAction *action, + GVariant *parameter, + gpointer userdata) +{ + /* FIXME */ +} + +static void +action_search (GSimpleAction *action, + GVariant *parameter, + gpointer userdata) +{ + YelpWindowPrivate *priv = GET_PRIV (userdata); + + gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->find_bar), FALSE); + gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->search_bar), TRUE); + gtk_widget_grab_focus (priv->search_entry); +} + +static void +action_find (GSimpleAction *action, + GVariant *parameter, + gpointer userdata) +{ + YelpWindowPrivate *priv = GET_PRIV (userdata); + + gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->search_bar), FALSE); + gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->find_bar), TRUE); + gtk_widget_grab_focus (priv->find_entry); +} + +/******************************************************************************/ + +static void window_drag_received (YelpWindow *window, GdkDragContext *context, gint x, @@ -704,83 +723,90 @@ window_resize_signal (YelpWindow *window) } static void -window_close (GtkAction *action, YelpWindow *window) +window_go_all (GtkAction *action, + YelpWindow *window) { - gboolean ret; - g_signal_emit_by_name (window, "delete-event", NULL, &ret); - gtk_widget_destroy (GTK_WIDGET (window)); + YelpWindowPrivate *priv = GET_PRIV (window); + yelp_view_load (priv->view, "help-list:"); } static void -window_go_all (GtkAction *action, - YelpWindow *window) +bookmark_activated (GtkListBox *box, + GtkListBoxRow *row, + YelpWindow *window) { + YelpUri *base, *uri; + gchar *xref; YelpWindowPrivate *priv = GET_PRIV (window); - yelp_view_load (priv->view, "help-list:"); + + gtk_widget_hide (priv->bookmark_menu); + + xref = g_strconcat ("xref:", + (gchar *) g_object_get_data (G_OBJECT (row), "page-id"), + NULL); + g_object_get (priv->view, "yelp-uri", &base, NULL); + uri = yelp_uri_new_relative (base, xref); + + yelp_view_load_uri (priv->view, uri); + + g_object_unref (base); + g_object_unref (uri); + g_free (xref); } static void -window_add_bookmark (GtkAction *action, - YelpWindow *window) +bookmark_removed (GtkButton *button, + YelpWindow *window) { YelpUri *uri; - gchar *doc_uri, *page_id, *icon, *title; + gchar *doc_uri; + gchar *page_id = NULL; YelpWindowPrivate *priv = GET_PRIV (window); - g_object_get (priv->view, - "yelp-uri", &uri, - "page-id", &page_id, - "page-icon", &icon, - "page-title", &title, - NULL); + g_object_get (priv->view, "yelp-uri", &uri, NULL); doc_uri = yelp_uri_get_document_uri (uri); - yelp_application_add_bookmark (YELP_BOOKMARKS (priv->application), - doc_uri, page_id, icon, title); + + /* The 'Remove Bookmark' button removes a bookmark for the current page. + The buttons next to each bookmark have page_id attached to them. + */ + if ((gpointer) button == (gpointer) priv->bookmark_remove) + g_object_get (priv->view, + "page-id", &page_id, + NULL); + + yelp_application_remove_bookmark (YELP_BOOKMARKS (priv->application), + doc_uri, + page_id ? page_id : + g_object_get_data (G_OBJECT (button), "page-id")); + if (page_id) + g_free (page_id); g_free (doc_uri); - g_free (page_id); - g_free (icon); - g_free (title); g_object_unref (uri); } static void -window_remove_bookmark (GtkAction *action, - YelpWindow *window) +bookmark_added (GtkButton *button, + YelpWindow *window) { YelpUri *uri; - gchar *doc_uri, *page_id; + gchar *doc_uri, *page_id, *icon, *title; YelpWindowPrivate *priv = GET_PRIV (window); g_object_get (priv->view, "yelp-uri", &uri, "page-id", &page_id, + "page-icon", &icon, + "page-title", &title, NULL); doc_uri = yelp_uri_get_document_uri (uri); - yelp_application_remove_bookmark (YELP_BOOKMARKS (priv->application), - doc_uri, page_id); + yelp_application_add_bookmark (YELP_BOOKMARKS (priv->application), + doc_uri, page_id, icon, title); g_free (doc_uri); g_free (page_id); + g_free (icon); + g_free (title); g_object_unref (uri); } -static void -window_load_bookmark (GtkAction *action, - YelpWindow *window) -{ - YelpUri *base, *uri; - gchar *xref; - YelpWindowPrivate *priv = GET_PRIV (window); - - /* Bookmark action names are prefixed with 'LoadBookmark-' */ - xref = g_strconcat ("xref:", gtk_action_get_name (action) + 13, NULL); - g_object_get (priv->view, "yelp-uri", &base, NULL); - uri = yelp_uri_new_relative (base, xref); - - yelp_view_load_uri (priv->view, uri); - - g_object_unref (base); - g_object_unref (uri); - g_free (xref); -} static void app_bookmarks_changed (YelpApplication *app, @@ -834,11 +860,17 @@ window_set_bookmarks (YelpWindow *window, GVariantIter *iter; gchar *page_id, *icon, *title; YelpWindowPrivate *priv = GET_PRIV (window); + GList *children, *cur; GSList *entries = NULL; - window_set_bookmark_action (window); + window_set_bookmark_buttons (window); - gtk_ui_manager_remove_ui (priv->ui_manager, priv->bookmarks_merge_id); + children = gtk_container_get_children (GTK_CONTAINER (priv->bookmark_list)); + for (cur = children ; cur != NULL; cur = cur->next) { + gtk_container_remove (GTK_CONTAINER (priv->bookmark_list), + GTK_WIDGET (cur->data)); + } + g_list_free (children); value = yelp_application_get_bookmarks (priv->application, doc_uri); g_variant_get (value, "a(sss)", &iter); @@ -850,41 +882,29 @@ window_set_bookmarks (YelpWindow *window, entries = g_slist_insert_sorted (entries, entry, (GCompareFunc) entry_compare); } for ( ; entries != NULL; entries = g_slist_delete_link (entries, entries)) { - GSList *cur; - GtkAction *bookmark; + GtkWidget *row, *box, *button; YelpMenuEntry *entry = (YelpMenuEntry *) entries->data; - gchar *action_id = g_strconcat ("LoadBookmark-", entry->page_id, NULL); - - bookmark = gtk_action_group_get_action (priv->bookmark_actions, action_id); - if (bookmark) { - /* The action might have been set by a different document using - * the same page ID. We can just reuse the action, since it's - * just a page ID relative to the current URI, but we need to - * reset the title and icon. - */ - g_object_set (bookmark, - "label", entry->title, - "icon-name", entry->icon, - NULL); - } else { - bookmark = gtk_action_new (action_id, entry->title, NULL, NULL); - g_signal_connect (bookmark, "activate", - G_CALLBACK (window_load_bookmark), window); - gtk_action_set_icon_name (bookmark, entry->icon); - gtk_action_group_add_action (priv->bookmark_actions, bookmark); - } - gtk_ui_manager_add_ui (priv->ui_manager, - priv->bookmarks_merge_id, - "ui/menubar/BookmarksMenu/Bookmarks", - action_id, action_id, - GTK_UI_MANAGER_MENUITEM, - FALSE); - gtk_ui_manager_ensure_update (priv->ui_manager); - for (cur = gtk_action_get_proxies (bookmark); cur != NULL; cur = cur->next) { - if (GTK_IS_IMAGE_MENU_ITEM (cur->data)) - g_object_set (cur->data, "always-show-image", TRUE, NULL); - } - g_free (action_id); + + row = gtk_list_box_row_new (); + g_object_set_data_full (G_OBJECT (row), "page-id", + g_strdup (entry->page_id), (GDestroyNotify) g_free); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_container_add (GTK_CONTAINER (row), box); + button = gtk_label_new (entry->title); + g_object_set (button, "halign", GTK_ALIGN_START, NULL); + gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0); + button = gtk_button_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU); + g_object_set (button, + "relief", GTK_RELIEF_NONE, + "focus-on-click", FALSE, + NULL); + g_object_set_data_full (G_OBJECT (button), "page-id", + g_strdup (entry->page_id), (GDestroyNotify) g_free); + g_signal_connect (button, "clicked", G_CALLBACK (bookmark_removed), window); + gtk_box_pack_end (GTK_BOX (box), button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (box), gtk_separator_new (GTK_ORIENTATION_VERTICAL), FALSE, FALSE, 0); + gtk_widget_show_all (row); + gtk_container_add (GTK_CONTAINER (priv->bookmark_list), row); g_free (entry->icon); g_free (entry); } @@ -894,31 +914,29 @@ window_set_bookmarks (YelpWindow *window, } static void -window_set_bookmark_action (YelpWindow *window) +window_set_bookmark_buttons (YelpWindow *window) { YelpUri *uri = NULL; gchar *doc_uri = NULL, *page_id = NULL; - GtkAction *action_add, *action_del; gboolean bookmarked; YelpWindowPrivate *priv = GET_PRIV (window); - action_add = gtk_action_group_get_action (priv->action_group, "AddBookmark"); - action_del = gtk_action_group_get_action (priv->action_group, "RemoveBookmark"); g_object_get (priv->view, "yelp-uri", &uri, "page-id", &page_id, NULL); if (page_id == NULL || uri == NULL) { - gtk_action_set_sensitive (action_add, FALSE); - gtk_action_set_sensitive (action_del, FALSE); + gtk_widget_hide (priv->bookmark_add); + gtk_widget_hide (priv->bookmark_remove); goto done; } doc_uri = yelp_uri_get_document_uri (uri); bookmarked = yelp_application_is_bookmarked (YELP_BOOKMARKS (priv->application), doc_uri, page_id); - gtk_action_set_sensitive (action_add, !bookmarked); - gtk_action_set_sensitive (action_del, bookmarked); + + gtk_widget_set_visible (priv->bookmark_add, !bookmarked); + gtk_widget_set_visible (priv->bookmark_remove, bookmarked); done: g_free (page_id); @@ -928,28 +946,15 @@ window_set_bookmark_action (YelpWindow *window) } static void -window_start_search (GtkAction *action, YelpWindow *window) -{ - YelpWindowPrivate *priv = GET_PRIV (window); - - yelp_location_entry_start_search (priv->entry); -} - -static void window_open_location (GtkAction *action, YelpWindow *window) { +#if 0 YelpUri *yuri = NULL; gchar *uri = NULL; GdkColor yellow; gchar *color; YelpWindowPrivate *priv = GET_PRIV (window); - gtk_container_remove (GTK_CONTAINER (priv->hbox), - priv->align_location); - gtk_box_pack_start (GTK_BOX (priv->hbox), - priv->align_hidden, - TRUE, TRUE, 0); - gtk_widget_show_all (priv->align_hidden); gtk_entry_set_text (GTK_ENTRY (priv->hidden_entry), ""); gtk_widget_grab_focus (priv->hidden_entry); @@ -978,6 +983,7 @@ window_open_location (GtkAction *action, YelpWindow *window) gtk_editable_select_region (GTK_EDITABLE (priv->hidden_entry), 5, -1); g_free (uri); } +#endif } static void @@ -1101,24 +1107,6 @@ app_read_later_changed (YelpApplication *app, } } -static void -window_find_in_page (GtkAction *action, - YelpWindow *window) -{ - YelpWindowPrivate *priv = GET_PRIV (window); - - if (gtk_widget_get_parent (priv->find_bar) != NULL) { - gtk_widget_grab_focus (priv->find_entry); - return; - } - - g_object_set (priv->find_entry, "width-request", 2 * priv->width / 3, NULL); - - gtk_box_pack_end (GTK_BOX (priv->vbox_view), priv->find_bar, FALSE, FALSE, 0); - gtk_widget_show_all (priv->find_bar); - gtk_widget_grab_focus (priv->find_entry); -} - static gboolean find_entry_key_press (GtkEntry *entry, GdkEventKey *event, @@ -1142,19 +1130,6 @@ find_entry_key_press (GtkEntry *entry, return FALSE; } -static gboolean -find_entry_focus_out (GtkEntry *entry, - GdkEventFocus *event, - YelpWindow *window) -{ - YelpWindowPrivate *priv = GET_PRIV (window); - webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (priv->view)); - webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (priv->view), FALSE); - if (gtk_widget_get_parent (priv->find_bar) != NULL) - gtk_container_remove (GTK_CONTAINER (priv->vbox_view), priv->find_bar); - return FALSE; -} - static void find_entry_changed (GtkEntry *entry, YelpWindow *window) @@ -1167,88 +1142,20 @@ find_entry_changed (GtkEntry *entry, text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); - if (text[0] == '\0') { - gtk_label_set_text (GTK_LABEL (priv->find_label), ""); - return; - } - count = webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (priv->view), text, FALSE, 0); if (count > 0) { - gchar *label = g_strdup_printf (ngettext ("%i match", "%i matches", count), count); webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (priv->view), TRUE); webkit_web_view_search_text (WEBKIT_WEB_VIEW (priv->view), text, FALSE, TRUE, TRUE); - gtk_label_set_text (GTK_LABEL (priv->find_label), label); - g_free (label); } else { webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (priv->view), FALSE); - gtk_label_set_text (GTK_LABEL (priv->find_label), _("No matches")); } g_free (text); } -static gboolean -entry_color_animate (YelpWindow *window) -{ - gchar *color; - GdkColor yellow, base; - YelpWindowPrivate *priv = GET_PRIV (window); - - color = yelp_settings_get_color (yelp_settings_get_default (), - YELP_SETTINGS_COLOR_YELLOW_BASE); - gdk_color_parse (color, &yellow); - g_free (color); - - color = yelp_settings_get_color (yelp_settings_get_default (), - YELP_SETTINGS_COLOR_BASE); - gdk_color_parse (color, &base); - g_free (color); - - yellow.red = priv->entry_color_step * yellow.red + (1.0 - priv->entry_color_step) * base.red; - yellow.green = priv->entry_color_step * yellow.green + (1.0 - priv->entry_color_step) * base.green; - yellow.blue = priv->entry_color_step * yellow.blue + (1.0 - priv->entry_color_step) * base.blue; - - gtk_widget_modify_base (gtk_bin_get_child (GTK_BIN (priv->entry)), GTK_STATE_NORMAL, &yellow); - - priv->entry_color_step -= 0.05; - - if (priv->entry_color_step < 0.0) { - priv->entry_color_animate = 0; - return FALSE; - } - - return TRUE; -} - -static gboolean -entry_focus_in (GtkEntry *entry, - GdkEventFocus *event, - YelpWindow *window) -{ - YelpWindowPrivate *priv = GET_PRIV (window); - - if (priv->entry_color_animate != 0) - return FALSE; - - priv->entry_color_step = 1.0; - priv->entry_color_animate = g_timeout_add (40, (GSourceFunc) entry_color_animate, window); - - return FALSE; -} - -static gboolean -entry_focus_out (YelpLocationEntry *entry, - GdkEventFocus *event, - YelpWindow *window) -{ - YelpWindowPrivate *priv = GET_PRIV (window); - gtk_widget_grab_focus (GTK_WIDGET (priv->view)); - return FALSE; -} - static void view_new_window (YelpView *view, YelpUri *uri, @@ -1348,14 +1255,22 @@ view_root_title (YelpView *view, GParamSpec *pspec, YelpWindow *window) { - gchar *title; - g_object_get (view, "root-title", &title, NULL); + YelpWindowPrivate *priv = GET_PRIV (window); + gchar *root_title, *page_title; + g_object_get (view, "root-title", &root_title, "page-title", &page_title, NULL); - if (title) { - gtk_window_set_title (GTK_WINDOW (window), title); - g_free (title); + if (page_title) { + gtk_header_bar_set_title (GTK_HEADER_BAR (priv->header), page_title); + g_free (page_title); } else { - gtk_window_set_title (GTK_WINDOW (window), _("Help")); + gtk_header_bar_set_title (GTK_HEADER_BAR (priv->header), _("Help")); + } + + if (root_title) { + gtk_header_bar_set_subtitle (GTK_HEADER_BAR (priv->header), root_title); + g_free (root_title); + } else { + gtk_header_bar_set_subtitle (GTK_HEADER_BAR (priv->header), NULL); } } @@ -1378,11 +1293,13 @@ hidden_entry_hide (YelpWindow *window) YelpWindowPrivate *priv = GET_PRIV (window); if (gtk_widget_get_parent (priv->align_hidden) != NULL) { +#if 0 gtk_container_remove (GTK_CONTAINER (priv->hbox), priv->align_hidden); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->align_location, TRUE, TRUE, 0); +#endif } } diff --git a/src/yelp-window.h b/src/yelp-window.h index 64db4c0f..a1303068 100644 --- a/src/yelp-window.h +++ b/src/yelp-window.h @@ -36,12 +36,12 @@ typedef struct _YelpWindowClass YelpWindowClass; struct _YelpWindow { - GtkWindow parent; + GtkApplicationWindow parent; }; struct _YelpWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; }; GType yelp_window_get_type (void); |