[gthumb] scripts: allow to specify a generic accelerator
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] scripts: allow to specify a generic accelerator
- Date: Mon, 31 Jul 2017 06:07:22 +0000 (UTC)
commit 1f8c167e612498c81902396eaeb8d67ed9f6c6f1
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Jul 4 15:26:55 2017 +0200
scripts: allow to specify a generic accelerator
extensions/list_tools/callbacks.c | 18 +-
.../list_tools/data/ui/personalize-scripts.ui | 3 +-
extensions/list_tools/data/ui/script-editor.ui | 29 +--
extensions/list_tools/dlg-personalize-scripts.c | 13 +-
extensions/list_tools/gth-script-editor-dialog.c | 91 ++-----
extensions/list_tools/gth-script.c | 80 +++---
extensions/list_tools/gth-script.h | 30 +-
gthumb/Makefile.am | 2 +
gthumb/gth-accel-button.c | 329 ++++++++++++++++++++
gthumb/gth-accel-button.h | 65 ++++
po/POTFILES.in | 2 +
11 files changed, 498 insertions(+), 164 deletions(-)
---
diff --git a/extensions/list_tools/callbacks.c b/extensions/list_tools/callbacks.c
index 87fc26b..5da5ad0 100644
--- a/extensions/list_tools/callbacks.c
+++ b/extensions/list_tools/callbacks.c
@@ -193,15 +193,23 @@ gpointer
list_tools__gth_browser_file_list_key_press_cb (GthBrowser *browser,
GdkEventKey *event)
{
- gpointer result = NULL;
- GList *script_list;
- GList *scan;
+ gpointer result = NULL;
+ guint event_key;
+ GdkModifierType event_modifiers;
+ GList *script_list;
+ GList *scan;
+
+ event_key = gdk_keyval_to_lower (event->keyval);
+ event_modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
script_list = gth_script_file_get_scripts (gth_script_file_get ());
for (scan = script_list; scan; scan = scan->next) {
- GthScript *script = scan->data;
+ GthScript *script = scan->data;
+ guint keyval;
+ GdkModifierType modifiers;
- if (gth_script_get_shortcut (script) == event->keyval) {
+ gth_script_get_accelerator (script, &keyval, &modifiers);
+ if ((keyval == event_key) && (modifiers == event_modifiers)) {
gth_browser_exec_script (browser, script);
result = GINT_TO_POINTER (1);
break;
diff --git a/extensions/list_tools/data/ui/personalize-scripts.ui
b/extensions/list_tools/data/ui/personalize-scripts.ui
index 6d8be8e..d04d634 100644
--- a/extensions/list_tools/data/ui/personalize-scripts.ui
+++ b/extensions/list_tools/data/ui/personalize-scripts.ui
@@ -30,7 +30,7 @@
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
@@ -45,6 +45,7 @@
<property name="height_request">300</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="vexpand">True</property>
<property name="shadow_type">etched-in</property>
<child>
<placeholder/>
diff --git a/extensions/list_tools/data/ui/script-editor.ui b/extensions/list_tools/data/ui/script-editor.ui
index cec4767..0f4b262 100644
--- a/extensions/list_tools/data/ui/script-editor.ui
+++ b/extensions/list_tools/data/ui/script-editor.ui
@@ -2,14 +2,6 @@
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.10"/>
- <object class="GtkListStore" id="shortcut_liststore">
- <columns>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name sensitive -->
- <column type="gboolean"/>
- </columns>
- </object>
<object class="GtkBox" id="script_editor">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -108,7 +100,6 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes">Sh_ortcut:</property>
<property name="use_underline">True</property>
- <property name="mnemonic_widget">shortcut_combobox</property>
<property name="xalign">1</property>
</object>
<packing>
@@ -119,28 +110,12 @@
</packing>
</child>
<child>
- <object class="GtkBox" id="hbox1">
+ <object class="GtkBox" id="accel_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkComboBox" id="shortcut_combobox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="model">shortcut_liststore</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
- <attributes>
- <attribute name="sensitive">1</attribute>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
+ <placeholder/>
</child>
<child>
<placeholder/>
diff --git a/extensions/list_tools/dlg-personalize-scripts.c b/extensions/list_tools/dlg-personalize-scripts.c
index 07eb516..0a765a3 100644
--- a/extensions/list_tools/dlg-personalize-scripts.c
+++ b/extensions/list_tools/dlg-personalize-scripts.c
@@ -133,16 +133,11 @@ row_inserted_cb (GtkTreeModel *tree_model,
static char *
get_script_shortcut (GthScript *script)
{
- guint keyval;
- char *shortcut;
+ guint keyval;
+ GdkModifierType modifiers;
- keyval = gth_script_get_shortcut (script);
- if ((keyval >= GDK_KEY_KP_0) && (keyval <= GDK_KEY_KP_9))
- shortcut = g_strdup_printf ("%c", '0' + (keyval - GDK_KEY_KP_0));
- else
- shortcut = g_strdup ("");
-
- return shortcut;
+ gth_script_get_accelerator (script, &keyval, &modifiers);
+ return gtk_accelerator_get_label (keyval, modifiers);
}
diff --git a/extensions/list_tools/gth-script-editor-dialog.c
b/extensions/list_tools/gth-script-editor-dialog.c
index 33d0b98..dab45d6 100644
--- a/extensions/list_tools/gth-script-editor-dialog.c
+++ b/extensions/list_tools/gth-script-editor-dialog.c
@@ -41,6 +41,7 @@ enum {
struct _GthScriptEditorDialogPrivate {
GtkBuilder *builder;
+ GtkWidget *accel_button;
char *script_id;
gboolean script_visible;
gboolean wait_command;
@@ -115,9 +116,6 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
const char *title,
GtkWindow *parent)
{
- GtkTreeIter iter;
- int i;
-
if (title != NULL)
gtk_window_set_title (GTK_WINDOW (self), title);
if (parent != NULL)
@@ -133,28 +131,15 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
self->priv->builder = gtk_builder_new_from_resource
("/org/gnome/gThumb/list_tools/data/ui/script-editor.ui");
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 ();
+ gtk_widget_show (self->priv->accel_button);
+ gtk_box_pack_start (GTK_BOX (GET_WIDGET ("accel_box")), self->priv->accel_button, FALSE, FALSE, 0);
+
g_signal_connect (GET_WIDGET ("command_entry"),
"icon-press",
G_CALLBACK (command_entry_icon_press_cb),
self);
- gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter);
- gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter,
- SHORTCUT_NAME_COLUMN, _("none"),
- -1);
-
- for (i = 0; i <= 9; i++) {
- char *value;
-
- value = g_strdup_printf (_("key %d on the numeric keypad"), i);
- gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter);
- gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter,
- SHORTCUT_NAME_COLUMN, value,
- -1);
-
- g_free (value);
- }
-
/**/
gth_script_editor_dialog_set_script (self, NULL);
@@ -184,7 +169,7 @@ _gth_script_editor_dialog_set_new_script (GthScriptEditorDialog *self)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("shell_script_checkbutton")), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("for_each_file_checkbutton")), FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("wait_command_checkbutton")), FALSE);
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("shortcut_combobox")), NO_SHORTCUT);
+ gth_accel_button_set_accelerator (GTH_ACCEL_BUTTON (self->priv->accel_button), 0, 0);
}
@@ -192,11 +177,6 @@ void
gth_script_editor_dialog_set_script (GthScriptEditorDialog *self,
GthScript *script)
{
- GtkTreeIter iter;
- GtkTreePath *path;
- GList *script_list;
- GList *scan;
-
g_free (self->priv->script_id);
self->priv->script_id = NULL;
self->priv->script_visible = TRUE;
@@ -204,7 +184,9 @@ gth_script_editor_dialog_set_script (GthScriptEditorDialog *self,
_gth_script_editor_dialog_set_new_script (self);
if (script != NULL) {
- guint keyval;
+ guint keyval;
+ GdkModifierType modifiers;
+
self->priv->script_id = g_strdup (gth_script_get_id (script));
self->priv->script_visible = gth_script_is_visible (script);
@@ -215,43 +197,10 @@ 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));
- keyval = gth_script_get_shortcut (script);
- if ((keyval >= GDK_KEY_KP_0) && (keyval <= GDK_KEY_KP_9))
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("shortcut_combobox")), (keyval -
GDK_KEY_KP_0) + 1);
- else
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("shortcut_combobox")),
NO_SHORTCUT);
+ gth_script_get_accelerator (script, &keyval, &modifiers);
+ gth_accel_button_set_accelerator (GTH_ACCEL_BUTTON (self->priv->accel_button), keyval,
modifiers);
}
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GET_WIDGET ("shortcut_liststore")), &iter)) {
- do {
- gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter,
- SHORTCUT_SENSITIVE_COLUMN, TRUE,
- -1);
- }
- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (GET_WIDGET ("shortcut_liststore")), &iter));
- }
-
- script_list = gth_script_file_get_scripts (gth_script_file_get ());
- for (scan = script_list; scan; scan = scan->next) {
- GthScript *other_script = scan->data;
- guint keyval;
-
- keyval = gth_script_get_shortcut (other_script);
- if ((keyval >= GDK_KEY_KP_0) && (keyval <= GDK_KEY_KP_9)) {
- if (g_strcmp0 (gth_script_get_id (other_script), self->priv->script_id) == 0)
- continue;
-
- path = gtk_tree_path_new_from_indices (keyval - GDK_KEY_KP_0 + 1, -1);
- gtk_tree_model_get_iter (GTK_TREE_MODEL (GET_WIDGET ("shortcut_liststore")), &iter,
path);
- gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("shortcut_liststore")), &iter,
- SHORTCUT_SENSITIVE_COLUMN, FALSE,
- -1);
-
- gtk_tree_path_free (path);
- }
- }
- _g_object_list_unref (script_list);
-
update_sensitivity (self);
}
@@ -260,19 +209,17 @@ GthScript *
gth_script_editor_dialog_get_script (GthScriptEditorDialog *self,
GError **error)
{
- GthScript *script;
- int keyval_index;
- guint keyval;
+ GthScript *script;
+ guint keyval;
+ GdkModifierType modifiers;
+ char *accelerator;
script = gth_script_new ();
if (self->priv->script_id != NULL)
g_object_set (script, "id", self->priv->script_id, NULL);
- keyval_index = gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("shortcut_combobox")));
- if ((keyval_index >= 1) && (keyval_index <= 10))
- keyval = GDK_KEY_KP_0 + (keyval_index - 1);
- else
- keyval = GDK_KEY_VoidSymbol;
+ gth_accel_button_get_accelerator (GTH_ACCEL_BUTTON (self->priv->accel_button), &keyval, &modifiers);
+ accelerator = gtk_accelerator_name (keyval, modifiers);
g_object_set (script,
"display-name", gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("name_entry"))),
@@ -281,7 +228,7 @@ gth_script_editor_dialog_get_script (GthScriptEditorDialog *self,
"shell-script", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET
("shell_script_checkbutton"))),
"for-each-file", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET
("for_each_file_checkbutton"))),
"wait-command", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET
("wait_command_checkbutton"))),
- "shortcut", keyval,
+ "accelerator", accelerator,
NULL);
if (g_strcmp0 (gth_script_get_display_name (script), "") == 0) {
@@ -296,5 +243,7 @@ gth_script_editor_dialog_get_script (GthScriptEditorDialog *self,
return NULL;
}
+ g_free (accelerator);
+
return script;
}
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index 6904171..0296376 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -47,19 +47,25 @@ enum {
PROP_SHELL_SCRIPT,
PROP_FOR_EACH_FILE,
PROP_WAIT_COMMAND,
- PROP_SHORTCUT
+ PROP_ACCELERATOR
};
+typedef struct {
+ guint keyval;
+ GdkModifierType modifiers;
+ char *name;
+} _Accel;
+
struct _GthScriptPrivate {
- char *id;
- char *display_name;
- char *command;
- gboolean visible;
- gboolean shell_script;
- gboolean for_each_file;
- gboolean wait_command;
- guint shortcut;
+ char *id;
+ char *display_name;
+ char *command;
+ gboolean visible;
+ gboolean shell_script;
+ gboolean for_each_file;
+ gboolean wait_command;
+ _Accel accelerator;
};
@@ -73,6 +79,7 @@ gth_script_real_create_element (DomDomizable *base,
g_return_val_if_fail (DOM_IS_DOCUMENT (doc), NULL);
self = GTH_SCRIPT (base);
+
element = dom_document_create_element (doc, "script",
"id", self->priv->id,
"display-name", self->priv->display_name,
@@ -80,7 +87,7 @@ 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"),
- "shortcut", gdk_keyval_name (self->priv->shortcut),
+ "accelerator", self->priv->accelerator.name,
NULL);
if (! self->priv->visible)
dom_element_set_attribute (element, "display", "none");
@@ -89,16 +96,6 @@ gth_script_real_create_element (DomDomizable *base,
}
-static guint
-_gdk_keyval_from_name (const gchar *keyval_name)
-{
- if (keyval_name != NULL)
- return gdk_keyval_from_name (keyval_name);
- else
- return GDK_KEY_VoidSymbol;
-}
-
-
static void
gth_script_real_load_from_element (DomDomizable *base,
DomElement *element)
@@ -116,7 +113,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),
- "shortcut", _gdk_keyval_from_name (dom_element_get_attribute (element, "shortcut")),
+ "accelerator", dom_element_get_attribute (element, "accelerator"),
NULL);
}
@@ -136,7 +133,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,
- "shortcut", script->priv->shortcut,
+ "accelerator", script->priv->accelerator.name,
NULL);
return (GObject *) new_script;
@@ -152,6 +149,7 @@ 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_OBJECT_CLASS (gth_script_parent_class)->finalize (base);
}
@@ -198,8 +196,11 @@ gth_script_set_property (GObject *object,
case PROP_WAIT_COMMAND:
self->priv->wait_command = g_value_get_boolean (value);
break;
- case PROP_SHORTCUT:
- self->priv->shortcut = g_value_get_uint (value);
+ 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);
break;
default:
break;
@@ -239,8 +240,8 @@ gth_script_get_property (GObject *object,
case PROP_WAIT_COMMAND:
g_value_set_boolean (value, self->priv->wait_command);
break;
- case PROP_SHORTCUT:
- g_value_set_uint (value, self->priv->wait_command);
+ case PROP_ACCELERATOR:
+ g_value_set_string (value, self->priv->accelerator.name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -313,14 +314,12 @@ gth_script_class_init (GthScriptClass *klass)
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
- PROP_SHORTCUT,
- g_param_spec_uint ("shortcut",
- "Shortcut",
- "The keyboard shortcut to activate the script",
- 0,
- G_MAXUINT,
- GDK_KEY_VoidSymbol,
- G_PARAM_READWRITE));
+ PROP_ACCELERATOR,
+ g_param_spec_string ("accelerator",
+ "Accelerator",
+ "The keyboard shortcut to activate the script",
+ "",
+ G_PARAM_READWRITE));
}
@@ -346,6 +345,9 @@ 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;
}
@@ -1024,8 +1026,12 @@ gth_script_get_command_line (GthScript *script,
}
-guint
-gth_script_get_shortcut (GthScript *script)
+void
+gth_script_get_accelerator (GthScript *self,
+ guint *keyval,
+ GdkModifierType *modifiers)
{
- return script->priv->shortcut;
+ g_return_if_fail (GTH_IS_SCRIPT (self));
+ if (keyval) *keyval = self->priv->accelerator.keyval;
+ if (modifiers) *modifiers = self->priv->accelerator.modifiers;
}
diff --git a/extensions/list_tools/gth-script.h b/extensions/list_tools/gth-script.h
index ab3e1a6..2c1891e 100644
--- a/extensions/list_tools/gth-script.h
+++ b/extensions/list_tools/gth-script.h
@@ -52,20 +52,22 @@ struct _GthScriptClass
GType gth_script_get_type (void) G_GNUC_CONST;
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);
-gboolean gth_script_is_visible (GthScript *script);
-gboolean gth_script_is_shell_script (GthScript *script);
-gboolean gth_script_for_each_file (GthScript *script);
-gboolean gth_script_wait_command (GthScript *script);
-char * gth_script_get_requested_attributes (GthScript *script);
-char * gth_script_get_command_line (GthScript *script,
- GtkWindow *parent,
- GList *file_list /* GthFileData */,
- gboolean can_skip,
- GError **error);
-guint gth_script_get_shortcut (GthScript *script);
+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);
+gboolean gth_script_is_visible (GthScript *script);
+gboolean gth_script_is_shell_script (GthScript *script);
+gboolean gth_script_for_each_file (GthScript *script);
+gboolean gth_script_wait_command (GthScript *script);
+char * gth_script_get_requested_attributes (GthScript *script);
+char * gth_script_get_command_line (GthScript *script,
+ GtkWindow *parent,
+ GList *file_list /* GthFileData */,
+ gboolean can_skip,
+ GError **error);
+void gth_script_get_accelerator (GthScript *script,
+ guint *keyval,
+ GdkModifierType *modifiers);
G_END_DECLS
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 4e1ca2a..acb743c 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -31,6 +31,7 @@ PUBLIC_HEADER_FILES = \
glib-utils.h \
gnome-desktop-thumbnail.h \
gsignature.h \
+ gth-accel-button.h \
gth-auto-paned.h \
gth-async-task.h \
gth-buffer-data.h \
@@ -175,6 +176,7 @@ gthumb_SOURCES = \
gio-utils.c \
glib-utils.c \
gsignature.c \
+ gth-accel-button.c \
gth-application.c \
gth-auto-paned.c \
gth-async-task.c \
diff --git a/gthumb/gth-accel-button.c b/gthumb/gth-accel-button.c
new file mode 100644
index 0000000..d75a3b1
--- /dev/null
+++ b/gthumb/gth-accel-button.c
@@ -0,0 +1,329 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include "gth-accel-button.h"
+#include "gtk-utils.h"
+
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_KEY,
+ PROP_MODS
+};
+
+/* Signals */
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+struct _GthAccelButtonPrivate {
+ guint keyval;
+ GdkModifierType modifiers;
+ gboolean valid;
+ GtkWidget *label;
+};
+
+
+static guint gth_accel_button_signals[LAST_SIGNAL] = { 0 };
+
+
+G_DEFINE_TYPE (GthAccelButton, gth_accel_button, GTK_TYPE_BUTTON)
+
+
+static void
+gth_accel_button_finalize (GObject *object)
+{
+ /*GthAccelButton *self;
+
+ self = GTH_ACCEL_BUTTON (object);*/
+
+
+ G_OBJECT_CLASS (gth_accel_button_parent_class)->finalize (object);
+}
+
+
+static void
+gth_accel_button_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GthAccelButton *self;
+
+ self = GTH_ACCEL_BUTTON (object);
+
+ switch (property_id) {
+ case PROP_KEY:
+ self->priv->keyval = g_value_get_uint (value);
+ break;
+ case PROP_MODS:
+ self->priv->modifiers = g_value_get_flags (value);
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void
+gth_accel_button_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GthAccelButton *self;
+
+ self = GTH_ACCEL_BUTTON (object);
+
+ switch (property_id) {
+ case PROP_KEY:
+ g_value_set_uint (value, self->priv->keyval);
+ break;
+ case PROP_MODS:
+ g_value_set_flags (value, self->priv->modifiers);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+gth_accel_button_class_init (GthAccelButtonClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (GthAccelButtonPrivate));
+
+ object_class = (GObjectClass*) klass;
+ object_class->set_property = gth_accel_button_set_property;
+ object_class->get_property = gth_accel_button_get_property;
+ object_class->finalize = gth_accel_button_finalize;
+
+ /* properties */
+
+ g_object_class_install_property (object_class,
+ PROP_KEY,
+ g_param_spec_uint ("key",
+ "Key",
+ "The key value",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_MODS,
+ g_param_spec_flags ("mods",
+ "Mods",
+ "The active modifiers",
+ GDK_TYPE_MODIFIER_TYPE,
+ 0,
+ G_PARAM_READWRITE));
+
+ /* signals */
+
+ gth_accel_button_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthAccelButtonClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+
+static void
+_update_label (GthAccelButton *self)
+{
+ self->priv->valid = gtk_accelerator_valid (self->priv->keyval, self->priv->modifiers);
+ if (self->priv->valid) {
+ char *label = gtk_accelerator_get_label (self->priv->keyval, self->priv->modifiers);
+ gtk_label_set_text (GTK_LABEL (self->priv->label), label);
+ g_free (label);
+ }
+ else
+ gtk_label_set_text (GTK_LABEL (self->priv->label), _("None"));
+}
+
+
+#define _RESPONSE_RESET 10
+
+
+static void
+accel_dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ GthAccelButton *accel_button = user_data;
+
+ switch (response_id) {
+ case GTK_RESPONSE_CANCEL:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+ case _RESPONSE_RESET:
+ gth_accel_button_set_accelerator (accel_button, 0, 0);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+ }
+}
+
+
+static gboolean
+accel_dialog_keypress_cb (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ GthAccelButton *accel_button = user_data;
+ GdkModifierType modifiers;
+
+ if (event->keyval == GDK_KEY_Escape)
+ return FALSE;
+
+ modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
+ if (gth_accel_button_set_accelerator (accel_button, event->keyval, modifiers))
+ gtk_widget_destroy (widget);
+
+ return TRUE;
+}
+
+
+static void
+button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ GtkWidget *dialog, *box, *label, *secondary_label, *content_area;
+
+ dialog = g_object_new (GTK_TYPE_DIALOG,
+ "use-header-bar", _gtk_settings_get_dialogs_use_header (),
+ "modal", TRUE,
+ "transient-for", gtk_widget_get_toplevel (GTK_WIDGET (button)),
+ "resizable", FALSE,
+ "title", _("Shortcut"),
+ NULL);
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
+ ! gth_accel_button_get_valid (GTH_ACCEL_BUTTON (button)) ? NULL :
_GTK_LABEL_DELETE,
+ _RESPONSE_RESET,
+ NULL);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ label = gtk_label_new (_("Press a combination of keys to use as shortcut."));
+ secondary_label = gtk_label_new (_("Press Esc to cancel"));
+ gtk_style_context_add_class (gtk_widget_get_style_context (secondary_label), "dim-label");
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 50);
+ gtk_widget_set_margin_top (box, 50);
+ gtk_widget_set_margin_bottom (box, 50);
+ gtk_widget_set_margin_start (box, 50);
+ gtk_widget_set_margin_end (box, 50);
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), secondary_label, TRUE, TRUE, 0);
+
+ g_signal_connect (dialog,
+ "response",
+ G_CALLBACK (accel_dialog_response_cb),
+ button);
+ g_signal_connect (dialog,
+ "key-press-event",
+ G_CALLBACK (accel_dialog_keypress_cb),
+ button);
+
+ gtk_container_add (GTK_CONTAINER (content_area), box);
+ gtk_widget_show_all (dialog);
+}
+
+
+static void
+gth_accel_button_init (GthAccelButton *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_ACCEL_BUTTON, GthAccelButtonPrivate);
+ self->priv->keyval = 0;
+ self->priv->modifiers = 0;
+ self->priv->valid = FALSE;
+
+ self->priv->label = gtk_label_new ("");
+ gtk_widget_show (self->priv->label);
+ gtk_container_add (GTK_CONTAINER (self), self->priv->label);
+
+ _update_label (self);
+
+ g_signal_connect (self, "clicked", G_CALLBACK (button_clicked_cb), self);
+}
+
+
+GtkWidget *
+gth_accel_button_new (void)
+{
+ return (GtkWidget*) g_object_new (GTH_TYPE_ACCEL_BUTTON, NULL);
+}
+
+
+gboolean
+gth_accel_button_set_accelerator (GthAccelButton *self,
+ guint keyval,
+ GdkModifierType modifiers)
+{
+ g_return_val_if_fail (GTH_IS_ACCEL_BUTTON (self), FALSE);
+
+ self->priv->keyval = keyval;
+ self->priv->modifiers = modifiers;
+
+ _update_label (self);
+
+ return self->priv->valid;
+}
+
+
+gboolean
+gth_accel_button_get_accelerator (GthAccelButton *self,
+ guint *keyval,
+ GdkModifierType *modifiers)
+{
+ g_return_val_if_fail (GTH_IS_ACCEL_BUTTON (self), FALSE);
+
+ if (! self->priv->valid) {
+ if (keyval) *keyval = 0;
+ if (modifiers) *modifiers = 0;
+ return FALSE;
+ }
+
+ if (keyval) *keyval = self->priv->keyval;
+ if (modifiers) *modifiers = self->priv->modifiers;
+
+ return TRUE;
+}
+
+
+gboolean
+gth_accel_button_get_valid (GthAccelButton *self)
+{
+ g_return_val_if_fail (GTH_IS_ACCEL_BUTTON (self), FALSE);
+ return self->priv->valid;
+}
diff --git a/gthumb/gth-accel-button.h b/gthumb/gth-accel-button.h
new file mode 100644
index 0000000..8d1fc63
--- /dev/null
+++ b/gthumb/gth-accel-button.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_ACCEL_BUTTON_H
+#define GTH_ACCEL_BUTTON_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_ACCEL_BUTTON (gth_accel_button_get_type ())
+#define GTH_ACCEL_BUTTON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTH_TYPE_ACCEL_BUTTON,
GthAccelButton))
+#define GTH_ACCEL_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTH_TYPE_ACCEL_BUTTON,
GthAccelButtonClass))
+#define GTH_IS_ACCEL_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTH_TYPE_ACCEL_BUTTON))
+#define GTH_IS_ACCEL_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTH_TYPE_ACCEL_BUTTON))
+#define GTH_ACCEL_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GTH_TYPE_ACCEL_BUTTON,
GthAccelButtonClass))
+
+typedef struct _GthAccelButton GthAccelButton;
+typedef struct _GthAccelButtonPrivate GthAccelButtonPrivate;
+typedef struct _GthAccelButtonClass GthAccelButtonClass;
+
+struct _GthAccelButton {
+ GtkButton __parent;
+ GthAccelButtonPrivate *priv;
+};
+
+struct _GthAccelButtonClass {
+ GtkButtonClass __parent_class;
+
+ /*< signals >*/
+
+ void (*changed) (GthAccelButton *accel_button);
+};
+
+GType gth_accel_button_get_type (void) G_GNUC_CONST;
+GtkWidget * gth_accel_button_new (void);
+gboolean gth_accel_button_set_accelerator (GthAccelButton *accel_button,
+ guint accelerator_key,
+ GdkModifierType accelerator_mods);
+gboolean gth_accel_button_get_accelerator (GthAccelButton *accel_button,
+ guint *accelerator_key,
+ GdkModifierType *accelerator_mods);
+gboolean gth_accel_button_get_valid (GthAccelButton *accel_button);
+
+G_END_DECLS
+
+#endif /* GTH_ACCEL_BUTTON_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3a894fd..e48a5fb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -706,6 +706,8 @@ gthumb/gnome-desktop-thumbnail.h
gthumb/gnome-thumbnail-pixbuf-utils.c
gthumb/gsignature.c
gthumb/gsignature.h
+gthumb/gth-accel-button.c
+gthumb/gth-accel-button.h
gthumb/gth-application.c
gthumb/gth-application.h
gthumb/gth-async-task.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]