[gnome-builder/wip/chergert/merge-shortcuts] shorcuts: update shortcut engine snapshot
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/merge-shortcuts] shorcuts: update shortcut engine snapshot
- Date: Fri, 26 May 2017 21:41:09 +0000 (UTC)
commit b081a5fd5241bb1b41c61cc27b1a591d80dd9517
Author: Christian Hergert <chergert redhat com>
Date: Fri May 26 14:40:56 2017 -0700
shorcuts: update shortcut engine snapshot
libide/shortcuts/ide-shortcut-controller.c | 26 +++++++++
libide/shortcuts/ide-shortcut-label.c | 34 +++++++-----
libide/shortcuts/ide-shortcut-manager.c | 37 +++++++++++++
libide/shortcuts/ide-shortcut-manager.h | 82 ++++++++++++++++------------
libide/shortcuts/ide-shortcut-private.h | 2 +
libide/shortcuts/ide-shortcut-theme-load.c | 10 ++++
libide/shortcuts/ide-shortcut-theme-save.c | 10 +++-
libide/shortcuts/ide-shortcut-theme.c | 74 +++++++++++++++++++++++++
libide/shortcuts/ide-shortcut-theme.h | 3 +
9 files changed, 228 insertions(+), 50 deletions(-)
---
diff --git a/libide/shortcuts/ide-shortcut-controller.c b/libide/shortcuts/ide-shortcut-controller.c
index a3ad070..3c7932e 100644
--- a/libide/shortcuts/ide-shortcut-controller.c
+++ b/libide/shortcuts/ide-shortcut-controller.c
@@ -78,6 +78,7 @@ typedef struct
*/
gulong hierarchy_changed_handler;
gulong widget_destroy_handler;
+ gulong manager_changed_handler;
} IdeShortcutControllerPrivate;
typedef struct
@@ -152,6 +153,19 @@ ide_shortcut_controller_remove (IdeShortcutController *self,
}
static void
+ide_shortcut_controller_on_manager_changed (IdeShortcutController *self,
+ IdeShortcutManager *manager)
+{
+ IdeShortcutControllerPrivate *priv = ide_shortcut_controller_get_instance_private (self);
+
+ g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
+ g_assert (IDE_IS_SHORTCUT_MANAGER (manager));
+
+ g_clear_pointer (&priv->current_chord, ide_shortcut_chord_free);
+ g_clear_object (&priv->context);
+}
+
+static void
ide_shortcut_controller_widget_destroy (IdeShortcutController *self,
GtkWidget *widget)
{
@@ -216,6 +230,9 @@ ide_shortcut_controller_disconnect (IdeShortcutController *self)
g_signal_handler_disconnect (priv->widget, priv->hierarchy_changed_handler);
priv->hierarchy_changed_handler = 0;
+
+ g_signal_handler_disconnect (ide_shortcut_manager_get_default (), priv->manager_changed_handler);
+ priv->manager_changed_handler = 0;
}
static void
@@ -226,6 +243,9 @@ ide_shortcut_controller_connect (IdeShortcutController *self)
g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
g_assert (GTK_IS_WIDGET (priv->widget));
+ g_clear_pointer (&priv->current_chord, ide_shortcut_chord_free);
+ g_clear_object (&priv->context);
+
priv->widget_destroy_handler =
g_signal_connect_swapped (priv->widget,
"destroy",
@@ -238,6 +258,12 @@ ide_shortcut_controller_connect (IdeShortcutController *self)
G_CALLBACK (ide_shortcut_controller_widget_hierarchy_changed),
self);
+ priv->manager_changed_handler =
+ g_signal_connect_swapped (ide_shortcut_manager_get_default (),
+ "changed",
+ G_CALLBACK (ide_shortcut_controller_on_manager_changed),
+ self);
+
ide_shortcut_controller_widget_hierarchy_changed (self, NULL, priv->widget);
}
diff --git a/libide/shortcuts/ide-shortcut-label.c b/libide/shortcuts/ide-shortcut-label.c
index f383026..85e7213 100644
--- a/libide/shortcuts/ide-shortcut-label.c
+++ b/libide/shortcuts/ide-shortcut-label.c
@@ -160,32 +160,40 @@ void
ide_shortcut_label_set_chord (IdeShortcutLabel *self,
const IdeShortcutChord *chord)
{
+ g_return_if_fail (IDE_IS_SHORTCUT_LABEL (self));
+
if (!ide_shortcut_chord_equal (chord, self->chord))
{
- g_autofree gchar *accel = NULL;
-
ide_shortcut_chord_free (self->chord);
self->chord = ide_shortcut_chord_copy (chord);
- if (self->chord != NULL)
- accel = ide_shortcut_chord_to_string (self->chord);
-
- gtk_container_foreach (GTK_CONTAINER (self),
- (GtkCallback) gtk_widget_destroy,
- NULL);
+ gtk_container_foreach (GTK_CONTAINER (self), (GtkCallback) gtk_widget_destroy, NULL);
- if (accel != NULL)
+ if (chord != NULL)
{
- g_auto(GStrv) parts = NULL;
+ GdkModifierType first_mod = 0;
+ guint len;
- parts = g_strsplit (accel, "|", 0);
+ len = ide_shortcut_chord_get_length (chord);
- for (guint i = 0; parts[i]; i++)
+ ide_shortcut_chord_get_nth_key (chord, 0, NULL, &first_mod);
+
+ for (guint i = 0; i < len; i++)
{
+ g_autofree gchar *accel = NULL;
GtkWidget *label;
+ GdkModifierType mod = 0;
+ guint keyval = 0;
+
+ ide_shortcut_chord_get_nth_key (chord, i, &keyval, &mod);
+
+ if (i > 0 && (mod & first_mod) == first_mod)
+ accel = gtk_accelerator_name (keyval, mod & ~first_mod);
+ else
+ accel = gtk_accelerator_name (keyval, mod);
label = g_object_new (GTK_TYPE_SHORTCUT_LABEL,
- "accelerator", parts[i],
+ "accelerator", accel,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (self), label);
diff --git a/libide/shortcuts/ide-shortcut-manager.c b/libide/shortcuts/ide-shortcut-manager.c
index 670cad8..4f23add 100644
--- a/libide/shortcuts/ide-shortcut-manager.c
+++ b/libide/shortcuts/ide-shortcut-manager.c
@@ -962,3 +962,40 @@ _ide_shortcut_manager_get_root (IdeShortcutManager *self)
return priv->root;
}
+
+/**
+ * ide_shortcut_manager_add_shortcut_entries:
+ * @self: (nullable): a #IdeShortcutManager or %NULL for the default
+ * @shortcuts: (array length=n_shortcuts): shortcuts to add
+ * @n_shortcuts: the number of entries in @shortcuts
+ * @translation_domain: (nullable): the gettext domain to use for translations
+ *
+ * This method will add @shortcuts to the #IdeShortcutManager.
+ *
+ * This provides a simple way for widgets to add their shortcuts to the manager
+ * so that they may be overriden by themes or the end user.
+ */
+void
+ide_shortcut_manager_add_shortcut_entries (IdeShortcutManager *self,
+ const IdeShortcutEntry *shortcuts,
+ guint n_shortcuts,
+ const gchar *translation_domain)
+{
+ g_return_if_fail (!self || IDE_IS_SHORTCUT_MANAGER (self));
+ g_return_if_fail (shortcuts != NULL || n_shortcuts == 0);
+
+ if (self == NULL)
+ self = ide_shortcut_manager_get_default ();
+
+ for (guint i = 0; i < n_shortcuts; i++)
+ {
+ const IdeShortcutEntry *entry = &shortcuts[i];
+
+ ide_shortcut_manager_add_command (self,
+ g_dgettext (translation_domain, entry->command),
+ g_dgettext (translation_domain, entry->section),
+ g_dgettext (translation_domain, entry->group),
+ g_dgettext (translation_domain, entry->title),
+ g_dgettext (translation_domain, entry->subtitle));
+ }
+}
diff --git a/libide/shortcuts/ide-shortcut-manager.h b/libide/shortcuts/ide-shortcut-manager.h
index eeaec24..181e2e4 100644
--- a/libide/shortcuts/ide-shortcut-manager.h
+++ b/libide/shortcuts/ide-shortcut-manager.h
@@ -30,6 +30,16 @@ G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (IdeShortcutManager, ide_shortcut_manager, IDE, SHORTCUT_MANAGER, GObject)
+typedef struct
+{
+ const gchar *command;
+ const gchar *section;
+ const gchar *group;
+ const gchar *title;
+ const gchar *subtitle;
+ /* TODO: Should we add a default accelerator to add to the default theme? */
+} IdeShortcutEntry;
+
struct _IdeShortcutManagerClass
{
GObjectClass parent_instance;
@@ -45,40 +55,44 @@ struct _IdeShortcutManagerClass
};
IdeShortcutManager *ide_shortcut_manager_get_default (void);
-void ide_shortcut_manager_append_search_path (IdeShortcutManager *self,
- const gchar *directory);
-void ide_shortcut_manager_prepend_search_path (IdeShortcutManager *self,
- const gchar *directory);
-IdeShortcutTheme *ide_shortcut_manager_get_theme (IdeShortcutManager *self);
-void ide_shortcut_manager_set_theme (IdeShortcutManager *self,
- IdeShortcutTheme *theme);
-const gchar *ide_shortcut_manager_get_theme_name (IdeShortcutManager *self);
-void ide_shortcut_manager_set_theme_name (IdeShortcutManager *self,
- const gchar *theme_name);
-gboolean ide_shortcut_manager_handle_event (IdeShortcutManager *self,
- const GdkEventKey *event,
- GtkWidget *toplevel);
-void ide_shortcut_manager_add_theme (IdeShortcutManager *self,
- IdeShortcutTheme *theme);
-void ide_shortcut_manager_remove_theme (IdeShortcutManager *self,
- IdeShortcutTheme *theme);
-const gchar *ide_shortcut_manager_get_user_dir (IdeShortcutManager *self);
-void ide_shortcut_manager_set_user_dir (IdeShortcutManager *self,
- const gchar *user_dir);
-void ide_shortcut_manager_add_action (IdeShortcutManager *self,
- const gchar *detailed_action_name,
- const gchar *section,
- const gchar *group,
- const gchar *title,
- const gchar *subtitle);
-void ide_shortcut_manager_add_command (IdeShortcutManager *self,
- const gchar *command,
- const gchar *section,
- const gchar *group,
- const gchar *title,
- const gchar *subtitle);
-void ide_shortcut_manager_add_shortcuts_to_window (IdeShortcutManager *self,
- IdeShortcutsWindow *window);
+void ide_shortcut_manager_append_search_path (IdeShortcutManager *self,
+ const gchar *directory);
+void ide_shortcut_manager_prepend_search_path (IdeShortcutManager *self,
+ const gchar *directory);
+IdeShortcutTheme *ide_shortcut_manager_get_theme (IdeShortcutManager *self);
+void ide_shortcut_manager_set_theme (IdeShortcutManager *self,
+ IdeShortcutTheme *theme);
+const gchar *ide_shortcut_manager_get_theme_name (IdeShortcutManager *self);
+void ide_shortcut_manager_set_theme_name (IdeShortcutManager *self,
+ const gchar *theme_name);
+gboolean ide_shortcut_manager_handle_event (IdeShortcutManager *self,
+ const GdkEventKey *event,
+ GtkWidget *toplevel);
+void ide_shortcut_manager_add_theme (IdeShortcutManager *self,
+ IdeShortcutTheme *theme);
+void ide_shortcut_manager_remove_theme (IdeShortcutManager *self,
+ IdeShortcutTheme *theme);
+const gchar *ide_shortcut_manager_get_user_dir (IdeShortcutManager *self);
+void ide_shortcut_manager_set_user_dir (IdeShortcutManager *self,
+ const gchar *user_dir);
+void ide_shortcut_manager_add_action (IdeShortcutManager *self,
+ const gchar
*detailed_action_name,
+ const gchar *section,
+ const gchar *group,
+ const gchar *title,
+ const gchar *subtitle);
+void ide_shortcut_manager_add_command (IdeShortcutManager *self,
+ const gchar *command,
+ const gchar *section,
+ const gchar *group,
+ const gchar *title,
+ const gchar *subtitle);
+void ide_shortcut_manager_add_shortcut_entries (IdeShortcutManager *self,
+ const IdeShortcutEntry *shortcuts,
+ guint n_shortcuts,
+ const gchar
*translation_domain);
+void ide_shortcut_manager_add_shortcuts_to_window (IdeShortcutManager *self,
+ IdeShortcutsWindow *window);
G_END_DECLS
diff --git a/libide/shortcuts/ide-shortcut-private.h b/libide/shortcuts/ide-shortcut-private.h
index 8a6895e..d07e8df 100644
--- a/libide/shortcuts/ide-shortcut-private.h
+++ b/libide/shortcuts/ide-shortcut-private.h
@@ -85,6 +85,8 @@ typedef enum
GNode *_ide_shortcut_manager_get_root (IdeShortcutManager *self);
GtkTreeModel *_ide_shortcut_theme_create_model (IdeShortcutTheme *self);
GHashTable *_ide_shortcut_theme_get_contexts (IdeShortcutTheme *self);
+void _ide_shortcut_theme_set_name (IdeShortcutTheme *self,
+ const gchar *name);
IdeShortcutChordTable *_ide_shortcut_context_get_table (IdeShortcutContext *self);
void _ide_shortcut_chord_table_iter_init (IdeShortcutChordTableIter *iter,
IdeShortcutChordTable *table);
diff --git a/libide/shortcuts/ide-shortcut-theme-load.c b/libide/shortcuts/ide-shortcut-theme-load.c
index 585355e..b64b7b1 100644
--- a/libide/shortcuts/ide-shortcut-theme-load.c
+++ b/libide/shortcuts/ide-shortcut-theme-load.c
@@ -21,6 +21,7 @@
#include <string.h>
#include "ide-shortcut-context.h"
+#include "ide-shortcut-private.h"
#include "ide-shortcut-theme.h"
typedef enum
@@ -324,6 +325,8 @@ theme_start_element (GMarkupParseContext *context,
if (g_strcmp0 (element_name, "theme") == 0)
{
+ const gchar *name = NULL;
+ const gchar *parent = NULL;
const gchar *domain = NULL;
if (state->stack != NULL)
@@ -336,6 +339,8 @@ theme_start_element (GMarkupParseContext *context,
}
if (!g_markup_collect_attributes (element_name, attr_names, attr_values, error,
+ G_MARKUP_COLLECT_STRING, "name", &name,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "parent",
&parent,
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL,
"translation-domain", &domain,
G_MARKUP_COLLECT_INVALID))
return;
@@ -343,6 +348,11 @@ theme_start_element (GMarkupParseContext *context,
if (domain != NULL)
state->translation_domain = g_intern_string (domain);
+ _ide_shortcut_theme_set_name (state->self, name);
+
+ if (parent != NULL)
+ ide_shortcut_theme_set_parent_name (state->self, parent);
+
load_state_push (state, load_state_frame_new (LOAD_STATE_THEME));
}
else if (g_strcmp0 (element_name, "property") == 0)
diff --git a/libide/shortcuts/ide-shortcut-theme-save.c b/libide/shortcuts/ide-shortcut-theme-save.c
index b89be0b..bad4f98 100644
--- a/libide/shortcuts/ide-shortcut-theme-save.c
+++ b/libide/shortcuts/ide-shortcut-theme-save.c
@@ -30,6 +30,7 @@ ide_shortcut_theme_save_to_stream (IdeShortcutTheme *self,
GHashTable *contexts;
GHashTableIter iter;
const gchar *name;
+ const gchar *parent;
const gchar *title;
const gchar *subtitle;
@@ -41,13 +42,16 @@ ide_shortcut_theme_save_to_stream (IdeShortcutTheme *self,
str = g_string_new ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
- g_string_append (str, "<theme>\n");
-
name = ide_shortcut_theme_get_name (self);
+ parent = ide_shortcut_theme_get_parent_name (self);
title = ide_shortcut_theme_get_title (self);
subtitle = ide_shortcut_theme_get_subtitle (self);
- g_string_append_printf (str, " <property name=\"name\">%s</property>\n", name ? name : "");
+ if (parent != NULL)
+ g_string_append_printf (str, "<theme name=\"%s\" parent=\"%s\">\n", name, parent);
+ else
+ g_string_append_printf (str, "<theme name=\"%s\">\n", name);
+
g_string_append_printf (str, " <property name=\"title\" translatable=\"yes\">%s</property>\n", title ?
title : "");
g_string_append_printf (str, " <property name=\"subtitle\" translatable=\"yes\">%s</property>\n",
subtitle ? subtitle : "");
diff --git a/libide/shortcuts/ide-shortcut-theme.c b/libide/shortcuts/ide-shortcut-theme.c
index d26d5a5..e8628c2 100644
--- a/libide/shortcuts/ide-shortcut-theme.c
+++ b/libide/shortcuts/ide-shortcut-theme.c
@@ -24,6 +24,7 @@
typedef struct
{
gchar *name;
+ gchar *parent_name;
gchar *title;
gchar *subtitle;
GHashTable *contexts;
@@ -34,6 +35,7 @@ typedef struct
enum {
PROP_0,
PROP_NAME,
+ PROP_PARENT_NAME,
PROP_SUBTITLE,
PROP_TITLE,
N_PROPS
@@ -50,6 +52,7 @@ ide_shortcut_theme_finalize (GObject *object)
IdeShortcutThemePrivate *priv = ide_shortcut_theme_get_instance_private (self);
g_clear_pointer (&priv->name, g_free);
+ g_clear_pointer (&priv->parent_name, g_free);
g_clear_pointer (&priv->title, g_free);
g_clear_pointer (&priv->subtitle, g_free);
g_clear_pointer (&priv->contexts, g_hash_table_unref);
@@ -73,6 +76,10 @@ ide_shortcut_theme_get_property (GObject *object,
g_value_set_string (value, ide_shortcut_theme_get_name (self));
break;
+ case PROP_PARENT_NAME:
+ g_value_set_string (value, ide_shortcut_theme_get_parent_name (self));
+ break;
+
case PROP_TITLE:
g_value_set_string (value, ide_shortcut_theme_get_title (self));
break;
@@ -101,11 +108,17 @@ ide_shortcut_theme_set_property (GObject *object,
priv->name = g_value_dup_string (value);
break;
+ case PROP_PARENT_NAME:
+ ide_shortcut_theme_set_parent_name (self, g_value_get_string (value));
+ break;
+
case PROP_TITLE:
+ g_free (priv->title);
priv->title = g_value_dup_string (value);
break;
case PROP_SUBTITLE:
+ g_free (priv->subtitle);
priv->subtitle = g_value_dup_string (value);
break;
@@ -128,6 +141,13 @@ ide_shortcut_theme_class_init (IdeShortcutThemeClass *klass)
"Name",
"The name of the theme",
NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_PARENT_NAME] =
+ g_param_spec_string ("parent-name",
+ "Parent Name",
+ "The name of the parent shortcut theme",
+ NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties [PROP_TITLE] =
@@ -385,3 +405,57 @@ ide_shortcut_theme_set_accel_for_command (IdeShortcutTheme *self,
ide_shortcut_theme_set_chord_for_command (self, detailed_command_name, chord);
}
}
+
+void
+_ide_shortcut_theme_set_name (IdeShortcutTheme *self,
+ const gchar *name)
+{
+ IdeShortcutThemePrivate *priv = ide_shortcut_theme_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_SHORTCUT_THEME (self));
+
+ if (g_strcmp0 (name, priv->name) != 0)
+ {
+ g_free (priv->name);
+ priv->name = g_strdup (name);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]);
+ }
+}
+
+/**
+ * ide_shortcut_theme_get_parent_name:
+ * @self: a #IdeShortcutTheme
+ *
+ * Gets the name of the parent shortcut theme.
+ *
+ * This is used to resolve shortcuts from the parent theme without having to
+ * copy them directly into this shortcut theme. It allows for some level of
+ * copy-on-write (CoW).
+ *
+ * Returns: (nullable): The name of the parent theme, or %NULL if none is set.
+ */
+const gchar *
+ide_shortcut_theme_get_parent_name (IdeShortcutTheme *self)
+{
+ IdeShortcutThemePrivate *priv = ide_shortcut_theme_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_SHORTCUT_THEME (self), NULL);
+
+ return priv->parent_name;
+}
+
+void
+ide_shortcut_theme_set_parent_name (IdeShortcutTheme *self,
+ const gchar *parent_name)
+{
+ IdeShortcutThemePrivate *priv = ide_shortcut_theme_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_SHORTCUT_THEME (self));
+
+ if (g_strcmp0 (parent_name, priv->parent_name) != 0)
+ {
+ g_free (priv->parent_name);
+ priv->parent_name = g_strdup (parent_name);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PARENT_NAME]);
+ }
+}
diff --git a/libide/shortcuts/ide-shortcut-theme.h b/libide/shortcuts/ide-shortcut-theme.h
index 5fd8b82..888ff54 100644
--- a/libide/shortcuts/ide-shortcut-theme.h
+++ b/libide/shortcuts/ide-shortcut-theme.h
@@ -48,6 +48,9 @@ IdeShortcutTheme *ide_shortcut_theme_new (const gchar
const gchar *ide_shortcut_theme_get_name (IdeShortcutTheme *self);
const gchar *ide_shortcut_theme_get_title (IdeShortcutTheme *self);
const gchar *ide_shortcut_theme_get_subtitle (IdeShortcutTheme *self);
+const gchar *ide_shortcut_theme_get_parent_name (IdeShortcutTheme *self);
+void ide_shortcut_theme_set_parent_name (IdeShortcutTheme *self,
+ const gchar *parent_name);
IdeShortcutContext *ide_shortcut_theme_find_default_context (IdeShortcutTheme *self,
GtkWidget *widget);
IdeShortcutContext *ide_shortcut_theme_find_context_by_name (IdeShortcutTheme *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]