[geany/geany-plugins] a6152b: webhelper: Add support for basic bookmarks

Colomban Wendling git-noreply at xxxxx
Wed Dec 17 19:20:39 UTC 2014


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Wed, 17 Dec 2014 19:20:39 UTC
Commit:      a6152b072365126e7b77c606a8b391dee9cbbf21
             https://github.com/geany/geany-plugins/commit/a6152b072365126e7b77c606a8b391dee9cbbf21

Log Message:
-----------
webhelper: Add support for basic bookmarks


Modified Paths:
--------------
    webhelper/README
    webhelper/src/gwh-browser.c
    webhelper/src/gwh-browser.h
    webhelper/src/gwh-keybindings.h
    webhelper/src/gwh-plugin.c

Modified: webhelper/README
13 lines changed, 12 insertions(+), 1 deletions(-)
===================================================================
@@ -19,7 +19,8 @@ Prominent features
 * Possible automatic reloading of the web view upon document saving;
 * A web inspector/debugging tool for the web view's content (including a
   JavaScript console, a viewer and editor of processed HTML and CSS, a network
-  usage analysis tool and many more, thanks to WebKit).
+  usage analysis tool and many more, thanks to WebKit);
+* Basic bookmarks for quicker access to frequently used URL.
 
 
 Requirements
@@ -46,6 +47,16 @@ When loaded into Geany, this plugins adds a web view in the message window
 (the default), the sidebar or in a separate window. You can find most of the
 features from this view.
 
+Bookmarks
+---------
+
+To add a bookmark, you can click on the website's icon next to its URL and
+check the "Bookmark this website" item.  You can alternatively use the
+configurable keybinding to toggle the bookmark for the current URL.
+
+Bookmarks are displayed in the drop-down menu of the URL bar, sorted
+alphabetically by domain.
+
 
 License
 =======


Modified: webhelper/src/gwh-browser.c
234 lines changed, 232 insertions(+), 2 deletions(-)
===================================================================
@@ -22,6 +22,8 @@
 #include "config.h"
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
@@ -49,6 +51,26 @@
   (GTK_WIDGET_MAPPED ((w)))
 # endif /* defined (gtk_widget_get_mapped) */
 #endif /* GTK_CHECK_VERSION (2, 20, 0) */
+#if ! GTK_CHECK_VERSION (2, 24, 0)
+# define GtkComboBoxText GtkComboBox
+# define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX
+# define GTK_IS_COMBO_BOX_TEXT GTK_IS_COMBO_BOX
+# define gtk_combo_box_text_new_with_entry gtk_combo_box_entry_new_text
+# define gtk_combo_box_text_append_text gtk_combo_box_append_text
+#endif /* GTK_CHECK_VERSION (2, 24, 0) */
+#if ! GTK_CHECK_VERSION (3, 0, 0)
+static void
+combo_box_text_remove_all (GtkComboBoxText *combo_box)
+{
+  GtkListStore *store;
+
+  g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (combo_box));
+
+  store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)));
+  gtk_list_store_clear (store);
+}
+# define gtk_combo_box_text_remove_all combo_box_text_remove_all
+#endif /* GTK_CHECK_VERSION (3, 0, 0) */
 #if GTK_CHECK_VERSION (3, 0, 0)
 /* alias GtkObject, we implement the :destroy signal */
 # define GtkObject          GtkWidget
@@ -76,6 +98,7 @@ struct _GwhBrowserPrivate
   GtkWidget          *inspector_web_view;
   
   GtkWidget    *url_entry;
+  GtkWidget    *url_combo;
   GtkToolItem  *item_prev;
   GtkToolItem  *item_next;
   GtkToolItem  *item_cancel;
@@ -174,6 +197,28 @@ on_settings_browser_last_uri_notify (GObject    *object,
 }
 
 static void
+on_settings_browser_bookmarks_notify (GObject    *object,
+                                      GParamSpec *pspec,
+                                      GwhBrowser *self)
+{
+  gchar **bookmarks;
+  
+  g_return_if_fail (GWH_IS_BROWSER (self));
+  
+  gtk_combo_box_text_remove_all (GTK_COMBO_BOX_TEXT (self->priv->url_combo));
+  bookmarks = gwh_browser_get_bookmarks (self);
+  if (bookmarks) {
+    gchar **p;
+    
+    for (p = bookmarks; *p; p++) {
+      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->priv->url_combo),
+                                      *p);
+    }
+    g_strfreev (bookmarks);
+  }
+}
+
+static void
 on_settings_browser_orientation_notify (GObject    *object,
                                         GParamSpec *pspec,
                                         GwhBrowser *self)
