1
/* -*- mode: c; style: linux -*- */
3
/* gnome-keyboard-properties-xkbltadd.c
4
* Copyright (C) 2007 Sergey V. Udaltsov
6
* Written by: Sergey V. Udaltsov <svu@gnome.org>
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)
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.
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
30
#include <libgnomekbd/gkbd-keyboard-drawing.h>
31
#include <libgnomekbd/gkbd-util.h>
33
#include "capplet-util.h"
34
#include "gnome-keyboard-properties-xkb.h"
37
COMBO_BOX_MODEL_COL_SORT,
38
COMBO_BOX_MODEL_COL_VISIBLE,
39
COMBO_BOX_MODEL_COL_XKB_ID,
40
COMBO_BOX_MODEL_COL_REAL_ID
43
typedef void (*LayoutIterFunc) (XklConfigRegistry * config,
44
ConfigItemProcessFunc func, gpointer data);
47
GtkListStore *list_store;
61
xkb_layout_chooser_available_layouts_fill (GtkBuilder * chooser_dialog,
64
LayoutIterFunc layout_iterator,
67
GCallback combo_changed_notify);
79
xkb_layout_chooser_available_language_variants_fill (GtkBuilder *
92
xkb_layout_chooser_available_country_variants_fill (GtkBuilder *
96
xkb_layout_chooser_add_variant_to_available_country_variants
97
(XklConfigRegistry * config_registry,
98
XklConfigItem * parent_config_item, XklConfigItem * config_item,
99
AddVariantData * data) {
100
gchar *utf_variant_name = config_item ?
101
xkb_layout_description_utf8 (gkbd_keyboard_config_merge_items
102
(parent_config_item->name,
103
config_item->name)) :
104
xci_desc_to_utf8 (parent_config_item);
106
const gchar *xkb_id =
108
gkbd_keyboard_config_merge_items (parent_config_item->name,
110
parent_config_item->name;
112
if (config_item && g_object_get_data
113
(G_OBJECT (config_item), XCI_PROP_EXTRA_ITEM)) {
115
g_strdup_printf ("<i>%s</i>", utf_variant_name);
116
gtk_list_store_insert_with_values (data->list_store, &iter,
118
COMBO_BOX_MODEL_COL_SORT,
120
COMBO_BOX_MODEL_COL_VISIBLE,
122
COMBO_BOX_MODEL_COL_XKB_ID,
126
gtk_list_store_insert_with_values (data->list_store, &iter,
128
COMBO_BOX_MODEL_COL_SORT,
130
COMBO_BOX_MODEL_COL_VISIBLE,
132
COMBO_BOX_MODEL_COL_XKB_ID,
134
g_free (utf_variant_name);
138
xkb_layout_chooser_add_variant_to_available_language_variants
139
(XklConfigRegistry * config_registry,
140
XklConfigItem * parent_config_item, XklConfigItem * config_item,
141
AddVariantData * data) {
142
xkb_layout_chooser_add_variant_to_available_country_variants
143
(config_registry, parent_config_item, config_item, data);
147
xkb_layout_chooser_add_language_to_available_languages (XklConfigRegistry *
154
gtk_list_store_insert_with_values (list_store, NULL, -1,
155
COMBO_BOX_MODEL_COL_SORT,
156
config_item->description,
157
COMBO_BOX_MODEL_COL_VISIBLE,
158
config_item->description,
159
COMBO_BOX_MODEL_COL_REAL_ID,
160
config_item->name, -1);
164
xkb_layout_chooser_add_country_to_available_countries (XklConfigRegistry *
171
gtk_list_store_insert_with_values (list_store, NULL, -1,
172
COMBO_BOX_MODEL_COL_SORT,
173
config_item->description,
174
COMBO_BOX_MODEL_COL_VISIBLE,
175
config_item->description,
176
COMBO_BOX_MODEL_COL_REAL_ID,
177
config_item->name, -1);
181
xkb_layout_chooser_enable_disable_buttons (GtkBuilder * chooser_dialog)
184
CWID (gtk_notebook_get_current_page
185
(GTK_NOTEBOOK (CWID ("choosers_nb"))) ?
186
"xkb_language_variants_available" :
187
"xkb_country_variants_available");
190
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv),
193
gtk_dialog_set_response_sensitive (GTK_DIALOG
195
("xkb_layout_chooser")),
196
GTK_RESPONSE_OK, enable_ok);
197
gtk_widget_set_sensitive (CWID ("btnPrint"), enable_ok);
201
xkb_layout_chooser_available_variant_changed (GtkBuilder * chooser_dialog)
203
xkb_layout_preview_update (chooser_dialog);
204
xkb_layout_chooser_enable_disable_buttons (chooser_dialog);
208
xkb_layout_chooser_available_language_changed (GtkBuilder * chooser_dialog)
210
xkb_layout_chooser_available_language_variants_fill
212
xkb_layout_chooser_available_variant_changed (chooser_dialog);
216
xkb_layout_chooser_available_country_changed (GtkBuilder * chooser_dialog)
218
xkb_layout_chooser_available_country_variants_fill
220
xkb_layout_chooser_available_variant_changed (chooser_dialog);
224
xkb_layout_chooser_page_changed (GtkWidget * notebook, GtkWidget * page,
226
GtkBuilder * chooser_dialog)
228
xkb_layout_chooser_available_variant_changed (chooser_dialog);
232
xkb_layout_chooser_available_language_variants_fill (GtkBuilder *
235
GtkWidget *cbl = CWID ("xkb_languages_available");
236
GtkWidget *cbv = CWID ("xkb_language_variants_available");
237
GtkListStore *list_store;
240
list_store = gtk_list_store_new
241
(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
244
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbl), &liter)) {
246
gtk_combo_box_get_model (GTK_COMBO_BOX (cbl));
248
AddVariantData data = { list_store, 0 };
250
/* Now the variants of the selected layout */
251
gtk_tree_model_get (lm, &liter,
252
COMBO_BOX_MODEL_COL_REAL_ID,
254
data.lang_id = lang_id;
256
xkl_config_registry_foreach_language_variant
257
(config_registry, lang_id, (TwoConfigItemsProcessFunc)
258
xkb_layout_chooser_add_variant_to_available_language_variants,
263
/* Turn on sorting after filling the store, since that's faster */
264
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
266
COMBO_BOX_MODEL_COL_SORT,
269
gtk_combo_box_set_model (GTK_COMBO_BOX (cbv),
270
GTK_TREE_MODEL (list_store));
271
gtk_combo_box_set_active (GTK_COMBO_BOX (cbv), 0);
275
xkb_layout_chooser_available_country_variants_fill (GtkBuilder *
278
GtkWidget *cbl = CWID ("xkb_countries_available");
279
GtkWidget *cbv = CWID ("xkb_country_variants_available");
280
GtkListStore *list_store;
283
list_store = gtk_list_store_new
284
(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
287
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbl), &liter)) {
289
gtk_combo_box_get_model (GTK_COMBO_BOX (cbl));
291
AddVariantData data = { list_store, 0 };
293
/* Now the variants of the selected layout */
294
gtk_tree_model_get (lm, &liter,
295
COMBO_BOX_MODEL_COL_REAL_ID,
297
xkl_config_registry_foreach_country_variant
298
(config_registry, country_id,
299
(TwoConfigItemsProcessFunc)
300
xkb_layout_chooser_add_variant_to_available_country_variants,
305
/* Turn on sorting after filling the store, since that's faster */
306
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
308
COMBO_BOX_MODEL_COL_SORT,
311
gtk_combo_box_set_model (GTK_COMBO_BOX (cbv),
312
GTK_TREE_MODEL (list_store));
313
gtk_combo_box_set_active (GTK_COMBO_BOX (cbv), 0);
317
xkb_layout_chooser_available_layouts_fill (GtkBuilder *
321
LayoutIterFunc layout_iterator,
322
ConfigItemProcessFunc
324
GCallback combo_changed_notify)
326
GtkWidget *cbl = CWID (cblid);
327
GtkWidget *cbev = CWID (cbvid);
328
GtkCellRenderer *renderer;
329
GtkListStore *list_store;
331
list_store = gtk_list_store_new
332
(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
335
gtk_combo_box_set_model (GTK_COMBO_BOX (cbl),
336
GTK_TREE_MODEL (list_store));
338
renderer = gtk_cell_renderer_text_new ();
339
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbl), renderer, TRUE);
340
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbl),
342
COMBO_BOX_MODEL_COL_VISIBLE, NULL);
344
layout_iterator (config_registry, layout_handler, list_store);
346
/* Turn on sorting after filling the model since that's faster */
347
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
349
COMBO_BOX_MODEL_COL_SORT,
352
g_signal_connect_swapped (G_OBJECT (cbl), "changed",
353
combo_changed_notify, chooser_dialog);
355
/* Setup the variants combo */
356
renderer = gtk_cell_renderer_text_new ();
357
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbev),
359
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbev),
361
COMBO_BOX_MODEL_COL_VISIBLE, NULL);
363
g_signal_connect_swapped (G_OBJECT (cbev), "changed",
365
(xkb_layout_chooser_available_variant_changed),
370
xkl_layout_chooser_add_default_switcher_if_necessary (GSList *
373
GSList *options_list = xkb_options_get_selected_list ();
374
gboolean was_appended;
377
gkbd_keyboard_config_add_default_switch_option_if_necessary
378
(layouts_list, options_list, &was_appended);
380
xkb_options_set_selected_list (options_list);
381
clear_xkb_elements_list (options_list);
385
xkb_layout_chooser_print (GtkBuilder * chooser_dialog)
387
GtkWidget *chooser = CWID ("xkb_layout_chooser");
389
GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw"));
391
xkb_layout_chooser_get_selected_id (chooser_dialog);
392
char *descr = xkb_layout_description_utf8 (id);
393
gkbd_keyboard_drawing_print (GKBD_KEYBOARD_DRAWING
396
("xkb_layout_chooser")),
402
xkb_layout_chooser_response (GtkDialog * dialog,
403
gint response, GtkBuilder * chooser_dialog)
407
if (response == GTK_RESPONSE_OK) {
408
gchar *selected_id = (gchar *)
409
xkb_layout_chooser_get_selected_id (chooser_dialog);
411
if (selected_id != NULL) {
412
GSList *layouts_list =
413
xkb_layouts_get_selected_list ();
415
selected_id = g_strdup (selected_id);
418
g_slist_append (layouts_list, selected_id);
419
xkb_layouts_set_selected_list (layouts_list);
421
xkl_layout_chooser_add_default_switcher_if_necessary
424
clear_xkb_elements_list (layouts_list);
426
} else if (response == gtk_dialog_get_response_for_widget
427
(dialog, CWID ("btnPrint"))) {
428
xkb_layout_chooser_print (chooser_dialog);
429
g_signal_stop_emission_by_name (dialog, "response");
433
gtk_window_get_position (GTK_WINDOW (dialog), &rect.x, &rect.y);
434
gtk_window_get_size (GTK_WINDOW (dialog), &rect.width,
436
gkbd_preview_save_position (&rect);
440
xkb_layout_choose (GtkBuilder * dialog)
442
GtkBuilder *chooser_dialog;
444
chooser_dialog = gtk_builder_new ();
445
gtk_builder_add_from_file (chooser_dialog, GNOMECC_UI_DIR
446
"/gnome-keyboard-properties-layout-chooser.ui",
448
GtkWidget *chooser = CWID ("xkb_layout_chooser");
449
GtkWidget *lang_chooser = CWID ("xkb_languages_available");
450
GtkWidget *notebook = CWID ("choosers_nb");
451
GtkWidget *kbdraw = NULL;
452
GtkWidget *toplevel = NULL;
454
gtk_window_set_transient_for (GTK_WINDOW (chooser),
456
("keyboard_dialog")));
458
xkb_layout_chooser_available_layouts_fill (chooser_dialog,
459
"xkb_countries_available",
460
"xkb_country_variants_available",
461
xkl_config_registry_foreach_country,
462
(ConfigItemProcessFunc)
463
xkb_layout_chooser_add_country_to_available_countries,
465
(xkb_layout_chooser_available_country_changed));
466
xkb_layout_chooser_available_layouts_fill (chooser_dialog,
467
"xkb_languages_available",
468
"xkb_language_variants_available",
469
xkl_config_registry_foreach_language,
470
(ConfigItemProcessFunc)
471
xkb_layout_chooser_add_language_to_available_languages,
473
(xkb_layout_chooser_available_language_changed));
475
g_signal_connect_after (G_OBJECT (notebook), "switch_page",
477
(xkb_layout_chooser_page_changed),
480
gtk_combo_box_set_active (GTK_COMBO_BOX
481
(CWID ("xkb_countries_available")),
484
if (gtk_tree_model_iter_n_children
485
(gtk_combo_box_get_model (GTK_COMBO_BOX (lang_chooser)),
487
gtk_combo_box_set_active (GTK_COMBO_BOX
489
("xkb_languages_available")),
492
/* If language info is not available - remove the corresponding tab,
493
pretend there is no notebook at all */
494
gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), 1);
495
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook),
497
gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook),
501
#ifdef HAVE_X11_EXTENSIONS_XKB_H
502
if (!strcmp (xkl_engine_get_backend_name (engine), "XKB")) {
503
kbdraw = xkb_layout_preview_create_widget (chooser_dialog);
504
g_object_set_data (G_OBJECT (chooser), "kbdraw", kbdraw);
505
gtk_container_add (GTK_CONTAINER
506
(CWID ("previewFrame")), kbdraw);
507
gtk_widget_show_all (kbdraw);
508
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX
516
gtk_widget_hide_all (CWID ("vboxPreview"));
517
gtk_widget_hide (CWID ("btnPrint"));
520
g_signal_connect (G_OBJECT (chooser),
522
G_CALLBACK (xkb_layout_chooser_response),
525
toplevel = gtk_widget_get_toplevel (chooser);
526
if (gtk_widget_is_toplevel (toplevel)) {
527
GdkRectangle *rect = gkbd_preview_load_position ();
529
gtk_window_move (GTK_WINDOW (toplevel),
531
gtk_window_resize (GTK_WINDOW (toplevel),
532
rect->width, rect->height);
537
xkb_layout_preview_update (chooser_dialog);
538
gtk_dialog_run (GTK_DIALOG (chooser));
539
gtk_widget_destroy (chooser);
543
xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog)
546
CWID (gtk_notebook_get_current_page
547
(GTK_NOTEBOOK (CWID ("choosers_nb"))) ?
548
"xkb_language_variants_available" :
549
"xkb_country_variants_available");
550
GtkTreeModel *vm = gtk_combo_box_get_model (GTK_COMBO_BOX (cbv));
554
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (cbv), &viter))
557
gtk_tree_model_get (vm, &viter,
558
COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1);