~kroq-gar78/ubuntu/precise/gnome-control-center/fix-885947

« back to all changes in this revision

Viewing changes to capplets/keyboard/gnome-keyboard-properties-xkblt.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2011-05-17 10:47:27 UTC
  • mfrom: (0.1.11 experimental) (1.1.45 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517104727-lqel6m8vhfw5jby1
Tags: 1:3.0.1.1-1ubuntu1
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Build-Depend on hardening-wrapper, dpkg-dev and dh-autoreconf
  - Add dependency on ubuntu-system-service
  - Remove dependency on gnome-icon-theme-symbolic
  - Move dependency on apg, gnome-icon-theme-symbolic and accountsservice to
    be a Recommends: until we get them in main
* debian/rules:
  - Use autoreconf
  - Add binary-post-install rule for gnome-control-center-data
  - Run dh-autoreconf
* debian/gnome-control-center.dirs:
* debian/gnome-control-center.links:
  - Add a link to the control center shell for indicators
* debian/patches/00_disable-nm.patch:
  - Temporary patch to disable building with NetworkManager until we get
    the new one in the archive
* debian/patches/01_git_remove_gettext_calls.patch:
  - Remove calls to AM_GNU_GETTEXT, IT_PROG_INTLTOOL should be enough
* debian/patches/01_git_kill_warning.patch:
  - Kill warning
* debian/patches/50_ubuntu_systemwide_prefs.patch:
  - Ubuntu specific proxy preferences
* debian/patches/51_ubuntu_system_keyboard.patch:
  - Implement the global keyboard spec at https://wiki.ubuntu.com/DefaultKeyboardSettings

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c; style: linux -*- */
2
 
 
3
 
/* gnome-keyboard-properties-xkblt.c
4
 
 * Copyright (C) 2003-2007 Sergey V. Udaltsov
5
 
 *
6
 
 * Written by: Sergey V. Udaltsov <svu@gnome.org>
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2, or (at your option)
11
 
 * any later version.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 * GNU General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program; if not, write to the Free Software
20
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
 
 * 02111-1307, USA.
22
 
 */
23
 
 
24
 
#ifdef HAVE_CONFIG_H
25
 
#  include <config.h>
26
 
#endif
27
 
 
28
 
#include <gdk/gdkx.h>
29
 
#include <gconf/gconf-client.h>
30
 
#include <glib/gi18n.h>
31
 
 
32
 
#include <libgnomekbd/gkbd-desktop-config.h>
33
 
#include <libgnomekbd/gkbd-keyboard-drawing.h>
34
 
 
35
 
#include "capplet-util.h"
36
 
#include "gnome-keyboard-properties-xkb.h"
37
 
 
38
 
 
39
 
#define SEL_LAYOUT_TREE_COL_DESCRIPTION 0
40
 
#define SEL_LAYOUT_TREE_COL_ID 1
41
 
#define SEL_LAYOUT_TREE_COL_ENABLED 2
42
 
 
43
 
static int idx2select = -1;
44
 
static int max_selected_layouts = -1;
45
 
static int default_group = -1;
46
 
 
47
 
static GtkCellRenderer *text_renderer;
48
 
 
49
 
static gboolean disable_buttons_sensibility_update = FALSE;
50
 
 
51
 
void
52
 
clear_xkb_elements_list (GSList * list)
53
 
{
54
 
        while (list != NULL) {
55
 
                GSList *p = list;
56
 
                list = list->next;
57
 
                g_free (p->data);
58
 
                g_slist_free_1 (p);
59
 
        }
60
 
}
61
 
 
62
 
static gint
63
 
find_selected_layout_idx (GtkBuilder * dialog)
64
 
{
65
 
        GtkTreeSelection *selection =
66
 
            gtk_tree_view_get_selection (GTK_TREE_VIEW
67
 
                                         (WID ("xkb_layouts_selected")));
68
 
        GtkTreeIter selected_iter;
69
 
        GtkTreeModel *model;
70
 
        GtkTreePath *path;
71
 
        gint *indices;
72
 
        gint rv;
73
 
 
74
 
        if (!gtk_tree_selection_get_selected
75
 
            (selection, &model, &selected_iter))
76
 
                return -1;
77
 
 
78
 
        path = gtk_tree_model_get_path (model, &selected_iter);
79
 
        if (path == NULL)
80
 
                return -1;
81
 
 
82
 
        indices = gtk_tree_path_get_indices (path);
83
 
        rv = indices[0];
84
 
        gtk_tree_path_free (path);
85
 
        return rv;
86
 
}
87
 
 
88
 
GSList *
89
 
xkb_layouts_get_selected_list (void)
90
 
{
91
 
        GSList *retval;
92
 
 
93
 
        retval = gconf_client_get_list (xkb_gconf_client,
94
 
                                        GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS,
95
 
                                        GCONF_VALUE_STRING, NULL);
96
 
        if (retval == NULL) {
97
 
                GSList *cur_layout;
98
 
 
99
 
                for (cur_layout = initial_config.layouts_variants;
100
 
                     cur_layout != NULL; cur_layout = cur_layout->next)
101
 
                        retval =
102
 
                            g_slist_prepend (retval,
103
 
                                             g_strdup (cur_layout->data));
104
 
 
105
 
                retval = g_slist_reverse (retval);
106
 
        }
107
 
 
108
 
        return retval;
109
 
}
110
 
 
111
 
gint
112
 
xkb_get_default_group ()
113
 
{
114
 
        return gconf_client_get_int (xkb_gconf_client,
115
 
                                     GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP,
116
 
                                     NULL);
117
 
}
118
 
 
119
 
void
120
 
xkb_save_default_group (gint default_group)
121
 
{
122
 
        if (default_group != xkb_get_default_group ())
123
 
                gconf_client_set_int (xkb_gconf_client,
124
 
                                      GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP,
125
 
                                      default_group, NULL);
126
 
}
127
 
 
128
 
static void
129
 
xkb_layouts_enable_disable_buttons (GtkBuilder * dialog)
130
 
{
131
 
        GtkWidget *add_layout_btn = WID ("xkb_layouts_add");
132
 
        GtkWidget *show_layout_btn = WID ("xkb_layouts_show");
133
 
        GtkWidget *del_layout_btn = WID ("xkb_layouts_remove");
134
 
        GtkWidget *selected_layouts_tree = WID ("xkb_layouts_selected");
135
 
        GtkWidget *move_up_layout_btn = WID ("xkb_layouts_move_up");
136
 
        GtkWidget *move_down_layout_btn = WID ("xkb_layouts_move_down");
137
 
 
138
 
        GtkTreeSelection *s_selection =
139
 
            gtk_tree_view_get_selection (GTK_TREE_VIEW
140
 
                                         (selected_layouts_tree));
141
 
        const int n_selected_selected_layouts =
142
 
            gtk_tree_selection_count_selected_rows (s_selection);
143
 
        GtkTreeModel *selected_layouts_model = gtk_tree_view_get_model
144
 
            (GTK_TREE_VIEW (selected_layouts_tree));
145
 
        const int n_selected_layouts =
146
 
            gtk_tree_model_iter_n_children (selected_layouts_model,
147
 
                                            NULL);
148
 
        gint sidx = find_selected_layout_idx (dialog);
149
 
 
150
 
        if (disable_buttons_sensibility_update)
151
 
                return;
152
 
 
153
 
        gtk_widget_set_sensitive (add_layout_btn,
154
 
                                  (n_selected_layouts <
155
 
                                   max_selected_layouts
156
 
                                   || max_selected_layouts == 0));
157
 
        gtk_widget_set_sensitive (del_layout_btn, (n_selected_layouts > 1)
158
 
                                  && (n_selected_selected_layouts > 0));
159
 
        gtk_widget_set_sensitive (show_layout_btn,
160
 
                                  (n_selected_selected_layouts > 0));
161
 
        gtk_widget_set_sensitive (move_up_layout_btn, sidx > 0);
162
 
        gtk_widget_set_sensitive (move_down_layout_btn, sidx >= 0
163
 
                                  && sidx < (n_selected_layouts - 1));
164
 
}
165
 
 
166
 
static void
167
 
xkb_layouts_dnd_data_get (GtkWidget * widget, GdkDragContext * dc,
168
 
                          GtkSelectionData * selection_data, guint info,
169
 
                          guint t, GtkBuilder * dialog)
170
 
{
171
 
        /* Storing the value into selection -
172
 
         * while it is actually not used
173
 
         */
174
 
        gint idx = find_selected_layout_idx (dialog);
175
 
        gtk_selection_data_set (selection_data,
176
 
                                GDK_SELECTION_TYPE_INTEGER, 32,
177
 
                                (guchar *) & idx, sizeof (idx));
178
 
}
179
 
 
180
 
static void
181
 
xkb_layouts_dnd_data_received (GtkWidget * widget, GdkDragContext * dc,
182
 
                               gint x, gint y,
183
 
                               GtkSelectionData * selection_data,
184
 
                               guint info, guint t, GtkBuilder * dialog)
185
 
{
186
 
        gint sidx = find_selected_layout_idx (dialog);
187
 
        GtkWidget *tree_view = WID ("xkb_layouts_selected");
188
 
        GtkTreePath *path = NULL;
189
 
        GtkTreeViewDropPosition pos;
190
 
        gint didx;
191
 
        gchar *id;
192
 
        GSList *layouts_list;
193
 
        GSList *node2Remove;
194
 
 
195
 
        if (sidx == -1)
196
 
                return;
197
 
 
198
 
        layouts_list = xkb_layouts_get_selected_list ();
199
 
        node2Remove = g_slist_nth (layouts_list, sidx);
200
 
 
201
 
        id = (gchar *) node2Remove->data;
202
 
        layouts_list = g_slist_delete_link (layouts_list, node2Remove);
203
 
 
204
 
        if (!gtk_tree_view_get_dest_row_at_pos
205
 
            (GTK_TREE_VIEW (tree_view), x, y, &path, &pos)) {
206
 
                /* Move to the very end */
207
 
                layouts_list =
208
 
                    g_slist_append (layouts_list, g_strdup (id));
209
 
                xkb_layouts_set_selected_list (layouts_list);
210
 
        } else if (path != NULL) {
211
 
                gint *indices = gtk_tree_path_get_indices (path);
212
 
                didx = indices[0];
213
 
                gtk_tree_path_free (path);
214
 
                /* Move to the new position */
215
 
                if (sidx != didx) {
216
 
                        layouts_list =
217
 
                            g_slist_insert (layouts_list, g_strdup (id),
218
 
                                            didx);
219
 
                        xkb_layouts_set_selected_list (layouts_list);
220
 
                }
221
 
        }
222
 
        g_free (id);
223
 
        clear_xkb_elements_list (layouts_list);
224
 
}
225
 
 
226
 
void
227
 
xkb_layouts_prepare_selected_tree (GtkBuilder * dialog,
228
 
                                   GConfChangeSet * changeset)
229
 
{
230
 
        GtkListStore *list_store =
231
 
            gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,
232
 
                                G_TYPE_BOOLEAN);
233
 
        GtkWidget *tree_view = WID ("xkb_layouts_selected");
234
 
        GtkTreeSelection *selection;
235
 
        GtkTargetEntry self_drag_target =
236
 
            { "xkb_layouts_selected", GTK_TARGET_SAME_WIDGET, 0 };
237
 
        GtkTreeViewColumn *desc_column;
238
 
 
239
 
        text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ());
