[gnome-control-center/wip/gbsneto/new-keyboard-panel: 6/9] keyboard: use CcKeyboardManager



commit 58eee830e946fb2dcabbd75f7ee558efa75ea412
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Jul 13 13:54:26 2016 -0300

    keyboard: use CcKeyboardManager
    
    After introducing the manager object to handle the backend
    code, this patch ports both CcKeyboardShortcutEditor and
    CcKeyboardPanel to use the new class instead of manually
    handling backend code.

 panels/keyboard/cc-keyboard-panel.c           |  847 +------------------------
 panels/keyboard/cc-keyboard-shortcut-editor.c |   68 +--
 panels/keyboard/cc-keyboard-shortcut-editor.h |    4 +-
 3 files changed, 35 insertions(+), 884 deletions(-)
---
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c
index f02d922..2d4b106 100644
--- a/panels/keyboard/cc-keyboard-panel.c
+++ b/panels/keyboard/cc-keyboard-panel.c
@@ -23,20 +23,13 @@
 #include <glib/gi18n.h>
 
 #include "cc-keyboard-item.h"
+#include "cc-keyboard-manager.h"
 #include "cc-keyboard-option.h"
 #include "cc-keyboard-panel.h"
 #include "cc-keyboard-resources.h"
 #include "cc-keyboard-shortcut-editor.h"
 
 #include "keyboard-shortcuts.h"
-#include "wm-common.h"
-
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkx.h>
-#endif
-
-#define BINDINGS_SCHEMA       "org.gnome.settings-daemon.plugins.media-keys"
-#define CUSTOM_SHORTCUTS_ID   "custom"
 
 typedef struct
 {
@@ -50,24 +43,15 @@ struct _CcKeyboardPanel
   CcPanel             parent;
 
   /* Shortcut view */
-  GtkListStore       *shortcuts_model;
-  GtkListStore       *sections_store;
-  GtkTreeModel       *sections_model;
   GtkWidget          *listbox;
   GtkListBoxRow      *add_shortcut_row;
 
   /* Custom shortcut dialog */
   GtkWidget          *shortcut_editor;
 
-  GHashTable         *kb_system_sections;
-  GHashTable         *kb_apps_sections;
-  GHashTable         *kb_user_sections;
-
-  GSettings          *binding_settings;
-
   GRegex             *pictures_regex;
 
-  gpointer            wm_changed_id;
+  CcKeyboardManager  *manager;
 };
 
 CC_PANEL_REGISTER (CcKeyboardPanel, cc_keyboard_panel)
@@ -310,726 +294,6 @@ header_function (GtkListBoxRow *row,
     }
 }
 
