[gthumb] scripts: save the accelerators as window shortcuts
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] scripts: save the accelerators as window shortcuts
- Date: Sun, 24 Nov 2019 12:33:03 +0000 (UTC)
commit 3450a75e015d5b891d36be30e39efc02b50cf4f1
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Nov 16 10:14:54 2019 +0100
scripts: save the accelerators as window shortcuts
This allows to handle accelerator collisions and change the
script shortcuts from the preferences dialog as well.
extensions/list_tools/callbacks.c | 13 +--
extensions/list_tools/dlg-personalize-scripts.c | 125 +++++++++++++++++------
extensions/list_tools/gth-script-editor-dialog.c | 60 ++++++++---
extensions/list_tools/gth-script-editor-dialog.h | 1 +
extensions/list_tools/gth-script.c | 79 ++++++++------
extensions/list_tools/gth-script.h | 7 +-
extensions/list_tools/shortcuts.h | 1 +
gthumb/dlg-preferences-shortcuts.c | 96 +++++------------
gthumb/gth-shortcut.c | 80 ++++++++++++---
gthumb/gth-shortcut.h | 10 +-
gthumb/gth-window.c | 115 +++++++++++++++++++--
gthumb/gth-window.h | 8 ++
12 files changed, 413 insertions(+), 182 deletions(-)
---
diff --git a/extensions/list_tools/callbacks.c b/extensions/list_tools/callbacks.c
index 2c23533e..fffa1732 100644
--- a/extensions/list_tools/callbacks.c
+++ b/extensions/list_tools/callbacks.c
@@ -29,10 +29,10 @@
#include "gth-script-file.h"
#include "gth-script-task.h"
#include "list-tools.h"
+#include "shortcuts.h"
#define BROWSER_DATA_KEY "list-tools-browser-data"
-#define SCRIPTS_GROUP "scripts"
static const GActionEntry actions[] = {
@@ -76,23 +76,18 @@ update_scripts (BrowserData *data)
GthScript *script = scan->data;
GthShortcut *shortcut;
- shortcut = gth_script_get_shortcut (script);
+ shortcut = gth_script_create_shortcut (script);
gth_window_add_removable_shortcut (GTH_WINDOW (data->browser),
SCRIPTS_GROUP,
shortcut);
if (gth_script_is_visible (script)) {
- char *detailed_action;
-
- detailed_action = g_strdup_printf ("win.exec-script('%s')", gth_script_get_id
(script));
gth_menu_manager_append_entry (menu_manager,
data->menu_merge_id,
gth_script_get_display_name (script),
- detailed_action,
- shortcut->label,
+ shortcut->detailed_action,
+ "",
NULL);
-
- g_free (detailed_action);
}
gth_shortcut_free (shortcut);
diff --git a/extensions/list_tools/dlg-personalize-scripts.c b/extensions/list_tools/dlg-personalize-scripts.c
index 0a765a3f..6737adcd 100644
--- a/extensions/list_tools/dlg-personalize-scripts.c
+++ b/extensions/list_tools/dlg-personalize-scripts.c
@@ -27,6 +27,7 @@
#include "gth-script.h"
#include "gth-script-editor-dialog.h"
#include "gth-script-file.h"
+#include "shortcuts.h"
#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
@@ -131,13 +132,15 @@ row_inserted_cb (GtkTreeModel *tree_model,
static char *
-get_script_shortcut (GthScript *script)
+get_shortcut_label (DialogData *data,
+ GthScript *script)
{
- guint keyval;
- GdkModifierType modifiers;
+ GthShortcut *shortcut;
- gth_script_get_accelerator (script, &keyval, &modifiers);
- return gtk_accelerator_get_label (keyval, modifiers);
+ shortcut = gth_window_get_shortcut (GTH_WINDOW (data->browser),
+ gth_script_get_detailed_action (script));
+
+ return (shortcut != NULL) ? shortcut->label : "";
}
@@ -151,20 +154,15 @@ set_script_list (DialogData *data,
for (scan = script_list; scan; scan = scan->next) {
GthScript *script = scan->data;
- char *shortcut;
GtkTreeIter iter;
- shortcut = get_script_shortcut (script);
-
gtk_list_store_append (data->list_store, &iter);
gtk_list_store_set (data->list_store, &iter,
COLUMN_SCRIPT, script,
COLUMN_NAME, gth_script_get_display_name (script),
- COLUMN_SHORTCUT, shortcut,
+ COLUMN_SHORTCUT, get_shortcut_label (data, script),
COLUMN_VISIBLE, gth_script_is_visible (script),
-1);
-
- g_free (shortcut);
}
g_signal_handlers_unblock_by_func (data->list_store, row_inserted_cb, data);
@@ -295,7 +293,31 @@ add_columns (GtkTreeView *treeview,
static gboolean
-get_script_iter (DialogData *data,
+get_iter_for_shortcut (DialogData *data,
+ GthShortcut *shortcut,
+ GtkTreeIter *iter)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (data->list_store);
+ gboolean found = FALSE;
+ if (! gtk_tree_model_get_iter_first (model, iter))
+ return FALSE;
+
+ do {
+ GthScript *script;
+
+ gtk_tree_model_get (model, iter, COLUMN_SCRIPT, &script, -1);
+ found = g_strcmp0 (shortcut->detailed_action, gth_script_get_detailed_action (script)) == 0;
+
+ g_object_unref (script);
+ }
+ while (! found && gtk_tree_model_iter_next (model, iter));
+
+ return found;
+}
+
+
+static gboolean
+get_iter_script (DialogData *data,
GthScript *script,
GtkTreeIter *iter)
{
@@ -329,16 +351,12 @@ script_editor_dialog__response_cb (GtkDialog *dialog,
DialogData *data = user_data;
GthScript *script;
GError *error = NULL;
+ GPtrArray *shortcuts_v;
GthScriptFile *script_file;
gboolean new_script;
+ GthShortcut *shortcut;
GtkTreeIter iter;
- gboolean change_list = TRUE;
-
-
- if (response == GTK_RESPONSE_HELP) {
- /* FIXME: show help dialog */
- return;
- }
+ gboolean change_list;
if (response != GTK_RESPONSE_OK) {
gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -352,42 +370,71 @@ script_editor_dialog__response_cb (GtkDialog *dialog,
return;
}
- /* update the script file */
+ /* update the shortcuts */
+
+ shortcuts_v = g_ptr_array_copy (gth_window_get_shortcuts (GTH_WINDOW (data->browser)),
+ (GCopyFunc) gth_shortcut_dup,
+ NULL);
+
+ /* If another shortcut has the same accelerator, reset the accelerator
+ * for that shortcut. */
+
+ shortcut = gth_shortcut_array_find_by_accel (shortcuts_v,
+ GTH_SHORTCUT_CONTEXT_BROWSER_VIEWER,
+ gth_script_get_accelerator (script));
+ if (shortcut != NULL) {
+ if (g_strcmp0 (shortcut->detailed_action, gth_script_get_detailed_action (script)) != 0) {
+ if (get_iter_for_shortcut (data, shortcut, &iter))
+ gtk_list_store_set (data->list_store, &iter,
+ COLUMN_SHORTCUT, "",
+ -1);
+ gth_shortcut_set_key (shortcut, 0, 0);
+ }
+ }
+
+ /* update the script shortcut */
+
+ shortcut = gth_shortcut_array_find_by_action (shortcuts_v, gth_script_get_detailed_action (script));
+ if (shortcut != NULL)
+ g_ptr_array_remove (shortcuts_v, shortcut);
+
+ shortcut = gth_script_create_shortcut (script);
+ g_ptr_array_add (shortcuts_v, shortcut);
+
+ /* save the script */
script_file = gth_script_file_get ();
new_script = ! gth_script_file_has_script (script_file, script);
g_signal_handlers_block_by_func (script_file, scripts_changed_cb, data);
gth_script_file_add (script_file, script);
- gth_script_file_save (script_file, NULL); /* FIXME: handle errors */
+ gth_script_file_save (script_file, NULL);
g_signal_handlers_unblock_by_func (script_file, scripts_changed_cb, data);
+ gth_main_shortcuts_changed (shortcuts_v);
+
/* update the script list */
if (new_script) {
g_signal_handlers_block_by_func (data->list_store, row_inserted_cb, data);
gtk_list_store_append (data->list_store, &iter);
g_signal_handlers_unblock_by_func (data->list_store, row_inserted_cb, data);
+ change_list = TRUE;
}
else
- change_list = get_script_iter (data, script, &iter);
+ change_list = get_iter_script (data, script, &iter);
- if (change_list) {
- char *shortcut;
-
- shortcut = get_script_shortcut (script);
+ if (change_list)
gtk_list_store_set (data->list_store, &iter,
COLUMN_SCRIPT, script,
COLUMN_NAME, gth_script_get_display_name (script),
- COLUMN_SHORTCUT, shortcut,
+ COLUMN_SHORTCUT, shortcut->label,
COLUMN_VISIBLE, gth_script_is_visible (script),
-1);
- g_free (shortcut);
- }
-
gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_ptr_array_unref (shortcuts_v);
g_object_unref (script);
}
@@ -398,7 +445,7 @@ new_script_cb (GtkButton *button,
{
GtkWidget *dialog;
- dialog = gth_script_editor_dialog_new (_("New Command"), GTK_WINDOW (data->dialog));
+ dialog = gth_script_editor_dialog_new (_("New Command"), GTH_WINDOW (data->browser), GTK_WINDOW
(data->dialog));
g_signal_connect (dialog, "response",
G_CALLBACK (script_editor_dialog__response_cb),
data);
@@ -425,7 +472,7 @@ edit_script_cb (GtkButton *button,
if (script == NULL)
return;
- dialog = gth_script_editor_dialog_new (_("Edit Command"), GTK_WINDOW (data->dialog));
+ dialog = gth_script_editor_dialog_new (_("Edit Command"), GTH_WINDOW (data->browser), GTK_WINDOW
(data->dialog));
gth_script_editor_dialog_set_script (GTH_SCRIPT_EDITOR_DIALOG (dialog), script);
g_signal_connect (dialog,
"response",
@@ -448,6 +495,8 @@ delete_script_cb (GtkButton *button,
GtkTreeModel *model = GTK_TREE_MODEL (data->list_store);
GtkTreeIter iter;
GthScript *script;
+ GPtrArray *shortcuts_v;
+ GthShortcut *shortcut;
GthScriptFile *script_file;
d = _gtk_message_dialog_new (GTK_WINDOW (data->dialog),
@@ -471,6 +520,16 @@ delete_script_cb (GtkButton *button,
if (script == NULL)
return;
+ /* update the shortcuts */
+
+ shortcuts_v = g_ptr_array_copy (gth_window_get_shortcuts (GTH_WINDOW (data->browser)),
+ (GCopyFunc) gth_shortcut_dup,
+ NULL);
+
+ shortcut = gth_shortcut_array_find_by_action (shortcuts_v, gth_script_get_detailed_action (script));
+ if (shortcut != NULL)
+ g_ptr_array_remove (shortcuts_v, shortcut);
+
/* update the script file */
script_file = gth_script_file_get ();
@@ -479,6 +538,8 @@ delete_script_cb (GtkButton *button,
gth_script_file_save (script_file, NULL);
g_signal_handlers_unblock_by_func (script_file, scripts_changed_cb, data);
+ gth_main_shortcuts_changed (shortcuts_v);
+
/* update the script list */
g_signal_handlers_block_by_func (data->list_store, row_deleted_cb, data);
diff --git a/extensions/list_tools/gth-script-editor-dialog.c
b/extensions/list_tools/gth-script-editor-dialog.c
index 48333c78..659c4a22 100644
--- a/extensions/list_tools/gth-script-editor-dialog.c
+++ b/extensions/list_tools/gth-script-editor-dialog.c
@@ -37,14 +37,16 @@ enum {
};
struct _GthScriptEditorDialogPrivate {
- GtkBuilder *builder;
- GtkWidget *accel_button;
- char *script_id;
- gboolean script_visible;
- gboolean wait_command;
- gboolean shell_script;
- gboolean for_each_file;
- gboolean help_visible;
+ GthWindow *shortcut_window;
+ GtkBuilder *builder;
+ GtkWidget *accel_button;
+ char *script_id;
+ gboolean script_visible;
+ gboolean wait_command;
+ gboolean shell_script;
+ gboolean for_each_file;
+ gboolean help_visible;
+ GthShortcut *shortcut;
};
@@ -90,6 +92,8 @@ gth_script_editor_dialog_init (GthScriptEditorDialog *dialog)
dialog->priv->shell_script = FALSE;
dialog->priv->for_each_file = FALSE;
dialog->priv->help_visible = FALSE;
+ dialog->priv->shortcut = NULL;
+ dialog->priv->shortcut_window = NULL;
}
@@ -117,6 +121,26 @@ command_entry_icon_press_cb (GtkEntry *entry,
}
+static gboolean
+accel_button_change_value_cb (GthAccelButton *button,
+ guint keycode,
+ GdkModifierType modifiers,
+ gpointer user_data)
+{
+ GthScriptEditorDialog *self = user_data;
+ gboolean change;
+
+ change = gth_window_can_change_shortcut (self->priv->shortcut_window,
+ self->priv->shortcut != NULL ?
self->priv->shortcut->detailed_action : NULL,
+ GTH_SHORTCUT_CONTEXT_BROWSER_VIEWER,
+ keycode,
+ modifiers,
+ GTK_WINDOW (self));
+
+ return change ? GDK_EVENT_PROPAGATE : GDK_EVENT_STOP;
+}
+
+
static void
gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
const char *title,
@@ -138,6 +162,11 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))),
_gtk_builder_get_widget (self->priv->builder, "script_editor"), TRUE, TRUE, 0);
self->priv->accel_button = gth_accel_button_new ();
+ g_signal_connect (self->priv->accel_button,
+ "change-value",
+ G_CALLBACK (accel_button_change_value_cb),
+ self);
+
gtk_widget_show (self->priv->accel_button);
gtk_box_pack_start (GTK_BOX (GET_WIDGET ("accel_box")), self->priv->accel_button, FALSE, FALSE, 0);
@@ -154,6 +183,7 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
GtkWidget *
gth_script_editor_dialog_new (const char *title,
+ GthWindow *shortcut_window,
GtkWindow *parent)
{
GthScriptEditorDialog *self;
@@ -161,6 +191,7 @@ gth_script_editor_dialog_new (const char *title,
self = g_object_new (GTH_TYPE_SCRIPT_EDITOR_DIALOG,
"use-header-bar", _gtk_settings_get_dialogs_use_header (),
NULL);
+ self->priv->shortcut_window = shortcut_window;
gth_script_editor_dialog_construct (self, title, parent);
return (GtkWidget *) self;
@@ -186,14 +217,11 @@ gth_script_editor_dialog_set_script (GthScriptEditorDialog *self,
g_free (self->priv->script_id);
self->priv->script_id = NULL;
self->priv->script_visible = TRUE;
+ self->priv->shortcut = NULL;
_gth_script_editor_dialog_set_new_script (self);
if (script != NULL) {
- guint keyval;
- GdkModifierType modifiers;
-
-
self->priv->script_id = g_strdup (gth_script_get_id (script));
self->priv->script_visible = gth_script_is_visible (script);
@@ -203,8 +231,12 @@ gth_script_editor_dialog_set_script (GthScriptEditorDialog *self,
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("for_each_file_checkbutton")),
gth_script_for_each_file (script));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("wait_command_checkbutton")),
gth_script_wait_command (script));
- gth_script_get_accelerator (script, &keyval, &modifiers);
- gth_accel_button_set_accelerator (GTH_ACCEL_BUTTON (self->priv->accel_button), keyval,
modifiers);
+ self->priv->shortcut = gth_window_get_shortcut (self->priv->shortcut_window,
gth_script_get_detailed_action (script));
+ if (self->priv->shortcut != NULL) {
+ gth_accel_button_set_accelerator (GTH_ACCEL_BUTTON (self->priv->accel_button),
+ self->priv->shortcut->keyval,
+ self->priv->shortcut->modifiers);
+ }
}
update_sensitivity (self);
diff --git a/extensions/list_tools/gth-script-editor-dialog.h
b/extensions/list_tools/gth-script-editor-dialog.h
index 2a17a69e..bee9cf15 100644
--- a/extensions/list_tools/gth-script-editor-dialog.h
+++ b/extensions/list_tools/gth-script-editor-dialog.h
@@ -49,6 +49,7 @@ struct _GthScriptEditorDialogClass {
GType gth_script_editor_dialog_get_type (void);
GtkWidget * gth_script_editor_dialog_new (const char *title,
+ GthWindow *shortcut_window,
GtkWindow *parent);
void gth_script_editor_dialog_set_script (GthScriptEditorDialog *self,
GthScript *script);
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index 891868fe..cca9191e 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -43,12 +43,6 @@ enum {
};
-typedef struct {
- guint keyval;
- GdkModifierType modifiers;
- char *name;
-} _Accel;
-
struct _GthScriptPrivate {
char *id;
char *display_name;
@@ -57,7 +51,8 @@ struct _GthScriptPrivate {
gboolean shell_script;
gboolean for_each_file;
gboolean wait_command;
- _Accel accelerator;
+ char *accelerator;
+ char *detailed_action;
};
@@ -89,7 +84,6 @@ gth_script_real_create_element (DomDomizable *base,
"shell-script", (self->priv->shell_script ? "true" : "false"),
"for-each-file", (self->priv->for_each_file ? "true" :
"false"),
"wait-command", (self->priv->wait_command ? "true" : "false"),
- "accelerator", self->priv->accelerator.name,
NULL);
if (! self->priv->visible)
dom_element_set_attribute (element, "display", "none");
@@ -115,7 +109,7 @@ gth_script_real_load_from_element (DomDomizable *base,
"shell-script", (g_strcmp0 (dom_element_get_attribute (element, "shell-script"),
"true") == 0),
"for-each-file", (g_strcmp0 (dom_element_get_attribute (element, "for-each-file"),
"true") == 0),
"wait-command", (g_strcmp0 (dom_element_get_attribute (element, "wait-command"),
"true") == 0),
- "accelerator", dom_element_get_attribute (element, "accelerator"),
+ "accelerator", "",
NULL);
}
@@ -135,7 +129,7 @@ gth_script_real_duplicate (GthDuplicable *duplicable)
"shell-script", script->priv->shell_script,
"for-each-file", script->priv->for_each_file,
"wait-command", script->priv->wait_command,
- "accelerator", script->priv->accelerator.name,
+ "accelerator", script->priv->accelerator,
NULL);
return (GObject *) new_script;
@@ -151,12 +145,28 @@ gth_script_finalize (GObject *base)
g_free (self->priv->id);
g_free (self->priv->display_name);
g_free (self->priv->command);
- g_free (self->priv->accelerator.name);
+ g_free (self->priv->accelerator);
+ g_free (self->priv->detailed_action);
G_OBJECT_CLASS (gth_script_parent_class)->finalize (base);
}
+static char *
+detailed_action_from_id (char *id)
+{
+ GVariant *param;
+ char *detailed_action;
+
+ param = g_variant_new_string (id);
+ detailed_action = g_action_print_detailed_name ("exec-script", param);
+
+ g_variant_unref (param);
+
+ return detailed_action;
+}
+
+
static void
gth_script_set_property (GObject *object,
guint property_id,
@@ -173,6 +183,8 @@ gth_script_set_property (GObject *object,
self->priv->id = g_value_dup_string (value);
if (self->priv->id == NULL)
self->priv->id = g_strdup ("");
+ g_free (self->priv->detailed_action);
+ self->priv->detailed_action = detailed_action_from_id (self->priv->id);
break;
case PROP_DISPLAY_NAME:
g_free (self->priv->display_name);
@@ -199,10 +211,8 @@ gth_script_set_property (GObject *object,
self->priv->wait_command = g_value_get_boolean (value);
break;
case PROP_ACCELERATOR:
- self->priv->accelerator.name = g_value_dup_string (value);
- gtk_accelerator_parse (self->priv->accelerator.name,
- &self->priv->accelerator.keyval,
- &self->priv->accelerator.modifiers);
+ g_free (self->priv->accelerator);
+ self->priv->accelerator = g_value_dup_string (value);
break;
default:
break;
@@ -243,7 +253,7 @@ gth_script_get_property (GObject *object,
g_value_set_boolean (value, self->priv->wait_command);
break;
case PROP_ACCELERATOR:
- g_value_set_string (value, self->priv->accelerator.name);
+ g_value_set_string (value, self->priv->accelerator);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -345,9 +355,12 @@ gth_script_init (GthScript *self)
self->priv->id = NULL;
self->priv->display_name = NULL;
self->priv->command = NULL;
- self->priv->accelerator.name = NULL;
- self->priv->accelerator.keyval = 0;
- self->priv->accelerator.modifiers = 0;
+ self->priv->visible = FALSE;
+ self->priv->shell_script = FALSE;
+ self->priv->for_each_file = FALSE;
+ self->priv->wait_command = FALSE;
+ self->priv->accelerator = NULL;
+ self->priv->detailed_action = NULL;
}
@@ -386,6 +399,13 @@ gth_script_get_command (GthScript *script)
}
+const char *
+gth_script_get_detailed_action (GthScript *self)
+{
+ return self->priv->detailed_action;
+}
+
+
gboolean
gth_script_is_visible (GthScript *script)
{
@@ -1026,30 +1046,25 @@ gth_script_get_command_line (GthScript *script,
}
-void
-gth_script_get_accelerator (GthScript *self,
- guint *keyval,
- GdkModifierType *modifiers)
+const char *
+gth_script_get_accelerator (GthScript *self)
{
- g_return_if_fail (GTH_IS_SCRIPT (self));
- if (keyval) *keyval = self->priv->accelerator.keyval;
- if (modifiers) *modifiers = self->priv->accelerator.modifiers;
+ g_return_val_if_fail (GTH_IS_SCRIPT (self), NULL);
+ return self->priv->accelerator;
}
GthShortcut *
-gth_script_get_shortcut (GthScript *self)
+gth_script_create_shortcut (GthScript *self)
{
GthShortcut *shortcut;
- shortcut = gth_shortcut_new ();
- shortcut->action_name = g_strdup ("exec-script");
- shortcut->action_parameter = g_variant_ref_sink (g_variant_new_string (gth_script_get_id (self)));
+ shortcut = gth_shortcut_new ("exec-script", g_variant_new_string (gth_script_get_id (self)));
shortcut->description = g_strdup (self->priv->display_name);
shortcut->context = GTH_SHORTCUT_CONTEXT_BROWSER_VIEWER;
shortcut->category = GTH_SHORTCUT_CATEGORY_LIST_TOOLS;
- gth_shortcut_set_key (shortcut, self->priv->accelerator.keyval, self->priv->accelerator.modifiers);
- shortcut->default_accelerator = g_strdup (shortcut->accelerator);
+ gth_shortcut_set_accelerator (shortcut, self->priv->accelerator);
+ shortcut->default_accelerator = g_strdup ("");
return shortcut;
}
diff --git a/extensions/list_tools/gth-script.h b/extensions/list_tools/gth-script.h
index c3146d96..b7f7b2f6 100644
--- a/extensions/list_tools/gth-script.h
+++ b/extensions/list_tools/gth-script.h
@@ -55,6 +55,7 @@ GthScript * gth_script_new (void);
const char * gth_script_get_id (GthScript *script);
const char * gth_script_get_display_name (GthScript *script);
const char * gth_script_get_command (GthScript *script);
+const char * gth_script_get_detailed_action (GthScript *script);
gboolean gth_script_is_visible (GthScript *script);
gboolean gth_script_is_shell_script (GthScript *script);
gboolean gth_script_for_each_file (GthScript *script);
@@ -65,10 +66,8 @@ char * gth_script_get_command_line (GthScript *script,
GList *file_list /* GthFileData */,
gboolean can_skip,
GError **error);
-void gth_script_get_accelerator (GthScript *script,
- guint *keyval,
- GdkModifierType *modifiers);
-GthShortcut * gth_script_get_shortcut (GthScript *script);
+const char * gth_script_get_accelerator (GthScript *script);
+GthShortcut * gth_script_create_shortcut (GthScript *script);
G_END_DECLS
diff --git a/extensions/list_tools/shortcuts.h b/extensions/list_tools/shortcuts.h
index 2239ab61..8a78852b 100644
--- a/extensions/list_tools/shortcuts.h
+++ b/extensions/list_tools/shortcuts.h
@@ -23,5 +23,6 @@
#define LIST_TOOLS_SHORTCUTS_H
#define GTH_SHORTCUT_CATEGORY_LIST_TOOLS "list-tools"
+#define SCRIPTS_GROUP "scripts"
#endif /* LIST_TOOLS_SHORTCUTS_H */
diff --git a/gthumb/dlg-preferences-shortcuts.c b/gthumb/dlg-preferences-shortcuts.c
index f5d2c33d..07c6f407 100644
--- a/gthumb/dlg-preferences-shortcuts.c
+++ b/gthumb/dlg-preferences-shortcuts.c
@@ -129,7 +129,7 @@ find_row_by_shortcut (BrowserData *browser_data,
for (i = 0; i < browser_data->rows->len; i++) {
RowData *row_data = g_ptr_array_index (browser_data->rows, i);
- if (g_strcmp0 (row_data->shortcut->action_name, shortcut->action_name) == 0)
+ if (g_strcmp0 (row_data->shortcut->detailed_action, shortcut->detailed_action) == 0)
return row_data;
}
@@ -143,78 +143,36 @@ row_data_update_shortcut (RowData *row_data,
GdkModifierType modifiers,
GtkWindow *parent)
{
- GPtrArray *shortcuts_v;
- GthShortcut *shortcut;
-
- shortcuts_v = gth_window_get_shortcuts (GTH_WINDOW (row_data->browser_data->browser));
- shortcut = gth_shortcut_array_find (shortcuts_v,
- row_data->shortcut->context,
- keycode,
- modifiers);
-
- if (shortcut != NULL) {
- if (g_strcmp0 (shortcut->action_name, row_data->shortcut->action_name) != 0) {
- char *label;
- char *msg;
- GtkWidget *dialog;
- gboolean reassign;
-
- label = gtk_accelerator_get_label (keycode, modifiers);
- msg = g_strdup_printf (_("The key combination «%s» is already assigned to the action
«%s». Do you want to reassign it to «%s» instead?"),
- label,
- shortcut->description,
- row_data->shortcut->description);
-
- dialog = _gtk_yesno_dialog_new (parent,
- GTK_DIALOG_MODAL,
- msg,
- _GTK_LABEL_CANCEL,
- _("Reassign"));
-
- reassign = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- if (reassign) {
- gth_shortcut_set_key (shortcut, 0, 0);
- row_data_update_accel_label (find_row_by_shortcut (row_data->browser_data,
shortcut));
- }
-
- g_free (msg);
- g_free (label);
-
- if (! reassign)
- return FALSE;
- }
- else {
- char *label;
- char *msg;
- GtkWidget *dialog;
-
- label = gtk_accelerator_get_label (keycode, modifiers);
- msg = g_strdup_printf (_("The key combination «%s» is already assigned to this
action."), label);
- dialog = _gtk_message_dialog_new (parent,
- GTK_DIALOG_MODAL,
- _GTK_ICON_NAME_DIALOG_INFO,
- msg,
- NULL,
- _GTK_LABEL_CLOSE, GTK_RESPONSE_CANCEL,
- NULL);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- g_free (msg);
- g_free (label);
-
- return FALSE;
+ gboolean change;
+
+ change = gth_window_can_change_shortcut (GTH_WINDOW (row_data->browser_data->browser),
+ row_data->shortcut->detailed_action,
+ row_data->shortcut->context,
+ keycode,
+ modifiers,
+ parent);
+
+ if (change) {
+ GPtrArray *shortcuts_v;
+ GthShortcut *shortcut;
+
+ shortcuts_v = gth_window_get_shortcuts (GTH_WINDOW (row_data->browser_data->browser));
+ shortcut = gth_shortcut_array_find (shortcuts_v,
+ row_data->shortcut->context,
+ keycode,
+ modifiers);
+ if (shortcut != NULL) {
+ gth_shortcut_set_key (shortcut, 0, 0);
+ row_data_update_accel_label (find_row_by_shortcut (row_data->browser_data, shortcut));
}
- }
- gth_shortcut_set_key (row_data->shortcut, keycode, modifiers);
- row_data_update_accel_label (row_data);
+ gth_shortcut_set_key (row_data->shortcut, keycode, modifiers);
+ row_data_update_accel_label (row_data);
- gth_main_shortcuts_changed (gth_window_get_shortcuts (GTH_WINDOW (row_data->browser_data->browser)));
+ gth_main_shortcuts_changed (gth_window_get_shortcuts (GTH_WINDOW
(row_data->browser_data->browser)));
+ }
- return TRUE;
+ return change;
}
diff --git a/gthumb/gth-shortcut.c b/gthumb/gth-shortcut.c
index 4ae9b371..9dfb2199 100644
--- a/gthumb/gth-shortcut.c
+++ b/gthumb/gth-shortcut.c
@@ -29,13 +29,17 @@
GthShortcut *
-gth_shortcut_new (void)
+gth_shortcut_new (const char *action_name,
+ GVariant *param)
{
GthShortcut *shortcut;
+ g_return_val_if_fail (action_name != NULL, NULL);
+
shortcut = g_new (GthShortcut, 1);
- shortcut->action_name = NULL;
- shortcut->action_parameter = NULL;
+ shortcut->action_name = g_strdup (action_name);
+ shortcut->action_parameter = (param != NULL) ? g_variant_ref_sink (param) : NULL;
+ shortcut->detailed_action = g_action_print_detailed_name (shortcut->action_name,
shortcut->action_parameter);
shortcut->description = NULL;
shortcut->context = 0;
shortcut->category = NULL;
@@ -54,12 +58,7 @@ gth_shortcut_dup (const GthShortcut *shortcut)
{
GthShortcut *new_shortcut;
- new_shortcut = gth_shortcut_new ();
- new_shortcut->action_name = g_strdup (shortcut->action_name);
- if (shortcut->action_parameter != NULL)
- new_shortcut->action_parameter = g_variant_ref_sink (shortcut->action_parameter);
- else
- new_shortcut->action_parameter = NULL;
+ new_shortcut = gth_shortcut_new (shortcut->action_name, shortcut->action_parameter);
new_shortcut->description = g_strdup (shortcut->description);
new_shortcut->context = shortcut->context;
new_shortcut->category = shortcut->category;
@@ -76,6 +75,7 @@ gth_shortcut_free (GthShortcut *shortcut)
g_free (shortcut->action_name);
if (shortcut->action_parameter != NULL)
g_variant_unref (shortcut->action_parameter);
+ g_free (shortcut->detailed_action);
g_free (shortcut->description);
g_free (shortcut->default_accelerator);
g_free (shortcut->accelerator);
@@ -114,6 +114,14 @@ gth_shortcut_set_key (GthShortcut *shortcut,
}
+gboolean
+gth_shortcut_customizable (GthShortcut *shortcut)
+{
+ return ((shortcut->context & GTH_SHORTCUT_CONTEXT_FIXED) == 0)
+ && ((shortcut->context & GTH_SHORTCUT_CONTEXT_INTERNAL) == 0);
+}
+
+
GthShortcut *
gth_shortcut_array_find (GPtrArray *shortcuts_v,
int context,
@@ -140,6 +148,50 @@ gth_shortcut_array_find (GPtrArray *shortcuts_v,
}
+GthShortcut *
+gth_shortcut_array_find_by_accel (GPtrArray *shortcuts_v,
+ int context,
+ const char *accelerator)
+{
+ int i;
+
+ if (accelerator == NULL)
+ return NULL;
+
+ for (i = 0; i < shortcuts_v->len; i++) {
+ GthShortcut *shortcut = g_ptr_array_index (shortcuts_v, i);
+
+ if (((shortcut->context & context) == context)
+ && (g_strcmp0 (shortcut->accelerator, accelerator) == 0))
+ {
+ return shortcut;
+ }
+ }
+
+ return NULL;
+}
+
+
+GthShortcut *
+gth_shortcut_array_find_by_action (GPtrArray *shortcuts_v,
+ const char *detailed_action)
+{
+ int i;
+
+ if (detailed_action == NULL)
+ return NULL;
+
+ for (i = 0; i < shortcuts_v->len; i++) {
+ GthShortcut *shortcut = g_ptr_array_index (shortcuts_v, i);
+
+ if (g_strcmp0 (shortcut->detailed_action, detailed_action) == 0)
+ return shortcut;
+ }
+
+ return NULL;
+}
+
+
gboolean
gth_shortcut_valid (guint keycode,
GdkModifierType modifiers)
@@ -188,7 +240,7 @@ gth_shortcuts_write_to_file (GPtrArray *shortcuts_v,
dom_element_append_child (shortcuts,
dom_document_create_element (doc, "shortcut",
- "action", shortcut->action_name,
+ "action", shortcut->detailed_action,
"accelerator", shortcut->accelerator,
NULL));
}
@@ -230,17 +282,17 @@ gth_shortcuts_load_from_file (GPtrArray *shortcuts_v,
for (shortcut_node = node->first_child; shortcut_node; shortcut_node
= shortcut_node->next_sibling) {
if (g_strcmp0 (shortcut_node->tag_name, "shortcut") == 0) {
- const char *action_name;
+ const char *detailed_action;
const char *accelerator;
GthShortcut *shortcut;
- action_name = dom_element_get_attribute
(shortcut_node, "action");
+ detailed_action = dom_element_get_attribute
(shortcut_node, "action");
accelerator = dom_element_get_attribute
(shortcut_node, "accelerator");
- if (action_name == NULL)
+ if (detailed_action == NULL)
continue;
- shortcut = g_hash_table_lookup (shortcuts,
action_name);
+ shortcut = g_hash_table_lookup (shortcuts,
detailed_action);
if (shortcut != NULL)
gth_shortcut_set_accelerator (shortcut,
accelerator);
}
diff --git a/gthumb/gth-shortcut.h b/gthumb/gth-shortcut.h
index c194b9f8..38f2906b 100644
--- a/gthumb/gth-shortcut.h
+++ b/gthumb/gth-shortcut.h
@@ -53,10 +53,12 @@ typedef struct {
guint keyval;
GdkModifierType modifiers;
GVariant *action_parameter;
+ char *detailed_action;
} GthShortcut;
-GthShortcut * gth_shortcut_new (void);
+GthShortcut * gth_shortcut_new (const char *action_name,
+ GVariant *param);
GthShortcut * gth_shortcut_dup (const GthShortcut *shortcut);
void gth_shortcut_free (GthShortcut *shortcut);
void gth_shortcut_set_key (GthShortcut *shortcut,
@@ -64,10 +66,16 @@ void gth_shortcut_set_key (GthShortcut *shortcut,
GdkModifierType modifiers);
void gth_shortcut_set_accelerator (GthShortcut *shortcut,
const char *name);
+gboolean gth_shortcut_customizable (GthShortcut *shortcut);
GthShortcut * gth_shortcut_array_find (GPtrArray *shortcuts_v,
int context,
guint keycode,
GdkModifierType modifiers);
+GthShortcut * gth_shortcut_array_find_by_accel (GPtrArray *shortcuts_v,
+ int context,
+ const char *accelerator);
+GthShortcut * gth_shortcut_array_find_by_action (GPtrArray *shortcuts_v,
+ const char *detailed_action);
gboolean gth_shortcut_valid (guint keycode,
GdkModifierType modifiers);
gboolean gth_shortcuts_write_to_file (GPtrArray *shortcuts_v,
diff --git a/gthumb/gth-window.c b/gthumb/gth-window.c
index 2cad403a..336206ca 100644
--- a/gthumb/gth-window.c
+++ b/gthumb/gth-window.c
@@ -709,10 +709,10 @@ static void
_gth_window_add_shortcut (GthWindow *window,
GthShortcut *shorcut)
{
+ g_ptr_array_add (window->priv->shortcuts_v, shorcut);
g_hash_table_insert (window->priv->shortcuts,
- g_strdup (shorcut->action_name),
+ g_strdup (shorcut->detailed_action),
shorcut);
- g_ptr_array_add (window->priv->shortcuts_v, shorcut);
}
@@ -720,7 +720,7 @@ static void
_gth_window_remove_shortcut (GthWindow *window,
GthShortcut *shorcut)
{
- g_hash_table_remove (window->priv->shortcuts, shorcut->action_name);
+ g_hash_table_remove (window->priv->shortcuts, shorcut->detailed_action);
g_ptr_array_remove (window->priv->shortcuts_v, shorcut);
}
@@ -744,8 +744,7 @@ gth_window_add_accelerators (GthWindow *window,
acc->accelerator,
NULL);
- shortcut = gth_shortcut_new ();
- shortcut->action_name = g_strdup (acc->action_name);
+ shortcut = gth_shortcut_new (acc->action_name, NULL);
shortcut->context = GTH_SHORTCUT_CONTEXT_INTERNAL | GTH_SHORTCUT_CONTEXT_ANY;
shortcut->category = GTH_SHORTCUT_CATEGORY_HIDDEN;
gth_shortcut_set_accelerator (shortcut, acc->accelerator);
@@ -836,6 +835,16 @@ gth_window_get_shortcuts (GthWindow *window)
}
+GthShortcut *
+gth_window_get_shortcut (GthWindow *window,
+ const char *detailed_action)
+{
+ g_return_val_if_fail (GTH_IS_WINDOW (window), NULL);
+
+ return g_hash_table_lookup (window->priv->shortcuts, detailed_action);
+}
+
+
static int
sort_shortcuts_by_category (gconstpointer a,
gconstpointer b)
@@ -918,10 +927,15 @@ gth_window_add_removable_shortcut (GthWindow *window,
GthShortcut *shortcut)
{
GPtrArray *shortcuts_v;
+ GthShortcut *old_shortcut;
GthShortcut *new_shortcut;
g_return_if_fail (GTH_IS_WINDOW (window));
g_return_if_fail (group_name != NULL);
+ g_return_if_fail (shortcut != NULL);
+ g_return_if_fail (shortcut->detailed_action != NULL);
+
+ /* create the group if it doesn't exist. */
shortcuts_v = g_hash_table_lookup (window->priv->shortcut_groups, group_name);
if (shortcuts_v == NULL) {
@@ -931,10 +945,18 @@ gth_window_add_removable_shortcut (GthWindow *window,
shortcuts_v);
}
+ /* remove the old shortcut */
+
+ old_shortcut = g_hash_table_lookup (window->priv->shortcuts, shortcut->detailed_action);
+ if (old_shortcut != NULL) {
+ g_ptr_array_remove (shortcuts_v, old_shortcut);
+ _gth_window_remove_shortcut (window, old_shortcut);
+ }
+
+ /* add the new shortcut */
+
new_shortcut = gth_shortcut_dup (shortcut);
- gth_shortcut_set_accelerator (new_shortcut, shortcut->default_accelerator);
_gth_window_add_shortcut (window, new_shortcut);
-
g_ptr_array_add (shortcuts_v, new_shortcut);
}
@@ -960,3 +982,82 @@ gth_window_remove_shortcuts (GthWindow *window,
g_hash_table_remove (window->priv->shortcut_groups, group_name);
}
+
+
+gboolean
+gth_window_can_change_shortcut (GthWindow *window,
+ const char *detailed_action,
+ int context,
+ guint keycode,
+ GdkModifierType modifiers,
+ GtkWindow *parent)
+{
+ GthShortcut *shortcut;
+
+ if (window == NULL)
+ return TRUE;
+
+ shortcut = gth_shortcut_array_find (gth_window_get_shortcuts (window ),
+ GTH_SHORTCUT_CONTEXT_BROWSER_VIEWER,
+ keycode,
+ modifiers);
+
+ if (shortcut == NULL)
+ return TRUE;
+
+ if (g_strcmp0 (shortcut->detailed_action, detailed_action) == 0)
+ return FALSE;
+
+ if (gth_shortcut_customizable (shortcut)) {
+ char *label;
+ char *msg;
+ GtkWidget *dialog;
+ gboolean reassign;
+
+ label = gtk_accelerator_get_label (keycode, modifiers);
+ msg = g_strdup_printf (_("The key combination «%s» is already assigned to the action «%s».
Do you want to reassign it to this action instead?"),
+ label,
+ shortcut->description);
+
+ dialog = _gtk_yesno_dialog_new (parent,
+ GTK_DIALOG_MODAL,
+ msg,
+ _GTK_LABEL_CANCEL,
+ _("Reassign"));
+
+ reassign = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ g_free (msg);
+ g_free (label);
+
+ if (! reassign)
+ return FALSE;
+ }
+ else {
+ char *label;
+ char *msg;
+ GtkWidget *dialog;
+
+ label = gtk_accelerator_get_label (keycode, modifiers);
+ msg = g_strdup_printf (_("The key combination «%s» is already assigned to the action «%s»."),
+ label,
+ shortcut->description);
+ dialog = _gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ _GTK_ICON_NAME_DIALOG_ERROR,
+ NULL,
+ msg,
+ _GTK_LABEL_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ g_free (msg);
+ g_free (label);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/gthumb/gth-window.h b/gthumb/gth-window.h
index 7eeb89e4..89843e1c 100644
--- a/gthumb/gth-window.h
+++ b/gthumb/gth-window.h
@@ -125,6 +125,8 @@ void gth_window_add_shortcuts (GthWindow *window,
const GthShortcut *shortcuts,
int n_shortcuts);
GPtrArray * gth_window_get_shortcuts (GthWindow *window);
+GthShortcut * gth_window_get_shortcut (GthWindow *window,
+ const char *detailed_action);
GPtrArray * gth_window_get_shortcuts_by_category
(GthWindow *window);
gboolean gth_window_activate_shortcut (GthWindow *window,
@@ -138,6 +140,12 @@ void gth_window_add_removable_shortcut
GthShortcut *shortcut);
void gth_window_remove_shortcuts (GthWindow *window,
const char *group_name);
+gboolean gth_window_can_change_shortcut (GthWindow *window,
+ const char *detailed_action,
+ int context,
+ guint keycode,
+ GdkModifierType modifiers,
+ GtkWindow *parent);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]