240
 
 
241
 
        desc_column =
242
 
            gtk_tree_view_column_new_with_attributes (_("Layout"),
243
 
                                                      text_renderer,
244
 
                                                      "text",
245
 
                                                      SEL_LAYOUT_TREE_COL_DESCRIPTION,
246
 
                                                      "sensitive",
247
 
                                                      SEL_LAYOUT_TREE_COL_ENABLED,
248
 
                                                      NULL);
249
 
        selection =
250
 
            gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
251
 
 
252
 
        gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view),
253
 
                                 GTK_TREE_MODEL (list_store));
254
 
 
255
 
        gtk_tree_view_column_set_sizing (desc_column,
256
 
                                         GTK_TREE_VIEW_COLUMN_AUTOSIZE);
257
 
        gtk_tree_view_column_set_resizable (desc_column, TRUE);
258
 
        gtk_tree_view_column_set_expand (desc_column, TRUE);
259
 
 
260
 
        gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
261
 
                                     desc_column);
262
 
 
263
 
        g_signal_connect_swapped (G_OBJECT (selection), "changed",
264
 
                                  G_CALLBACK
265
 
                                  (xkb_layouts_enable_disable_buttons),
266
 
                                  dialog);
267
 
        max_selected_layouts = xkl_engine_get_max_num_groups (engine);
