[PATCH] keyboard accelerators for bookmarks
Juho Snellman <[email protected]>
| Newsgroups | gmane.comp.web.galeon.devel |
|---|---|
| Message-ID | <[email protected]> |
Attached patch adds support for using any keyboard accelerator information that's found in the bookmark files. There's no UI for adding/modifying accelerators, so as for now it's mainly good for maintaining galeon1 compability. Adding UI support beyond "type a text representation of the shortcut into a text entry field" is beyond my meagre GTK skills. (Too bad that bonobo-ui menus don't seem to support gtk-can-change-accels). The patch also resurrects the galeon1 behaviour on selecting a smart bookmark from a menu/with a keyboard shortcut. A dialog with a text entry widget is popped up, and any text entered there is treated the same way as text entered into the corresponding field in the smart bookmark toolbar. If needed, I can supply separate patches for the above items. -- Juho Snellman
galeon-bookmark-accel-2003-04-01.patch
(text/plain, 21.1 KB)
diff -ur --new-file clean.galeon/bookmarks/bookmarks.c galeon/bookmarks/bookmarks.c
--- clean.galeon/bookmarks/bookmarks.c 2003-04-01 21:43:51.000000000 +0300
+++ galeon/bookmarks/bookmarks.c 2003-04-01 22:05:11.000000000 +0300
@@ -32,6 +32,7 @@
#include "gul-gobject-misc.h"
#include <string.h>
#include "galeon-autocompletion-source.h"
+#include "bonobo/bonobo-ui-util.h"
#define NOT_IMPLEMENTED g_warning ("not implemented: " G_STRLOC);
@@ -909,6 +910,8 @@
{
g_free (c->url);
c->url = g_strdup (b->url);
+ g_free (c->accel_name);
+ c->accel_name = g_strdup (b->accel_name);
c->accel_key = b->accel_key;
c->accel_mods = b->accel_mods;
c->time_visited = b->time_visited;
@@ -970,6 +973,8 @@
g_free (alias->url);
alias->url = s->url;
+ g_free (alias->url);
+ alias->accel_name = s->accel_name;
alias->accel_key = s->accel_key;
alias->accel_mods = s->accel_mods;
alias->time_visited = s->time_visited;
@@ -1039,15 +1044,28 @@
void
gb_site_set_accel (GbSite *b, guint accel_key, guint accel_mods)
{
+ gchar *accel_name = NULL;
+ GbBookmarkSet *set;
+
g_return_if_fail (GB_IS_BOOKMARK (b));
b = GB_SITE (gb_bookmark_real_bookmark ((GbBookmark *) b));
-
+
+ accel_name = bonobo_ui_util_accel_name(accel_key, accel_mods);
+ set = GB_BOOKMARK(b)->set;
+
+ if (set != NULL && accel_name != NULL) {
+ g_hash_table_insert (set->accel_to_bookmark, accel_name, b);
+ }
+
+ g_free(b->accel_name);
+
gb_bookmark_set_needs_saving (b);
do {
- b->accel_mods = accel_mods;
- b->accel_key = accel_key;
+ b->accel_name = accel_name;
+ b->accel_key = accel_key;
+ b->accel_mods = accel_mods;
g_signal_emit (b, GbBookmarkSignals[GB_BOOKMARK_MODIFIED], 0);
gb_folder_emit_child_modified (((GbBookmark *)b)->parent, (GbBookmark *) b);
} while ((b = (GbSite *) ((GbBookmark *) b)->alias) != NULL);
@@ -2437,6 +2455,7 @@
b->default_folder = b->root;
b->id_to_bookmark = g_hash_table_new (NULL, NULL);
b->url_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
+ b->accel_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
#ifdef NICK_HASHTABLE
b->nick_to_bookmark = g_hash_table_new (g_str_hash, g_str_equal);
#endif
@@ -2500,6 +2519,7 @@
g_hash_table_size (set->url_to_bookmark),
g_hash_table_size (set->id_to_bookmark)));
+ g_hash_table_destroy (set->accel_to_bookmark);
g_hash_table_destroy (set->url_to_bookmark);
#ifdef NICK_HASHTABLE
g_hash_table_destroy (set->nick_to_bookmark);
@@ -2791,6 +2811,13 @@
return g_hash_table_lookup (set->url_to_bookmark, url);
}
+GbBookmark *
+gb_bookmark_set_get_bookmark_by_accel (GbBookmarkSet *set,
+ const gchar *accel_name)
+{
+ return g_hash_table_lookup (set->accel_to_bookmark, accel_name);
+}
+
static GbBookmark *
gb_bookmark_set_get_bookmark_by_nick_rec (GbFolder *root,
const gchar *nick)
diff -ur --new-file clean.galeon/bookmarks/bookmarks.h galeon/bookmarks/bookmarks.h
--- clean.galeon/bookmarks/bookmarks.h 2003-04-01 21:43:51.000000000 +0300
+++ galeon/bookmarks/bookmarks.h 2003-04-01 19:09:14.000000000 +0300
@@ -183,6 +183,7 @@
/* accel data */
guint accel_key;
guint accel_mods;
+ gchar *accel_name;
/* time info */
GTime time_visited;
@@ -442,6 +443,7 @@
GHashTable *id_to_bookmark;
GHashTable *url_to_bookmark;
+ GHashTable *accel_to_bookmark;
GSList *unresolved_aliases;
@@ -475,6 +477,8 @@
void gb_bookmark_set_fix_galeon1_mess (GbBookmarkSet *set);
GbBookmark * gb_bookmark_set_get_bookmark_by_url (GbBookmarkSet *set,
const gchar *url);
+GbBookmark * gb_bookmark_set_get_bookmark_by_accel (GbBookmarkSet *set,
+ const gchar *accel_name);
GbBookmark * gb_bookmark_set_get_bookmark_by_nick (GbBookmarkSet *set,
const gchar *nick);
gchar * gb_bookmark_set_get_url_by_nick_and_args (GbBookmarkSet *set,
diff -ur --new-file clean.galeon/bookmarks/xbel.c galeon/bookmarks/xbel.c
--- clean.galeon/bookmarks/xbel.c 2003-04-01 21:43:52.000000000 +0300
+++ galeon/bookmarks/xbel.c 2003-04-01 22:06:14.000000000 +0300
@@ -726,9 +726,11 @@
md->smart_site_history = gb_smart_site_get_history (GB_SMART_SITE (b), 0);
}
md->t_vis = b->time_visited;
+
+
md->acc_mod = b->accel_mods;
- md->acc_key = b->accel_key;
-
+ md->acc_key = b->accel_key;
+
xbel_save_galeon_metadata (newNode, md);
gb_xbel_metadata_free (md);
diff -ur --new-file clean.galeon/src/galeon-window.c galeon/src/galeon-window.c
--- clean.galeon/src/galeon-window.c 2003-04-01 21:43:54.000000000 +0300
+++ galeon/src/galeon-window.c 2003-04-01 21:50:46.000000000 +0300
@@ -35,6 +35,7 @@
#include "galeon-shell.h"
#include "bookmarks-bonoboui-menu.h"
#include "bookmarks-bonoboui-tb.h"
+#include "bookmarks-util.h"
#include "gul-bonobo-extensions.h"
#include "eel-gconf-extensions.h"
#include "prefs-strings.h"
@@ -43,6 +44,7 @@
#include "bookmarks-editor-dockable.h"
#include "window-recent-history-menu.h"
#include "galeon-embed-prefs.h"
+#include "smart-bookmark-dialog.h"
#include <stdlib.h>
#include <string.h>
@@ -220,6 +222,10 @@
void /* yes, this is not static */
galeon_window_bookmark_activate (GaleonWindow *w, GbBookmarkEventActivated *ev);
+void
+static galeon_window_show_smart_bookmark_dialog (GaleonWindow *window,
+ GbSmartSite *bookmark);
+
static char *
galeon_window_gb_location_source_get_location (GbLocationSource *src);
static char *
@@ -276,6 +282,9 @@
GdkEventKey *event,
GaleonWindow *window)
{
+ GbBookmarkSet *bs;
+ GbSite *s;
+ gchar *accel_name;
int page;
if ((event->state & GDK_Shift_L) || (event->state & GDK_Shift_R))
@@ -296,6 +305,23 @@
}
}
+ accel_name = bonobo_ui_util_accel_name(event->keyval, event->state);
+
+ bs = galeon_shell_get_bookmark_set (galeon_shell);
+ s = GB_SITE (gb_bookmark_set_get_bookmark_by_accel (bs, accel_name));
+ g_free(accel_name);
+
+ if (s != NULL) {
+ GbBookmarkEventActivated event = { GB_BOOKMARK (s),
+ s->url, GB_BAF_DEFAULT,
+ NULL};
+ galeon_window_bookmark_activate ( GALEON_WINDOW (widget),
+ &event );
+ /* galeon_window_load_url ( GALEON_WINDOW (widget), s->url); */
+ return TRUE;
+ }
+
+
return FALSE;
}
@@ -1981,7 +2023,17 @@
if (GB_IS_SITE (b) && f == GB_BAF_DEFAULT)
{
- galeon_window_load_url (w, url);
+ if (GB_IS_SMART_SITE (b) &&
+ /* The smart bookmark url being the same as the
+ * event url implies that the user selected the
+ * bookmark from a menu or using a keyboard shortcut.
+ */
+ strcmp(GB_SMART_SITE(b)->smarturl, url) == 0)
+ {
+ galeon_window_show_smart_bookmark_dialog (w, GB_SMART_SITE(b));
+ } else {
+ galeon_window_load_url (w, url);
+ }
return;
}
@@ -2146,6 +2198,14 @@
}
void
+static galeon_window_show_smart_bookmark_dialog (GaleonWindow *window,
+ GbSmartSite *bookmark)
+{
+ GaleonDialog *dialog = smart_bookmark_dialog_new (window, bookmark);
+ galeon_dialog_show (dialog);
+}
+
+void
galeon_window_show_history (GaleonWindow *window)
{
GaleonEmbed *embed;
diff -ur --new-file clean.galeon/src/Makefile.am galeon/src/Makefile.am
--- clean.galeon/src/Makefile.am 2003-04-01 21:43:53.000000000 +0300
+++ galeon/src/Makefile.am 2003-03-31 23:28:59.000000000 +0300
@@ -87,6 +87,8 @@
network-prefs.h \
pdm-dialog.c \
pdm-dialog.h \
+ smart-bookmark-dialog.c \
+ smart-bookmark-dialog.h \
galeon-bookmarks-icon-provider.h \
galeon-bookmarks-icon-provider.c \
window-recent-history.h \
diff -ur --new-file clean.galeon/src/smart-bookmark-dialog.c galeon/src/smart-bookmark-dialog.c
--- clean.galeon/src/smart-bookmark-dialog.c 1970-01-01 02:00:00.000000000 +0200
+++ galeon/src/smart-bookmark-dialog.c 2003-04-01 13:06:57.000000000 +0300
@@ -0,0 +1,172 @@
+/*
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "smart-bookmark-dialog.h"
+#include "galeon-shell.h"
+#include "bookmarks.h"
+#include "gtk/gtkentry.h"
+#include "gtk/gtklabel.h"
+#include "gtk/gtkbutton.h"
+
+static GObjectClass *parent_class = NULL;
+
+static void
+smart_bookmark_dialog_class_init (SmartBookmarkDialogClass *klass);
+static void
+smart_bookmark_dialog_init (SmartBookmarkDialog *dialog);
+static void
+smart_bookmark_dialog_finalize (GObject *object);
+
+void
+smart_bookmark_dialog_ok_cb (GtkButton *button,
+ SmartBookmarkDialog *dialog);
+void
+smart_bookmark_dialog_cancel_cb (GtkButton *button,
+ SmartBookmarkDialog *dialog);
+
+enum
+{
+ PROP_BOOKMARK_NAME,
+ PROP_BOOKMARK_DATA,
+ PROP_OK_BUTTON,
+ PROP_CANCEL_BUTTON
+};
+
+static const
+GaleonDialogProperty properties [] =
+{
+ { PROP_BOOKMARK_NAME, "bookmark_name_label", NULL, PT_NORMAL, NULL },
+ { PROP_BOOKMARK_DATA, "bookmark_data_entry", NULL, PT_NORMAL, NULL },
+ { PROP_OK_BUTTON, "ok_button", NULL, PT_NORMAL, NULL },
+ { PROP_CANCEL_BUTTON, "cancel_button", NULL, PT_NORMAL, NULL },
+
+ { -1, NULL, NULL }
+};
+
+GType
+smart_bookmark_dialog_get_type (void)
+{
+ static GType smart_bookmark_dialog_type = 0;
+
+ if (smart_bookmark_dialog_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (SmartBookmarkDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) smart_bookmark_dialog_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (SmartBookmarkDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) smart_bookmark_dialog_init
+ };
+
+ smart_bookmark_dialog_type = g_type_register_static (GALEON_DIALOG_TYPE,
+ "SmartBookmarkDialog",
+ &our_info, 0);
+ }
+
+ return smart_bookmark_dialog_type;
+}
+
+static void
+smart_bookmark_dialog_class_init (SmartBookmarkDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = smart_bookmark_dialog_finalize;
+}
+
+static void
+smart_bookmark_dialog_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+smart_bookmark_dialog_set_bookmark (SmartBookmarkDialog *dialog,
+ GbSmartSite *bookmark)
+{
+ GtkLabel *name_label;
+
+ dialog->bookmark = bookmark;
+
+ name_label = GTK_LABEL(galeon_dialog_get_control(GALEON_DIALOG(dialog),
+ PROP_BOOKMARK_NAME));
+
+ gtk_label_set_text(name_label, GB_BOOKMARK(bookmark)->name);
+}
+
+GaleonDialog *
+smart_bookmark_dialog_new (GaleonWindow *parent, GbSmartSite *bookmark)
+{
+ GaleonDialog *dialog;
+
+ dialog = GALEON_DIALOG (g_object_new (SMART_BOOKMARK_DIALOG_TYPE,
+ NULL));
+
+ SMART_BOOKMARK_DIALOG (dialog)->window = parent;
+ smart_bookmark_dialog_set_bookmark (SMART_BOOKMARK_DIALOG (dialog),
+ bookmark);
+
+ return dialog;
+}
+
+static void
+smart_bookmark_dialog_init (SmartBookmarkDialog *dialog)
+{
+ galeon_dialog_construct (GALEON_DIALOG(dialog),
+ properties,
+ "galeon.glade",
+ "smart_bookmark_dialog");
+}
+
+static const gchar*
+smart_bookmark_dialog_get_url (SmartBookmarkDialog *dialog)
+{
+ GtkEntry *data_entry = GTK_ENTRY(galeon_dialog_get_control(GALEON_DIALOG(dialog),
+ PROP_BOOKMARK_DATA));
+ return gtk_entry_get_text(data_entry);
+}
+
+void
+smart_bookmark_dialog_ok_cb (GtkButton *button,
+ SmartBookmarkDialog *dialog)
+{
+ const gchar *arg = smart_bookmark_dialog_get_url(dialog);
+ const gchar *args[] = { arg, NULL };
+ const gchar *url = gb_smart_site_subst_args(dialog->bookmark, args);
+
+ printf("url=%s\n", url);
+
+ galeon_window_load_url(dialog->window, url);
+
+ galeon_dialog_destruct (GALEON_DIALOG (dialog));
+ g_object_unref (dialog);
+ g_free(url);
+}
+
+void
+smart_bookmark_dialog_cancel_cb (GtkButton *button,
+ SmartBookmarkDialog *dialog) {
+ galeon_dialog_destruct (GALEON_DIALOG (dialog));
+ g_object_unref (dialog);
+}
diff -ur --new-file clean.galeon/src/smart-bookmark-dialog.h galeon/src/smart-bookmark-dialog.h
--- clean.galeon/src/smart-bookmark-dialog.h 1970-01-01 02:00:00.000000000 +0200
+++ galeon/src/smart-bookmark-dialog.h 2003-04-01 00:33:36.000000000 +0300
@@ -0,0 +1,54 @@
+/*
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SMART_BOOKMARK_DIALOG_H
+#define SMART_BOOKMARK_DIALOG_H
+
+#include <galeon-dialog.h>
+#include <glib-object.h>
+#include <glib.h>
+
+#include "bookmarks.h"
+#include "galeon-window.h"
+
+typedef struct SmartBookmarkDialog SmartBookmarkDialog;
+typedef struct SmartBookmarkDialogClass SmartBookmarkDialogClass;
+
+#define SMART_BOOKMARK_DIALOG_TYPE (smart_bookmark_dialog_get_type ())
+#define SMART_BOOKMARK_DIALOG(obj) (GTK_CHECK_CAST ((obj), SMART_BOOKMARK_DIALOG_TYPE, SmartBookmarkDialog))
+#define SMART_BOOKMARK_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SMART_BOOKMARK_DIALOG, SmartBookmarkDialogClass))
+#define IS_SMART_BOOKMARK_DIALOG(obj) (GTK_CHECK_TYPE ((obj), SMART_BOOKMARK_DIALOG_TYPE))
+#define IS_SMART_BOOKMARK_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SMART_BOOKMARK_DIALOG))
+
+typedef struct SmartBookmarkDialogPrivate SmartBookmarkDialogPrivate;
+
+struct SmartBookmarkDialog
+{
+ GaleonDialog parent;
+ GbSmartSite *bookmark;
+ GaleonWindow *window;
+};
+
+struct SmartBookmarkDialogClass
+{
+ GaleonDialogClass parent_class;
+};
+
+GType smart_bookmark_dialog_get_type (void);
+GaleonDialog *smart_bookmark_dialog_new (GaleonWindow *parent,
+ GbSmartSite *bookmark);
+
+#endif
diff -ur --new-file clean.galeon/ui/galeon.glade galeon/ui/galeon.glade
--- clean.galeon/ui/galeon.glade 2003-04-01 21:44:02.000000000 +0300
+++ galeon/ui/galeon.glade 2003-04-01 13:38:16.000000000 +0300
@@ -4060,4 +4060,118 @@
</child>
</widget>
+<widget class="GtkDialog" id="smart_bookmark_dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Galeon smart bookmark</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox29">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area29">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancel_button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-6</property>
+ <signal name="clicked" handler="smart_bookmark_dialog_cancel_cb" last_modification_time="Mon, 31 Mar 2003 20:53:24 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="ok_button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-5</property>
+ <signal name="clicked" handler="smart_bookmark_dialog_ok_cb" last_modification_time="Mon, 31 Mar 2003 20:52:43 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox137">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="bookmark_name_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">BOOKMARK_NAME</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="bookmark_data_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
</glade-interface>