@@ -393,6 +438,53 @@ on_url_entry_activate (GtkEntry    *entry,
 }
 
 static void
+on_url_combo_active_notify (GtkComboBox  *combo,
+                            GParamSpec   *pspec,
+                            GwhBrowser   *self)
+{
+  if (gtk_combo_box_get_active (combo) != -1) {
+    const gchar *uri = gtk_entry_get_text (GTK_ENTRY (self->priv->url_entry));
+    
+    gwh_browser_set_uri (self, uri);
+  }
+}
+
+static void
+on_item_bookmark_toggled (GtkCheckMenuItem *item,
+                          GwhBrowser       *self)
+{
+  if (gtk_check_menu_item_get_active (item)) {
+    gwh_browser_add_bookmark (self, gwh_browser_get_uri (self));
+  } else {
+    gwh_browser_remove_bookmark (self, gwh_browser_get_uri (self));
+  }
+}
+
+static void
+on_url_entry_icon_press (GtkEntry            *entry,
+                         GtkEntryIconPosition icon_pos,
+                         GdkEventButton      *event,
+                         GwhBrowser          *self)
+{
+  if (icon_pos == GTK_ENTRY_ICON_PRIMARY) {
+    GtkWidget    *menu = gtk_menu_new ();
+    GtkWidget    *item;
+    const gchar  *uri = gwh_browser_get_uri (self);
+    
+    item = gtk_check_menu_item_new_with_mnemonic (_("Bookmark this website"));
+    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+                                    gwh_browser_has_bookmark (self, uri));
+    g_signal_connect (item, "toggled",
+                      G_CALLBACK (on_item_bookmark_toggled), self);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+    gtk_widget_show (item);
+    
+    gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+                    event->button, event->time);
+  }
+}
+
+static void
 update_history (GwhBrowser *self)
 {
   WebKitWebView  *web_view = WEBKIT_WEB_VIEW (self->priv->web_view);
@@ -671,6 +763,7 @@ gwh_browser_constructed (GObject *object)
   
   /* a bit ugly, fake notifications */
   g_object_notify (G_OBJECT (self->priv->settings), "browser-last-uri");
+  g_object_notify (G_OBJECT (self->priv->settings), "browser-bookmarks");
   g_object_notify (G_OBJECT (self->priv->settings), "browser-orientation");
   g_object_notify (G_OBJECT (self->priv->settings), "inspector-window-geometry");
 }
@@ -827,14 +920,19 @@ create_toolbar (GwhBrowser *self)
   gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->priv->item_reload, -1);
   gtk_widget_show (GTK_WIDGET (self->priv->item_reload));
   
-  self->priv->url_entry = gtk_entry_new ();
+  self->priv->url_combo = gtk_combo_box_text_new_with_entry ();
   item = gtk_tool_item_new ();
   gtk_tool_item_set_is_important (item, TRUE);
-  gtk_container_add (GTK_CONTAINER (item), self->priv->url_entry);
+  gtk_container_add (GTK_CONTAINER (item), self->priv->url_combo);
   gtk_tool_item_set_expand (item, TRUE);
   gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
   gtk_widget_show_all (GTK_WIDGET (item));
   
+  self->priv->url_entry = gtk_bin_get_child (GTK_BIN (self->priv->url_combo));
+  gtk_entry_set_icon_tooltip_text (GTK_ENTRY (self->priv->url_entry),
+                                   GTK_ENTRY_ICON_PRIMARY,
+                                   _("Website information and settings"));
+  
   self->priv->item_inspector = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_INFO);
   gtk_tool_button_set_label (GTK_TOOL_BUTTON (self->priv->item_inspector), _("Web inspector"));
   gtk_tool_item_set_tooltip_text (self->priv->item_inspector, _("Toggle web inspector"));
@@ -863,6 +961,10 @@ create_toolbar (GwhBrowser *self)
                     G_CALLBACK (on_item_inspector_toggled), self);
   g_signal_connect (G_OBJECT (self->priv->url_entry), "activate",
                     G_CALLBACK (on_url_entry_activate), self);