268
 
 
269
 
        /* Setting up DnD */
270
 
        gtk_drag_source_set (tree_view, GDK_BUTTON1_MASK,
271
 
                             &self_drag_target, 1, GDK_ACTION_MOVE);
272
 
        gtk_drag_source_set_icon_name (tree_view, "input-keyboard");
273
 
        gtk_drag_dest_set (tree_view, GTK_DEST_DEFAULT_ALL,
274
 
                           &self_drag_target, 1, GDK_ACTION_MOVE);
275
 
 
276
 
        g_signal_connect (G_OBJECT (tree_view), "drag_data_get",
277
 
                          G_CALLBACK (xkb_layouts_dnd_data_get), dialog);
278
 
        g_signal_connect (G_OBJECT (tree_view), "drag_data_received",
279
 
                          G_CALLBACK (xkb_layouts_dnd_data_received),
280
 
                          dialog);
281
 
}
282
 
 
283
 
gchar *
284
 
xkb_layout_description_utf8 (const gchar * visible)
285
 
{
286
 
        char *l, *sl, *v, *sv;
287
 
        if (gkbd_keyboard_config_get_descriptions
288
 
            (config_registry, visible, &sl, &l, &sv, &v))
289
 
                visible = gkbd_keyboard_config_format_full_layout (l, v);
290
 
        return g_strstrip (g_strdup (visible));
291
 
}
292
 
 
293
 