-static GHashTable*
-get_hash_for_group (CcKeyboardPanel  *self,
-                    BindingGroupType  group)
-{
-  GHashTable *hash;
-
-  switch (group)
-    {
-    case BINDING_GROUP_SYSTEM:
-      hash = self->kb_system_sections;
-      break;
-    case BINDING_GROUP_APPS:
-      hash = self->kb_apps_sections;
-      break;
-    case BINDING_GROUP_USER:
-      hash = self->kb_user_sections;
-      break;
-    default:
-      hash = NULL;
-    }
-
-  return hash;
-}
-
-static gboolean
-have_key_for_group (CcKeyboardPanel *self,
-                    int              group,
-                    const gchar     *name)
-{
-  GHashTableIter iter;
-  GPtrArray *keys;
-  gint i;
-
-  g_hash_table_iter_init (&iter, get_hash_for_group (self, group));
-  while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &keys))
-    {
-      for (i = 0; i < keys->len; i++)
-        {
-          CcKeyboardItem *item = g_ptr_array_index (keys, i);
-
-          if (item->type == CC_KEYBOARD_ITEM_TYPE_GSETTINGS &&
-              g_strcmp0 (name, item->key) == 0)
-            {
-              return TRUE;
-            }
-
-          return FALSE;
-        }
-    }
-
-  return FALSE;
-}
-
-static void
-free_key_array (GPtrArray *keys)
-{
-  if (keys != NULL)
-    {
-      gint i;
-
-      for (i = 0; i < keys->len; i++)
-        {
-          CcKeyboardItem *item;
-
-          item = g_ptr_array_index (keys, i);
-
-          g_object_unref (item);
-        }
-
-      g_ptr_array_free (keys, TRUE);
-    }
-}
-
-static char*
-binding_name (guint                   keyval,
-              guint                   keycode,
-              GdkModifierType         mask,
-              gboolean                translate)
-{
-  if (keyval != 0 || keycode != 0)
-    {
-      return translate ? gtk_accelerator_get_label_with_keycode (NULL, keyval, keycode, mask) :
-                         gtk_accelerator_name_with_keycode (NULL, keyval, keycode, mask);
-    }
-  else
-    {
-      return g_strdup (translate ? _("Disabled") : NULL);
-    }
-}
-
-
-static gboolean
-keybinding_key_changed_foreach (GtkTreeModel   *model,
-                                GtkTreePath    *path,
-                                GtkTreeIter    *iter,
-                                CcKeyboardItem *item)
-{
-  CcKeyboardItem *tmp_item;
-
-  gtk_tree_model_get (item->model,
-                      iter,
-                      DETAIL_KEYENTRY_COLUMN, &tmp_item,
-                      -1);
-
-  if (item == tmp_item)
-    {
-      gtk_tree_model_row_changed (item->model, path, iter);
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-static void
-item_changed (CcKeyboardItem *item,
-              GParamSpec     *pspec,
-              gpointer        user_data)
-{
-  /* update the model */
-  gtk_tree_model_foreach (item->model,
-                          (GtkTreeModelForeachFunc) keybinding_key_changed_foreach,
-                          item);
-}
-
-static void
-append_section (CcKeyboardPanel    *self,
-                const gchar        *title,
-                const gchar        *id,
-                BindingGroupType    group,
-                const KeyListEntry *keys_list)
-{
-  GtkTreeModel *shortcut_model;
-  GtkTreeIter iter;
-  GHashTable *reverse_items;
-  GHashTable *hash;
-  GPtrArray *keys_array;
-  gboolean is_new;
-  gint i;
-
-  hash = get_hash_for_group (self, group);
-
-  if (!hash)
-    return;
-
-  shortcut_model = GTK_TREE_MODEL (self->shortcuts_model);
-
-  /* Add all CcKeyboardItems for this section */
-  is_new = FALSE;
-  keys_array = g_hash_table_lookup (hash, id);
-  if (keys_array == NULL)
-    {
-      keys_array = g_ptr_array_new ();
-      is_new = TRUE;
-    }
-
-  reverse_items = g_hash_table_new (g_str_hash, g_str_equal);
-
-  for (i = 0; keys_list != NULL && keys_list[i].name != NULL; i++)
-    {
-      CcKeyboardItem *item;
-      gboolean ret;
-
-      if (have_key_for_group (self, group, keys_list[i].name))
-        continue;
-
-      item = cc_keyboard_item_new (keys_list[i].type);
-      switch (keys_list[i].type)
-        {
-        case CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH:
-          ret = cc_keyboard_item_load_from_gsettings_path (item, keys_list[i].name, FALSE);
-          break;
-
-        case CC_KEYBOARD_ITEM_TYPE_GSETTINGS:
-          ret = cc_keyboard_item_load_from_gsettings (item,
-                                                      keys_list[i].description,
-                                                      keys_list[i].schema,
-                                                      keys_list[i].name);
-          if (ret && keys_list[i].reverse_entry != NULL)
-            {
-              CcKeyboardItem *reverse_item;
-              reverse_item = g_hash_table_lookup (reverse_items,
-                                                  keys_list[i].reverse_entry);
-              if (reverse_item != NULL)
-                {
-                  cc_keyboard_item_add_reverse_item (item,
-                                                     reverse_item,
-                                                     keys_list[i].is_reversed);
-                }
-              else
-                {
-                  g_hash_table_insert (reverse_items,
-                                       keys_list[i].name,
-                                       item);
-                }
-            }
-          break;
-
-        default:
-          g_assert_not_reached ();
-        }
-
-      if (ret == FALSE)
-        {
-          /* We don't actually want to popup a dialog - just skip this one */
-          g_object_unref (item);
-          continue;
-        }
-
-      cc_keyboard_item_set_hidden (item, keys_list[i].hidden);
-      item->model = shortcut_model;
-      item->group = group;
-
-      g_signal_connect (G_OBJECT (item),
-                        "notify",
-                        G_CALLBACK (item_changed),
-                        NULL);
-
-      g_ptr_array_add (keys_array, item);
-    }
-
-  g_hash_table_destroy (reverse_items);
-
-  /* Add the keys to the hash table */
-  if (is_new)
-    {
-      g_hash_table_insert (hash, g_strdup (id), keys_array);
-
-      /* Append the section to the left tree view */
-      gtk_list_store_append (GTK_LIST_STORE (self->sections_store), &iter);
-      gtk_list_store_set (GTK_LIST_STORE (self->sections_store),
-                          &iter,
-                          SECTION_DESCRIPTION_COLUMN, title,
-                          SECTION_ID_COLUMN, id,
-                          SECTION_GROUP_COLUMN, group,
-                          -1);
-    }
-}
-
-static void
-append_sections_from_file (CcKeyboardPanel  *self,
-                           const gchar      *path,
-                           const char       *datadir,
-                           gchar           **wm_keybindings)
-{
-  GError *err = NULL;
-  char *buf;
-  gsize buf_len;
-  KeyList *keylist;
-  KeyListEntry *keys;
-  KeyListEntry key = { 0, 0, 0, 0, 0, 0, 0 };
-  const char *title;
-  int group;
-  guint i;
-  GMarkupParseContext *ctx;
-  GMarkupParser parser = { parse_start_tag, NULL, NULL, NULL, NULL };
-
-  /* Parse file */
-  if (!g_file_get_contents (path, &buf, &buf_len, &err))
-    return;
-
-  keylist = g_new0 (KeyList, 1);
-  keylist->entries = g_array_new (FALSE, TRUE, sizeof (KeyListEntry));
-  ctx = g_markup_parse_context_new (&parser, 0, keylist, NULL);
-
-  if (!g_markup_parse_context_parse (ctx, buf, buf_len, &err))
-    {
-      g_warning ("Failed to parse '%s': '%s'", path, err->message);
-      g_error_free (err);
-      g_free (keylist->name);
-      g_free (keylist->package);
-      g_free (keylist->wm_name);
-
-      for (i = 0; i < keylist->entries->len; i++)
-        g_free (((KeyListEntry *) &(keylist->entries->data[i]))->name);
-
-      g_array_free (keylist->entries, TRUE);
-      g_free (keylist);
-      keylist = NULL;
-    }
-  g_markup_parse_context_free (ctx);
-  g_free (buf);
-
-  if (keylist == NULL)
-    return;
-
-#define const_strv(s) ((const gchar* const*) s)
-
-  /* If there's no keys to add, or the settings apply to a window manager
-   * that's not the one we're running */
-  if (keylist->entries->len == 0 ||
-      (keylist->wm_name != NULL && !g_strv_contains (const_strv (wm_keybindings), keylist->wm_name)) ||
-      keylist->name == NULL)
-    {
-      g_free (keylist->name);
-      g_free (keylist->package);
-      g_free (keylist->wm_name);
-      g_array_free (keylist->entries, TRUE);
-      g_free (keylist);
-      return;
-    }
-
-#undef const_strv
-
-  /* Empty KeyListEntry to end the array */
-  key.name = NULL;
-  g_array_append_val (keylist->entries, key);
-
-  keys = (KeyListEntry *) g_array_free (keylist->entries, FALSE);
-  if (keylist->package)
-    {
-      char *localedir;
-
-      localedir = g_build_filename (datadir, "locale", NULL);
-      bindtextdomain (keylist->package, localedir);
-      g_free (localedir);
-
-      title = dgettext (keylist->package, keylist->name);
-    } else {
-      title = _(keylist->name);
-    }
-
-  if (keylist->group && strcmp (keylist->group, "system") == 0)
-    group = BINDING_GROUP_SYSTEM;
-  else
-    group = BINDING_GROUP_APPS;
-
-
-
-  append_section (self, title, keylist->name, group, keys);
-
-  g_free (keylist->name);
-  g_free (keylist->package);
-  g_free (keylist->wm_name);
-  g_free (keylist->schema);
-  g_free (keylist->group);
-
-  for (i = 0; keys[i].name != NULL; i++)
-    {
-      KeyListEntry *entry = &keys[i];
-      g_free (entry->schema);
-      g_free (entry->description);
-      g_free (entry->name);
-      g_free (entry->reverse_entry);
-    }
-
-  g_free (keylist);
-  g_free (keys);
-}
-
-static void
-append_sections_from_gsettings (CcKeyboardPanel *self)
-{
-  char **custom_paths;
-  GArray *entries;
-  KeyListEntry key = { 0, 0, 0, 0, 0, 0, 0 };
-  int i;
-
-  /* load custom shortcuts from GSettings */
-  entries = g_array_new (FALSE, TRUE, sizeof (KeyListEntry));
-
-  custom_paths = g_settings_get_strv (self->binding_settings, "custom-keybindings");
-  for (i = 0; custom_paths[i]; i++)
-    {
-      key.name = g_strdup (custom_paths[i]);
-      if (!have_key_for_group (self, BINDING_GROUP_USER, key.name))
-        {
-          key.type = CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH;
-          g_array_append_val (entries, key);
-        }
-      else
-        g_free (key.name);
-    }
-  g_strfreev (custom_paths);
-
-  if (entries->len > 0)
-    {
-      KeyListEntry *keys;
-      int i;
-
-      /* Empty KeyListEntry to end the array */
-      key.name = NULL;
-      g_array_append_val (entries, key);
-
-      keys = (KeyListEntry *) entries->data;
-      append_section (self, _("Custom Shortcuts"), CUSTOM_SHORTCUTS_ID, BINDING_GROUP_USER, keys);
-      for (i = 0; i < entries->len; ++i)
-        {
-          g_free (keys[i].name);
-        }
-    }
-  else
-    {
-      append_section (self, _("Custom Shortcuts"), CUSTOM_SHORTCUTS_ID, BINDING_GROUP_USER, NULL);
-    }
-
-  g_array_free (entries, TRUE);
-}
-
-static void
-reload_sections (CcKeyboardPanel *self)
-{
-  GtkTreeModel *shortcut_model;
-  GHashTable *loaded_files;
-  GDir *dir;
-  gchar *default_wm_keybindings[] = { "Mutter", "GNOME Shell", NULL };
-  gchar **wm_keybindings;
-  const gchar * const * data_dirs;
-  guint i;
-
-  shortcut_model = GTK_TREE_MODEL (self->shortcuts_model);
-  /* FIXME: get current selection and keep it after refreshing */
-
-  /* Clear previous models and hash tables */
-  gtk_list_store_clear (GTK_LIST_STORE (self->sections_store));
-  gtk_list_store_clear (GTK_LIST_STORE (shortcut_model));
-
-  g_clear_pointer (&self->kb_system_sections, g_hash_table_destroy);
-  self->kb_system_sections = g_hash_table_new_full (g_str_hash,
-                                                    g_str_equal,
-                                                    g_free,
-                                                    (GDestroyNotify) free_key_array);
-
-  g_clear_pointer (&self->kb_apps_sections, g_hash_table_destroy);
-  self->kb_apps_sections = g_hash_table_new_full (g_str_hash,
-                                                  g_str_equal,
-                                                  g_free,
-                                                  (GDestroyNotify) free_key_array);
-
-  g_clear_pointer (&self->kb_user_sections, g_hash_table_destroy);
-  self->kb_user_sections = g_hash_table_new_full (g_str_hash,
-                                                  g_str_equal,
-                                                  g_free,
-                                                  (GDestroyNotify) free_key_array);
-
-  /* Load WM keybindings */
-#ifdef GDK_WINDOWING_X11
-  if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
-    wm_keybindings = wm_common_get_current_keybindings ();
-  else
-#endif
-    wm_keybindings = g_strdupv (default_wm_keybindings);
-
-  loaded_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-  data_dirs = g_get_system_data_dirs ();
-  for (i = 0; data_dirs[i] != NULL; i++)
-    {
-      char *dir_path;
-      const gchar *name;
-
-      dir_path = g_build_filename (data_dirs[i], "gnome-control-center", "keybindings", NULL);
-
-      dir = g_dir_open (dir_path, 0, NULL);
-      if (!dir)
-        {
-          g_free (dir_path);
-          continue;
-        }
-
-      for (name = g_dir_read_name (dir) ; name ; name = g_dir_read_name (dir))
-        {
-          gchar *path;
-
-          if (g_str_has_suffix (name, ".xml") == FALSE)
-            continue;
-
-          if (g_hash_table_lookup (loaded_files, name) != NULL)
-            {
-              g_debug ("Not loading %s, it was already loaded from another directory", name);
-              continue;
-            }
-
-          g_hash_table_insert (loaded_files, g_strdup (name), GINT_TO_POINTER (1));
-          path = g_build_filename (dir_path, name, NULL);
-          append_sections_from_file (self, path, data_dirs[i], wm_keybindings);
-          g_free (path);
-        }
-      g_free (dir_path);
-      g_dir_close (dir);
-    }
-
-  g_hash_table_destroy (loaded_files);
-  g_strfreev (wm_keybindings);
-
-  /* Load custom keybindings */
-  append_sections_from_gsettings (self);
-}
-
-static int
-section_sort_item  (GtkTreeModel *model,
-                    GtkTreeIter  *a,
-                    GtkTreeIter  *b,
-                    gpointer      data)
-{
-  char *a_desc;
-  int   a_group;
-  char *b_desc;
-  int   b_group;
-  int   ret;
-
-  gtk_tree_model_get (model, a,
-                      SECTION_DESCRIPTION_COLUMN, &a_desc,
-                      SECTION_GROUP_COLUMN, &a_group,
-                      -1);
-  gtk_tree_model_get (model, b,
-                      SECTION_DESCRIPTION_COLUMN, &b_desc,
-                      SECTION_GROUP_COLUMN, &b_group,
-                      -1);
-
-  if (a_group == b_group && a_desc && b_desc)
-    ret = g_utf8_collate (a_desc, b_desc);
-  else
-    ret = a_group - b_group;
-
-  g_free (a_desc);
-  g_free (b_desc);
-
-  return ret;
-}
-
-static void
-add_shortcuts (CcKeyboardPanel *self)
-{
-  GtkTreeIter sections_iter;
-  gboolean can_continue;
-
-  can_continue = gtk_tree_model_get_iter_first (self->sections_model, &sections_iter);
-
-  while (can_continue)
-    {
-      BindingGroupType group;
-      GPtrArray *keys;
-      gchar *id, *title;
-      gint i;
-
-      gtk_tree_model_get (self->sections_model,
-                          &sections_iter,
-                          SECTION_DESCRIPTION_COLUMN, &title,
-                          SECTION_GROUP_COLUMN, &group,
-                          SECTION_ID_COLUMN, &id,
-                          -1);
-
-      /* Ignore separators */
-      if (group == BINDING_GROUP_SEPARATOR)
-        {
-          can_continue = gtk_tree_model_iter_next (self->sections_model, &sections_iter);
-          continue;
-        }
-
-      keys = g_hash_table_lookup (get_hash_for_group (self, group), id);
-
-      for (i = 0; i < keys->len; i++)
-        {
-          CcKeyboardItem *item = g_ptr_array_index (keys, i);
-
-          if (!cc_keyboard_item_is_hidden (item))
-            {
-              GtkTreeIter new_row;
-
-              gtk_list_store_append (self->shortcuts_model, &new_row);
-              gtk_list_store_set (self->shortcuts_model,
-                                  &new_row,
-                                  DETAIL_DESCRIPTION_COLUMN, item->description,
-                                  DETAIL_KEYENTRY_COLUMN, item,
-                                  DETAIL_TYPE_COLUMN, SHORTCUT_TYPE_KEY_ENTRY,
-                                  -1);
-
-              add_item (self, item, id, title);
-            }
-        }
-
-      can_continue = gtk_tree_model_iter_next (self->sections_model, &sections_iter);
-
-      g_free (title);
-      g_free (id);
-    }
-}
-
-static void
-shortcut_selection_changed (GtkTreeSelection *selection,
-                            GtkWidget        *button)
-{
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  gboolean can_remove;
-
-  can_remove = FALSE;
-
-  if (gtk_tree_selection_get_selected (selection, &model, &iter))
-    {
-      CcKeyboardItem *item;
-      ShortcutType type;
-
-      gtk_tree_model_get (model, &iter,
-                          DETAIL_KEYENTRY_COLUMN, &item,
-                          DETAIL_TYPE_COLUMN, &type,
-                          -1);
-
-      if (type == SHORTCUT_TYPE_KEY_ENTRY &&
-          item &&
-          item->command != NULL &&
-          item->editable)
-        {
-          can_remove = TRUE;
-        }
-    }
-
-  gtk_widget_set_sensitive (button, can_remove);
-}
-
-
-static gboolean
-remove_custom_shortcut (CcKeyboardShortcutEditor *editor,
-                        CcKeyboardItem           *item,
-                        CcKeyboardPanel          *self)
-{
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  GPtrArray *keys_array;
-  GVariantBuilder builder;
-  gboolean valid;
-  char **settings_paths;
-  int i;
-
-  model = GTK_TREE_MODEL (self->shortcuts_model);
-  valid = gtk_tree_model_get_iter_first (model, &iter);
-
-  /* Search for the iter */
-  while (valid)
-    {
-      CcKeyboardItem  *current_item;
-
-      gtk_tree_model_get (model, &iter,
-                          DETAIL_KEYENTRY_COLUMN, &current_item,
-                          -1);
-
-      if (current_item == item)
-        break;
-
-      valid = gtk_tree_model_iter_next (model, &iter);
-
-      g_clear_object (&current_item);
-    }
-
-  /* Shortcut not found or not a custom shortcut */
-  g_assert (valid);
-  g_assert (item->type == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH);
-
-  remove_item (self, item);
-
-  g_settings_delay (item->settings);
-  g_settings_reset (item->settings, "name");
-  g_settings_reset (item->settings, "command");
-  g_settings_reset (item->settings, "binding");
-  g_settings_apply (item->settings);
-  g_settings_sync ();
-
-  settings_paths = g_settings_get_strv (self->binding_settings, "custom-keybindings");
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
-
-  for (i = 0; settings_paths[i]; i++)
-    if (strcmp (settings_paths[i], item->gsettings_path) != 0)
-      g_variant_builder_add (&builder, "s", settings_paths[i]);
-
-  g_settings_set_value (self->binding_settings,
-                        "custom-keybindings",
-                        g_variant_builder_end (&builder));
-
-  g_strfreev (settings_paths);
-  g_object_unref (item);
-
-  keys_array = g_hash_table_lookup (get_hash_for_group (self, BINDING_GROUP_USER), CUSTOM_SHORTCUTS_ID);
-  g_ptr_array_remove (keys_array, item);
-
-  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
-  return TRUE;
-}
-
-static void
-add_custom_shortcut (CcKeyboardShortcutEditor *editor,
-                     CcKeyboardItem           *item,
-                     CcKeyboardPanel          *self)
-{
-  GtkTreePath *path;
-  GPtrArray *keys_array;
-  GtkTreeIter iter;
-  GHashTable *hash;
-  GVariantBuilder builder;
-  char **settings_paths;
-  int i;
-
-  hash = get_hash_for_group (self, BINDING_GROUP_USER);
-  keys_array = g_hash_table_lookup (hash, CUSTOM_SHORTCUTS_ID);
-  if (keys_array == NULL)
-    {
-      keys_array = g_ptr_array_new ();
-      g_hash_table_insert (hash, g_strdup (CUSTOM_SHORTCUTS_ID), keys_array);
-    }
-
-  g_ptr_array_add (keys_array, item);
-
-  gtk_list_store_append (self->shortcuts_model, &iter);
-  gtk_list_store_set (self->shortcuts_model, &iter, DETAIL_KEYENTRY_COLUMN, item, -1);
-
-  settings_paths = g_settings_get_strv (self->binding_settings, "custom-keybindings");
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
-  for (i = 0; settings_paths[i]; i++)
-    g_variant_builder_add (&builder, "s", settings_paths[i]);
-  g_variant_builder_add (&builder, "s", item->gsettings_path);
-  g_settings_set_value (self->binding_settings, "custom-keybindings",
-                        g_variant_builder_end (&builder));
-
-  /* make the new shortcut visible */
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->shortcuts_model), &iter);
-  gtk_tree_path_free (path);
-
-  add_item (self, item, CUSTOM_SHORTCUTS_ID, _("Custom Shortcuts"));
-}
-
 static void
 shortcut_row_activated (GtkWidget       *button,
                         GtkListBoxRow   *row,
@@ -1056,34 +320,6 @@ shortcut_row_activated (GtkWidget       *button,
 }
 
 static void
-setup_tree_views (CcKeyboardPanel *self)
-{
-  /* Setup the section treeview */
-  self->sections_store = gtk_list_store_new (SECTION_N_COLUMNS,
-                                             G_TYPE_STRING,
-                                             G_TYPE_STRING,
-                                             G_TYPE_INT);
-  self->sections_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->sections_store));
-
-  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self->sections_model),
-                                   SECTION_DESCRIPTION_COLUMN,
-                                   section_sort_item,
-                                   self,
-                                   NULL);
-
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->sections_model),
-                                        SECTION_DESCRIPTION_COLUMN,
-                                        GTK_SORT_ASCENDING);
-
-  self->shortcuts_model = gtk_list_store_new (DETAIL_N_COLUMNS,
-                                              G_TYPE_STRING,
-                                              G_TYPE_POINTER,
-                                              G_TYPE_INT);
-
-  setup_keyboard_options (self->shortcuts_model);
-}
-
-static void
 cc_keyboard_panel_set_property (GObject      *object,
                                guint         property_id,
                                const GValue *value,
@@ -1110,13 +346,7 @@ cc_keyboard_panel_finalize (GObject *object)
 {
   CcKeyboardPanel *self = CC_KEYBOARD_PANEL (object);
 
-  g_clear_pointer (&self->kb_system_sections, g_hash_table_destroy);
-  g_clear_pointer (&self->kb_apps_sections, g_hash_table_destroy);
-  g_clear_pointer (&self->kb_user_sections, g_hash_table_destroy);
   g_clear_pointer (&self->pictures_regex, g_regex_unref);
-  g_clear_pointer (&self->wm_changed_id, wm_common_unregister_window_manager_change);
-
-  g_clear_object (&self->binding_settings);
 
   cc_keyboard_option_clear_all ();
 
@@ -1124,13 +354,6 @@ cc_keyboard_panel_finalize (GObject *object)
 }
 
 static void
-on_window_manager_change (const char      *wm_name,
-                          CcKeyboardPanel *self)
-{
-  reload_sections (self);
-}
-
-static void
 cc_keyboard_panel_constructed (GObject *object)
 {
   CcKeyboardPanel *self = CC_KEYBOARD_PANEL (object);
@@ -1141,17 +364,6 @@ cc_keyboard_panel_constructed (GObject *object)
   /* Setup the dialog's transient parent */
   toplevel = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self))));
   gtk_window_set_transient_for (GTK_WINDOW (self->shortcut_editor), toplevel);