+  g_signal_connect (G_OBJECT (self->priv->url_entry), "icon-press",
+                    G_CALLBACK (on_url_entry_icon_press), self);
+  g_signal_connect (G_OBJECT (self->priv->url_combo), "notify::active",
+                    G_CALLBACK (on_url_combo_active_notify), self);
   
   return toolbar;
 }
@@ -1059,6 +1161,8 @@ gwh_browser_init (GwhBrowser *self)
   
   g_signal_connect (self->priv->settings, "notify::browser-last-uri",
                     G_CALLBACK (on_settings_browser_last_uri_notify), self);
+  g_signal_connect (self->priv->settings, "notify::browser-bookmarks",
+                    G_CALLBACK (on_settings_browser_bookmarks_notify), self);
   g_signal_connect (self->priv->settings, "notify::browser-orientation",
                     G_CALLBACK (on_settings_browser_orientation_notify), self);
   g_signal_connect (self->priv->settings, "notify::inspector-detached",
@@ -1161,3 +1265,129 @@ gwh_browser_toggle_inspector (GwhBrowser *self)
   
   inspector_set_visible (self, ! INSPECTOR_VISIBLE (self));
 }
+
+gchar **
+gwh_browser_get_bookmarks (GwhBrowser *self)
+{
+  gchar **bookmarks = NULL;
+  
+  g_return_val_if_fail (GWH_IS_BROWSER (self), NULL);
+  
+  g_object_get (self->priv->settings, "browser-bookmarks", &bookmarks, NULL);
+  
+  return bookmarks;
+}
+
+static void
+gwh_browser_set_bookmarks (GwhBrowser  *self,
+                           gchar      **bookmarks)
+{
+  g_object_set (self->priv->settings, "browser-bookmarks", bookmarks, NULL);
+}
+
+static gint
+strv_index (gchar       **strv,
+            const gchar  *str)
+{
+  g_return_val_if_fail (str != NULL, -1);
+  
+  if (strv) {
+    gint idx;
+    
+    for (idx = 0; *strv; strv++, idx++) {
+      if (strcmp (str, *strv) == 0) {
+        return idx;
+      }
+    }
+  }
+  
+  return -1;
+}
+
+gboolean
+gwh_browser_has_bookmark (GwhBrowser   *self,
+                          const gchar  *uri)
+{
+  gchar   **bookmarks = NULL;
+  gboolean  exists    = FALSE;
+  
+  g_return_val_if_fail (GWH_IS_BROWSER (self), FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  bookmarks = gwh_browser_get_bookmarks (self);
+  exists = strv_index (bookmarks, uri) >= 0;
+  g_strfreev (bookmarks);
+  
+  return exists;
+}
+
+static const gchar *
+uri_skip_scheme (const gchar *uri)
+{
+  if (g_ascii_isalpha (*uri)) {
+    do {
+      uri++;
+    } while (*uri == '+' || *uri == '-' || *uri == '.' ||
+             g_ascii_isalnum (*uri));
+    /* this is not strictly correct but good enough for what we do */
+    while (*uri == ':' || *uri == '/')
+      uri++;
+  }
+  
+  return uri;
+}
+
+static int
+sort_uris (gconstpointer a,
+           gconstpointer b)
+{
+  const gchar *uri1 = uri_skip_scheme (*(const gchar *const *) a);
+  const gchar *uri2 = uri_skip_scheme (*(const gchar *const *) b);
+  
+  return g_ascii_strcasecmp (uri1, uri2);
+}
+
+void
+gwh_browser_add_bookmark (GwhBrowser   *self,
+                          const gchar  *uri)
+{
+  gchar **bookmarks = NULL;
+  
+  g_return_if_fail (GWH_IS_BROWSER (self));
+  g_return_if_fail (uri != NULL);
+  
+  bookmarks = gwh_browser_get_bookmarks (self);
+  if (strv_index (bookmarks, uri) < 0) {
+    gsize length = bookmarks ? g_strv_length (bookmarks) : 0;
+    
+    bookmarks = g_realloc (bookmarks, (length + 2) * sizeof *bookmarks);
+    bookmarks[length] = g_strdup (uri);
+    bookmarks[length + 1] = NULL;
+    /* it would be faster to insert directly at the right place but who cares */
+    qsort (bookmarks, length + 1, sizeof *bookmarks, sort_uris);
+    gwh_browser_set_bookmarks (self, bookmarks);
+  }
+  g_strfreev (bookmarks);
+}
+
+void
+gwh_browser_remove_bookmark (GwhBrowser  *self,
+                             const gchar *uri)
+{
+  gchar **bookmarks = NULL;
+  gint    idx;
+  
+  g_return_if_fail (GWH_IS_BROWSER (self));
+  g_return_if_fail (uri != NULL);
+  
+  bookmarks = gwh_browser_get_bookmarks (self);
+  idx = strv_index (bookmarks, uri);
+  if (idx >= 0) {
+    gsize length = g_strv_length (bookmarks);
+    
+    memmove (&bookmarks[idx], &bookmarks[idx + 1],
+             (length - (gsize) idx) * sizeof *bookmarks);
+    gwh_browser_set_bookmarks (self, bookmarks);
+  }
+  g_strfreev (bookmarks);
+}


Modified: webhelper/src/gwh-browser.h
11 lines changed, 11 insertions(+), 0 deletions(-)
===================================================================
@@ -83,6 +83,17 @@ G_GNUC_INTERNAL
 GtkWindow      *gwh_browser_get_inspector_transient_for   (GwhBrowser *self);
 G_GNUC_INTERNAL
 void            gwh_browser_toggle_inspector              (GwhBrowser *self);
+G_GNUC_INTERNAL
+gchar         **gwh_browser_get_bookmarks                 (GwhBrowser *self);
+G_GNUC_INTERNAL
+gboolean        gwh_browser_has_bookmark                  (GwhBrowser  *self,
+                                                           const gchar *uri);
+G_GNUC_INTERNAL
+void            gwh_browser_add_bookmark                  (GwhBrowser  *self,
+                                                           const gchar *uri);
+G_GNUC_INTERNAL
+void            gwh_browser_remove_bookmark               (GwhBrowser  *self,
+                                                           const gchar *uri);
 
 
 G_END_DECLS


Modified: webhelper/src/gwh-keybindings.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
 enum {
   GWH_KB_TOGGLE_INSPECTOR,
   GWH_KB_SHOW_HIDE_SEPARATE_WINDOW,
+  GWH_KB_TOGGLE_BOOKMARK,
   GWH_KB_COUNT
 };
 


Modified: webhelper/src/gwh-plugin.c
21 lines changed, 21 insertions(+), 0 deletions(-)
===================================================================
@@ -284,6 +284,18 @@ on_kb_show_hide_separate_window (guint key_id)
   }
 }
 
