| File: | capplets/keybindings/cafe-keybinding-properties.c |
| Warning: | line 1208, column 51 Access to field 'message' results in a dereference of a null pointer (loaded from variable 'err') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* This program was written with lots of love under the GPL by Jonathan | |||
| 2 | * Blandford <jrb@gnome.org> | |||
| 3 | */ | |||
| 4 | ||||
| 5 | #include <config.h> | |||
| 6 | ||||
| 7 | #include <stdlib.h> | |||
| 8 | #include <string.h> | |||
| 9 | #include <ctk/ctk.h> | |||
| 10 | #include <gio/gio.h> | |||
| 11 | #include <cdk/cdkx.h> | |||
| 12 | #include <X11/Xatom.h> | |||
| 13 | #include <glib/gi18n.h> | |||
| 14 | #include <cdk/cdkkeysyms.h> | |||
| 15 | ||||
| 16 | #include "wm-common.h" | |||
| 17 | #include "capplet-util.h" | |||
| 18 | #include "eggcellrendererkeys.h" | |||
| 19 | #include "activate-settings-daemon.h" | |||
| 20 | #include "dconf-util.h" | |||
| 21 | ||||
| 22 | #define GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/" "/org/cafe/desktop/keybindings/" | |||
| 23 | #define CUSTOM_KEYBINDING_SCHEMA"org.cafe.control-center.keybinding" "org.cafe.control-center.keybinding" | |||
| 24 | ||||
| 25 | #define MAX_ELEMENTS_BEFORE_SCROLLING10 10 | |||
| 26 | #define MAX_CUSTOM_SHORTCUTS1000 1000 | |||
| 27 | #define RESPONSE_ADD0 0 | |||
| 28 | #define RESPONSE_REMOVE1 1 | |||
| 29 | ||||
| 30 | typedef struct { | |||
| 31 | /* The untranslated name, combine with ->package to translate */ | |||
| 32 | char *name; | |||
| 33 | /* The gettext package to use to translate the section title */ | |||
| 34 | char *package; | |||
| 35 | /* Name of the window manager the keys would apply to */ | |||
| 36 | char *wm_name; | |||
| 37 | /* The GSettings schema for the whole file */ | |||
| 38 | char *schema; | |||
| 39 | /* an array of KeyListEntry */ | |||
| 40 | GArray *entries; | |||
| 41 | } KeyList; | |||
| 42 | ||||
| 43 | typedef enum { | |||
| 44 | COMPARISON_NONE = 0, | |||
| 45 | COMPARISON_GT, | |||
| 46 | COMPARISON_LT, | |||
| 47 | COMPARISON_EQ | |||
| 48 | } Comparison; | |||
| 49 | ||||
| 50 | typedef struct | |||
| 51 | { | |||
| 52 | char *gsettings_path; | |||
| 53 | char *schema; | |||
| 54 | char *name; | |||
| 55 | int value; | |||
| 56 | char *value_schema; /* gsettings schema for key/value */ | |||
| 57 | char *value_key; | |||
| 58 | char *description; | |||
| 59 | char *description_key; | |||
| 60 | char *cmd_key; | |||
| 61 | Comparison comparison; | |||
| 62 | } KeyListEntry; | |||
| 63 | ||||
| 64 | enum | |||
| 65 | { | |||
| 66 | DESCRIPTION_COLUMN, | |||
| 67 | KEYENTRY_COLUMN, | |||
| 68 | N_COLUMNS | |||
| 69 | }; | |||
| 70 | ||||
| 71 | typedef struct | |||
| 72 | { | |||
| 73 | GSettings *settings; | |||
| 74 | char *gsettings_path; | |||
| 75 | char *gsettings_key; | |||
| 76 | guint keyval; | |||
| 77 | guint keycode; | |||
| 78 | EggVirtualModifierType mask; | |||
| 79 | gboolean editable; | |||
| 80 | CtkTreeModel *model; | |||
| 81 | char *description; | |||
| 82 | char *desc_gsettings_key; | |||
| 83 | gboolean desc_editable; | |||
| 84 | char *command; | |||
| 85 | char *cmd_gsettings_key; | |||
| 86 | gboolean cmd_editable; | |||
| 87 | gulong gsettings_cnxn; | |||
| 88 | gulong gsettings_cnxn_desc; | |||
| 89 | gulong gsettings_cnxn_cmd; | |||
| 90 | } KeyEntry; | |||
| 91 | ||||
| 92 | static gboolean block_accels = FALSE(0); | |||
| 93 | static CtkWidget *custom_shortcut_dialog = NULL((void*)0); | |||
| 94 | static CtkWidget *custom_shortcut_name_entry = NULL((void*)0); | |||
| 95 | static CtkWidget *custom_shortcut_command_entry = NULL((void*)0); | |||
| 96 | ||||
| 97 | static CtkWidget* _ctk_builder_get_widget(CtkBuilder* builder, const gchar* name) | |||
| 98 | { | |||
| 99 | return CTK_WIDGET (ctk_builder_get_object (builder, name))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, name))), ((ctk_widget_get_type ())))))); | |||
| 100 | } | |||
| 101 | ||||
| 102 | static CtkBuilder * | |||
| 103 | create_builder (void) | |||
| 104 | { | |||
| 105 | CtkBuilder *builder = ctk_builder_new(); | |||
| 106 | GError *error = NULL((void*)0); | |||
| 107 | ||||
| 108 | if (ctk_builder_add_from_resource (builder, "/org/cafe/ccc/keybindings/cafe-keybinding-properties.ui", &error) == 0) { | |||
| 109 | g_warning ("Could not load UI: %s", error->message); | |||
| 110 | g_error_free (error); | |||
| 111 | g_object_unref (builder); | |||
| 112 | builder = NULL((void*)0); | |||
| 113 | } | |||
| 114 | ||||
| 115 | return builder; | |||
| 116 | } | |||
| 117 | ||||
| 118 | static char* binding_name(guint keyval, guint keycode, EggVirtualModifierType mask, gboolean translate) | |||
| 119 | { | |||
| 120 | if (keyval != 0 || keycode != 0) | |||
| 121 | { | |||
| 122 | if (translate) | |||
| 123 | { | |||
| 124 | return egg_virtual_accelerator_label (keyval, keycode, mask); | |||
| 125 | } | |||
| 126 | else | |||
| 127 | { | |||
| 128 | return egg_virtual_accelerator_name (keyval, keycode, mask); | |||
| 129 | } | |||
| 130 | } | |||
| 131 | else | |||
| 132 | { | |||
| 133 | return g_strdup (translate ? _("Disabled") : "")g_strdup_inline (translate ? gettext ("Disabled") : ""); | |||
| 134 | } | |||
| 135 | } | |||
| 136 | ||||
| 137 | static gboolean | |||
| 138 | binding_from_string (const char *str, | |||
| 139 | guint *accelerator_key, | |||
| 140 | guint *keycode, | |||
| 141 | EggVirtualModifierType *accelerator_mods) | |||
| 142 | { | |||
| 143 | g_return_val_if_fail (accelerator_key != NULL, FALSE)do { if ((accelerator_key != ((void*)0))) { } else { g_return_if_fail_warning ("keybinding-properties", ((const char*) (__func__)), "accelerator_key != NULL" ); return ((0)); } } while (0); | |||
| 144 | ||||
| 145 | if (str == NULL((void*)0) || strcmp (str, "disabled") == 0) | |||
| 146 | { | |||
| 147 | *accelerator_key = 0; | |||
| 148 | *keycode = 0; | |||
| 149 | *accelerator_mods = 0; | |||
| 150 | return TRUE(!(0)); | |||
| 151 | } | |||
| 152 | ||||
| 153 | egg_accelerator_parse_virtual (str, accelerator_key, keycode, accelerator_mods); | |||
| 154 | ||||
| 155 | if (*accelerator_key == 0) | |||
| 156 | return FALSE(0); | |||
| 157 | else | |||
| 158 | return TRUE(!(0)); | |||
| 159 | } | |||
| 160 | ||||
| 161 | static void | |||
| 162 | accel_set_func (CtkTreeViewColumn *tree_column, | |||
| 163 | CtkCellRenderer *cell, | |||
| 164 | CtkTreeModel *model, | |||
| 165 | CtkTreeIter *iter, | |||
| 166 | gpointer data) | |||
| 167 | { | |||
| 168 | KeyEntry *key_entry; | |||
| 169 | ||||
| 170 | ctk_tree_model_get (model, iter, | |||
| 171 | KEYENTRY_COLUMN, &key_entry, | |||
| 172 | -1); | |||
| 173 | ||||
| 174 | if (key_entry == NULL((void*)0)) | |||
| 175 | g_object_set (cell, | |||
| 176 | "visible", FALSE(0), | |||
| 177 | NULL((void*)0)); | |||
| 178 | else if (! key_entry->editable) | |||
| 179 | g_object_set (cell, | |||
| 180 | "visible", TRUE(!(0)), | |||
| 181 | "editable", FALSE(0), | |||
| 182 | "accel_key", key_entry->keyval, | |||
| 183 | "accel_mask", key_entry->mask, | |||
| 184 | "keycode", key_entry->keycode, | |||
| 185 | "style", PANGO_STYLE_ITALIC, | |||
| 186 | NULL((void*)0)); | |||
| 187 | else | |||
| 188 | g_object_set (cell, | |||
| 189 | "visible", TRUE(!(0)), | |||
| 190 | "editable", TRUE(!(0)), | |||
| 191 | "accel_key", key_entry->keyval, | |||
| 192 | "accel_mask", key_entry->mask, | |||
| 193 | "keycode", key_entry->keycode, | |||
| 194 | "style", PANGO_STYLE_NORMAL, | |||
| 195 | NULL((void*)0)); | |||
| 196 | } | |||
| 197 | ||||
| 198 | static void | |||
| 199 | description_set_func (CtkTreeViewColumn *tree_column, | |||
| 200 | CtkCellRenderer *cell, | |||
| 201 | CtkTreeModel *model, | |||
| 202 | CtkTreeIter *iter, | |||
| 203 | gpointer data) | |||
| 204 | { | |||
| 205 | KeyEntry *key_entry; | |||
| 206 | ||||
| 207 | ctk_tree_model_get (model, iter, | |||
| 208 | KEYENTRY_COLUMN, &key_entry, | |||
| 209 | -1); | |||
| 210 | ||||
| 211 | if (key_entry != NULL((void*)0)) | |||
| 212 | g_object_set (cell, | |||
| 213 | "editable", FALSE(0), | |||
| 214 | "text", key_entry->description != NULL((void*)0) ? | |||
| 215 | key_entry->description : _("<Unknown Action>")gettext ("<Unknown Action>"), | |||
| 216 | NULL((void*)0)); | |||
| 217 | else | |||
| 218 | g_object_set (cell, | |||
| 219 | "editable", FALSE(0), NULL((void*)0)); | |||
| 220 | } | |||
| 221 | ||||
| 222 | static gboolean | |||
| 223 | keybinding_key_changed_foreach (CtkTreeModel *model, | |||
| 224 | CtkTreePath *path, | |||
| 225 | CtkTreeIter *iter, | |||
| 226 | gpointer user_data) | |||
| 227 | { | |||
| 228 | KeyEntry *key_entry; | |||
| 229 | KeyEntry *tmp_key_entry; | |||
| 230 | ||||
| 231 | key_entry = (KeyEntry *)user_data; | |||
| 232 | ctk_tree_model_get (key_entry->model, iter, | |||
| 233 | KEYENTRY_COLUMN, &tmp_key_entry, | |||
| 234 | -1); | |||
| 235 | ||||
| 236 | if (key_entry == tmp_key_entry) | |||
| 237 | { | |||
| 238 | ctk_tree_model_row_changed (key_entry->model, path, iter); | |||
| 239 | return TRUE(!(0)); | |||
| 240 | } | |||
| 241 | return FALSE(0); | |||
| 242 | } | |||
| 243 | ||||
| 244 | static void | |||
| 245 | keybinding_key_changed (GSettings *settings, | |||
| 246 | gchar *key, | |||
| 247 | KeyEntry *key_entry) | |||
| 248 | { | |||
| 249 | gchar *key_value; | |||
| 250 | ||||
| 251 | key_value = g_settings_get_string (settings, key); | |||
| 252 | ||||
| 253 | binding_from_string (key_value, &key_entry->keyval, &key_entry->keycode, &key_entry->mask); | |||
| 254 | key_entry->editable = g_settings_is_writable (settings, key); | |||
| 255 | ||||
| 256 | /* update the model */ | |||
| 257 | ctk_tree_model_foreach (key_entry->model, keybinding_key_changed_foreach, key_entry); | |||
| 258 | } | |||
| 259 | ||||
| 260 | static void | |||
| 261 | keybinding_description_changed (GSettings *settings, | |||
| 262 | gchar *key, | |||
| 263 | KeyEntry *key_entry) | |||
| 264 | { | |||
| 265 | gchar *key_value; | |||
| 266 | ||||
| 267 | key_value = g_settings_get_string (settings, key); | |||
| 268 | ||||
| 269 | g_free (key_entry->description); | |||
| 270 | key_entry->description = key_value ? g_strdup (key_value)g_strdup_inline (key_value) : NULL((void*)0); | |||
| 271 | g_free (key_value); | |||
| 272 | ||||
| 273 | key_entry->desc_editable = g_settings_is_writable (settings, key); | |||
| 274 | ||||
| 275 | /* update the model */ | |||
| 276 | ctk_tree_model_foreach (key_entry->model, keybinding_key_changed_foreach, key_entry); | |||
| 277 | } | |||
| 278 | ||||
| 279 | static void | |||
| 280 | keybinding_command_changed (GSettings *settings, | |||
| 281 | gchar *key, | |||
| 282 | KeyEntry *key_entry) | |||
| 283 | { | |||
| 284 | gchar *key_value; | |||
| 285 | ||||
| 286 | key_value = g_settings_get_string (settings, key); | |||
| 287 | ||||
| 288 | g_free (key_entry->command); | |||
| 289 | key_entry->command = key_value ? g_strdup (key_value)g_strdup_inline (key_value) : NULL((void*)0); | |||
| 290 | key_entry->cmd_editable = g_settings_is_writable (settings, key); | |||
| 291 | g_free (key_value); | |||
| 292 | ||||
| 293 | /* update the model */ | |||
| 294 | ctk_tree_model_foreach (key_entry->model, keybinding_key_changed_foreach, key_entry); | |||
| 295 | } | |||
| 296 | ||||
| 297 | static int | |||
| 298 | keyentry_sort_func (CtkTreeModel *model, | |||
| 299 | CtkTreeIter *a, | |||
| 300 | CtkTreeIter *b, | |||
| 301 | gpointer user_data) | |||
| 302 | { | |||
| 303 | KeyEntry *key_entry_a; | |||
| 304 | KeyEntry *key_entry_b; | |||
| 305 | int retval; | |||
| 306 | ||||
| 307 | key_entry_a = NULL((void*)0); | |||
| 308 | ctk_tree_model_get (model, a, | |||
| 309 | KEYENTRY_COLUMN, &key_entry_a, | |||
| 310 | -1); | |||
| 311 | ||||
| 312 | key_entry_b = NULL((void*)0); | |||
| 313 | ctk_tree_model_get (model, b, | |||
| 314 | KEYENTRY_COLUMN, &key_entry_b, | |||
| 315 | -1); | |||
| 316 | ||||
| 317 | if (key_entry_a && key_entry_b) | |||
| 318 | { | |||
| 319 | if ((key_entry_a->keyval || key_entry_a->keycode) && | |||
| 320 | (key_entry_b->keyval || key_entry_b->keycode)) | |||
| 321 | { | |||
| 322 | gchar *name_a, *name_b; | |||
| 323 | ||||
| 324 | name_a = binding_name (key_entry_a->keyval, | |||
| 325 | key_entry_a->keycode, | |||
| 326 | key_entry_a->mask, | |||
| 327 | TRUE(!(0))); | |||
| 328 | ||||
| 329 | name_b = binding_name (key_entry_b->keyval, | |||
| 330 | key_entry_b->keycode, | |||
| 331 | key_entry_b->mask, | |||
| 332 | TRUE(!(0))); | |||
| 333 | ||||
| 334 | retval = g_utf8_collate (name_a, name_b); | |||
| 335 | ||||
| 336 | g_free (name_a); | |||
| 337 | g_free (name_b); | |||
| 338 | } | |||
| 339 | else if (key_entry_a->keyval || key_entry_a->keycode) | |||
| 340 | retval = -1; | |||
| 341 | else if (key_entry_b->keyval || key_entry_b->keycode) | |||
| 342 | retval = 1; | |||
| 343 | else | |||
| 344 | retval = 0; | |||
| 345 | } | |||
| 346 | else if (key_entry_a) | |||
| 347 | retval = -1; | |||
| 348 | else if (key_entry_b) | |||
| 349 | retval = 1; | |||
| 350 | else | |||
| 351 | retval = 0; | |||
| 352 | ||||
| 353 | return retval; | |||
| 354 | } | |||
| 355 | ||||
| 356 | static void | |||
| 357 | clear_old_model (CtkBuilder *builder) | |||
| 358 | { | |||
| 359 | CtkWidget *tree_view; | |||
| 360 | CtkWidget *actions_swindow; | |||
| 361 | CtkTreeModel *model; | |||
| 362 | ||||
| 363 | tree_view = _ctk_builder_get_widget (builder, "shortcut_treeview"); | |||
| 364 | model = ctk_tree_view_get_model (CTK_TREE_VIEW (tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_tree_view_get_type ()))))))); | |||
| 365 | ||||
| 366 | if (model == NULL((void*)0)) | |||
| 367 | { | |||
| 368 | /* create a new model */ | |||
| 369 | model = (CtkTreeModel *) ctk_tree_store_new (N_COLUMNS, G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_POINTER((GType) ((17) << (2)))); | |||
| 370 | ||||
| 371 | ctk_tree_sortable_set_sort_func (CTK_TREE_SORTABLE (model)((((CtkTreeSortable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_sortable_get_type ())))))), | |||
| 372 | KEYENTRY_COLUMN, | |||
| 373 | keyentry_sort_func, | |||
| 374 | NULL((void*)0), NULL((void*)0)); | |||
| 375 | ||||
| 376 | ctk_tree_view_set_model (CTK_TREE_VIEW (tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_tree_view_get_type ())))))), model); | |||
| 377 | ||||
| 378 | g_object_unref (model); | |||
| 379 | } | |||
| 380 | else | |||
| 381 | { | |||
| 382 | /* clear the existing model */ | |||
| 383 | gboolean valid; | |||
| 384 | CtkTreeIter iter; | |||
| 385 | KeyEntry *key_entry; | |||
| 386 | ||||
| 387 | for (valid = ctk_tree_model_get_iter_first (model, &iter); | |||
| 388 | valid; | |||
| 389 | valid = ctk_tree_model_iter_next (model, &iter)) | |||
| 390 | { | |||
| 391 | ctk_tree_model_get (model, &iter, | |||
| 392 | KEYENTRY_COLUMN, &key_entry, | |||
| 393 | -1); | |||
| 394 | ||||
| 395 | if (key_entry != NULL((void*)0)) | |||
| 396 | { | |||
| 397 | g_signal_handler_disconnect (key_entry->settings, key_entry->gsettings_cnxn); | |||
| 398 | if (key_entry->gsettings_cnxn_desc != 0) | |||
| 399 | g_signal_handler_disconnect (key_entry->settings, key_entry->gsettings_cnxn_desc); | |||
| 400 | if (key_entry->gsettings_cnxn_cmd != 0) | |||
| 401 | g_signal_handler_disconnect (key_entry->settings, key_entry->gsettings_cnxn_cmd); | |||
| 402 | ||||
| 403 | g_object_unref (key_entry->settings); | |||
| 404 | if (key_entry->gsettings_path) | |||
| 405 | g_free (key_entry->gsettings_path); | |||
| 406 | g_free (key_entry->gsettings_key); | |||
| 407 | g_free (key_entry->description); | |||
| 408 | g_free (key_entry->desc_gsettings_key); | |||
| 409 | g_free (key_entry->command); | |||
| 410 | g_free (key_entry->cmd_gsettings_key); | |||
| 411 | g_free (key_entry); | |||
| 412 | } | |||
| 413 | } | |||
| 414 | ||||
| 415 | ctk_tree_store_clear (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ()))))))); | |||
| 416 | } | |||
| 417 | ||||
| 418 | actions_swindow = _ctk_builder_get_widget (builder, "actions_swindow"); | |||
| 419 | ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (actions_swindow)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((actions_swindow)), ((ctk_scrolled_window_get_type ())))))), | |||
| 420 | CTK_POLICY_NEVER, CTK_POLICY_NEVER); | |||
| 421 | ctk_widget_set_size_request (actions_swindow, -1, -1); | |||
| 422 | } | |||
| 423 | ||||
| 424 | typedef struct { | |||
| 425 | const char *key; | |||
| 426 | const char *path; | |||
| 427 | const char *schema; | |||
| 428 | gboolean found; | |||
| 429 | } KeyMatchData; | |||
| 430 | ||||
| 431 | static gboolean key_match(CtkTreeModel* model, CtkTreePath* path, CtkTreeIter* iter, gpointer data) | |||
| 432 | { | |||
| 433 | KeyMatchData* match_data = data; | |||
| 434 | KeyEntry* element = NULL((void*)0); | |||
| 435 | gchar *element_schema = NULL((void*)0); | |||
| 436 | gchar *element_path = NULL((void*)0); | |||
| 437 | ||||
| 438 | ctk_tree_model_get(model, iter, | |||
| 439 | KEYENTRY_COLUMN, &element, | |||
| 440 | -1); | |||
| 441 | ||||
| 442 | if (element && element->settings && G_IS_SETTINGS(element->settings)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (element->settings)); GType __t = ((g_settings_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
| 443 | { | |||
| 444 | g_object_get (element->settings, "schema-id", &element_schema, NULL((void*)0)); | |||
| 445 | g_object_get (element->settings, "path", &element_path, NULL((void*)0)); | |||
| 446 | } | |||
| 447 | ||||
| 448 | if (element && g_strcmp0(element->gsettings_key, match_data->key) == 0 | |||
| 449 | && g_strcmp0(element_schema, match_data->schema) == 0 | |||
| 450 | && g_strcmp0(element_path, match_data->path) == 0) | |||
| 451 | { | |||
| 452 | match_data->found = TRUE(!(0)); | |||
| 453 | return TRUE(!(0)); | |||
| 454 | } | |||
| 455 | ||||
| 456 | return FALSE(0); | |||
| 457 | } | |||
| 458 | ||||
| 459 | static gboolean key_is_already_shown(CtkTreeModel* model, const KeyListEntry* entry) | |||
| 460 | { | |||
| 461 | KeyMatchData data; | |||
| 462 | ||||
| 463 | data.key = entry->name; | |||
| 464 | data.schema = entry->schema; | |||
| 465 | data.path = entry->gsettings_path; | |||
| 466 | data.found = FALSE(0); | |||
| 467 | ctk_tree_model_foreach(model, key_match, &data); | |||
| 468 | ||||
| 469 | return data.found; | |||
| 470 | } | |||
| 471 | ||||
| 472 | static gboolean should_show_key(const KeyListEntry* entry) | |||
| 473 | { | |||
| 474 | GSettings *settings; | |||
| 475 | int value; | |||
| 476 | ||||
| 477 | if (entry->comparison == COMPARISON_NONE) | |||
| 478 | { | |||
| 479 | return TRUE(!(0)); | |||
| 480 | } | |||
| 481 | ||||
| 482 | g_return_val_if_fail(entry->value_key != NULL, FALSE)do { if ((entry->value_key != ((void*)0))) { } else { g_return_if_fail_warning ("keybinding-properties", ((const char*) (__func__)), "entry->value_key != NULL" ); return ((0)); } } while (0); | |||
| 483 | g_return_val_if_fail(entry->value_schema != NULL, FALSE)do { if ((entry->value_schema != ((void*)0))) { } else { g_return_if_fail_warning ("keybinding-properties", ((const char*) (__func__)), "entry->value_schema != NULL" ); return ((0)); } } while (0); | |||
| 484 | ||||
| 485 | settings = g_settings_new (entry->value_schema); | |||
| 486 | value = g_settings_get_int (settings, entry->value_key); | |||
| 487 | g_object_unref (settings); | |||
| 488 | ||||
| 489 | switch (entry->comparison) | |||
| 490 | { | |||
| 491 | case COMPARISON_NONE: | |||
| 492 | /* For compiler warnings */ | |||
| 493 | g_assert_not_reached ()do { g_assertion_message_expr ("keybinding-properties", "cafe-keybinding-properties.c" , 493, ((const char*) (__func__)), ((void*)0)); } while (0); | |||
| 494 | return FALSE(0); | |||
| 495 | case COMPARISON_GT: | |||
| 496 | if (value > entry->value) | |||
| 497 | { | |||
| 498 | return TRUE(!(0)); | |||
| 499 | } | |||
| 500 | break; | |||
| 501 | case COMPARISON_LT: | |||
| 502 | if (value < entry->value) | |||
| 503 | { | |||
| 504 | return TRUE(!(0)); | |||
| 505 | } | |||
| 506 | break; | |||
| 507 | case COMPARISON_EQ: | |||
| 508 | if (value == entry->value) | |||
| 509 | { | |||
| 510 | return TRUE(!(0)); | |||
| 511 | } | |||
| 512 | break; | |||
| 513 | } | |||
| 514 | ||||
| 515 | return FALSE(0); | |||
| 516 | } | |||
| 517 | ||||
| 518 | static gboolean | |||
| 519 | count_rows_foreach (CtkTreeModel *model, CtkTreePath *path, CtkTreeIter *iter, gpointer data) | |||
| 520 | { | |||
| 521 | gint *rows = data; | |||
| 522 | ||||
| 523 | (*rows)++; | |||
| 524 | ||||
| 525 | return FALSE(0); | |||
| 526 | } | |||
| 527 | ||||
| 528 | static void | |||
| 529 | ensure_scrollbar (CtkBuilder *builder, int i) | |||
| 530 | { | |||
| 531 | if (i == MAX_ELEMENTS_BEFORE_SCROLLING10) | |||
| 532 | { | |||
| 533 | CtkRequisition rectangle; | |||
| 534 | GObject *actions_swindow = ctk_builder_get_object (builder, | |||
| 535 | "actions_swindow"); | |||
| 536 | CtkWidget *treeview = _ctk_builder_get_widget (builder, | |||
| 537 | "shortcut_treeview"); | |||
| 538 | ctk_widget_get_preferred_size (treeview, &rectangle, NULL((void*)0)); | |||
| 539 | ctk_widget_set_size_request (treeview, -1, rectangle.height); | |||
| 540 | ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (actions_swindow)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((actions_swindow)), ((ctk_scrolled_window_get_type ())))))), | |||
| 541 | CTK_POLICY_NEVER, CTK_POLICY_AUTOMATIC); | |||
| 542 | } | |||
| 543 | } | |||
| 544 | ||||
| 545 | static void | |||
| 546 | find_section (CtkTreeModel *model, | |||
| 547 | CtkTreeIter *iter, | |||
| 548 | const char *title) | |||
| 549 | { | |||
| 550 | gboolean success; | |||
| 551 | ||||
| 552 | success = ctk_tree_model_get_iter_first (model, iter); | |||
| 553 | while (success) | |||
| 554 | { | |||
| 555 | char *description = NULL((void*)0); | |||
| 556 | ||||
| 557 | ctk_tree_model_get (model, iter, | |||
| 558 | DESCRIPTION_COLUMN, &description, | |||
| 559 | -1); | |||
| 560 | ||||
| 561 | if (g_strcmp0 (description, title) == 0) | |||
| 562 | return; | |||
| 563 | success = ctk_tree_model_iter_next (model, iter); | |||
| 564 | } | |||
| 565 | ||||
| 566 | ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), iter, NULL((void*)0)); | |||
| 567 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), iter, | |||
| 568 | DESCRIPTION_COLUMN, title, | |||
| 569 | -1); | |||
| 570 | } | |||
| 571 | ||||
| 572 | static void | |||
| 573 | append_keys_to_tree (CtkBuilder *builder, | |||
| 574 | const gchar *title, | |||
| 575 | const gchar *schema, | |||
| 576 | const gchar *package, | |||
| 577 | const KeyListEntry *keys_list) | |||
| 578 | { | |||
| 579 | CtkTreeIter parent_iter, iter; | |||
| 580 | CtkTreeModel *model; | |||
| 581 | gint i, j; | |||
| 582 | ||||
| 583 | model = ctk_tree_view_get_model (CTK_TREE_VIEW (ctk_builder_get_object (builder, "shortcut_treeview"))((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ()))))))); | |||
| 584 | ||||
| 585 | /* Try to find a section parent iter, if it already exists */ | |||
| 586 | find_section (model, &iter, title); | |||
| 587 | parent_iter = iter; | |||
| 588 | ||||
| 589 | i = 0; | |||
| 590 | ctk_tree_model_foreach (model, count_rows_foreach, &i); | |||
| 591 | ||||
| 592 | /* If the header we just added is the MAX_ELEMENTS_BEFORE_SCROLLING th, | |||
| 593 | * then we need to scroll now */ | |||
| 594 | ensure_scrollbar (builder, i - 1); | |||
| 595 | ||||
| 596 | for (j = 0; keys_list[j].name != NULL((void*)0); j++) | |||
| 597 | { | |||
| 598 | GSettings *settings = NULL((void*)0); | |||
| 599 | gchar *settings_path; | |||
| 600 | KeyEntry *key_entry; | |||
| 601 | const gchar *key_string; | |||
| 602 | gchar *key_value; | |||
| 603 | gchar *description; | |||
| 604 | gchar *command; | |||
| 605 | ||||
| 606 | if (!should_show_key (&keys_list[j])) | |||
| 607 | continue; | |||
| 608 | ||||
| 609 | if (key_is_already_shown (model, &keys_list[j])) | |||
| 610 | continue; | |||
| 611 | ||||
| 612 | key_string = keys_list[j].name; | |||
| 613 | ||||
| 614 | if (keys_list[j].gsettings_path != NULL((void*)0)) | |||
| 615 | { | |||
| 616 | settings = g_settings_new_with_path (schema, keys_list[j].gsettings_path); | |||
| 617 | settings_path = g_strdup(keys_list[j].gsettings_path)g_strdup_inline (keys_list[j].gsettings_path); | |||
| 618 | } | |||
| 619 | else | |||
| 620 | { | |||
| 621 | settings = g_settings_new (schema); | |||
| 622 | settings_path = NULL((void*)0); | |||
| 623 | } | |||
| 624 | ||||
| 625 | if (keys_list[j].description_key != NULL((void*)0)) | |||
| 626 | { | |||
| 627 | /* it's a custom shortcut, so description is in gsettings */ | |||
| 628 | description = g_settings_get_string (settings, keys_list[j].description_key); | |||
| 629 | } | |||
| 630 | else | |||
| 631 | { | |||
| 632 | /* it's from keyfile, so description need to be translated */ | |||
| 633 | description = keys_list[j].description; | |||
| 634 | if (package) | |||
| 635 | { | |||
| 636 | bind_textdomain_codeset (package, "UTF-8"); | |||
| 637 | description = dgettext (package, description); | |||
| 638 | } | |||
| 639 | else | |||
| 640 | { | |||
| 641 | description = _(description)gettext (description); | |||
| 642 | } | |||
| 643 | } | |||
| 644 | ||||
| 645 | if (description == NULL((void*)0)) | |||
| 646 | { | |||
| 647 | /* Only print a warning for keys that should have a schema */ | |||
| 648 | if (keys_list[j].description_key == NULL((void*)0)) | |||
| 649 | g_warning ("No description for key '%s'", key_string); | |||
| 650 | } | |||
| 651 | ||||
| 652 | ||||
| 653 | ||||
| 654 | if (keys_list[j].cmd_key != NULL((void*)0)) | |||
| 655 | { | |||
| 656 | command = g_settings_get_string (settings, keys_list[j].cmd_key); | |||
| 657 | } | |||
| 658 | else | |||
| 659 | { | |||
| 660 | command = NULL((void*)0); | |||
| 661 | } | |||
| 662 | ||||
| 663 | key_entry = g_new0 (KeyEntry, 1)((KeyEntry *) g_malloc0_n ((1), sizeof (KeyEntry))); | |||
| 664 | key_entry->settings = settings; | |||
| 665 | key_entry->gsettings_path = settings_path; | |||
| 666 | key_entry->gsettings_key = g_strdup (key_string)g_strdup_inline (key_string); | |||
| 667 | key_entry->editable = g_settings_is_writable (settings, key_string); | |||
| 668 | key_entry->model = model; | |||
| 669 | key_entry->description = description; | |||
| 670 | key_entry->command = command; | |||
| 671 | if (keys_list[j].description_key != NULL((void*)0)) | |||
| 672 | { | |||
| 673 | key_entry->desc_gsettings_key = g_strdup (keys_list[j].description_key)g_strdup_inline (keys_list[j].description_key); | |||
| 674 | key_entry->desc_editable = g_settings_is_writable (settings, key_entry->desc_gsettings_key); | |||
| 675 | gchar *gsettings_signal = g_strconcat ("changed::", key_entry->desc_gsettings_key, NULL((void*)0)); | |||
| 676 | key_entry->gsettings_cnxn_desc = g_signal_connect (settings,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_description_changed))), (key_entry), ((void*)0) , (GConnectFlags) 0) | |||
| 677 | gsettings_signal,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_description_changed))), (key_entry), ((void*)0) , (GConnectFlags) 0) | |||
| 678 | G_CALLBACK (keybinding_description_changed),g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_description_changed))), (key_entry), ((void*)0) , (GConnectFlags) 0) | |||
| 679 | key_entry)g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_description_changed))), (key_entry), ((void*)0) , (GConnectFlags) 0); | |||
| 680 | g_free (gsettings_signal); | |||
| 681 | } | |||
| 682 | if (keys_list[j].cmd_key != NULL((void*)0)) | |||
| 683 | { | |||
| 684 | key_entry->cmd_gsettings_key = g_strdup (keys_list[j].cmd_key)g_strdup_inline (keys_list[j].cmd_key); | |||
| 685 | key_entry->cmd_editable = g_settings_is_writable (settings, key_entry->cmd_gsettings_key); | |||
| 686 | gchar *gsettings_signal = g_strconcat ("changed::", key_entry->cmd_gsettings_key, NULL((void*)0)); | |||
| 687 | key_entry->gsettings_cnxn_cmd = g_signal_connect (settings,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 688 | gsettings_signal,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 689 | G_CALLBACK (keybinding_command_changed),g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 690 | key_entry)g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0); | |||
| 691 | g_free (gsettings_signal); | |||
| 692 | } | |||
| 693 | ||||
| 694 | gchar *gsettings_signal = g_strconcat ("changed::", key_string, NULL((void*)0)); | |||
| 695 | key_entry->gsettings_cnxn = g_signal_connect (settings,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_key_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 696 | gsettings_signal,g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_key_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 697 | G_CALLBACK (keybinding_key_changed),g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_key_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0) | |||
| 698 | key_entry)g_signal_connect_data ((settings), (gsettings_signal), (((GCallback ) (keybinding_key_changed))), (key_entry), ((void*)0), (GConnectFlags ) 0); | |||
| 699 | g_free (gsettings_signal); | |||
| 700 | ||||
| 701 | key_value = g_settings_get_string (settings, key_string); | |||
| 702 | binding_from_string (key_value, &key_entry->keyval, &key_entry->keycode, &key_entry->mask); | |||
| 703 | g_free (key_value); | |||
| 704 | ||||
| 705 | ensure_scrollbar (builder, i); | |||
| 706 | ||||
| 707 | ++i; | |||
| 708 | ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &iter, &parent_iter); | |||
| 709 | /* we use the DESCRIPTION_COLUMN only for the section headers */ | |||
| 710 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &iter, | |||
| 711 | KEYENTRY_COLUMN, key_entry, | |||
| 712 | -1); | |||
| 713 | ctk_tree_view_expand_all (CTK_TREE_VIEW (ctk_builder_get_object (builder, "shortcut_treeview"))((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ()))))))); | |||
| 714 | } | |||
| 715 | ||||
| 716 | /* Don't show an empty section */ | |||
| 717 | if (ctk_tree_model_iter_n_children (model, &parent_iter) == 0) | |||
| 718 | ctk_tree_store_remove (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &parent_iter); | |||
| 719 | ||||
| 720 | if (i == 0) | |||
| 721 | ctk_widget_hide (_ctk_builder_get_widget (builder, "shortcuts_vbox")); | |||
| 722 | else | |||
| 723 | ctk_widget_show (_ctk_builder_get_widget (builder, "shortcuts_vbox")); | |||
| 724 | } | |||
| 725 | ||||
| 726 | static void | |||
| 727 | parse_start_tag (GMarkupParseContext *ctx, | |||
| 728 | const gchar *element_name, | |||
| 729 | const gchar **attr_names, | |||
| 730 | const gchar **attr_values, | |||
| 731 | gpointer user_data, | |||
| 732 | GError **error) | |||
| 733 | { | |||
| 734 | KeyList *keylist = (KeyList *) user_data; | |||
| 735 | KeyListEntry key; | |||
| 736 | const char *name, *value_key, *description, *value_schema; | |||
| 737 | int value; | |||
| 738 | Comparison comparison; | |||
| 739 | const char *schema = NULL((void*)0); | |||
| 740 | ||||
| 741 | name = NULL((void*)0); | |||
| 742 | ||||
| 743 | /* The top-level element, names the section in the tree */ | |||
| 744 | if (g_str_equal (element_name, "KeyListEntries")(strcmp ((const char *) (element_name), (const char *) ("KeyListEntries" )) == 0)) | |||
| 745 | { | |||
| 746 | const char *wm_name = NULL((void*)0); | |||
| 747 | const char *package = NULL((void*)0); | |||
| 748 | ||||
| 749 | while (*attr_names && *attr_values) | |||
| 750 | { | |||
| 751 | if (g_str_equal (*attr_names, "name")(strcmp ((const char *) (*attr_names), (const char *) ("name" )) == 0)) | |||
| 752 | { | |||
| 753 | if (**attr_values) | |||
| 754 | name = *attr_values; | |||
| 755 | } | |||
| 756 | else if (g_str_equal (*attr_names, "wm_name")(strcmp ((const char *) (*attr_names), (const char *) ("wm_name" )) == 0)) | |||
| 757 | { | |||
| 758 | if (**attr_values) | |||
| 759 | wm_name = *attr_values; | |||
| 760 | } | |||
| 761 | else if (g_str_equal (*attr_names, "package")(strcmp ((const char *) (*attr_names), (const char *) ("package" )) == 0)) | |||
| 762 | { | |||
| 763 | if (**attr_values) | |||
| 764 | package = *attr_values; | |||
| 765 | } | |||
| 766 | else if (g_str_equal (*attr_names, "schema")(strcmp ((const char *) (*attr_names), (const char *) ("schema" )) == 0)) | |||
| 767 | { | |||
| 768 | if (**attr_values) | |||
| 769 | schema = *attr_values; | |||
| 770 | } | |||
| 771 | ++attr_names; | |||
| 772 | ++attr_values; | |||
| 773 | } | |||
| 774 | ||||
| 775 | if (name) | |||
| 776 | { | |||
| 777 | if (keylist->name) | |||
| 778 | g_warning ("Duplicate section name"); | |||
| 779 | g_free (keylist->name); | |||
| 780 | keylist->name = g_strdup (name)g_strdup_inline (name); | |||
| 781 | } | |||
| 782 | if (wm_name) | |||
| 783 | { | |||
| 784 | if (keylist->wm_name) | |||
| 785 | g_warning ("Duplicate window manager name"); | |||
| 786 | g_free (keylist->wm_name); | |||
| 787 | keylist->wm_name = g_strdup (wm_name)g_strdup_inline (wm_name); | |||
| 788 | } | |||
| 789 | if (package) | |||
| 790 | { | |||
| 791 | if (keylist->package) | |||
| 792 | g_warning ("Duplicate gettext package name"); | |||
| 793 | g_free (keylist->package); | |||
| 794 | keylist->package = g_strdup (package)g_strdup_inline (package); | |||
| 795 | } | |||
| 796 | if (schema) | |||
| 797 | { | |||
| 798 | if (keylist->schema) | |||
| 799 | g_warning ("Duplicate schema name"); | |||
| 800 | g_free (keylist->schema); | |||
| 801 | keylist->schema = g_strdup (schema)g_strdup_inline (schema); | |||
| 802 | } | |||
| 803 | return; | |||
| 804 | } | |||
| 805 | ||||
| 806 | if (!g_str_equal (element_name, "KeyListEntry")(strcmp ((const char *) (element_name), (const char *) ("KeyListEntry" )) == 0) | |||
| 807 | || attr_names == NULL((void*)0) | |||
| 808 | || attr_values == NULL((void*)0)) | |||
| 809 | return; | |||
| 810 | ||||
| 811 | value = 0; | |||
| 812 | comparison = COMPARISON_NONE; | |||
| 813 | value_key = NULL((void*)0); | |||
| 814 | value_schema = NULL((void*)0); | |||
| 815 | description = NULL((void*)0); | |||
| 816 | ||||
| 817 | while (*attr_names && *attr_values) | |||
| 818 | { | |||
| 819 | if (g_str_equal (*attr_names, "name")(strcmp ((const char *) (*attr_names), (const char *) ("name" )) == 0)) | |||
| 820 | { | |||
| 821 | /* skip if empty */ | |||
| 822 | if (**attr_values) | |||
| 823 | name = *attr_values; | |||
| 824 | } else if (g_str_equal (*attr_names, "value")(strcmp ((const char *) (*attr_names), (const char *) ("value" )) == 0)) { | |||
| 825 | if (**attr_values) { | |||
| 826 | value = (int) g_ascii_strtoull (*attr_values, NULL((void*)0), 0); | |||
| 827 | } | |||
| 828 | } else if (g_str_equal (*attr_names, "key")(strcmp ((const char *) (*attr_names), (const char *) ("key") ) == 0)) { | |||
| 829 | if (**attr_values) { | |||
| 830 | value_key = *attr_values; | |||
| 831 | } | |||
| 832 | } else if (g_str_equal (*attr_names, "comparison")(strcmp ((const char *) (*attr_names), (const char *) ("comparison" )) == 0)) { | |||
| 833 | if (**attr_values) { | |||
| 834 | if (g_str_equal (*attr_values, "gt")(strcmp ((const char *) (*attr_values), (const char *) ("gt") ) == 0)) { | |||
| 835 | comparison = COMPARISON_GT; | |||
| 836 | } else if (g_str_equal (*attr_values, "lt")(strcmp ((const char *) (*attr_values), (const char *) ("lt") ) == 0)) { | |||
| 837 | comparison = COMPARISON_LT; | |||
| 838 | } else if (g_str_equal (*attr_values, "eq")(strcmp ((const char *) (*attr_values), (const char *) ("eq") ) == 0)) { | |||
| 839 | comparison = COMPARISON_EQ; | |||
| 840 | } | |||
| 841 | } | |||
| 842 | } else if (g_str_equal (*attr_names, "description")(strcmp ((const char *) (*attr_names), (const char *) ("description" )) == 0)) { | |||
| 843 | if (**attr_values) { | |||
| 844 | description = *attr_values; | |||
| 845 | } | |||
| 846 | } else if (g_str_equal (*attr_names, "schema")(strcmp ((const char *) (*attr_names), (const char *) ("schema" )) == 0)) { | |||
| 847 | if (**attr_values) { | |||
| 848 | value_schema = *attr_values; | |||
| 849 | } | |||
| 850 | } | |||
| 851 | ||||
| 852 | ++attr_names; | |||
| 853 | ++attr_values; | |||
| 854 | } | |||
| 855 | ||||
| 856 | if (name == NULL((void*)0)) | |||
| 857 | return; | |||
| 858 | ||||
| 859 | key.name = g_strdup (name)g_strdup_inline (name); | |||
| 860 | key.gsettings_path = NULL((void*)0); | |||
| 861 | key.description_key = NULL((void*)0); | |||
| 862 | key.description = g_strdup(description)g_strdup_inline (description); | |||
| 863 | key.schema = g_strdup(schema)g_strdup_inline (schema); | |||
| 864 | key.value = value; | |||
| 865 | if (value_key) { | |||
| 866 | key.value_key = g_strdup (value_key)g_strdup_inline (value_key); | |||
| 867 | key.value_schema = g_strdup (value_schema)g_strdup_inline (value_schema); | |||
| 868 | } | |||
| 869 | else { | |||
| 870 | key.value_key = NULL((void*)0); | |||
| 871 | key.value_schema = NULL((void*)0); | |||
| 872 | } | |||
| 873 | key.comparison = comparison; | |||
| 874 | key.cmd_key = NULL((void*)0); | |||
| 875 | g_array_append_val (keylist->entries, key)g_array_append_vals (keylist->entries, &(key), 1); | |||
| 876 | } | |||
| 877 | ||||
| 878 | static gboolean | |||
| 879 | strv_contains (char **strv, | |||
| 880 | char *str) | |||
| 881 | { | |||
| 882 | char **p = strv; | |||
| 883 | for (p = strv; *p; p++) | |||
| 884 | if (strcmp (*p, str) == 0) | |||
| 885 | return TRUE(!(0)); | |||
| 886 | ||||
| 887 | return FALSE(0); | |||
| 888 | } | |||
| 889 | ||||
| 890 | static void | |||
| 891 | append_keys_to_tree_from_file (CtkBuilder *builder, | |||
| 892 | const char *filename, | |||
| 893 | char **wm_keybindings) | |||
| 894 | { | |||
| 895 | GMarkupParseContext *ctx; | |||
| 896 | GMarkupParser parser = { parse_start_tag, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0) }; | |||
| 897 | KeyList *keylist; | |||
| 898 | KeyListEntry key, *keys; | |||
| 899 | GError *err = NULL((void*)0); | |||
| 900 | char *buf; | |||
| 901 | const char *title; | |||
| 902 | gsize buf_len; | |||
| 903 | guint i; | |||
| 904 | ||||
| 905 | if (!g_file_get_contents (filename, &buf, &buf_len, &err)) | |||
| 906 | return; | |||
| 907 | ||||
| 908 | keylist = g_new0 (KeyList, 1)((KeyList *) g_malloc0_n ((1), sizeof (KeyList))); | |||
| 909 | keylist->entries = g_array_new (FALSE(0), TRUE(!(0)), sizeof (KeyListEntry)); | |||
| 910 | ctx = g_markup_parse_context_new (&parser, 0, keylist, NULL((void*)0)); | |||
| 911 | ||||
| 912 | if (!g_markup_parse_context_parse (ctx, buf, buf_len, &err)) | |||
| 913 | { | |||
| 914 | g_warning ("Failed to parse '%s': '%s'", filename, err->message); | |||
| 915 | g_error_free (err); | |||
| 916 | g_free (keylist->name); | |||
| 917 | g_free (keylist->package); | |||
| 918 | g_free (keylist->wm_name); | |||
| 919 | g_free (keylist->schema); | |||
| 920 | for (i = 0; i < keylist->entries->len; i++) | |||
| 921 | g_free (((KeyListEntry *) &(keylist->entries->data[i]))->name); | |||
| 922 | g_array_free (keylist->entries, TRUE(!(0))); | |||
| 923 | g_free (keylist); | |||
| 924 | keylist = NULL((void*)0); | |||
| 925 | } | |||
| 926 | g_markup_parse_context_free (ctx); | |||
| 927 | g_free (buf); | |||
| 928 | ||||
| 929 | if (keylist == NULL((void*)0)) | |||
| 930 | return; | |||
| 931 | ||||
| 932 | /* If there's no keys to add, or the settings apply to a window manager | |||
| 933 | * that's not the one we're running */ | |||
| 934 | if (keylist->entries->len == 0 | |||
| 935 | || (keylist->wm_name != NULL((void*)0) && !strv_contains (wm_keybindings, keylist->wm_name)) | |||
| 936 | || keylist->name == NULL((void*)0)) | |||
| 937 | { | |||
| 938 | g_free (keylist->name); | |||
| 939 | g_free (keylist->package); | |||
| 940 | g_free (keylist->wm_name); | |||
| 941 | g_free (keylist->schema); | |||
| 942 | g_array_free (keylist->entries, TRUE(!(0))); | |||
| 943 | g_free (keylist); | |||
| 944 | return; | |||
| 945 | } | |||
| 946 | ||||
| 947 | /* Empty KeyListEntry to end the array */ | |||
| 948 | key.name = NULL((void*)0); | |||
| 949 | key.description_key = NULL((void*)0); | |||
| 950 | key.value_key = NULL((void*)0); | |||
| 951 | key.value = 0; | |||
| 952 | key.comparison = COMPARISON_NONE; | |||
| 953 | g_array_append_val (keylist->entries, key)g_array_append_vals (keylist->entries, &(key), 1); | |||
| 954 | ||||
| 955 | keys = (KeyListEntry *) g_array_free (keylist->entries, FALSE(0)); | |||
| 956 | if (keylist->package) | |||
| 957 | { | |||
| 958 | bind_textdomain_codeset (keylist->package, "UTF-8"); | |||
| 959 | title = dgettext (keylist->package, keylist->name); | |||
| 960 | } else { | |||
| 961 | title = _(keylist->name)gettext (keylist->name); | |||
| 962 | } | |||
| 963 | ||||
| 964 | append_keys_to_tree (builder, title, keylist->schema, keylist->package, keys); | |||
| 965 | ||||
| 966 | g_free (keylist->name); | |||
| 967 | g_free (keylist->package); | |||
| 968 | for (i = 0; keys[i].name != NULL((void*)0); i++) | |||
| 969 | g_free (keys[i].name); | |||
| 970 | g_free (keylist); | |||
| 971 | } | |||
| 972 | ||||
| 973 | static void | |||
| 974 | append_keys_to_tree_from_gsettings (CtkBuilder *builder, const gchar *gsettings_path) | |||
| 975 | { | |||
| 976 | gchar **custom_list; | |||
| 977 | GArray *entries; | |||
| 978 | KeyListEntry key; | |||
| 979 | guint i; | |||
| 980 | ||||
| 981 | /* load custom shortcuts from GSettings */ | |||
| 982 | entries = g_array_new (FALSE(0), TRUE(!(0)), sizeof (KeyListEntry)); | |||
| 983 | ||||
| 984 | key.value_key = NULL((void*)0); | |||
| 985 | key.value = 0; | |||
| 986 | key.comparison = COMPARISON_NONE; | |||
| 987 | ||||
| 988 | custom_list = dconf_util_list_subdirs (gsettings_path, FALSE(0)); | |||
| 989 | ||||
| 990 | if (custom_list != NULL((void*)0)) | |||
| 991 | { | |||
| 992 | for (i = 0; custom_list[i] != NULL((void*)0); i++) | |||
| 993 | { | |||
| 994 | key.gsettings_path = g_strdup_printf("%s%s", gsettings_path, custom_list[i]); | |||
| 995 | key.name = g_strdup("binding")g_strdup_inline ("binding"); | |||
| 996 | key.cmd_key = g_strdup("action")g_strdup_inline ("action"); | |||
| 997 | key.description_key = g_strdup("name")g_strdup_inline ("name"); | |||
| 998 | key.schema = NULL((void*)0); | |||
| 999 | g_array_append_val (entries, key)g_array_append_vals (entries, &(key), 1); | |||
| 1000 | } | |||
| 1001 | } | |||
| 1002 | ||||
| 1003 | g_strfreev (custom_list); | |||
| 1004 | ||||
| 1005 | if (entries->len > 0) | |||
| 1006 | { | |||
| 1007 | KeyListEntry *keys; | |||
| 1008 | ||||
| 1009 | /* Empty KeyListEntry to end the array */ | |||
| 1010 | key.gsettings_path = NULL((void*)0); | |||
| 1011 | key.name = NULL((void*)0); | |||
| 1012 | key.description_key = NULL((void*)0); | |||
| 1013 | key.cmd_key = NULL((void*)0); | |||
| 1014 | g_array_append_val (entries, key)g_array_append_vals (entries, &(key), 1); | |||
| 1015 | ||||
| 1016 | keys = (KeyListEntry *) entries->data; | |||
| 1017 | append_keys_to_tree (builder, _("Custom Shortcuts")gettext ("Custom Shortcuts"), CUSTOM_KEYBINDING_SCHEMA"org.cafe.control-center.keybinding", NULL((void*)0), keys); | |||
| 1018 | for (i = 0; i < entries->len; ++i) | |||
| 1019 | { | |||
| 1020 | g_free (keys[i].name); | |||
| 1021 | g_free (keys[i].description_key); | |||
| 1022 | g_free (keys[i].cmd_key); | |||
| 1023 | g_free (keys[i].gsettings_path); | |||
| 1024 | } | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | g_array_free (entries, TRUE(!(0))); | |||
| 1028 | } | |||
| 1029 | ||||
| 1030 | static void | |||
| 1031 | reload_key_entries (CtkBuilder *builder) | |||
| 1032 | { | |||
| 1033 | gchar **wm_keybindings; | |||
| 1034 | GList *list, *l; | |||
| 1035 | const gchar * const * data_dirs; | |||
| 1036 | GHashTable *loaded_files; | |||
| 1037 | guint i; | |||
| 1038 | ||||
| 1039 | wm_keybindings = wm_common_get_current_keybindings(); | |||
| 1040 | ||||
| 1041 | clear_old_model (builder); | |||
| 1042 | ||||
| 1043 | loaded_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); | |||
| 1044 | data_dirs = g_get_system_data_dirs (); | |||
| 1045 | for (i = 0; data_dirs[i] != NULL((void*)0); i++) | |||
| 1046 | { | |||
| 1047 | g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *dir_path = NULL((void*)0); | |||
| 1048 | GDir *dir; | |||
| 1049 | const gchar *name; | |||
| 1050 | ||||
| 1051 | dir_path = g_build_filename (data_dirs[i], "cafe-control-center", "keybindings", NULL((void*)0)); | |||
| 1052 | g_debug ("Keybinding dir: %s", dir_path); | |||
| 1053 | ||||
| 1054 | dir = g_dir_open (dir_path, 0, NULL((void*)0)); | |||
| 1055 | if (!dir) | |||
| 1056 | continue; | |||
| 1057 | ||||
| 1058 | for (name = g_dir_read_name (dir) ; name ; name = g_dir_read_name (dir)) | |||
| 1059 | { | |||
| 1060 | if (g_str_has_suffix (name, ".xml")(__builtin_constant_p (".xml")? __extension__ ({ const char * const __str = (name); const char * const __suffix = (".xml") ; gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix ))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len ) == 0; } __result; }) : (g_str_has_suffix) (name, ".xml") ) == FALSE(0)) | |||
| 1061 | continue; | |||
| 1062 | ||||
| 1063 | if (g_hash_table_lookup (loaded_files, name) != NULL((void*)0)) | |||
| 1064 | { | |||
| 1065 | g_debug ("Not loading %s, it was already loaded from another directory", name); | |||
| 1066 | continue; | |||
| 1067 | } | |||
| 1068 | ||||
| 1069 | g_hash_table_insert (loaded_files, g_strdup (name)g_strdup_inline (name), g_strdup (dir_path)g_strdup_inline (dir_path)); | |||
| 1070 | } | |||
| 1071 | ||||
| 1072 | g_dir_close (dir); | |||
| 1073 | } | |||
| 1074 | list = g_hash_table_get_keys (loaded_files); | |||
| 1075 | list = g_list_sort(list, (GCompareFunc) g_str_equal); | |||
| 1076 | for (l = list; l != NULL((void*)0); l = l->next) | |||
| 1077 | { | |||
| 1078 | g_autofree__attribute__((cleanup(g_autoptr_cleanup_generic_gfree))) gchar *path = NULL((void*)0); | |||
| 1079 | path = g_build_filename (g_hash_table_lookup (loaded_files, l->data), l->data, NULL((void*)0)); | |||
| 1080 | g_debug ("Keybinding file: %s", path); | |||
| 1081 | append_keys_to_tree_from_file (builder, path, wm_keybindings); | |||
| 1082 | } | |||
| 1083 | g_list_free (list); | |||
| 1084 | g_hash_table_destroy (loaded_files); | |||
| 1085 | ||||
| 1086 | /* Load custom shortcuts _after_ system-provided ones, | |||
| 1087 | * since some of the custom shortcuts may also be listed | |||
| 1088 | * in a file. Loading the custom shortcuts last makes | |||
| 1089 | * such keys not show up in the custom section. | |||
| 1090 | */ | |||
| 1091 | append_keys_to_tree_from_gsettings (builder, GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/"); | |||
| 1092 | ||||
| 1093 | g_strfreev (wm_keybindings); | |||
| 1094 | } | |||
| 1095 | ||||
| 1096 | static void | |||
| 1097 | key_entry_controlling_key_changed (GSettings *settings, gchar *key, gpointer user_data) | |||
| 1098 | { | |||
| 1099 | reload_key_entries (user_data); | |||
| 1100 | } | |||
| 1101 | ||||
| 1102 | static gboolean cb_check_for_uniqueness(CtkTreeModel* model, CtkTreePath* path, CtkTreeIter* iter, KeyEntry* new_key) | |||
| 1103 | { | |||
| 1104 | KeyEntry* element; | |||
| 1105 | ||||
| 1106 | ctk_tree_model_get (new_key->model, iter, | |||
| 1107 | KEYENTRY_COLUMN, &element, | |||
| 1108 | -1); | |||
| 1109 | ||||
| 1110 | /* no conflict for : blanks, different modifiers, or ourselves */ | |||
| 1111 | if (element == NULL((void*)0) || new_key->mask != element->mask) | |||
| 1112 | { | |||
| 1113 | return FALSE(0); | |||
| 1114 | } | |||
| 1115 | ||||
| 1116 | gchar *new_key_schema = NULL((void*)0); | |||
| 1117 | gchar *element_schema = NULL((void*)0); | |||
| 1118 | gchar *new_key_path = NULL((void*)0); | |||
| 1119 | gchar *element_path = NULL((void*)0); | |||
| 1120 | ||||
| 1121 | if (new_key && new_key->settings) | |||
| 1122 | { | |||
| 1123 | g_object_get (new_key->settings, "schema-id", &new_key_schema, NULL((void*)0)); | |||
| 1124 | g_object_get (new_key->settings, "path", &new_key_path, NULL((void*)0)); | |||
| 1125 | } | |||
| 1126 | ||||
| 1127 | if (element->settings) | |||
| 1128 | { | |||
| 1129 | g_object_get (element->settings, "schema-id", &element_schema, NULL((void*)0)); | |||
| 1130 | g_object_get (element->settings, "path", &element_path, NULL((void*)0)); | |||
| 1131 | } | |||
| 1132 | ||||
| 1133 | if (!g_strcmp0 (new_key->gsettings_key, element->gsettings_key) && | |||
| 1134 | !g_strcmp0 (new_key_schema, element_schema) && | |||
| 1135 | !g_strcmp0 (new_key_path, element_path)) | |||
| 1136 | { | |||
| 1137 | return FALSE(0); | |||
| 1138 | } | |||
| 1139 | ||||
| 1140 | if (new_key->keyval != 0) | |||
| 1141 | { | |||
| 1142 | if (new_key->keyval != element->keyval) | |||
| 1143 | { | |||
| 1144 | return FALSE(0); | |||
| 1145 | } | |||
| 1146 | } | |||
| 1147 | else if (element->keyval != 0 || new_key->keycode != element->keycode) | |||
| 1148 | { | |||
| 1149 | return FALSE(0); | |||
| 1150 | } | |||
| 1151 | ||||
| 1152 | new_key->editable = FALSE(0); | |||
| 1153 | new_key->settings = element->settings; | |||
| 1154 | new_key->gsettings_key = element->gsettings_key; | |||
| 1155 | new_key->description = element->description; | |||
| 1156 | new_key->desc_gsettings_key = element->desc_gsettings_key; | |||
| 1157 | new_key->desc_editable = element->desc_editable; | |||
| 1158 | ||||
| 1159 | return TRUE(!(0)); | |||
| 1160 | } | |||
| 1161 | ||||
| 1162 | static const guint forbidden_keyvals[] = { | |||
| 1163 | /* Navigation keys */ | |||
| 1164 | CDK_KEY_Home0xff50, | |||
| 1165 | CDK_KEY_Left0xff51, | |||
| 1166 | CDK_KEY_Up0xff52, | |||
| 1167 | CDK_KEY_Right0xff53, | |||
| 1168 | CDK_KEY_Down0xff54, | |||
| 1169 | CDK_KEY_Page_Up0xff55, | |||
| 1170 | CDK_KEY_Page_Down0xff56, | |||
| 1171 | CDK_KEY_End0xff57, | |||
| 1172 | CDK_KEY_Tab0xff09, | |||
| 1173 | ||||
| 1174 | /* Return */ | |||
| 1175 | CDK_KEY_KP_Enter0xff8d, | |||
| 1176 | CDK_KEY_Return0xff0d, | |||
| 1177 | ||||
| 1178 | CDK_KEY_space0x020, | |||
| 1179 | CDK_KEY_Mode_switch0xff7e | |||
| 1180 | }; | |||
| 1181 | ||||
| 1182 | static gboolean keyval_is_forbidden(guint keyval) | |||
| 1183 | { | |||
| 1184 | guint i; | |||
| 1185 | ||||
| 1186 | for (i = 0; i < G_N_ELEMENTS(forbidden_keyvals)(sizeof (forbidden_keyvals) / sizeof ((forbidden_keyvals)[0]) ); i++) | |||
| 1187 | { | |||
| 1188 | if (keyval == forbidden_keyvals[i]) | |||
| 1189 | { | |||
| 1190 | return TRUE(!(0)); | |||
| 1191 | } | |||
| 1192 | } | |||
| 1193 | ||||
| 1194 | return FALSE(0); | |||
| 1195 | } | |||
| 1196 | ||||
| 1197 | static void show_error(CtkWindow* parent, GError* err) | |||
| 1198 | { | |||
| 1199 | CtkWidget *dialog; | |||
| 1200 | ||||
| 1201 | dialog = ctk_message_dialog_new (parent, | |||
| 1202 | CTK_DIALOG_DESTROY_WITH_PARENT | CTK_DIALOG_MODAL, | |||
| 1203 | CTK_MESSAGE_WARNING, | |||
| 1204 | CTK_BUTTONS_OK, | |||
| 1205 | _("Error saving the new shortcut")gettext ("Error saving the new shortcut")); | |||
| 1206 | ||||
| 1207 | ctk_message_dialog_format_secondary_text (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ()) ))))), | |||
| 1208 | "%s", err->message); | |||
| ||||
| 1209 | ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_dialog_get_type ()))))))); | |||
| 1210 | ctk_widget_destroy (dialog); | |||
| 1211 | } | |||
| 1212 | ||||
| 1213 | static void accel_edited_callback(CtkCellRendererText* cell, const char* path_string, guint keyval, EggVirtualModifierType mask, guint keycode, gpointer data) | |||
| 1214 | { | |||
| 1215 | CtkTreeView* view = (CtkTreeView*) data; | |||
| 1216 | CtkTreeModel* model; | |||
| 1217 | CtkTreePath* path = ctk_tree_path_new_from_string (path_string); | |||
| 1218 | CtkTreeIter iter; | |||
| 1219 | KeyEntry* key_entry, tmp_key; | |||
| 1220 | char* str; | |||
| 1221 | ||||
| 1222 | block_accels = FALSE(0); | |||
| 1223 | ||||
| 1224 | model = ctk_tree_view_get_model (view); | |||
| 1225 | ctk_tree_model_get_iter (model, &iter, path); | |||
| 1226 | ctk_tree_path_free (path); | |||
| 1227 | ctk_tree_model_get (model, &iter, | |||
| 1228 | KEYENTRY_COLUMN, &key_entry, | |||
| 1229 | -1); | |||
| 1230 | ||||
| 1231 | /* sanity check */ | |||
| 1232 | if (key_entry == NULL((void*)0)) | |||
| 1233 | { | |||
| 1234 | return; | |||
| 1235 | } | |||
| 1236 | ||||
| 1237 | /* CapsLock isn't supported as a keybinding modifier, so keep it from confusing us */ | |||
| 1238 | mask &= ~EGG_VIRTUAL_LOCK_MASK; | |||
| 1239 | ||||
| 1240 | tmp_key.model = model; | |||
| 1241 | tmp_key.keyval = keyval; | |||
| 1242 | tmp_key.keycode = keycode; | |||
| 1243 | tmp_key.mask = mask; | |||
| 1244 | tmp_key.settings = key_entry->settings; | |||
| 1245 | tmp_key.gsettings_key = key_entry->gsettings_key; | |||
| 1246 | tmp_key.description = NULL((void*)0); | |||
| 1247 | tmp_key.editable = TRUE(!(0)); /* kludge to stuff in a return flag */ | |||
| 1248 | ||||
| 1249 | if (keyval != 0 || keycode != 0) /* any number of keys can be disabled */ | |||
| 1250 | { | |||
| 1251 | ctk_tree_model_foreach(model, (CtkTreeModelForeachFunc) cb_check_for_uniqueness, &tmp_key); | |||
| 1252 | } | |||
| 1253 | ||||
| 1254 | /* Check for unmodified keys */ | |||
| 1255 | if (tmp_key.mask == 0 && tmp_key.keycode != 0) | |||
| 1256 | { | |||
| 1257 | if ((tmp_key.keyval >= CDK_KEY_a0x061 && tmp_key.keyval <= CDK_KEY_z0x07a) | |||
| 1258 | || (tmp_key.keyval >= CDK_KEY_A0x041 && tmp_key.keyval <= CDK_KEY_Z0x05a) | |||
| 1259 | || (tmp_key.keyval >= CDK_KEY_00x030 && tmp_key.keyval <= CDK_KEY_90x039) | |||
| 1260 | || (tmp_key.keyval >= CDK_KEY_kana_fullstop0x4a1 && tmp_key.keyval <= CDK_KEY_semivoicedsound0x4df) | |||
| 1261 | || (tmp_key.keyval >= CDK_KEY_Arabic_comma0x5ac && tmp_key.keyval <= CDK_KEY_Arabic_sukun0x5f2) | |||
| 1262 | || (tmp_key.keyval >= CDK_KEY_Serbian_dje0x6a1 && tmp_key.keyval <= CDK_KEY_Cyrillic_HARDSIGN0x6ff) | |||
| 1263 | || (tmp_key.keyval >= CDK_KEY_Greek_ALPHAaccent0x7a1 && tmp_key.keyval <= CDK_KEY_Greek_omega0x7f9) | |||
| 1264 | || (tmp_key.keyval >= CDK_KEY_hebrew_doublelowline0xcdf && tmp_key.keyval <= CDK_KEY_hebrew_taf0xcfa) | |||
| 1265 | || (tmp_key.keyval >= CDK_KEY_Thai_kokai0xda1 && tmp_key.keyval <= CDK_KEY_Thai_lekkao0xdf9) | |||
| 1266 | || (tmp_key.keyval >= CDK_KEY_Hangul0xff31 && tmp_key.keyval <= CDK_KEY_Hangul_Special0xff3f) | |||
| 1267 | || (tmp_key.keyval >= CDK_KEY_Hangul_Kiyeog0xea1 && tmp_key.keyval <= CDK_KEY_Hangul_J_YeorinHieuh0xefa) | |||
| 1268 | || keyval_is_forbidden (tmp_key.keyval)) | |||
| 1269 | { | |||
| 1270 | ||||
| 1271 | CtkWidget *dialog; | |||
| 1272 | char *name; | |||
| 1273 | ||||
| 1274 | name = binding_name (keyval, keycode, mask, TRUE(!(0))); | |||
| 1275 | ||||
| 1276 | dialog = ctk_message_dialog_new ( | |||
| 1277 | CTK_WINDOW (ctk_widget_get_toplevel (CTK_WIDGET (view)))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_toplevel (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((view)), ((ctk_widget_get_type ())))))))) ), ((ctk_window_get_type ())))))), | |||
| 1278 | CTK_DIALOG_DESTROY_WITH_PARENT | CTK_DIALOG_MODAL, | |||
| 1279 | CTK_MESSAGE_WARNING, | |||
| 1280 | CTK_BUTTONS_CANCEL, | |||
| 1281 | _("The shortcut \"%s\" cannot be used because it will become impossible to type using this key.\n"gettext ("The shortcut \"%s\" cannot be used because it will become impossible to type using this key.\n" "Please try with a key such as Control, Alt or Shift at the same time." ) | |||
| 1282 | "Please try with a key such as Control, Alt or Shift at the same time.")gettext ("The shortcut \"%s\" cannot be used because it will become impossible to type using this key.\n" "Please try with a key such as Control, Alt or Shift at the same time." ), | |||
| 1283 | name); | |||
| 1284 | ||||
| 1285 | g_free (name); | |||
| 1286 | ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_dialog_get_type ()))))))); | |||
| 1287 | ctk_widget_destroy (dialog); | |||
| 1288 | ||||
| 1289 | /* set it back to its previous value. */ | |||
| 1290 | egg_cell_renderer_keys_set_accelerator( | |||
| 1291 | EGG_CELL_RENDERER_KEYS(cell)((((EggCellRendererKeys*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((cell)), ((egg_cell_renderer_keys_get_type ())))))), | |||
| 1292 | key_entry->keyval, | |||
| 1293 | key_entry->keycode, | |||
| 1294 | key_entry->mask); | |||
| 1295 | return; | |||
| 1296 | } | |||
| 1297 | } | |||
| 1298 | ||||
| 1299 | /* flag to see if the new accelerator was in use by something */ | |||
| 1300 | if (!tmp_key.editable) | |||
| 1301 | { | |||
| 1302 | CtkWidget* dialog; | |||
| 1303 | char* name; | |||
| 1304 | int response; | |||
| 1305 | ||||
| 1306 | name = binding_name(keyval, keycode, mask, TRUE(!(0))); | |||
| 1307 | ||||
| 1308 | dialog = ctk_message_dialog_new( | |||
| 1309 | CTK_WINDOW(ctk_widget_get_toplevel(CTK_WIDGET(view)))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_toplevel(((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((view)), ((ctk_widget_get_type ())))))))) ), ((ctk_window_get_type ())))))), | |||
| 1310 | CTK_DIALOG_DESTROY_WITH_PARENT | CTK_DIALOG_MODAL, | |||
| 1311 | CTK_MESSAGE_WARNING, | |||
| 1312 | CTK_BUTTONS_CANCEL, | |||
| 1313 | _("The shortcut \"%s\" is already used for\n\"%s\"")gettext ("The shortcut \"%s\" is already used for\n\"%s\""), | |||
| 1314 | name, | |||
| 1315 | tmp_key.description ? tmp_key.description : tmp_key.gsettings_key); | |||
| 1316 | g_free (name); | |||
| 1317 | ||||
| 1318 | ctk_message_dialog_format_secondary_text ( | |||
| 1319 | CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ()) ))))), | |||
| 1320 | _("If you reassign the shortcut to \"%s\", the \"%s\" shortcut "gettext ("If you reassign the shortcut to \"%s\", the \"%s\" shortcut " "will be disabled.") | |||
| 1321 | "will be disabled.")gettext ("If you reassign the shortcut to \"%s\", the \"%s\" shortcut " "will be disabled."), | |||
| 1322 | key_entry->description ? key_entry->description : key_entry->gsettings_key, | |||
| 1323 | tmp_key.description ? tmp_key.description : tmp_key.gsettings_key); | |||
| 1324 | ||||
| 1325 | ctk_dialog_add_button(CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_dialog_get_type ())))))), _("_Reassign")gettext ("_Reassign"), CTK_RESPONSE_ACCEPT); | |||
| 1326 | ||||
| 1327 | ctk_dialog_set_default_response(CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_dialog_get_type ())))))), CTK_RESPONSE_ACCEPT); | |||
| 1328 | ||||
| 1329 | response = ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_dialog_get_type ()))))))); | |||
| 1330 | ctk_widget_destroy (dialog); | |||
| 1331 | ||||
| 1332 | if (response == CTK_RESPONSE_ACCEPT) | |||
| 1333 | { | |||
| 1334 | g_settings_set_string (tmp_key.settings, tmp_key.gsettings_key, "disabled"); | |||
| 1335 | ||||
| 1336 | str = binding_name (keyval, keycode, mask, FALSE(0)); | |||
| 1337 | g_settings_set_string (key_entry->settings, key_entry->gsettings_key, str); | |||
| 1338 | ||||
| 1339 | g_free (str); | |||
| 1340 | } | |||
| 1341 | else | |||
| 1342 | { | |||
| 1343 | /* set it back to its previous value. */ | |||
| 1344 | egg_cell_renderer_keys_set_accelerator( | |||
| 1345 | EGG_CELL_RENDERER_KEYS(cell)((((EggCellRendererKeys*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((cell)), ((egg_cell_renderer_keys_get_type ())))))), | |||
| 1346 | key_entry->keyval, | |||
| 1347 | key_entry->keycode, | |||
| 1348 | key_entry->mask); | |||
| 1349 | } | |||
| 1350 | ||||
| 1351 | return; | |||
| 1352 | } | |||
| 1353 | ||||
| 1354 | str = binding_name (keyval, keycode, mask, FALSE(0)); | |||
| 1355 | ||||
| 1356 | g_settings_set_string( | |||
| 1357 | key_entry->settings, | |||
| 1358 | key_entry->gsettings_key, | |||
| 1359 | str); | |||
| 1360 | ||||
| 1361 | g_free (str); | |||
| 1362 | ||||
| 1363 | } | |||
| 1364 | ||||
| 1365 | static void | |||
| 1366 | accel_cleared_callback (CtkCellRendererText *cell, | |||
| 1367 | const char *path_string, | |||
| 1368 | gpointer data) | |||
| 1369 | { | |||
| 1370 | CtkTreeView *view = (CtkTreeView *) data; | |||
| 1371 | CtkTreePath *path = ctk_tree_path_new_from_string (path_string); | |||
| 1372 | KeyEntry *key_entry; | |||
| 1373 | CtkTreeIter iter; | |||
| 1374 | CtkTreeModel *model; | |||
| 1375 | ||||
| 1376 | block_accels = FALSE(0); | |||
| 1377 | ||||
| 1378 | model = ctk_tree_view_get_model (view); | |||
| 1379 | ctk_tree_model_get_iter (model, &iter, path); | |||
| 1380 | ctk_tree_path_free (path); | |||
| 1381 | ctk_tree_model_get (model, &iter, | |||
| 1382 | KEYENTRY_COLUMN, &key_entry, | |||
| 1383 | -1); | |||
| 1384 | ||||
| 1385 | /* sanity check */ | |||
| 1386 | if (key_entry == NULL((void*)0)) | |||
| 1387 | return; | |||
| 1388 | ||||
| 1389 | /* Unset the key */ | |||
| 1390 | g_settings_set_string (key_entry->settings, | |||
| 1391 | key_entry->gsettings_key, | |||
| 1392 | "disabled"); | |||
| 1393 | } | |||
| 1394 | ||||
| 1395 | static void | |||
| 1396 | description_edited_callback (CtkCellRendererText *renderer, | |||
| 1397 | gchar *path_string, | |||
| 1398 | gchar *new_text, | |||
| 1399 | gpointer user_data) | |||
| 1400 | { | |||
| 1401 | CtkTreeView *view = CTK_TREE_VIEW (user_data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((user_data)), ((ctk_tree_view_get_type ())))))); | |||
| 1402 | CtkTreeModel *model; | |||
| 1403 | CtkTreePath *path = ctk_tree_path_new_from_string (path_string); | |||
| 1404 | CtkTreeIter iter; | |||
| 1405 | KeyEntry *key_entry; | |||
| 1406 | ||||
| 1407 | model = ctk_tree_view_get_model (view); | |||
| 1408 | ctk_tree_model_get_iter (model, &iter, path); | |||
| 1409 | ctk_tree_path_free (path); | |||
| 1410 | ||||
| 1411 | ctk_tree_model_get (model, &iter, | |||
| 1412 | KEYENTRY_COLUMN, &key_entry, | |||
| 1413 | -1); | |||
| 1414 | ||||
| 1415 | /* sanity check */ | |||
| 1416 | if (key_entry == NULL((void*)0) || key_entry->desc_gsettings_key == NULL((void*)0)) | |||
| 1417 | return; | |||
| 1418 | ||||
| 1419 | if (!g_settings_set_string (key_entry->settings, key_entry->desc_gsettings_key, new_text)) | |||
| 1420 | key_entry->desc_editable = FALSE(0); | |||
| 1421 | } | |||
| 1422 | ||||
| 1423 | ||||
| 1424 | typedef struct | |||
| 1425 | { | |||
| 1426 | CtkTreeView *tree_view; | |||
| 1427 | CtkTreePath *path; | |||
| 1428 | CtkTreeViewColumn *column; | |||
| 1429 | } IdleData; | |||
| 1430 | ||||
| 1431 | static gboolean | |||
| 1432 | real_start_editing_cb (IdleData *idle_data) | |||
| 1433 | { | |||
| 1434 | ctk_widget_grab_focus (CTK_WIDGET (idle_data->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((idle_data->tree_view)), ((ctk_widget_get_type ()))))) )); | |||
| 1435 | ctk_tree_view_set_cursor (idle_data->tree_view, | |||
| 1436 | idle_data->path, | |||
| 1437 | idle_data->column, | |||
| 1438 | TRUE(!(0))); | |||
| 1439 | ctk_tree_path_free (idle_data->path); | |||
| 1440 | g_free (idle_data); | |||
| 1441 | return FALSE(0); | |||
| 1442 | } | |||
| 1443 | ||||
| 1444 | static gboolean | |||
| 1445 | edit_custom_shortcut (KeyEntry *key) | |||
| 1446 | { | |||
| 1447 | gint result; | |||
| 1448 | const gchar *text; | |||
| 1449 | gboolean ret; | |||
| 1450 | ||||
| 1451 | ctk_entry_set_text (CTK_ENTRY (custom_shortcut_name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_name_entry)), ((ctk_entry_get_type ()))) ))), key->description ? key->description : ""); | |||
| 1452 | ctk_widget_set_sensitive (custom_shortcut_name_entry, key->desc_editable); | |||
| 1453 | ctk_widget_grab_focus (custom_shortcut_name_entry); | |||
| 1454 | ctk_entry_set_text (CTK_ENTRY (custom_shortcut_command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_command_entry)), ((ctk_entry_get_type () )))))), key->command ? key->command : ""); | |||
| 1455 | ctk_widget_set_sensitive (custom_shortcut_command_entry, key->cmd_editable); | |||
| 1456 | ||||
| 1457 | ctk_window_present (CTK_WINDOW (custom_shortcut_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_dialog)), ((ctk_window_get_type ()))))))); | |||
| 1458 | result = ctk_dialog_run (CTK_DIALOG (custom_shortcut_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_dialog)), ((ctk_dialog_get_type ()))))))); | |||
| 1459 | switch (result) | |||
| 1460 | { | |||
| 1461 | case CTK_RESPONSE_OK: | |||
| 1462 | text = ctk_entry_get_text (CTK_ENTRY (custom_shortcut_name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_name_entry)), ((ctk_entry_get_type ()))) )))); | |||
| 1463 | g_free (key->description); | |||
| 1464 | key->description = g_strdup (text)g_strdup_inline (text); | |||
| 1465 | text = ctk_entry_get_text (CTK_ENTRY (custom_shortcut_command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_command_entry)), ((ctk_entry_get_type () ))))))); | |||
| 1466 | g_free (key->command); | |||
| 1467 | key->command = g_strdup (text)g_strdup_inline (text); | |||
| 1468 | ret = TRUE(!(0)); | |||
| 1469 | break; | |||
| 1470 | default: | |||
| 1471 | ret = FALSE(0); | |||
| 1472 | break; | |||
| 1473 | } | |||
| 1474 | ||||
| 1475 | ctk_widget_hide (custom_shortcut_dialog); | |||
| 1476 | ||||
| 1477 | return ret; | |||
| 1478 | } | |||
| 1479 | ||||
| 1480 | static gboolean | |||
| 1481 | remove_custom_shortcut (CtkTreeModel *model, CtkTreeIter *iter) | |||
| 1482 | { | |||
| 1483 | CtkTreeIter parent; | |||
| 1484 | KeyEntry *key; | |||
| 1485 | ||||
| 1486 | ctk_tree_model_get (model, iter, | |||
| 1487 | KEYENTRY_COLUMN, &key, | |||
| 1488 | -1); | |||
| 1489 | ||||
| 1490 | /* not a custom shortcut */ | |||
| 1491 | if (key->command == NULL((void*)0)) | |||
| 1492 | return FALSE(0); | |||
| 1493 | ||||
| 1494 | g_signal_handler_disconnect (key->settings, key->gsettings_cnxn); | |||
| 1495 | if (key->gsettings_cnxn_desc != 0) | |||
| 1496 | g_signal_handler_disconnect (key->settings, key->gsettings_cnxn_desc); | |||
| 1497 | if (key->gsettings_cnxn_cmd != 0) | |||
| 1498 | g_signal_handler_disconnect (key->settings, key->gsettings_cnxn_cmd); | |||
| 1499 | ||||
| 1500 | dconf_util_recursive_reset (key->gsettings_path, NULL((void*)0)); | |||
| 1501 | g_object_unref (key->settings); | |||
| 1502 | ||||
| 1503 | g_free (key->gsettings_path); | |||
| 1504 | g_free (key->gsettings_key); | |||
| 1505 | g_free (key->description); | |||
| 1506 | g_free (key->desc_gsettings_key); | |||
| 1507 | g_free (key->command); | |||
| 1508 | g_free (key->cmd_gsettings_key); | |||
| 1509 | g_free (key); | |||
| 1510 | ||||
| 1511 | ctk_tree_model_iter_parent (model, &parent, iter); | |||
| 1512 | ctk_tree_store_remove (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), iter); | |||
| 1513 | if (!ctk_tree_model_iter_has_child (model, &parent)) | |||
| 1514 | ctk_tree_store_remove (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &parent); | |||
| 1515 | ||||
| 1516 | return TRUE(!(0)); | |||
| 1517 | } | |||
| 1518 | ||||
| 1519 | static void | |||
| 1520 | update_custom_shortcut (CtkTreeModel *model, CtkTreeIter *iter) | |||
| 1521 | { | |||
| 1522 | KeyEntry *key; | |||
| 1523 | ||||
| 1524 | ctk_tree_model_get (model, iter, | |||
| 1525 | KEYENTRY_COLUMN, &key, | |||
| 1526 | -1); | |||
| 1527 | ||||
| 1528 | edit_custom_shortcut (key); | |||
| 1529 | if (key->command == NULL((void*)0) || key->command[0] == '\0') | |||
| 1530 | { | |||
| 1531 | remove_custom_shortcut (model, iter); | |||
| 1532 | } | |||
| 1533 | else | |||
| 1534 | { | |||
| 1535 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), iter, | |||
| 1536 | KEYENTRY_COLUMN, key, -1); | |||
| 1537 | if (key->description != NULL((void*)0)) | |||
| 1538 | g_settings_set_string (key->settings, key->desc_gsettings_key, key->description); | |||
| 1539 | else | |||
| 1540 | g_settings_reset (key->settings, key->desc_gsettings_key); | |||
| 1541 | g_settings_set_string (key->settings, key->cmd_gsettings_key, key->command); | |||
| 1542 | } | |||
| 1543 | } | |||
| 1544 | ||||
| 1545 | static gchar * | |||
| 1546 | find_free_gsettings_path (GError **error) | |||
| 1547 | { | |||
| 1548 | gchar **existing_dirs; | |||
| 1549 | gchar *dir = NULL((void*)0); | |||
| 1550 | gchar *fulldir = NULL((void*)0); | |||
| 1551 | int i; | |||
| 1552 | int j; | |||
| 1553 | gboolean found; | |||
| 1554 | ||||
| 1555 | existing_dirs = dconf_util_list_subdirs (GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/", FALSE(0)); | |||
| 1556 | ||||
| 1557 | for (i = 0; i < MAX_CUSTOM_SHORTCUTS1000; i++) | |||
| 1558 | { | |||
| 1559 | found = TRUE(!(0)); | |||
| 1560 | dir = g_strdup_printf ("custom%d/", i); | |||
| 1561 | for (j = 0; existing_dirs[j] != NULL((void*)0); j++) | |||
| 1562 | if (!g_strcmp0(dir, existing_dirs[j])) | |||
| 1563 | { | |||
| 1564 | found = FALSE(0); | |||
| 1565 | g_free (dir); | |||
| 1566 | break; | |||
| 1567 | } | |||
| 1568 | if (found
| |||
| 1569 | break; | |||
| 1570 | } | |||
| 1571 | g_strfreev (existing_dirs); | |||
| 1572 | ||||
| 1573 | if (i
| |||
| 1574 | { | |||
| 1575 | g_free (dir); | |||
| 1576 | dir = NULL((void*)0); | |||
| 1577 | g_set_error_literal (error, | |||
| 1578 | g_quark_from_string ("Keyboard Shortcuts"), | |||
| 1579 | 0, | |||
| 1580 | _("Too many custom shortcuts")gettext ("Too many custom shortcuts")); | |||
| 1581 | } | |||
| 1582 | ||||
| 1583 | fulldir = g_strdup_printf ("%s%s", GSETTINGS_KEYBINDINGS_DIR"/org/cafe/desktop/keybindings/", dir); | |||
| 1584 | g_free (dir); | |||
| 1585 | return fulldir; | |||
| 1586 | } | |||
| 1587 | ||||
| 1588 | static void | |||
| 1589 | add_custom_shortcut (CtkTreeView *tree_view, | |||
| 1590 | CtkTreeModel *model) | |||
| 1591 | { | |||
| 1592 | KeyEntry *key_entry; | |||
| 1593 | CtkTreeIter iter; | |||
| 1594 | CtkTreeIter parent_iter; | |||
| 1595 | CtkTreePath *path; | |||
| 1596 | gchar *dir; | |||
| 1597 | GError *error; | |||
| 1598 | ||||
| 1599 | error = NULL((void*)0); | |||
| 1600 | dir = find_free_gsettings_path (&error); | |||
| 1601 | if (dir == NULL((void*)0)) | |||
| 1602 | { | |||
| 1603 | show_error (CTK_WINDOW (ctk_widget_get_toplevel (CTK_WIDGET (tree_view)))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_widget_get_toplevel (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view)), ((ctk_widget_get_type ()))) )))))), ((ctk_window_get_type ())))))), error); | |||
| 1604 | ||||
| 1605 | g_error_free (error); | |||
| 1606 | return; | |||
| 1607 | } | |||
| 1608 | ||||
| 1609 | key_entry = g_new0 (KeyEntry, 1)((KeyEntry *) g_malloc0_n ((1), sizeof (KeyEntry))); | |||
| 1610 | key_entry->gsettings_path = g_strdup(dir)g_strdup_inline (dir); | |||
| 1611 | key_entry->gsettings_key = g_strdup("binding")g_strdup_inline ("binding"); | |||
| 1612 | key_entry->editable = TRUE(!(0)); | |||
| 1613 | key_entry->model = model; | |||
| 1614 | key_entry->desc_gsettings_key = g_strdup("name")g_strdup_inline ("name"); | |||
| 1615 | key_entry->description = g_strdup ("")g_strdup_inline (""); | |||
| 1616 | key_entry->desc_editable = TRUE(!(0)); | |||
| 1617 | key_entry->cmd_gsettings_key = g_strdup("action")g_strdup_inline ("action"); | |||
| 1618 | key_entry->command = g_strdup ("")g_strdup_inline (""); | |||
| 1619 | key_entry->cmd_editable = TRUE(!(0)); | |||
| 1620 | g_free (dir); | |||
| 1621 | ||||
| 1622 | if (edit_custom_shortcut (key_entry) && | |||
| 1623 | key_entry->command && key_entry->command[0]) | |||
| 1624 | { | |||
| 1625 | find_section (model, &iter, _("Custom Shortcuts")gettext ("Custom Shortcuts")); | |||
| 1626 | parent_iter = iter; | |||
| 1627 | ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &iter, &parent_iter); | |||
| 1628 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &iter, KEYENTRY_COLUMN, key_entry, -1); | |||
| 1629 | ||||
| 1630 | /* store in gsettings */ | |||
| 1631 | key_entry->settings = g_settings_new_with_path (CUSTOM_KEYBINDING_SCHEMA"org.cafe.control-center.keybinding", key_entry->gsettings_path); | |||
| 1632 | g_settings_set_string (key_entry->settings, key_entry->gsettings_key, "disabled"); | |||
| 1633 | g_settings_set_string (key_entry->settings, key_entry->desc_gsettings_key, key_entry->description); | |||
| 1634 | g_settings_set_string (key_entry->settings, key_entry->cmd_gsettings_key, key_entry->command); | |||
| 1635 | ||||
| 1636 | /* add gsettings watches */ | |||
| 1637 | key_entry->gsettings_cnxn_desc = g_signal_connect (key_entry->settings,g_signal_connect_data ((key_entry->settings), ("changed::name" ), (((GCallback) (keybinding_description_changed))), (key_entry ), ((void*)0), (GConnectFlags) 0) | |||
| 1638 | "changed::name",g_signal_connect_data ((key_entry->settings), ("changed::name" ), (((GCallback) (keybinding_description_changed))), (key_entry ), ((void*)0), (GConnectFlags) 0) | |||
| 1639 | G_CALLBACK (keybinding_description_changed),g_signal_connect_data ((key_entry->settings), ("changed::name" ), (((GCallback) (keybinding_description_changed))), (key_entry ), ((void*)0), (GConnectFlags) 0) | |||
| 1640 | key_entry)g_signal_connect_data ((key_entry->settings), ("changed::name" ), (((GCallback) (keybinding_description_changed))), (key_entry ), ((void*)0), (GConnectFlags) 0); | |||
| 1641 | key_entry->gsettings_cnxn_cmd = g_signal_connect (key_entry->settings,g_signal_connect_data ((key_entry->settings), ("changed::action" ), (((GCallback) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags) 0) | |||
| 1642 | "changed::action",g_signal_connect_data ((key_entry->settings), ("changed::action" ), (((GCallback) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags) 0) | |||
| 1643 | G_CALLBACK (keybinding_command_changed),g_signal_connect_data ((key_entry->settings), ("changed::action" ), (((GCallback) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags) 0) | |||
| 1644 | key_entry)g_signal_connect_data ((key_entry->settings), ("changed::action" ), (((GCallback) (keybinding_command_changed))), (key_entry), ((void*)0), (GConnectFlags) 0); | |||
| 1645 | key_entry->gsettings_cnxn = g_signal_connect (key_entry->settings,g_signal_connect_data ((key_entry->settings), ("changed::binding" ), (((GCallback) (keybinding_key_changed))), (key_entry), ((void *)0), (GConnectFlags) 0) | |||
| 1646 | "changed::binding",g_signal_connect_data ((key_entry->settings), ("changed::binding" ), (((GCallback) (keybinding_key_changed))), (key_entry), ((void *)0), (GConnectFlags) 0) | |||
| 1647 | G_CALLBACK (keybinding_key_changed),g_signal_connect_data ((key_entry->settings), ("changed::binding" ), (((GCallback) (keybinding_key_changed))), (key_entry), ((void *)0), (GConnectFlags) 0) | |||
| 1648 | key_entry)g_signal_connect_data ((key_entry->settings), ("changed::binding" ), (((GCallback) (keybinding_key_changed))), (key_entry), ((void *)0), (GConnectFlags) 0); | |||
| 1649 | ||||
| 1650 | /* make the new shortcut visible */ | |||
| 1651 | path = ctk_tree_model_get_path (model, &iter); | |||
| 1652 | ctk_tree_view_expand_to_path (tree_view, path); | |||
| 1653 | ctk_tree_view_scroll_to_cell (tree_view, path, NULL((void*)0), FALSE(0), 0, 0); | |||
| 1654 | ctk_tree_path_free (path); | |||
| 1655 | } | |||
| 1656 | else | |||
| 1657 | { | |||
| 1658 | g_free (key_entry->gsettings_path); | |||
| 1659 | g_free (key_entry->gsettings_key); | |||
| 1660 | g_free (key_entry->description); | |||
| 1661 | g_free (key_entry->desc_gsettings_key); | |||
| 1662 | g_free (key_entry->command); | |||
| 1663 | g_free (key_entry->cmd_gsettings_key); | |||
| 1664 | g_free (key_entry); | |||
| 1665 | } | |||
| 1666 | } | |||
| 1667 | ||||
| 1668 | static void | |||
| 1669 | start_editing_kb_cb (CtkTreeView *treeview, | |||
| 1670 | CtkTreePath *path, | |||
| 1671 | CtkTreeViewColumn *column, | |||
| 1672 | gpointer user_data) | |||
| 1673 | { | |||
| 1674 | CtkTreeModel *model; | |||
| 1675 | CtkTreeIter iter; | |||
| 1676 | KeyEntry *key; | |||
| 1677 | ||||
| 1678 | model = ctk_tree_view_get_model (treeview); | |||
| 1679 | ctk_tree_model_get_iter (model, &iter, path); | |||
| 1680 | ctk_tree_model_get (model, &iter, | |||
| 1681 | KEYENTRY_COLUMN, &key, | |||
| 1682 | -1); | |||
| 1683 | ||||
| 1684 | if (key == NULL((void*)0)) | |||
| 1685 | { | |||
| 1686 | /* This is a section heading - expand or collapse */ | |||
| 1687 | if (ctk_tree_view_row_expanded (treeview, path)) | |||
| 1688 | ctk_tree_view_collapse_row (treeview, path); | |||
| 1689 | else | |||
| 1690 | ctk_tree_view_expand_row (treeview, path, FALSE(0)); | |||
| 1691 | return; | |||
| 1692 | } | |||
| 1693 | ||||
| 1694 | /* if only the accel can be edited on the selected row | |||
| 1695 | * always select the accel column */ | |||
| 1696 | if (key->desc_editable && | |||
| 1697 | column == ctk_tree_view_get_column (treeview, 0)) | |||
| 1698 | { | |||
| 1699 | ctk_widget_grab_focus (CTK_WIDGET (treeview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((treeview)), ((ctk_widget_get_type ()))))))); | |||
| 1700 | ctk_tree_view_set_cursor (treeview, path, | |||
| 1701 | ctk_tree_view_get_column (treeview, 0), | |||
| 1702 | FALSE(0)); | |||
| 1703 | update_custom_shortcut (model, &iter); | |||
| 1704 | } | |||
| 1705 | else | |||
| 1706 | { | |||
| 1707 | ctk_widget_grab_focus (CTK_WIDGET (treeview)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((treeview)), ((ctk_widget_get_type ()))))))); | |||
| 1708 | ctk_tree_view_set_cursor (treeview, | |||
| 1709 | path, | |||
| 1710 | ctk_tree_view_get_column (treeview, 1), | |||
| 1711 | TRUE(!(0))); | |||
| 1712 | } | |||
| 1713 | } | |||
| 1714 | ||||
| 1715 | static gboolean | |||
| 1716 | start_editing_cb (CtkTreeView *tree_view, | |||
| 1717 | CdkEventButton *event, | |||
| 1718 | gpointer user_data) | |||
| 1719 | { | |||
| 1720 | CtkTreePath *path; | |||
| 1721 | CtkTreeViewColumn *column; | |||
| 1722 | ||||
| 1723 | if ((event->window != ctk_tree_view_get_bin_window (tree_view)) || | |||
| 1724 | (event->type != CDK_2BUTTON_PRESS)) | |||
| 1725 | return FALSE(0); | |||
| 1726 | ||||
| 1727 | if (ctk_tree_view_get_path_at_pos (tree_view, | |||
| 1728 | (gint) event->x, | |||
| 1729 | (gint) event->y, | |||
| 1730 | &path, &column, | |||
| 1731 | NULL((void*)0), NULL((void*)0))) | |||
| 1732 | { | |||
| 1733 | IdleData *idle_data; | |||
| 1734 | CtkTreeModel *model; | |||
| 1735 | CtkTreeIter iter; | |||
| 1736 | KeyEntry *key; | |||
| 1737 | ||||
| 1738 | if (ctk_tree_path_get_depth (path) == 1) | |||
| 1739 | { | |||
| 1740 | ctk_tree_path_free (path); | |||
| 1741 | return FALSE(0); | |||
| 1742 | } | |||
| 1743 | ||||
| 1744 | model = ctk_tree_view_get_model (tree_view); | |||
| 1745 | ctk_tree_model_get_iter (model, &iter, path); | |||
| 1746 | ctk_tree_model_get (model, &iter, | |||
| 1747 | KEYENTRY_COLUMN, &key, | |||
| 1748 | -1); | |||
| 1749 | ||||
| 1750 | /* if only the accel can be edited on the selected row | |||
| 1751 | * always select the accel column */ | |||
| 1752 | if (key->desc_editable && | |||
| 1753 | column == ctk_tree_view_get_column (tree_view, 0)) | |||
| 1754 | { | |||
| 1755 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); | |||
| 1756 | ctk_tree_view_set_cursor (tree_view, path, | |||
| 1757 | ctk_tree_view_get_column (tree_view, 0), | |||
| 1758 | FALSE(0)); | |||
| 1759 | update_custom_shortcut (model, &iter); | |||
| 1760 | } | |||
| 1761 | else | |||
| 1762 | { | |||
| 1763 | idle_data = g_new (IdleData, 1)((IdleData *) g_malloc_n ((1), sizeof (IdleData))); | |||
| 1764 | idle_data->tree_view = tree_view; | |||
| 1765 | idle_data->path = path; | |||
| 1766 | idle_data->column = key->desc_editable ? column : | |||
| 1767 | ctk_tree_view_get_column (tree_view, 1); | |||
| 1768 | g_idle_add ((GSourceFunc) real_start_editing_cb, idle_data); | |||
| 1769 | block_accels = TRUE(!(0)); | |||
| 1770 | } | |||
| 1771 | g_signal_stop_emission_by_name (tree_view, "button_press_event"); | |||
| 1772 | } | |||
| 1773 | return TRUE(!(0)); | |||
| 1774 | } | |||
| 1775 | ||||
| 1776 | /* this handler is used to keep accels from activating while the user | |||
| 1777 | * is assigning a new shortcut so that he won't accidentally trigger one | |||
| 1778 | * of the widgets */ | |||
| 1779 | static gboolean maybe_block_accels(CtkWidget* widget, CdkEventKey* event, gpointer user_data) | |||
| 1780 | { | |||
| 1781 | if (block_accels) | |||
| 1782 | { | |||
| 1783 | return ctk_window_propagate_key_event(CTK_WINDOW(widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_window_get_type ())))))), event); | |||
| 1784 | } | |||
| 1785 | ||||
| 1786 | return FALSE(0); | |||
| 1787 | } | |||
| 1788 | ||||
| 1789 | static void | |||
| 1790 | cb_dialog_response (CtkWidget *widget, gint response_id, gpointer data) | |||
| 1791 | { | |||
| 1792 | CtkBuilder *builder = data; | |||
| 1793 | CtkTreeView *treeview; | |||
| 1794 | CtkTreeModel *model; | |||
| 1795 | CtkTreeSelection *selection; | |||
| 1796 | CtkTreeIter iter; | |||
| 1797 | ||||
| 1798 | treeview = CTK_TREE_VIEW (ctk_builder_get_object (builder,((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ())))))) | |||
| 1799 | "shortcut_treeview"))((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ())))))); | |||
| 1800 | model = ctk_tree_view_get_model (treeview); | |||
| 1801 | ||||
| 1802 | if (response_id == CTK_RESPONSE_HELP) | |||
| ||||
| 1803 | { | |||
| 1804 | capplet_help (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_window_get_type ())))))), | |||
| 1805 | "goscustdesk-39"); | |||
| 1806 | } | |||
| 1807 | else if (response_id == RESPONSE_ADD0) | |||
| 1808 | { | |||
| 1809 | add_custom_shortcut (treeview, model); | |||
| 1810 | } | |||
| 1811 | else if (response_id == RESPONSE_REMOVE1) | |||
| 1812 | { | |||
| 1813 | selection = ctk_tree_view_get_selection (treeview); | |||
| 1814 | if (ctk_tree_selection_get_selected (selection, NULL((void*)0), &iter)) | |||
| 1815 | { | |||
| 1816 | remove_custom_shortcut (model, &iter); | |||
| 1817 | } | |||
| 1818 | } | |||
| 1819 | else | |||
| 1820 | { | |||
| 1821 | clear_old_model (builder); | |||
| 1822 | ctk_main_quit (); | |||
| 1823 | } | |||
| 1824 | } | |||
| 1825 | ||||
| 1826 | static void | |||
| 1827 | selection_changed (CtkTreeSelection *selection, gpointer data) | |||
| 1828 | { | |||
| 1829 | CtkWidget *button = data; | |||
| 1830 | CtkTreeModel *model; | |||
| 1831 | CtkTreeIter iter; | |||
| 1832 | KeyEntry *key; | |||
| 1833 | gboolean can_remove; | |||
| 1834 | ||||
| 1835 | can_remove = FALSE(0); | |||
| 1836 | if (ctk_tree_selection_get_selected (selection, &model, &iter)) | |||
| 1837 | { | |||
| 1838 | ctk_tree_model_get (model, &iter, KEYENTRY_COLUMN, &key, -1); | |||
| 1839 | if (key && key->command != NULL((void*)0) && key->editable) | |||
| 1840 | can_remove = TRUE(!(0)); | |||
| 1841 | } | |||
| 1842 | ||||
| 1843 | ctk_widget_set_sensitive (button, can_remove); | |||
| 1844 | } | |||
| 1845 | ||||
| 1846 | static void | |||
| 1847 | cb_app_dialog_response (CtkWidget *dialog, gint response_id, gpointer data) | |||
| 1848 | { | |||
| 1849 | if (response_id == CTK_RESPONSE_OK) | |||
| 1850 | { | |||
| 1851 | GAppInfo *info; | |||
| 1852 | const gchar *custom_name; | |||
| 1853 | ||||
| 1854 | info = ctk_app_chooser_get_app_info (CTK_APP_CHOOSER (dialog)((((CtkAppChooser*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dialog)), ((ctk_app_chooser_get_type ()))))))); | |||
| 1855 | ||||
| 1856 | ctk_entry_set_text (CTK_ENTRY (custom_shortcut_command_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_command_entry)), ((ctk_entry_get_type () )))))), | |||
| 1857 | g_app_info_get_executable (info)); | |||
| 1858 | /* if name isn't set yet, use the associated one */ | |||
| 1859 | custom_name = ctk_entry_get_text (CTK_ENTRY (custom_shortcut_name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_name_entry)), ((ctk_entry_get_type ()))) )))); | |||
| 1860 | if (! custom_name || custom_name[0] == '\0') | |||
| 1861 | ctk_entry_set_text (CTK_ENTRY (custom_shortcut_name_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_name_entry)), ((ctk_entry_get_type ()))) ))), | |||
| 1862 | g_app_info_get_display_name (info)); | |||
| 1863 | ||||
| 1864 | g_object_unref (info); | |||
| 1865 | } | |||
| 1866 | ||||
| 1867 | ctk_widget_hide (dialog); | |||
| 1868 | } | |||
| 1869 | ||||
| 1870 | static void | |||
| 1871 | setup_dialog (CtkBuilder *builder, GSettings *croma_settings) | |||
| 1872 | { | |||
| 1873 | CtkCellRenderer *renderer; | |||
| 1874 | CtkTreeViewColumn *column; | |||
| 1875 | CtkWidget *widget; | |||
| 1876 | CtkTreeView *treeview; | |||
| 1877 | CtkTreeSelection *selection; | |||
| 1878 | CtkWidget *button; | |||
| 1879 | ||||
| 1880 | treeview = CTK_TREE_VIEW (ctk_builder_get_object (builder,((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ())))))) | |||
| 1881 | "shortcut_treeview"))((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((ctk_builder_get_object (builder, "shortcut_treeview"))), ((ctk_tree_view_get_type ())))))); | |||
| 1882 | ||||
| 1883 | g_signal_connect (treeview, "button_press_event",g_signal_connect_data ((treeview), ("button_press_event"), (( (GCallback) (start_editing_cb))), (builder), ((void*)0), (GConnectFlags ) 0) | |||
| 1884 | G_CALLBACK (start_editing_cb), builder)g_signal_connect_data ((treeview), ("button_press_event"), (( (GCallback) (start_editing_cb))), (builder), ((void*)0), (GConnectFlags ) 0); | |||
| 1885 | g_signal_connect (treeview, "row-activated",g_signal_connect_data ((treeview), ("row-activated"), (((GCallback ) (start_editing_kb_cb))), (((void*)0)), ((void*)0), (GConnectFlags ) 0) | |||
| 1886 | G_CALLBACK (start_editing_kb_cb), NULL)g_signal_connect_data ((treeview), ("row-activated"), (((GCallback ) (start_editing_kb_cb))), (((void*)0)), ((void*)0), (GConnectFlags ) 0); | |||
| 1887 | ||||
| 1888 | renderer = ctk_cell_renderer_text_new (); | |||
| 1889 | ||||
| 1890 | g_signal_connect (renderer, "edited",g_signal_connect_data ((renderer), ("edited"), (((GCallback) ( description_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1891 | G_CALLBACK (description_edited_callback),g_signal_connect_data ((renderer), ("edited"), (((GCallback) ( description_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1892 | treeview)g_signal_connect_data ((renderer), ("edited"), (((GCallback) ( description_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0); | |||
| 1893 | ||||
| 1894 | column = ctk_tree_view_column_new_with_attributes (_("Action")gettext ("Action"), | |||
| 1895 | renderer, | |||
| 1896 | "text", DESCRIPTION_COLUMN, | |||
| 1897 | NULL((void*)0)); | |||
| 1898 | ctk_tree_view_column_set_cell_data_func (column, renderer, description_set_func, NULL((void*)0), NULL((void*)0)); | |||
| 1899 | ctk_tree_view_column_set_resizable (column, FALSE(0)); | |||
| 1900 | ||||
| 1901 | ctk_tree_view_append_column (treeview, column); | |||
| 1902 | ctk_tree_view_column_set_sort_column_id (column, DESCRIPTION_COLUMN); | |||
| 1903 | ||||
| 1904 | renderer = (CtkCellRenderer *) g_object_new (EGG_TYPE_CELL_RENDERER_KEYS(egg_cell_renderer_keys_get_type ()), | |||
| 1905 | "accel_mode", EGG_CELL_RENDERER_KEYS_MODE_X, | |||
| 1906 | NULL((void*)0)); | |||
| 1907 | ||||
| 1908 | g_signal_connect (renderer, "accel_edited",g_signal_connect_data ((renderer), ("accel_edited"), (((GCallback ) (accel_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1909 | G_CALLBACK (accel_edited_callback),g_signal_connect_data ((renderer), ("accel_edited"), (((GCallback ) (accel_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1910 | treeview)g_signal_connect_data ((renderer), ("accel_edited"), (((GCallback ) (accel_edited_callback))), (treeview), ((void*)0), (GConnectFlags ) 0); | |||
| 1911 | ||||
| 1912 | g_signal_connect (renderer, "accel_cleared",g_signal_connect_data ((renderer), ("accel_cleared"), (((GCallback ) (accel_cleared_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1913 | G_CALLBACK (accel_cleared_callback),g_signal_connect_data ((renderer), ("accel_cleared"), (((GCallback ) (accel_cleared_callback))), (treeview), ((void*)0), (GConnectFlags ) 0) | |||
| 1914 | treeview)g_signal_connect_data ((renderer), ("accel_cleared"), (((GCallback ) (accel_cleared_callback))), (treeview), ((void*)0), (GConnectFlags ) 0); | |||
| 1915 | ||||
| 1916 | column = ctk_tree_view_column_new_with_attributes (_("Shortcut")gettext ("Shortcut"), renderer, NULL((void*)0)); | |||
| 1917 | ctk_tree_view_column_set_cell_data_func (column, renderer, accel_set_func, NULL((void*)0), NULL((void*)0)); | |||
| 1918 | ctk_tree_view_column_set_resizable (column, FALSE(0)); | |||
| 1919 | ||||
| 1920 | ctk_tree_view_append_column (treeview, column); | |||
| 1921 | ctk_tree_view_column_set_sort_column_id (column, KEYENTRY_COLUMN); | |||
| 1922 | ||||
| 1923 | g_signal_connect (croma_settings,g_signal_connect_data ((croma_settings), ("changed::num-workspaces" ), (((GCallback) (key_entry_controlling_key_changed))), (builder ), ((void*)0), (GConnectFlags) 0) | |||
| 1924 | "changed::num-workspaces",g_signal_connect_data ((croma_settings), ("changed::num-workspaces" ), (((GCallback) (key_entry_controlling_key_changed))), (builder ), ((void*)0), (GConnectFlags) 0) | |||
| 1925 | G_CALLBACK (key_entry_controlling_key_changed),g_signal_connect_data ((croma_settings), ("changed::num-workspaces" ), (((GCallback) (key_entry_controlling_key_changed))), (builder ), ((void*)0), (GConnectFlags) 0) | |||
| 1926 | builder)g_signal_connect_data ((croma_settings), ("changed::num-workspaces" ), (((GCallback) (key_entry_controlling_key_changed))), (builder ), ((void*)0), (GConnectFlags) 0); | |||
| 1927 | ||||
| 1928 | /* set up the dialog */ | |||
| 1929 | reload_key_entries (builder); | |||
| 1930 | ||||
| 1931 | widget = _ctk_builder_get_widget (builder, "cafe-keybinding-dialog"); | |||
| 1932 | ctk_window_set_default_size (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_window_get_type ())))))), 400, 500); | |||
| 1933 | widget = _ctk_builder_get_widget (builder, "label-suggest"); | |||
| 1934 | ctk_label_set_line_wrap (CTK_LABEL (widget)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_label_get_type ())))))), TRUE(!(0))); | |||
| 1935 | ctk_label_set_max_width_chars (CTK_LABEL (widget)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_label_get_type ())))))), 60); | |||
| 1936 | ||||
| 1937 | widget = _ctk_builder_get_widget (builder, "cafe-keybinding-dialog"); | |||
| 1938 | capplet_set_icon (widget, "preferences-desktop-keyboard-shortcuts"); | |||
| 1939 | ctk_widget_show (widget); | |||
| 1940 | ||||
| 1941 | g_signal_connect (widget, "key_press_event", G_CALLBACK (maybe_block_accels), NULL)g_signal_connect_data ((widget), ("key_press_event"), (((GCallback ) (maybe_block_accels))), (((void*)0)), ((void*)0), (GConnectFlags ) 0); | |||
| 1942 | g_signal_connect (widget, "response", G_CALLBACK (cb_dialog_response), builder)g_signal_connect_data ((widget), ("response"), (((GCallback) ( cb_dialog_response))), (builder), ((void*)0), (GConnectFlags) 0); | |||
| 1943 | ||||
| 1944 | selection = ctk_tree_view_get_selection (CTK_TREE_VIEW (treeview)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((treeview)), ((ctk_tree_view_get_type ()))))))); | |||
| 1945 | g_signal_connect (selection, "changed",g_signal_connect_data ((selection), ("changed"), (((GCallback ) (selection_changed))), (_ctk_builder_get_widget (builder, "remove-button" )), ((void*)0), (GConnectFlags) 0) | |||
| 1946 | G_CALLBACK (selection_changed),g_signal_connect_data ((selection), ("changed"), (((GCallback ) (selection_changed))), (_ctk_builder_get_widget (builder, "remove-button" )), ((void*)0), (GConnectFlags) 0) | |||
| 1947 | _ctk_builder_get_widget (builder, "remove-button"))g_signal_connect_data ((selection), ("changed"), (((GCallback ) (selection_changed))), (_ctk_builder_get_widget (builder, "remove-button" )), ((void*)0), (GConnectFlags) 0); | |||
| 1948 | ||||
| 1949 | /* setup the custom shortcut dialog */ | |||
| 1950 | custom_shortcut_dialog = _ctk_builder_get_widget (builder, | |||
| 1951 | "custom-shortcut-dialog"); | |||
| 1952 | custom_shortcut_name_entry = _ctk_builder_get_widget (builder, | |||
| 1953 | "custom-shortcut-name-entry"); | |||
| 1954 | custom_shortcut_command_entry = _ctk_builder_get_widget (builder, | |||
| 1955 | "custom-shortcut-command-entry"); | |||
| 1956 | ctk_dialog_set_default_response (CTK_DIALOG (custom_shortcut_dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_dialog)), ((ctk_dialog_get_type ())))))), | |||
| 1957 | CTK_RESPONSE_OK); | |||
| 1958 | ctk_window_set_transient_for (CTK_WINDOW (custom_shortcut_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((custom_shortcut_dialog)), ((ctk_window_get_type ())))))), | |||
| 1959 | CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_window_get_type ()))))))); | |||
| 1960 | button = _ctk_builder_get_widget (builder, "custom-shortcut-command-button"); | |||
| 1961 | widget = _ctk_builder_get_widget (builder, "custom-shortcut-application-dialog"); | |||
| 1962 | g_signal_connect_swapped (button, "clicked", G_CALLBACK (ctk_dialog_run), widget)g_signal_connect_data ((button), ("clicked"), (((GCallback) ( ctk_dialog_run))), (widget), ((void*)0), G_CONNECT_SWAPPED); | |||
| 1963 | g_signal_connect (widget, "response", G_CALLBACK (cb_app_dialog_response), NULL)g_signal_connect_data ((widget), ("response"), (((GCallback) ( cb_app_dialog_response))), (((void*)0)), ((void*)0), (GConnectFlags ) 0); | |||
| 1964 | widget = ctk_app_chooser_dialog_get_widget (CTK_APP_CHOOSER_DIALOG (widget)((((CtkAppChooserDialog*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((widget)), ((ctk_app_chooser_dialog_get_type ()))))))); | |||
| 1965 | ctk_app_chooser_widget_set_show_all (CTK_APP_CHOOSER_WIDGET (widget)((((CtkAppChooserWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((widget)), ((ctk_app_chooser_widget_get_type ())))))), TRUE(!(0))); | |||
| 1966 | } | |||
| 1967 | ||||
| 1968 | static void | |||
| 1969 | on_window_manager_change (const char *wm_name, CtkBuilder *builder) | |||
| 1970 | { | |||
| 1971 | reload_key_entries (builder); | |||
| 1972 | } | |||
| 1973 | ||||
| 1974 | int | |||
| 1975 | main (int argc, char *argv[]) | |||
| 1976 | { | |||
| 1977 | CtkBuilder *builder; | |||
| 1978 | GSettings *croma_settings; | |||
| 1979 | ||||
| 1980 | capplet_init (NULL((void*)0), &argc, &argv); | |||
| 1981 | ||||
| 1982 | activate_settings_daemon (); | |||
| 1983 | ||||
| 1984 | builder = create_builder (); | |||
| 1985 | ||||
| 1986 | if (!builder) /* Warning was already printed to console */ | |||
| 1987 | exit (EXIT_FAILURE1); | |||
| 1988 | ||||
| 1989 | wm_common_register_window_manager_change ((GFunc) on_window_manager_change, builder); | |||
| 1990 | ||||
| 1991 | croma_settings = g_settings_new ("org.cafe.Croma.general"); | |||
| 1992 | ||||
| 1993 | setup_dialog (builder, croma_settings); | |||
| 1994 | ||||
| 1995 | g_object_set (ctk_settings_get_default (), "ctk-button-images", TRUE(!(0)), NULL((void*)0)); | |||
| 1996 | ||||
| 1997 | ctk_main (); | |||
| 1998 | ||||
| 1999 | g_object_unref (croma_settings); | |||
| 2000 | g_object_unref (builder); | |||
| 2001 | return 0; | |||
| 2002 | } | |||
| 2003 | ||||
| 2004 | /* | |||
| 2005 | * vim: sw=2 ts=8 cindent noai bs=2 | |||
| 2006 | */ |