-
-#ifdef GDK_WINDOWING_X11
-  if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
-    self->wm_changed_id = wm_common_register_window_manager_change ((GFunc) on_window_manager_change,
-                                                                    self);
-#endif
-
-  setup_tree_views (self);
-  reload_sections (self);
-
-  add_shortcuts (self);
 }
 
 static void
@@ -1175,7 +387,6 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
   gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, listbox);
 
   gtk_widget_class_bind_template_callback (widget_class, shortcut_row_activated);
-  gtk_widget_class_bind_template_callback (widget_class, shortcut_selection_changed);
 }
 
 static void
@@ -1186,21 +397,23 @@ cc_keyboard_panel_init (CcKeyboardPanel *self)
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  /* Bindings */
-  self->binding_settings = g_settings_new (BINDINGS_SCHEMA);
+  /* Shortcut manager */
+  self->manager = cc_keyboard_manager_new ();
 
-  /* Shortcut editor dialog */
-  self->shortcut_editor = cc_keyboard_shortcut_editor_new (self);
+  g_signal_connect_swapped (self->manager,
+                            "shortcut-added",
+                            G_CALLBACK (add_item),
+                            self);
 
-  g_signal_connect (self->shortcut_editor,
-                    "add-custom-shortcut",
-                    G_CALLBACK (add_custom_shortcut),
-                    self);
+  g_signal_connect_swapped (self->manager,
+                            "shortcut-removed",
+                            G_CALLBACK (remove_item),
+                            self);
 