+static void
+on_kb_toggle_bookmark (guint key_id)
+{
+  const gchar *uri = gwh_browser_get_uri (GWH_BROWSER (G_browser));
+  
+  if (gwh_browser_has_bookmark (GWH_BROWSER (G_browser), uri)) {
+    gwh_browser_remove_bookmark (GWH_BROWSER (G_browser), uri);
+  } else {
+    gwh_browser_add_bookmark (GWH_BROWSER (G_browser), uri);
+  }
+}
+
 
 static gchar *
 get_config_filename (void)
@@ -312,6 +324,12 @@ load_config (void)
     _("Last URI visited by the browser"),
     "about:blank",
     G_PARAM_READWRITE));
+  gwh_settings_install_property (G_settings, g_param_spec_boxed (
+    "browser-bookmarks",
+    _("Bookmarks"),
+    _("List of bookmarks"),
+    G_TYPE_STRV,
+    G_PARAM_READWRITE));
   gwh_settings_install_property (G_settings, g_param_spec_enum (
     "browser-orientation",
     _("Browser orientation"),
@@ -441,6 +459,9 @@ plugin_init (GeanyData *data)
                         on_kb_show_hide_separate_window, 0, 0,
                         "show_hide_separate_window",
                         _("Show/Hide Web View's Window"), NULL);
+  keybindings_set_item (gwh_keybindings_get_group (), GWH_KB_TOGGLE_BOOKMARK,
+                        on_kb_toggle_bookmark, 0, 0, "toggle_bookmark",
+                        _("Toggle bookmark for the current website"), NULL);
 }
 
 void



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list