void
294
 
xkb_layouts_fill_selected_tree (GtkBuilder * dialog)
295
 
{
296
 
        GSList *layouts = xkb_layouts_get_selected_list ();
297
 
        GSList *cur_layout;
298
 
        GtkListStore *list_store =
299
 
            GTK_LIST_STORE (gtk_tree_view_get_model
300
 
                            (GTK_TREE_VIEW
301
 
                             (WID ("xkb_layouts_selected"))));
302
 
        int counter = 0;
303
 
 
304
 
        /* temporarily disable the buttons' status update */
305
 
        disable_buttons_sensibility_update = TRUE;
306
 
 
307
 
        gtk_list_store_clear (list_store);
308
 
 
309
 
        for (cur_layout = layouts; cur_layout != NULL;
310
 
             cur_layout = cur_layout->next, counter++) {
311
 
                GtkTreeIter iter;
312
 
                const char *visible = (char *) cur_layout->data;
313
 
                gchar *utf_visible = xkb_layout_description_utf8 (visible);
314
 
                gtk_list_store_append (list_store, &iter);
315
 
                gtk_list_store_set (list_store, &iter,
316
 
                                    SEL_LAYOUT_TREE_COL_DESCRIPTION,
317
 
                                    utf_visible,
318
 
                                    SEL_LAYOUT_TREE_COL_ID,
319
 
                                    cur_layout->data,
320
 
                                    SEL_LAYOUT_TREE_COL_ENABLED,
321
 
                                    counter < max_selected_layouts, -1);
322
 
                g_free (utf_visible);
323
 
        }
324
 
 
325
 
        clear_xkb_elements_list (layouts);
326
 
 
327
 
        /* enable the buttons' status update */
328
 
        disable_buttons_sensibility_update = FALSE;
329
 
 
330
 
        if (idx2select != -1) {
331
 
                GtkTreeSelection *selection =
332
 
                    gtk_tree_view_get_selection ((GTK_TREE_VIEW
333
 
                                                  (WID
334
 
                                                   ("xkb_layouts_selected"))));
335
 
                GtkTreePath *path =
336
 
                    gtk_tree_path_new_from_indices (idx2select, -1);
337
 
                gtk_tree_selection_select_path (selection, path);
338
 
                gtk_tree_path_free (path);
339
 
                idx2select = -1;
340
 
        } else {
341
 
                /* if there is nothing to select - just enable/disable the buttons,
342
 
                   otherwise it would be done by the selection change */
343
 
                xkb_layouts_enable_disable_buttons (dialog);
344
 
        }
345
 
}
346
 
 
347
 
static void
348
 
add_selected_layout (GtkWidget * button, GtkBuilder * dialog)
349
 
{
350
 
        xkb_layout_choose (dialog);
351
 
}
352
 
 
353
 
static void
354
 
show_selected_layout (GtkWidget * button, GtkBuilder * dialog)
355
 
{
356
 
        gint idx = find_selected_layout_idx (dialog);
357
 
 
358
 
        if (idx != -1) {
359
 
                GSList *layouts_list = xkb_layouts_get_selected_list ();
360
 
                const gchar *id = g_slist_nth_data (layouts_list, idx);
361
 
                char *descr = xkb_layout_description_utf8 (id);
362
 
                GtkWidget *parent = WID ("keyboard_dialog");
363
 
                GtkWidget *popup = gkbd_keyboard_drawing_new_dialog (idx, descr);
364
 
                gtk_widget_set_parent (popup, parent);
365
 
                clear_xkb_elements_list (layouts_list);
366
 
                g_free (descr);
367
 
        }
368
 
}
369
 
 
370
 
static void
371
 
