gnome-commander r1657 - in trunk: . doc doc/C po src
- From: epiotr svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-commander r1657 - in trunk: . doc doc/C po src
- Date: Thu, 20 Mar 2008 21:27:51 +0000 (GMT)
Author: epiotr
Date: Thu Mar 20 21:27:50 2008
New Revision: 1657
URL: http://svn.gnome.org/viewvc/gnome-commander?rev=1657&view=rev
Log:
Added GUI for keyboard shortcuts management
Added:
trunk/src/gnome-cmd-key-shortcuts-dialog.cc
trunk/src/gnome-cmd-key-shortcuts-dialog.h
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/configure.in
trunk/doc/C/gnome-commander.xml
trunk/doc/ChangeLog
trunk/po/POTFILES.in
trunk/po/pl.po
trunk/src/Makefile.am
trunk/src/gnome-cmd-main-menu.cc
trunk/src/gnome-cmd-user-actions.cc
trunk/src/gnome-cmd-user-actions.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Mar 20 21:27:50 2008
@@ -8,6 +8,7 @@
New features:
* Root Mode for starting GNOME Commander with administrator privileges
+ * GUI for keyboard shortcuts management
* Multi-Rename-Tool - new $x and $X placeholders for random hexadecimal numbers
* Updated help docs
* New or updated translations: en_GB, es, eu, fi, oc, pl
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Thu Mar 20 21:27:50 2008
@@ -44,7 +44,7 @@
GLIB_REQ=2.6.0
GMODULE_REQ=2.0.0
-GTK_REQ=2.8.0
+GTK_REQ=2.10.0
GNOME_REQ=2.0.0
GNOMEUI_REQ=2.4.0
GNOMEVFS_REQ=2.0.0
Modified: trunk/doc/C/gnome-commander.xml
==============================================================================
--- trunk/doc/C/gnome-commander.xml (original)
+++ trunk/doc/C/gnome-commander.xml Thu Mar 20 21:27:50 2008
@@ -4306,8 +4306,7 @@
<sect2 id="gnome-commander-user-actions-managing">
<title>Managing user actions</title>
<para>Key bindings reside in [key-bindings] section of &app; config file
- (<term><guilabel>~/.gnome2/gnome-commander</guilabel></term>).
- Currently there is no GUI for key configuration management.</para>
+ (<term><guilabel>~/.gnome2/gnome-commander</guilabel></term>).</para>
<para>Config file syntax:</para>
<para>
<command>[<shift>][<control>][<alt>][<win>]key_name=action[|options]</command>
@@ -4587,7 +4586,12 @@
</row>
<row valign="top">
<entry><para>options.edit_mime_types</para></entry>
- <entry><para>Edit MIME types</para></entry>
+ <entry><para>Configure MIME types</para></entry>
+ <entry><para></para></entry>
+ </row>
+ <row valign="top">
+ <entry><para>options.shortcuts</para></entry>
+ <entry><para>Configure keyboard shortcuts</para></entry>
<entry><para></para></entry>
</row>
<row valign="top">
@@ -5828,6 +5832,9 @@
<para>Root Mode for starting GNOME Commander with administrator privileges</para>
</listitem>
<listitem>
+ <para>GUI for keyboard shortcuts management</para>
+ </listitem>
+ <listitem>
<para>Multi-Rename-Tool - new $x and $X placeholders for random hexadecimal numbers</para>
</listitem>
<listitem>
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Thu Mar 20 21:27:50 2008
@@ -29,6 +29,7 @@
src/gnome-cmd-file-props-dialog.cc
src/gnome-cmd-file-selector.cc
src/gnome-cmd-file.cc
+src/gnome-cmd-key-shortcuts-dialog.cc
src/gnome-cmd-list-popmenu.cc
src/gnome-cmd-main-menu.cc
src/gnome-cmd-main-win.cc
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Thu Mar 20 21:27:50 2008
@@ -50,6 +50,7 @@
gnome-cmd-file.h gnome-cmd-file.cc \
gnome-cmd-hintbox.h gnome-cmd-hintbox.cc \
gnome-cmd-includes.h \
+ gnome-cmd-key-shortcuts-dialog.h gnome-cmd-key-shortcuts-dialog.cc \
gnome-cmd-list-popmenu.h gnome-cmd-list-popmenu.cc \
gnome-cmd-main-menu.h gnome-cmd-main-menu.cc \
gnome-cmd-main-win.h gnome-cmd-main-win.cc \
Added: trunk/src/gnome-cmd-key-shortcuts-dialog.cc
==============================================================================
--- (empty file)
+++ trunk/src/gnome-cmd-key-shortcuts-dialog.cc Thu Mar 20 21:27:50 2008
@@ -0,0 +1,614 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+
+#include "gnome-cmd-includes.h"
+#include "gnome-cmd-key-shortcuts-dialog.h"
+#include "gnome-cmd-data.h"
+#include "gnome-cmd-hintbox.h"
+#include "dict.h"
+#include "utils.h"
+
+using namespace std;
+
+
+#define GNOME_CMD_TYPE_KEY_SHORTCUTS_DIALOG (gnome_cmd_key_shortcuts_dialog_get_type())
+#define GNOME_CMD_KEY_SHORTCUTS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_CMD_TYPE_KEY_SHORTCUTS_DIALOG, GnomeCmdKeyShortcutsDialog))
+#define GNOME_CMD_KEY_SHORTCUTS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_CMD_TYPE_KEY_SHORTCUTS_DIALOG, GnomeCmdKeyShortcutsDialogClass))
+#define GNOME_CMD_IS_KEY_SHORTCUTS_DIALOG(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), GNOME_CMD_TYPE_KEY_SHORTCUTS_DIALOG)
+
+
+typedef struct _GnomeCmdKeyShortcutsDialog GnomeCmdKeyShortcutsDialog;
+typedef struct _GnomeCmdKeyShortcutsDialogClass GnomeCmdKeyShortcutsDialogClass;
+
+
+struct GnomeCmdKeyShortcutsDialogPrivate
+{
+ GnomeCmdUserActions actions; // local copy of user actions
+
+ public:
+
+ GnomeCmdKeyShortcutsDialogPrivate();
+};
+
+
+struct _GnomeCmdKeyShortcutsDialog
+{
+ GtkDialog parent;
+
+ GnomeCmdKeyShortcutsDialogPrivate *priv;
+
+ static GnomeCmdUserActions *user_actions;
+};
+
+
+struct _GnomeCmdKeyShortcutsDialogClass
+{
+ GtkDialogClass parent_class;
+};
+
+
+inline GnomeCmdKeyShortcutsDialogPrivate::GnomeCmdKeyShortcutsDialogPrivate()
+{
+ if (_GnomeCmdKeyShortcutsDialog::user_actions)
+ actions = *_GnomeCmdKeyShortcutsDialog::user_actions;
+}
+
+
+GnomeCmdUserActions *_GnomeCmdKeyShortcutsDialog::user_actions = NULL;
+
+
+G_DEFINE_TYPE (GnomeCmdKeyShortcutsDialog, gnome_cmd_key_shortcuts_dialog, GTK_TYPE_DIALOG)
+
+
+static void gnome_cmd_key_shortcuts_dialog_finalize (GObject *object)
+{
+ GnomeCmdKeyShortcutsDialog *dialog = GNOME_CMD_KEY_SHORTCUTS_DIALOG (object);
+
+ delete dialog->priv;
+
+ G_OBJECT_CLASS (gnome_cmd_key_shortcuts_dialog_parent_class)->finalize (object);
+}
+
+
+static void response_callback (GnomeCmdKeyShortcutsDialog *dialog, int response_id, gpointer data)
+{
+ switch (response_id)
+ {
+ case GTK_RESPONSE_OK:
+ if (dialog->user_actions)
+ *dialog->user_actions = dialog->priv->actions;
+ break;
+
+ case GTK_RESPONSE_NONE:
+ case GTK_RESPONSE_DELETE_EVENT:
+ case GTK_RESPONSE_CANCEL:
+ break;
+
+ case GTK_RESPONSE_HELP:
+ gnome_cmd_help_display ("gnome-commander.xml", "gnome-commander-user-actions");
+ g_signal_stop_emission_by_name (dialog, "response");
+ break;
+
+ default :
+ g_assert_not_reached ();
+ }
+}
+
+
+static void gnome_cmd_key_shortcuts_dialog_class_init (GnomeCmdKeyShortcutsDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gnome_cmd_key_shortcuts_dialog_finalize;
+}
+
+
+inline GtkWidget *create_view_and_model (GnomeCmdUserActions &user_actions);
+inline GtkTreeModel *create_and_fill_model (GnomeCmdUserActions &user_actions);
+
+static void accel_edited_callback (GtkCellRendererAccel *accel, const char *path_string, guint accel_key, GdkModifierType accel_mask, guint hardware_keycode, GtkWidget *view);
+static void cell_edited_callback (GtkCellRendererText *cell, gchar *path_string, gchar *new_text, GtkWidget *view);
+static void add_clicked_callback (GtkButton *button, GtkWidget *view);
+static void remove_clicked_callback (GtkButton *button, GtkWidget *view);
+
+
+static void gnome_cmd_key_shortcuts_dialog_init (GnomeCmdKeyShortcutsDialog *dialog)
+{
+ dialog->priv = new GnomeCmdKeyShortcutsDialogPrivate;
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Keyboard Shortcuts"));
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+ gtk_widget_show (vbox);
+
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_add (GTK_CONTAINER (vbox), hbox);
+ gtk_widget_show (hbox);
+
+ GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_window);
+
+ GtkWidget *view = create_view_and_model (*dialog->user_actions);
+ gtk_widget_set_size_request (view, 600, 400);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), view);
+ gtk_widget_show (view);
+
+ GtkWidget *box = gnome_cmd_hint_box_new (_("To edit a shortcut key, click on the "
+ "corresponding row and type a new "
+ "accelerator, or press escape to "
+ "cancel."));
+ gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
+ gtk_widget_show (box);
+
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+ gtk_widget_show (vbox);
+
+ GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ g_signal_connect (button, "clicked", G_CALLBACK (add_clicked_callback), view);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+ g_signal_connect (button, "clicked", G_CALLBACK (remove_clicked_callback), view);
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (response_callback), dialog);
+
+ gtk_widget_grab_focus (view);
+}
+
+
+void gnome_cmd_key_shortcuts_dialog_new (GnomeCmdUserActions &user_actions)
+{
+ GnomeCmdKeyShortcutsDialog::user_actions = &user_actions; // ugly hack, but can't come to any better method of passing data to gnome_cmd_key_shortcuts_dialog_init ()
+
+ GtkWidget *dialog = gtk_widget_new (GNOME_CMD_TYPE_KEY_SHORTCUTS_DIALOG, NULL);
+
+ g_return_if_fail (dialog != NULL);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+}
+
+
+inline GtkTreeViewColumn *create_new_text_column (GtkTreeView *view, GtkCellRenderer *&renderer, gint COL_ID, const gchar *title=NULL)
+{
+ renderer = gtk_cell_renderer_text_new ();
+
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (title,
+ renderer,
+ "text", COL_ID,
+ NULL);
+ g_object_set (col,
+ "clickable", TRUE,
+ "resizable", TRUE,
+ NULL);
+
+ // pack tree view column into tree view
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+
+ return col;
+}
+
+
+inline GtkTreeViewColumn *create_new_text_column (GtkTreeView *view, gint COL_ID, const gchar *title=NULL)
+{
+ GtkCellRenderer *renderer = NULL;
+
+ return create_new_text_column (view, renderer, COL_ID, title);
+}
+
+
+inline GtkTreeViewColumn *create_new_accel_column (GtkTreeView *view, GtkCellRenderer *&renderer, gint COL_KEYS_ID, gint COL_MODS_ID, const gchar *title=NULL)
+{
+ renderer = gtk_cell_renderer_accel_new ();
+ renderer->mode = GTK_CELL_RENDERER_MODE_EDITABLE;
+ GTK_CELL_RENDERER_TEXT (renderer)->editable = TRUE;
+
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (title,
+ renderer,
+ "accel-key", COL_KEYS_ID,
+ "accel-mods", COL_MODS_ID,
+ // "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
+ NULL);
+ g_object_set (col,
+ "clickable", TRUE,
+ "resizable", TRUE,
+ NULL);
+
+ // pack tree view column into tree view
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+
+ return col;
+}
+
+
+inline GtkTreeViewColumn *create_new_combo_column (GtkTreeView *view, GtkCellRenderer *&renderer, gint COL_ID, const gchar *title=NULL)
+{
+ renderer = gtk_cell_renderer_combo_new ();
+
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (title,
+ renderer,
+ "text", COL_ID,
+ "has-entry", TRUE,
+ // "model", ...,
+ // "text-column", ...,
+ NULL);
+ g_object_set (col,
+ "clickable", TRUE,
+ "resizable", TRUE,
+ NULL);
+
+ // pack tree view column into tree view
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+
+ return col;
+}
+
+
+enum
+{
+ COL_SHORTCUT, // FIXME: temporarily, to be removed
+ COL_ACCEL_KEY,
+ COL_ACCEL_MASK,
+ COL_ACTION,
+ COL_ACCEL_CLOSURE,
+ COL_OPTION,
+ NUM_COLUMNS
+} ;
+
+
+enum
+{
+ SORTID_SHORTCUT, // FIXME: temporarily, to be removed
+ SORTID_ACCEL,
+ SORTID_ACTION,
+ SORTID_OPTION
+};
+
+
+inline GtkWidget *create_view_and_model (GnomeCmdUserActions &user_actions)
+{
+ GtkWidget *view = gtk_tree_view_new ();
+
+ g_object_set (view,
+ "rules-hint", TRUE,
+ "enable-search", TRUE,
+ "search-column", COL_ACTION,
+ NULL);
+
+ GtkCellRenderer *renderer = NULL;
+ GtkTreeViewColumn *col = NULL;
+
+ GtkTooltips *tips = gtk_tooltips_new ();
+
+ col = create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_SHORTCUT, "test: [key-bindings]"); // FIXME: temporarily, to be removed
+ gtk_tooltips_set_tip (tips, col->button, "Keyboard shortcuts as specified in ~/.gnome2/gnome-commander", NULL); // FIXME: temporarily, to be removed
+
+ g_object_set (renderer,
+ "foreground-set", TRUE,
+ "foreground", "DarkGray",
+ NULL);
+
+ col = create_new_accel_column (GTK_TREE_VIEW (view), renderer, COL_ACCEL_KEY, COL_ACCEL_MASK, _("Shortcut Key"));
+ gtk_tooltips_set_tip (tips, col->button, _("Keyboard shortcut for selected action"), NULL);
+ gtk_tree_view_column_set_sort_column_id (col, SORTID_ACCEL);
+
+ g_signal_connect (renderer, "accel-edited", G_CALLBACK (accel_edited_callback), view);
+ // g_signal_connect (renderer, "accel-cleared", G_CALLBACK (gimp_action_view_accel_cleared), view);
+
+ col = create_new_combo_column (GTK_TREE_VIEW (view), renderer, COL_ACTION, _("Action"));
+ gtk_tooltips_set_tip (tips, col->button, _("User action"), NULL);
+ gtk_tree_view_column_set_sort_column_id (col, SORTID_ACTION);
+
+ g_object_set (renderer,
+ "editable", TRUE,
+ NULL);
+
+ col = create_new_text_column (GTK_TREE_VIEW (view), renderer, COL_OPTION, _("Options"));
+ gtk_tooltips_set_tip (tips, col->button, _("Optional data"), NULL);
+ gtk_tree_view_column_set_sort_column_id (col, SORTID_OPTION);
+ g_signal_connect(renderer, "edited", (GCallback) cell_edited_callback, view);
+
+ g_object_set (renderer,
+ "editable", TRUE,
+ "ellipsize-set", TRUE,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ NULL);
+
+ GtkTreeModel *model = create_and_fill_model (user_actions);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
+
+ g_object_unref (model); // destroy model automatically with view
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter_first (gtk_tree_view_get_model (GTK_TREE_VIEW (view)), &iter)) // select the first row here...
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ return view;
+}
+
+
+static gint sort_by_col (GtkTreeModel *model, GtkTreeIter *i1, GtkTreeIter *i2, gpointer COL)
+{
+ gchar *s1;
+ gchar *s2;
+
+ gtk_tree_model_get (model, i1, GPOINTER_TO_UINT (COL), &s1, -1);
+ gtk_tree_model_get (model, i2, GPOINTER_TO_UINT (COL), &s2, -1);
+
+ gint retval = 0;
+
+ if (!s1 && !s2)
+ return retval;
+
+ if (!s1)
+ retval = 1;
+ else
+ if (!s2)
+ retval = -1;
+ else
+ {
+ // compare s1 and s2 in UTF8 aware way, case insensitive
+ gchar *is1 = g_utf8_casefold (s1, -1);
+ gchar *is2 = g_utf8_casefold (s2, -1);
+
+ retval = g_utf8_collate (is1, is2);
+
+ g_free (is1);
+ g_free (is2);
+ }
+
+ g_free (s1);
+ g_free (s2);
+
+ return retval;
+}
+
+
+static gint sort_by_accel (GtkTreeModel *model, GtkTreeIter *i1, GtkTreeIter *i2, gpointer user_data)
+{
+ guint key1, key2;
+ GdkModifierType mask1, mask2;
+
+ gtk_tree_model_get (model, i1, COL_ACCEL_KEY, &key1, COL_ACCEL_MASK, &mask1, -1);
+ gtk_tree_model_get (model, i2, COL_ACCEL_KEY, &key2, COL_ACCEL_MASK, &mask2, -1);
+
+ if (mask1<mask2)
+ return -1;
+
+ if (mask1>mask2)
+ return 1;
+
+ return key1 - key2;
+}
+
+
+inline GtkTreeModel *create_and_fill_model (GnomeCmdUserActions &user_actions)
+{
+ GtkListStore *store = gtk_list_store_new (NUM_COLUMNS,
+ G_TYPE_STRING, // COL_SHORTCUT // FIXME: temporarily, to be removed
+ G_TYPE_UINT, // COL_ACCEL_KEY
+ GDK_TYPE_MODIFIER_TYPE, // COL_ACCEL_MASK
+ G_TYPE_STRING, // COL_ACTION
+ G_TYPE_CLOSURE, // COL_ACCEL_CLOSURE
+ G_TYPE_STRING); // COL_OPTION
+
+ GtkTreeIter iter;
+
+ for (GnomeCmdUserActions::const_iterator i=user_actions.begin(); i!=user_actions.end(); ++i)
+ if (!ascii_isupper (*i)) // ignore lowercase keys as they duplicate uppercase ones
+ {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_SHORTCUT, user_actions.key(i), // FIXME: temporarily, to be removed
+ COL_ACCEL_KEY, i->first.keyval,
+ COL_ACCEL_MASK, i->first.state,
+ COL_ACTION, user_actions.description(i),
+ COL_OPTION, user_actions.options(i),
+ -1);
+ }
+
+ GtkTreeSortable *sortable = GTK_TREE_SORTABLE (store);
+
+ gtk_tree_sortable_set_sort_func (sortable, SORTID_ACCEL, sort_by_accel, NULL, NULL);
+ gtk_tree_sortable_set_sort_func (sortable, SORTID_ACTION, sort_by_col, GUINT_TO_POINTER (COL_ACTION), NULL);
+ gtk_tree_sortable_set_sort_func (sortable, SORTID_OPTION, sort_by_col, GUINT_TO_POINTER (COL_OPTION), NULL);
+
+ gtk_tree_sortable_set_sort_column_id (sortable, SORTID_ACTION, GTK_SORT_ASCENDING); // set initial sort order
+
+ return GTK_TREE_MODEL (store);
+}
+
+
+inline gboolean conflict_confirm (GtkWidget *view, const gchar *action, guint accel_key, GdkModifierType accel_mask)
+{
+ gchar *accel_string = gtk_accelerator_get_label (accel_key, accel_mask);
+
+ GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
+ (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ _("Shortcut \"%s\" is already taken by \"%s\"."),
+ accel_string, action);
+ gtk_dialog_add_buttons (GTK_DIALOG (dlg), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("_Reassign shortcut"), GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_CANCEL);
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Conflicting Shortcuts"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("Reassigning the shortcut will cause it "
+ "to be removed from \"%s\"."), action);
+ gtk_widget_show_all (dlg);
+ gint response = gtk_dialog_run (GTK_DIALOG (dlg));
+
+ gtk_widget_destroy (dlg);
+
+ g_free (accel_string);
+
+ return response==GTK_RESPONSE_OK;
+}
+
+
+inline gboolean equal_accel (GtkTreeModel *model, GtkTreeIter *i, guint key, GdkModifierType mask)
+{
+ guint accel_key = 0;
+ GdkModifierType accel_mask = (GdkModifierType) 0;
+
+ gtk_tree_model_get (model, i,
+ COL_ACCEL_KEY, &accel_key,
+ COL_ACCEL_MASK, &accel_mask,
+ -1);
+
+ return accel_key==key && accel_mask==mask;
+}
+
+
+inline gboolean find_accel (GtkTreeModel *model, GtkTreeIter *i, guint key, GdkModifierType mask)
+{
+ gboolean valid_iter;
+
+ for (valid_iter=gtk_tree_model_get_iter_first (model, i); valid_iter; valid_iter=gtk_tree_model_iter_next (model, i))
+ if (equal_accel (model, i, key, mask))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+inline void set_accel (GtkTreeModel *model, GtkTreePath *path, guint accel_key, GdkModifierType accel_mask)
+{
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_ACCEL_KEY, accel_key,
+ COL_ACCEL_MASK, accel_mask,
+ -1);
+}
+
+
+static void accel_edited_callback (GtkCellRendererAccel *accel, const char *path_string, guint accel_key, GdkModifierType accel_mask, guint hardware_keycode, GtkWidget *view)
+{
+ DEBUG('a', "Key event: %s (%#x)\n", key2str(accel_mask,accel_key).c_str(), accel_key);
+
+ if (!accel_key)
+ gnome_cmd_show_message (NULL, _("Invalid shortcut."));
+ else
+ {
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+ GtkTreeIter iter;
+
+ // do nothing if accelerators haven't changed...
+ if (gtk_tree_model_get_iter (model, &iter, path) && equal_accel (model, &iter, accel_key, accel_mask))
+ return;
+
+ if (!find_accel (model, &iter, accel_key, accel_mask)) // store new values if there isn't any duplicate...
+ set_accel (model, path, accel_key, accel_mask);
+ else
+ {
+ gchar *action;
+
+ gtk_tree_model_get (model, &iter, COL_ACTION, &action, -1); // ...otherwise retrieve conflicting action...
+
+ if (conflict_confirm (view, action, accel_key, accel_mask)) // ...and ask user for confirmation
+ {
+ set_accel (model, path, accel_key, accel_mask);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+
+ g_free (action);
+ }
+
+ gtk_tree_path_free (path);
+ }
+}
+
+
+static void cell_edited_callback (GtkCellRendererText *cell, gchar *path_string, gchar *new_text, GtkWidget *view)
+{
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_OPTION, new_text,
+ -1);
+}
+
+
+static void remove_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+ {
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+}
+
+
+static void add_clicked_callback (GtkButton *button, GtkWidget *view)
+{
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+ GtkTreeIter iter;
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_ACTION, _("Do nothing"), // FIXME: temporarily, use "no.action" -> _("Do nothing")
+ -1);
+
+ GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
+ gtk_widget_grab_focus (view);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, gtk_tree_view_get_column (GTK_TREE_VIEW (view),1), TRUE); // FIXME: temporarily, change col idx 1 -> 0
+ gtk_tree_path_free(path);
+ // start editing accelerator
+}
Added: trunk/src/gnome-cmd-key-shortcuts-dialog.h
==============================================================================
--- (empty file)
+++ trunk/src/gnome-cmd-key-shortcuts-dialog.h Thu Mar 20 21:27:50 2008
@@ -0,0 +1,26 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __GNOME_CMD_KEY_SHORTCUTS_DIALOG_H__
+#define __GNOME_CMD_KEY_SHORTCUTS_DIALOG_H__
+
+#include "gnome-cmd-user-actions.h"
+
+void gnome_cmd_key_shortcuts_dialog_new (GnomeCmdUserActions &user_actions);
+
+#endif // __GNOME_CMD_KEY_SHORTCUTS_DIALOG_H__
Modified: trunk/src/gnome-cmd-main-menu.cc
==============================================================================
--- trunk/src/gnome-cmd-main-menu.cc (original)
+++ trunk/src/gnome-cmd-main-menu.cc Thu Mar 20 21:27:50 2008
@@ -701,7 +701,13 @@
GNOME_APP_PIXMAP_STOCK, GTK_STOCK_PREFERENCES,
NULL
},
- {
+ {
+ MENU_TYPE_ITEM, _("_Keyboard Shortcuts..."), "", NULL,
+ (gpointer) options_edit_shortcuts, NULL,
+ GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ITALIC,
+ NULL
+ },
+ {
MENU_TYPE_ITEM, _("_MIME Types..."), "", NULL,
(gpointer) options_edit_mime_types, NULL,
GNOME_APP_PIXMAP_NONE, 0,
Modified: trunk/src/gnome-cmd-user-actions.cc
==============================================================================
--- trunk/src/gnome-cmd-user-actions.cc (original)
+++ trunk/src/gnome-cmd-user-actions.cc Thu Mar 20 21:27:50 2008
@@ -38,6 +38,7 @@
#include "gnome-cmd-prepare-move-dialog.h"
#include "gnome-cmd-python-plugin.h"
#include "gnome-cmd-search-dialog.h"
+#include "gnome-cmd-key-shortcuts-dialog.h"
#include "gnome-cmd-user-actions.h"
#include "plugin_manager.h"
#include "cap.h"
@@ -175,6 +176,7 @@
{no_action, "no.action", NN_("Do nothing")},
{options_edit, "options.edit", NN_("Options")},
{options_edit_mime_types, "options.edit_mime_types", NN_("MIME types")},
+ {options_edit_shortcuts, "options.shortcuts", NN_("Keyboard shortcuts")},
{plugins_configure, "plugins.configure", NN_("Configure plugins")},
{plugins_execute_python, "plugins.execute_python", NN_("Execute python plugin")},
{view_back, "view.back", NN_("Go back one directory")},
@@ -1122,6 +1124,12 @@
}
+void options_edit_shortcuts (GtkMenuItem *menuitem, gpointer not_used)
+{
+ gnome_cmd_key_shortcuts_dialog_new (gcmd_user_actions);
+}
+
+
void options_edit_mime_types (GtkMenuItem *menuitem, gpointer not_used)
{
edit_mimetypes (NULL, FALSE);
Modified: trunk/src/gnome-cmd-user-actions.h
==============================================================================
--- trunk/src/gnome-cmd-user-actions.h (original)
+++ trunk/src/gnome-cmd-user-actions.h Thu Mar 20 21:27:50 2008
@@ -180,6 +180,8 @@
const_iterator begin() { return action.begin(); }
const_iterator end() { return action.end(); }
+ const gchar *key(const_iterator &i) { return key2str(*i).c_str(); } // FIXME: temporarily, to be removed
+ const gchar *name(const_iterator &i) { return action_func[i->second.func].c_str(); } // FIXME: temporarily, to be removed
const gchar *description(const_iterator &i) { return _(action_name[i->second.func].c_str()); }
const gchar *options(const_iterator &i) { return i->second.user_data.c_str(); }
};
@@ -280,6 +282,7 @@
/************** Options Menu **************/
GNOME_CMD_USER_ACTION(options_edit);
GNOME_CMD_USER_ACTION(options_edit_mime_types);
+GNOME_CMD_USER_ACTION(options_edit_shortcuts);
/************** Connections Menu **************/
GNOME_CMD_USER_ACTION(connections_open);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]