-  g_signal_connect (self->shortcut_editor,
-                    "remove-custom-shortcut",
-                    G_CALLBACK (remove_custom_shortcut),
-                    self);
+  cc_keyboard_manager_load_shortcuts (self->manager);
+
+  /* Shortcut editor dialog */
+  self->shortcut_editor = cc_keyboard_shortcut_editor_new (self->manager);
 
   /* Setup the shortcuts listbox */
   gtk_list_box_set_sort_func (GTK_LIST_BOX (self->listbox),
@@ -1214,31 +427,3 @@ cc_keyboard_panel_init (CcKeyboardPanel *self)
                                 NULL);
 }
 
-/**
- * cc_keyboard_panel_create_custom_item:
- * @self: a #CcKeyboardPanel
- *
- * Creates a new temporary keyboard shortcut.
- *
- * Returns: (transfer full): a #CcKeyboardItem
- */
-CcKeyboardItem*
-cc_keyboard_panel_create_custom_item (CcKeyboardPanel *self)
-{
-  CcKeyboardItem *item;
-  gchar *settings_path;
-
-  g_return_val_if_fail (CC_IS_KEYBOARD_PANEL (self), NULL);
-
-  item = cc_keyboard_item_new (CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH);
-
-  settings_path = find_free_settings_path (self->binding_settings);
-  cc_keyboard_item_load_from_gsettings_path (item, settings_path, TRUE);
-  g_free (settings_path);
-
-  item->model = GTK_TREE_MODEL (self->shortcuts_model);
-  item->group = BINDING_GROUP_USER;
-
-  return item;
-}
-
diff --git a/panels/keyboard/cc-keyboard-shortcut-editor.c b/panels/keyboard/cc-keyboard-shortcut-editor.c
index 2eaef18..aaacdce 100644
--- a/panels/keyboard/cc-keyboard-shortcut-editor.c
+++ b/panels/keyboard/cc-keyboard-shortcut-editor.c
@@ -55,7 +55,7 @@ struct _CcKeyboardShortcutEditor
 
   GdkDevice          *grab_device;
 