remove_selected_layout (GtkWidget * button, GtkBuilder * dialog)
372
 
{
373
 
        gint idx = find_selected_layout_idx (dialog);
374
 
 
375
 
        if (idx != -1) {
376
 
                GSList *layouts_list = xkb_layouts_get_selected_list ();
377
 
                char *id = NULL;
378
 
                GSList *node2Remove = g_slist_nth (layouts_list, idx);
379
 
 
380
 
                layouts_list =
381
 
                    g_slist_remove_link (layouts_list, node2Remove);
382
 
 
383
 
                id = (char *) node2Remove->data;
384
 
                g_slist_free_1 (node2Remove);
385
 
                g_free (id);
386
 
 
387
 
                if (default_group > idx)
388
 
                        xkb_save_default_group (default_group - 1);
389
 
                else if (default_group == idx)
390
 
                        xkb_save_default_group (-1);
391
 
 
392
 
                xkb_layouts_set_selected_list (layouts_list);
393
 
                clear_xkb_elements_list (layouts_list);
394
 
        }
395
 
}
396
 
 
397
 
static void
398
 
move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog)
399
 
{
400
 
        gint idx = find_selected_layout_idx (dialog);
401
 
 
402
 
        if (idx != -1) {
403
 
                GSList *layouts_list = xkb_layouts_get_selected_list ();
404
 
                GSList *node2Remove = g_slist_nth (layouts_list, idx);
405
 
 
406
 
                layouts_list =
407
 
                    g_slist_remove_link (layouts_list, node2Remove);
408
 
                layouts_list =
409
 
                    g_slist_insert (layouts_list, node2Remove->data,
410
 
                                    idx - 1);
411
 
                g_slist_free_1 (node2Remove);
412
 
 
413
 
                idx2select = idx - 1;
414
 
                xkb_layouts_set_selected_list (layouts_list);
415
 
                clear_xkb_elements_list (layouts_list);
416
 
        }
417
 
}
418
 
 
419
 
static void
420
 
move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog)
421
 
{
422
 
        gint idx = find_selected_layout_idx (dialog);
423
 
 
424
 
        if (idx != -1) {
425
 
                GSList *layouts_list = xkb_layouts_get_selected_list ();
426
 
                GSList *node2Remove = g_slist_nth (layouts_list, idx);
427
 
 
428
 
                layouts_list =
429
 
                    g_slist_remove_link (layouts_list, node2Remove);
430
 
                layouts_list =
431
 
                    g_slist_insert (layouts_list, node2Remove->data,
432
 
                                    idx + 1);
433
 
                g_slist_free_1 (node2Remove);
434
 
 
435
 
                idx2select = idx + 1;
436
 
                xkb_layouts_set_selected_list (layouts_list);
437
 
                clear_xkb_elements_list (layouts_list);
438
 
        }
439
 
}
440
 
 
441
 
void
442
 
xkb_layouts_register_buttons_handlers (GtkBuilder * dialog)
443
 
{
444
 
        g_signal_connect (G_OBJECT (WID ("xkb_layouts_add")), "clicked",
445
 
                          G_CALLBACK (add_selected_layout), dialog);
446
 
        g_signal_connect (G_OBJECT (WID ("xkb_layouts_show")), "clicked",
447
 
                          G_CALLBACK (show_selected_layout), dialog);
448
 
        g_signal_connect (G_OBJECT (WID ("xkb_layouts_remove")), "clicked",
449
 
                          G_CALLBACK (remove_selected_layout), dialog);
450
 
        g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_up")),
451
 
                          "clicked", G_CALLBACK (move_up_selected_layout),
452
 
                          dialog);
453
 
        g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_down")),
454
 
                          "clicked",
455
 
                          G_CALLBACK (move_down_selected_layout), dialog);
456
 
}
457
 
 
458
 
static void
459
 
xkb_layouts_update_list (GConfClient * client,
460
 
                         guint cnxn_id, GConfEntry * entry,
461
 
                         GtkBuilder * dialog)
462
 
{
463
 
        xkb_layouts_fill_selected_tree (dialog);
464
 
        enable_disable_restoring (dialog);
465
 
}
466
 
 
467
 
void
468
 
xkb_layouts_register_gconf_listener (GtkBuilder * dialog)
469
 
{
470
 
        gconf_client_notify_add (xkb_gconf_client,
471
 
                                 GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS,
472
 
                                 (GConfClientNotifyFunc)
473
 
                                 xkb_layouts_update_list, dialog, NULL,
474
 
                                 NULL);
475
 
}