-  CcKeyboardPanel    *panel;
+  CcKeyboardManager  *manager;
   CcKeyboardItem     *item;
 
   /* Custom shortcuts */
@@ -77,19 +77,11 @@ enum
 {
   PROP_0,
   PROP_KEYBOARD_ITEM,
-  PROP_PANEL,
+  PROP_MANAGER,
   N_PROPS
 };
 
-enum
-{
-  ADD_CUSTOM_SHORTCUT,
-  REMOVE_CUSTOM_SHORTCUT,
-  LAST_SIGNAL
-};
-
 static GParamSpec *properties [N_PROPS] = { NULL, };
-static guint signals[LAST_SIGNAL] = { 0, };
 
 /*
  * Auxiliary methods
@@ -262,7 +254,7 @@ add_button_clicked_cb (CcKeyboardShortcutEditor *self)
 {
   CcKeyboardItem *item;
 
-  item = cc_keyboard_panel_create_custom_item (self->panel);
+  item = cc_keyboard_manager_create_custom_shortcut (self->manager);
 
   /* Apply the custom shortcut setup at the new item */
   apply_custom_item_fields (self, item);
@@ -270,7 +262,7 @@ add_button_clicked_cb (CcKeyboardShortcutEditor *self)
   /* Cleanup everything once we're done */
   clear_custom_entries (self);
 
-  g_signal_emit (self, signals[ADD_CUSTOM_SHORTCUT], 0, item);
+  cc_keyboard_manager_add_custom_shortcut (self->manager, item);
 
   gtk_widget_hide (GTK_WIDGET (self));
 }
@@ -313,7 +305,7 @@ remove_button_clicked_cb (CcKeyboardShortcutEditor *self)
 {
   gtk_widget_hide (GTK_WIDGET (self));
 
-  g_signal_emit (self, signals[REMOVE_CUSTOM_SHORTCUT], 0, self->item);
+  cc_keyboard_manager_remove_custom_shortcut (self->manager, self->item);
 }
 
 static void
@@ -380,7 +372,7 @@ cc_keyboard_shortcut_editor_finalize (GObject *object)
   CcKeyboardShortcutEditor *self = (CcKeyboardShortcutEditor *)object;
 
   g_clear_object (&self->item);
-  g_clear_object (&self->panel);
+  g_clear_object (&self->manager);
 
   G_OBJECT_CLASS (cc_keyboard_shortcut_editor_parent_class)->finalize (object);
 }
@@ -399,8 +391,8 @@ cc_keyboard_shortcut_editor_get_property (GObject    *object,
       g_value_set_object (value, self->item);
       break;
 
-    case PROP_PANEL:
-      g_value_set_object (value, self->panel);
+    case PROP_MANAGER:
+      g_value_set_object (value, self->manager);
       break;
 
     default:
@@ -422,8 +414,8 @@ cc_keyboard_shortcut_editor_set_property (GObject      *object,
       cc_keyboard_shortcut_editor_set_item (self, g_value_get_object (value));
       break;
 
-    case PROP_PANEL:
-      g_set_object (&self->panel, g_value_get_object (value));
+    case PROP_MANAGER:
+      g_set_object (&self->manager, g_value_get_object (value));
       break;
 
     default:
@@ -515,37 +507,11 @@ cc_keyboard_shortcut_editor_class_init (CcKeyboardShortcutEditorClass *klass)
    *
    * The current keyboard panel.
    */
-  properties[PROP_PANEL] = g_param_spec_object ("panel",
-                                                "Keyboard panel",
-                                                "The keyboard panel being edited",
-                                                CC_TYPE_KEYBOARD_PANEL,
-                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
-  /**
-   * CcKeyboardShortcutEditor:add-custom-shortcut:
-   *
-   * Emited when the user asks to add a custom shortcut.
-   */
-  signals[ADD_CUSTOM_SHORTCUT] = g_signal_new ("add-custom-shortcut",
-                                               CC_TYPE_KEYBOARD_SHORTCUT_EDITOR,
-                                               G_SIGNAL_RUN_FIRST,
-                                               0, NULL, NULL, NULL,
-                                               G_TYPE_NONE,
-                                               1,
-                                               CC_TYPE_KEYBOARD_ITEM);
-
-  /**
-   * CcKeyboardShortcutEditor:remove-custom-shortcut:
-   *
-   * Emited when the user asks to remove a custom shortcut.
-   */
-  signals[REMOVE_CUSTOM_SHORTCUT] = g_signal_new ("remove-custom-shortcut",
-                                                  CC_TYPE_KEYBOARD_SHORTCUT_EDITOR,
-                                                  G_SIGNAL_RUN_FIRST,
-                                                  0, NULL, NULL, NULL,
-                                                  G_TYPE_NONE,
-                                                  1,
-                                                  CC_TYPE_KEYBOARD_ITEM);
+  properties[PROP_MANAGER] = g_param_spec_object ("manager",
+                                                  "Keyboard manager",
+                                                  "The keyboard manager",
+                                                  CC_TYPE_KEYBOARD_MANAGER,
+                                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
 
   g_object_class_install_properties (object_class, N_PROPS, properties);
 
@@ -589,10 +555,10 @@ cc_keyboard_shortcut_editor_init (CcKeyboardShortcutEditor *self)
  * Returns: (transfer full): a newly created #CcKeyboardShortcutEditor.
  */
 GtkWidget*
-cc_keyboard_shortcut_editor_new (CcKeyboardPanel *panel)
+cc_keyboard_shortcut_editor_new (CcKeyboardManager *manager)
 {
   return g_object_new (CC_TYPE_KEYBOARD_SHORTCUT_EDITOR,
-                       "panel", panel,
+                       "manager", manager,
                        "use-header-bar", 1,
                        NULL);
 }
diff --git a/panels/keyboard/cc-keyboard-shortcut-editor.h b/panels/keyboard/cc-keyboard-shortcut-editor.h
index c0fe675..a9455a8 100644
--- a/panels/keyboard/cc-keyboard-shortcut-editor.h
+++ b/panels/keyboard/cc-keyboard-shortcut-editor.h
@@ -24,7 +24,7 @@
 #include <gtk/gtk.h>
 
 #include "cc-keyboard-item.h"
-#include "cc-keyboard-panel.h"
+#include "cc-keyboard-manager.h"
 
 G_BEGIN_DECLS
 
@@ -38,7 +38,7 @@ typedef enum
 
 G_DECLARE_FINAL_TYPE (CcKeyboardShortcutEditor, cc_keyboard_shortcut_editor, CC, KEYBOARD_SHORTCUT_EDITOR, 
GtkDialog)
 
-GtkWidget*           cc_keyboard_shortcut_editor_new             (CcKeyboardPanel          *panel);
+GtkWidget*           cc_keyboard_shortcut_editor_new             (CcKeyboardManager        *manager);
 
 CcKeyboardItem*      cc_keyboard_shortcut_editor_get_item        (CcKeyboardShortcutEditor *self);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]