~ubuntu-branches/ubuntu/trusty/gcompris/trusty

« back to all changes in this revision

Viewing changes to src/gcompris/board_config.c

  • Committer: Bazaar Package Importer
  • Author(s): Yann Dirson
  • Date: 2006-12-15 23:08:17 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215230817-exr5ks1hd73s3tlk
Tags: 8.2.2-1
* New upstream bugfix release, fixes among other things the support for
  the version of gnucap shipped in etch.
* Add missing dependency on python-gtk2 (Closes: #396523).
* Removed reference to non-existent sound file from memory.c (upstream
  fix - impacts 8.2 as well).  
* Now suggests gnuchess, gnucap, and tuxpaint.
* Updated extended description for the main package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gcompris - board_config.c
 
2
 *
 
3
 * Time-stamp: <2006/08/21 23:27:57 bruno>
 
4
 *
 
5
 * Copyright (C) 2001 Pascal Georges
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 */
 
21
 
 
22
#include <string.h>
 
23
 
 
24
#include "gcompris.h"
 
25
 
 
26
#define COMBOBOX_COL_MAX 15
 
27
 
 
28
static GcomprisBoard *config_board;
 
29
 
 
30
void
 
31
gc_board_config_start(GcomprisBoard *aBoard, GcomprisProfile *aProfile)
 
32
{
 
33
 
 
34
  if (aBoard->plugin == NULL){
 
35
    g_warning("gc_board_config_start: board %s/%s is not initialised ? Hummmm...", aBoard->section,aBoard->name);
 
36
    return;
 
37
  }
 
38
 
 
39
  if (aBoard->plugin->config_start == NULL) {
 
40
    g_warning("Trying to configure board %s/%s without config_start", aBoard->section,aBoard->name);
 
41
    return;
 
42
  }
 
43
 
 
44
  config_board = aBoard;
 
45
 
 
46
  aBoard->plugin->config_start(aBoard, aProfile);
 
47
  return;
 
48
}
 
49
 
 
50
 
 
51
  
 
52
void
 
53
gc_board_config_stop()
 
54
{
 
55
  if (!config_board)
 
56
    return;
 
57
 
 
58
  config_board->plugin->config_stop();
 
59
 
 
60
  config_board = NULL;
 
61
  return;
 
62
}
 
63
 
 
64
static GtkWindow *conf_window = NULL;
 
65
static GtkVBox *main_conf_box = NULL;
 
66
static GHashTable *hash_conf = NULL;
 
67
static GcomprisConfCallback Confcallback = NULL;
 
68
static gchar *label_markup = NULL;
 
69
 
 
70
 
 
71
static void
 
72
check_key(gchar *key)
 
73
{
 
74
  if ((strcmp(key, "locale") == 0) ||
 
75
      (strcmp(key, "locale_sound") == 0) ||
 
76
      (strcmp(key, "wordlist") == 0))
 
77
    g_error(" Key %s forbiden ! Change !", key);
 
78
}
 
79
 
 
80
void
 
81
gc_board_conf_close (GtkDialog *dialog,
 
82
                     gpointer   user_data)
 
83
{
 
84
  gtk_object_destroy(GTK_OBJECT(dialog));
 
85
  g_hash_table_destroy (hash_conf);
 
86
  hash_conf = NULL;
 
87
 
 
88
  /* in case we close without response */
 
89
  if (Confcallback){
 
90
    Confcallback(NULL);
 
91
    Confcallback = NULL;
 
92
  }
 
93
 
 
94
  g_free(label_markup);
 
95
}
 
96
 
 
97
void
 
98
_response_board_conf (GtkButton *button,
 
99
                      gint arg1,
 
100
                      gpointer user_data)
 
101
{
 
102
 
 
103
  if (Confcallback){
 
104
 
 
105
    switch (arg1){
 
106
    case GTK_RESPONSE_APPLY:
 
107
      Confcallback(hash_conf);
 
108
      break;
 
109
    case GTK_RESPONSE_CANCEL:
 
110
      Confcallback(NULL);
 
111
      break;
 
112
    case GTK_RESPONSE_NONE:
 
113
      Confcallback(NULL);
 
114
      break;
 
115
    default:
 
116
      Confcallback(NULL);
 
117
      break;
 
118
    }
 
119
 
 
120
    Confcallback = NULL;
 
121
  }
 
122
 
 
123
  gc_board_conf_close (GTK_DIALOG(conf_window), NULL);
 
124
 
 
125
}
 
126
 
 
127
#ifdef XF86_VIDMODE
 
128
static GdkEventConfigure last_configure_event;
 
129
 
 
130
static gint
 
131
_conf_window_configured(GtkWindow *window,
 
132
                        GdkEventConfigure *event, gpointer param)
 
133
{
 
134
  gint new_x, new_y;
 
135
  double screen_width, screen_height;
 
136
  /* Because we call gtk_window_move, we cause a configure event. Filter out
 
137
     identical events to avoid looping. */
 
138
  if (memcmp(&last_configure_event, event, sizeof(GdkEventConfigure)))
 
139
  {
 
140
    gnome_canvas_get_scroll_region( GNOME_CANVAS( gtk_bin_get_child( GTK_BIN(
 
141
      gc_get_window()))), NULL, NULL, &screen_width, &screen_height);
 
142
    /* strange but gcompris.c sets the scrollheight to screen_height + 30 */
 
143
    screen_height -= 30;
 
144
    new_x = ((gint)screen_width - event->width) / 2;
 
145
    new_y = ((gint)screen_height - event->height) / 2;
 
146
    /* printf("screen %dx%d, window %dx%d, place %dx%d\n", (int)screen_width, (int)screen_height, event->width, event->height, new_x, new_y); */
 
147
    gtk_window_move (conf_window, new_x, new_y);
 
148
    memcpy(&last_configure_event, event, sizeof(GdkEventConfigure));
 
149
  }
 
150
 
 
151
  /* Act as if we aren't there / aren't hooked up */
 
152
  return FALSE;
 
153
}
 
154
#endif
 
155
 
 
156
GtkVBox *
 
157
gc_board_config_window_display(gchar *label, GcomprisConfCallback callback)
 
158
{
 
159
  GtkWidget *header;
 
160
 
 
161
  /* init static values or callbacks */
 
162
  Confcallback = callback;
 
163
  hash_conf = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 
164
  
 
165
  /* Creating a config window will cause our main window to loose focus,
 
166
     this tells the main window to ignore the next focus out event (and thus
 
167
     stay in fullscreen mode if we're fullscreen). */
 
168
  gc_ignore_next_focus_out();
 
169
 
 
170
  /* main configuration window */
 
171
  conf_window = \
 
172
    GTK_WINDOW(gtk_dialog_new_with_buttons ("GCompris",
 
173
                                            GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET(gc_board_get_current()->canvas))),
 
174
                                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 
175
                                            GTK_STOCK_CANCEL,
 
176
                                            GTK_RESPONSE_CANCEL,
 
177
                                            GTK_STOCK_APPLY,
 
178
                                            GTK_RESPONSE_APPLY,
 
179
                                            NULL));
 
180
  
 
181
 
 
182
  /* parameters */
 
183
#ifdef XF86_VIDMODE
 
184
  if (gc_prop_get()->fullscreen &&
 
185
      !gc_prop_get()->noxf86vm)   
 
186
    {
 
187
      memset(&last_configure_event, 0, sizeof(GdkEventConfigure));
 
188
      gtk_widget_add_events(GTK_WIDGET(conf_window), GDK_STRUCTURE_MASK);
 
189
      gtk_signal_connect (GTK_OBJECT (conf_window), "configure_event",
 
190
        GTK_SIGNAL_FUNC (_conf_window_configured), 0);
 
191
    }
 
192
  else
 
193
#endif
 
194
      gtk_window_set_position (conf_window,
 
195
                                   GTK_WIN_POS_CENTER_ALWAYS);
 
196
 
 
197
  gtk_widget_show(GTK_WIDGET(conf_window));
 
198
 
 
199
  GcomprisProperties *properties = gc_prop_get();
 
200
  if (properties->fullscreen && !properties->noxf86vm)
 
201
    if (gdk_pointer_grab(gc_get_window()->window, TRUE, 0,
 
202
                         gc_get_window()->window, NULL, GDK_CURRENT_TIME) !=
 
203
        GDK_GRAB_SUCCESS)
 
204
      g_warning("Pointer grab failed");
 
205
 
 
206
  /* main vbox in window */
 
207
  main_conf_box = GTK_VBOX(GTK_DIALOG(conf_window)->vbox);
 
208
 
 
209
  g_signal_connect(G_OBJECT(conf_window), 
 
210
                   "response",
 
211
                   G_CALLBACK(_response_board_conf),
 
212
                   NULL);
 
213
 
 
214
  g_signal_connect (G_OBJECT(conf_window),
 
215
                    "close",
 
216
                    G_CALLBACK(gc_board_conf_close),
 
217
                    NULL);
 
218
 
 
219
  
 
220
 
 
221
  /* Label header */
 
222
  header = gtk_label_new ((gchar *)NULL);
 
223
  gtk_widget_show(header);
 
224
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
225
                      header,
 
226
                      FALSE,
 
227
                      FALSE,
 
228
                      0);
 
229
 
 
230
  gtk_label_set_justify (GTK_LABEL(header),
 
231
                         GTK_JUSTIFY_CENTER);
 
232
  
 
233
  label_markup = g_strdup_printf("<span size='large'>%s</span>",label);
 
234
  gtk_label_set_markup (GTK_LABEL(header),
 
235
                        (const gchar *)label_markup);
 
236
 
 
237
  gc_board_conf_separator();
 
238
  
 
239
  return main_conf_box;
 
240
}
 
241
 
 
242
void 
 
243
gc_board_conf_boolean_box_toggled (GtkToggleButton *togglebutton,
 
244
                              gpointer key)
 
245
{
 
246
  gchar *the_key = g_strdup((gchar *)key);
 
247
  gchar *value;
 
248
  
 
249
  if (gtk_toggle_button_get_active (togglebutton))
 
250
    value = g_strdup("True");
 
251
  else
 
252
    value = g_strdup("False");
 
253
  
 
254
  g_hash_table_replace(hash_conf, (gpointer) the_key, (gpointer) value);
 
255
}
 
256
 
 
257
GtkCheckButton *
 
258
gc_board_config_boolean_box(const gchar *label, gchar *key, gboolean initial_value)
 
259
{
 
260
  check_key( key);
 
261
 
 
262
  GtkWidget *CheckBox = gtk_check_button_new_with_label (label);
 
263
 
 
264
  gtk_widget_show(CheckBox);
 
265
 
 
266
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
267
                      CheckBox,
 
268
                      FALSE,
 
269
                      FALSE,
 
270
                      0);
 
271
 
 
272
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(CheckBox),
 
273
                                initial_value);
 
274
 
 
275
  g_signal_connect   (G_OBJECT(CheckBox),
 
276
                      "toggled",
 
277
                      G_CALLBACK(gc_board_conf_boolean_box_toggled),
 
278
                      key);
 
279
 
 
280
  return GTK_CHECK_BUTTON(CheckBox);
 
281
}
 
282
 
 
283
/* code get from gtk */
 
284
/* included here to not depend on gtk 2.6 */
 
285
 
 
286
static gchar *
 
287
_get_active_text (GtkComboBox *combo_box)
 
288
{
 
289
  GtkTreeIter iter;
 
290
  gchar *text = NULL;
 
291
 
 
292
  g_return_val_if_fail (GTK_IS_LIST_STORE (gtk_combo_box_get_model (combo_box)), NULL);
 
293
 
 
294
  if (gtk_combo_box_get_active_iter (combo_box, &iter))
 
295
    gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter, 
 
296
                        0, &text, -1);
 
297
 
 
298
  return text;
 
299
}
 
300
 
 
301
static void
 
302
_combo_box_changed(GtkComboBox *combobox,
 
303
                   gpointer key)
 
304
{
 
305
  gchar *the_key = g_strdup((gchar *)key);
 
306
 
 
307
  gchar *value = g_strdup_printf("%s", _get_active_text (combobox));
 
308
  
 
309
  g_hash_table_replace(hash_conf, (gpointer) the_key, (gpointer) value);
 
310
}
 
311
 
 
312
static inline int my_strcmp(gchar *a, gchar *b) { return strcmp( a, b); }
 
313
 
 
314
 
 
315
GtkComboBox *gc_board_config_combo_box(const gchar *label, GList *strings, gchar *key, gchar *init)
 
316
{
 
317
  check_key( key);
 
318
 
 
319
  GtkWidget *combobox;
 
320
  GtkWidget *hbox = gtk_hbox_new (FALSE, 8);
 
321
  GList *list;
 
322
  GtkWidget *label_combo;
 
323
  gint init_index = 0;
 
324
 
 
325
  if (init)
 
326
    init_index =  g_list_position ( strings, g_list_find_custom ( strings,(gconstpointer)  init, (GCompareFunc) my_strcmp));
 
327
  
 
328
  if (init_index < 0)
 
329
    init_index=0;
 
330
 
 
331
  gtk_widget_show(hbox);
 
332
  
 
333
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
334
                      hbox,
 
335
                      FALSE,
 
336
                      FALSE,
 
337
                      0);
 
338
 
 
339
  /* Label */
 
340
  label_combo = gtk_label_new ((gchar *)NULL);
 
341
  gtk_widget_show(label_combo);
 
342
  gtk_box_pack_start (GTK_BOX(hbox),
 
343
                      label_combo,
 
344
                      FALSE,
 
345
                      FALSE,
 
346
                      0);
 
347
 
 
348
  gtk_label_set_justify (GTK_LABEL(label_combo),
 
349
                         GTK_JUSTIFY_RIGHT);
 
350
 
 
351
  gtk_label_set_markup (GTK_LABEL(label_combo),
 
352
                        (const gchar *)label);
 
353
 
 
354
 
 
355
  combobox = gtk_combo_box_new_text();
 
356
 
 
357
  gtk_widget_show(combobox);
 
358
 
 
359
  gtk_box_pack_start (GTK_BOX(hbox),
 
360
                      combobox,
 
361
                      FALSE,
 
362
                      FALSE,
 
363
                      0);
 
364
 
 
365
 
 
366
  for (list = strings; list != NULL; list = list->next)
 
367
    gtk_combo_box_append_text       (GTK_COMBO_BOX(combobox),
 
368
                                     list->data);
 
369
 
 
370
  if (g_list_length(strings) > COMBOBOX_COL_MAX)
 
371
    gtk_combo_box_set_wrap_width    (GTK_COMBO_BOX(combobox),
 
372
             g_list_length(strings) / COMBOBOX_COL_MAX +1 );
 
373
  
 
374
  gtk_combo_box_set_active (GTK_COMBO_BOX(combobox),
 
375
                            init_index);
 
376
  
 
377
  g_signal_connect(G_OBJECT(combobox),
 
378
                   "changed",
 
379
                   G_CALLBACK(_combo_box_changed),
 
380
                   key);
 
381
 
 
382
  return GTK_COMBO_BOX(combobox);
 
383
}
 
384
 
 
385
static GSList *radio_group = NULL;
 
386
static GtkWidget *radio_box;
 
387
static gchar *radio_key = NULL;
 
388
static gchar *radio_text = NULL;
 
389
static gchar *radio_init = NULL;
 
390
 
 
391
static void radio_changed(GtkToggleButton *togglebutton,
 
392
                          gpointer key)
 
393
{
 
394
  gboolean state = gtk_toggle_button_get_active (togglebutton);
 
395
  gchar *h_key;
 
396
  gchar *h_value;
 
397
 
 
398
  if (state){
 
399
    h_key = g_strdup (radio_key);
 
400
    h_value = g_strdup((gchar *) key);
 
401
    g_hash_table_replace (hash_conf, h_key, h_value);
 
402
  }
 
403
}
 
404
 
 
405
static void
 
406
create_radio_buttons(gpointer key,
 
407
                     gpointer value,
 
408
                     gpointer hash_radio)
 
409
{
 
410
  GtkWidget *radio_button;
 
411
  gchar *key_copy;
 
412
 
 
413
  radio_button = gtk_radio_button_new_with_label (radio_group,
 
414
                                                  (const gchar *) g_strdup(value));
 
415
 
 
416
  gtk_box_pack_start (GTK_BOX (radio_box), radio_button, TRUE, TRUE, 2);
 
417
  
 
418
  gtk_widget_show (GTK_WIDGET (radio_button));
 
419
  
 
420
  radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button));
 
421
  
 
422
  key_copy = g_strdup ((gchar *)key);
 
423
 
 
424
  if (strcmp( key_copy, radio_init)==0)
 
425
    gtk_toggle_button_set_active    (GTK_TOGGLE_BUTTON(radio_button),TRUE);
 
426
 
 
427
  g_signal_connect(G_OBJECT(radio_button), 
 
428
                   "toggled", 
 
429
                   G_CALLBACK(radio_changed), 
 
430
                   (gpointer) key_copy);
 
431
  
 
432
  g_hash_table_replace ( hash_radio, (gpointer) key_copy, (gpointer) radio_button);
 
433
}
 
434
 
 
435
static void
 
436
destroy_hash (GtkObject *object,
 
437
              gpointer hash_table)
 
438
{
 
439
  g_hash_table_destroy((GHashTable *)hash_table);
 
440
  radio_group = NULL;
 
441
  g_free(radio_text);
 
442
  g_free(radio_key);
 
443
  g_free(radio_init);
 
444
}
 
445
 
 
446
GHashTable *
 
447
gc_board_config_radio_buttons(const gchar *label,
 
448
                       gchar *key,
 
449
                       GHashTable *buttons_label,
 
450
                       gchar *init)
 
451
{
 
452
  check_key( key);
 
453
 
 
454
  GtkWidget *radio_label;
 
455
 
 
456
  GHashTable *buttons = g_hash_table_new_full (g_str_hash,
 
457
                                               g_str_equal,
 
458
                                               g_free,
 
459
                                               NULL);
 
460
 
 
461
  radio_box = gtk_vbox_new (TRUE, 2);
 
462
  gtk_widget_show (GTK_WIDGET (radio_box));
 
463
 
 
464
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
465
                      radio_box,
 
466
                      FALSE,
 
467
                      FALSE,
 
468
                      0);
 
469
 
 
470
  radio_label = gtk_label_new ((gchar *)NULL);
 
471
  gtk_widget_show(radio_label);
 
472
 
 
473
  gtk_box_pack_start (GTK_BOX(radio_box),
 
474
                      radio_label,
 
475
                      FALSE,
 
476
                      FALSE,
 
477
                      0);
 
478
 
 
479
  gtk_label_set_justify (GTK_LABEL(radio_label),
 
480
                         GTK_JUSTIFY_CENTER);
 
481
  
 
482
  radio_text = g_strdup(label);
 
483
  gtk_label_set_markup (GTK_LABEL(radio_label),
 
484
                        (const gchar *)radio_text);
 
485
 
 
486
  radio_key = g_strdup(key);
 
487
  radio_init = g_strdup(init);
 
488
 
 
489
  g_hash_table_foreach( buttons_label, 
 
490
                        (GHFunc) create_radio_buttons,
 
491
                        (gpointer) buttons);
 
492
 
 
493
  g_signal_connect (G_OBJECT(radio_box), "destroy", G_CALLBACK(destroy_hash), (gpointer) buttons);
 
494
 
 
495
  return buttons;
 
496
}
 
497
 
 
498
static void
 
499
spin_changed (GtkSpinButton *spinbutton,
 
500
              gpointer key)
 
501
{
 
502
  gchar *h_key = g_strdup((gchar *) key);
 
503
  gchar *h_value = g_strdup_printf("%d",gtk_spin_button_get_value_as_int (spinbutton));
 
504
 
 
505
  g_hash_table_replace (hash_conf, h_key, h_value);
 
506
}
 
507
 
 
508
GtkSpinButton *
 
509
gc_board_config_spin_int(const gchar *label, gchar *key, gint min, gint max, gint step, gint init)
 
510
{
 
511
  check_key( key);
 
512
 
 
513
  GtkWidget *spin;
 
514
  GtkWidget *hbox = gtk_hbox_new (FALSE, 8);
 
515
  GtkWidget *label_spin;
 
516
 
 
517
  gtk_widget_show(hbox);
 
518
 
 
519
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
520
                      hbox,
 
521
                      FALSE,
 
522
                      FALSE,
 
523
                      0);
 
524
 
 
525
  /* Label */
 
526
  label_spin = gtk_label_new ((gchar *)NULL);
 
527
  gtk_widget_show(label_spin);
 
528
  gtk_box_pack_start (GTK_BOX(hbox),
 
529
                      label_spin,
 
530
                      FALSE,
 
531
                      FALSE,
 
532
                      0);
 
533
 
 
534
  gtk_label_set_justify (GTK_LABEL(label_spin),
 
535
                         GTK_JUSTIFY_RIGHT);
 
536
 
 
537
  gtk_label_set_markup (GTK_LABEL(label_spin),
 
538
                        (const gchar *)label);
 
539
 
 
540
  spin = gtk_spin_button_new_with_range  ((gdouble )min,
 
541
                                          (gdouble )max,
 
542
                                          (gdouble )step);
 
543
  gtk_widget_show(spin);
 
544
  gtk_box_pack_start (GTK_BOX(hbox),
 
545
                      spin,
 
546
                      FALSE,
 
547
                      FALSE,
 
548
                      0);
 
549
 
 
550
  gtk_spin_button_set_wrap ( GTK_SPIN_BUTTON(spin), TRUE);
 
551
  gtk_spin_button_set_numeric ( GTK_SPIN_BUTTON(spin), TRUE);
 
552
  gtk_spin_button_set_digits ( GTK_SPIN_BUTTON(spin), 0);
 
553
 
 
554
  gtk_spin_button_set_value ( GTK_SPIN_BUTTON(spin), (gdouble) init);
 
555
 
 
556
  g_signal_connect (G_OBJECT(spin), 
 
557
                    "value-changed",
 
558
                    G_CALLBACK(spin_changed),
 
559
                    key);
 
560
 
 
561
  return GTK_SPIN_BUTTON(spin);
 
562
 
 
563
}
 
564
 
 
565
GtkHSeparator *
 
566
gc_board_conf_separator()
 
567
{
 
568
  GtkWidget *separator = gtk_hseparator_new ();
 
569
 
 
570
  gtk_widget_show(separator);
 
571
 
 
572
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
573
                      separator,
 
574
                      FALSE,
 
575
                      FALSE,
 
576
                      8);
 
577
 
 
578
  return GTK_HSEPARATOR(separator);
 
579
 
 
580
}
 
581
 
 
582
/***********************************************/
 
583
/* L10n                                        */
 
584
/***********************************************/
 
585
 
 
586
/** \brief return the list of locales in which GCompris has been translated
 
587
 *         even partialy.
 
588
 *
 
589
 * \note The list is calculated at the first call and must not be freed.
 
590
 *       Uppon next call, the same list is returned.
 
591
 *
 
592
 * \return a list containing the locales we suport
 
593
 */
 
594
GList*
 
595
gc_locale_gets_list(){
 
596
 
 
597
  static GList *gcompris_locales_list = NULL;
 
598
 
 
599
  GcomprisProperties *properties = gc_prop_get();
 
600
  GDir   *textdomain_dir;
 
601
  GError **error = NULL;
 
602
  GList  *locales = NULL;
 
603
 
 
604
  if(gcompris_locales_list)
 
605
    return(gcompris_locales_list);
 
606
 
 
607
  /* There is no english locale but it exists anyway */
 
608
  locales = g_list_append(locales, g_strdup("en"));
 
609
 
 
610
  textdomain_dir = g_dir_open (properties->package_locale_dir, 0, error);
 
611
  const gchar *fname;
 
612
  gchar *fname_abs;
 
613
  gchar *catalog;
 
614
  
 
615
  while ((fname = g_dir_read_name(textdomain_dir))) {
 
616
    fname_abs = g_strdup_printf("%s/%s", properties->package_locale_dir, fname);
 
617
    if (!g_file_test(fname_abs, G_FILE_TEST_IS_DIR))
 
618
      continue;
 
619
 
 
620
    catalog = g_strdup_printf("%s/LC_MESSAGES/gcompris.mo", fname_abs);
 
621
 
 
622
    if (g_file_test(catalog, G_FILE_TEST_EXISTS)){
 
623
      locales = g_list_append(locales, g_strdup(fname));
 
624
    }
 
625
    g_free (fname_abs);
 
626
    g_free(catalog);
 
627
  }
 
628
 
 
629
  g_dir_close (textdomain_dir);
 
630
 
 
631
  /* Save it for next call */
 
632
  gcompris_locales_list = locales;
 
633
 
 
634
  return locales;
 
635
}
 
636
 
 
637
 
 
638
void 
 
639
gc_board_config_combo_locales_changed(GtkComboBox *combobox,
 
640
                               gpointer key)
 
641
{
 
642
  gchar *the_key = g_strdup((gchar *)key);
 
643
  gchar *value;
 
644
  gint index = gtk_combo_box_get_active (combobox);
 
645
 
 
646
  if (index == 0)
 
647
    /* Default value of gcompris selected */
 
648
    value = g_strdup ("NULL");
 
649
  else
 
650
    value = _get_active_text (combobox);
 
651
 
 
652
  g_hash_table_replace(hash_conf, (gpointer) the_key, (gpointer) value);
 
653
}
 
654
 
 
655
/* key = "locale" */
 
656
GtkComboBox*
 
657
gc_board_config_combo_locales(gchar *init)
 
658
{
 
659
 
 
660
  GtkWidget *combobox;
 
661
  GtkWidget *hbox = gtk_hbox_new (FALSE, 8);
 
662
  GList *list, *strings;
 
663
  GtkWidget *label_combo;
 
664
  gint init_index = 0;
 
665
 
 
666
  strings = gc_locale_gets_list();
 
667
 
 
668
  strings = g_list_prepend( strings, _("Default"));
 
669
 
 
670
  if (init)
 
671
    init_index = g_list_position(strings,
 
672
                                 g_list_find_custom(strings,
 
673
                                                    (gconstpointer) init,
 
674
                                                    (GCompareFunc) my_strcmp));
 
675
 
 
676
  if (init_index < 0)
 
677
    init_index=0;
 
678
  
 
679
  gtk_widget_show(hbox);
 
680
  
 
681
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
682
                      hbox,
 
683
                      FALSE,
 
684
                      FALSE,
 
685
                      0);
 
686
 
 
687
  /* Label */
 
688
  label_combo = gtk_label_new ((gchar *)NULL);
 
689
  gtk_widget_show(label_combo);
 
690
  gtk_box_pack_start (GTK_BOX(hbox),
 
691
                      label_combo,
 
692
                      FALSE,
 
693
                      FALSE,
 
694
                      0);
 
695
 
 
696
  gtk_label_set_justify (GTK_LABEL(label_combo),
 
697
                         GTK_JUSTIFY_RIGHT);
 
698
 
 
699
  gtk_label_set_markup (GTK_LABEL(label_combo),
 
700
                        _("Select the language\n to use in the board"));
 
701
 
 
702
  combobox = gtk_combo_box_new_text();
 
703
 
 
704
  gtk_widget_show(combobox);
 
705
 
 
706
  gtk_box_pack_start (GTK_BOX(hbox),
 
707
                      combobox,
 
708
                      FALSE,
 
709
                      FALSE,
 
710
                      0);
 
711
 
 
712
 
 
713
  for (list = strings; list != NULL; list = list->next)
 
714
    gtk_combo_box_append_text       (GTK_COMBO_BOX(combobox),
 
715
                                     list->data);
 
716
 
 
717
  if (g_list_length(strings) > COMBOBOX_COL_MAX)
 
718
    gtk_combo_box_set_wrap_width    (GTK_COMBO_BOX(combobox),
 
719
             g_list_length(strings) / COMBOBOX_COL_MAX +1 );
 
720
  
 
721
  gtk_combo_box_set_active (GTK_COMBO_BOX(combobox),
 
722
                            init_index);
 
723
  
 
724
  g_signal_connect(G_OBJECT(combobox),
 
725
                   "changed",
 
726
                   G_CALLBACK(gc_board_config_combo_locales_changed),
 
727
                   "locale");
 
728
 
 
729
  return GTK_COMBO_BOX(combobox);
 
730
 
 
731
}
 
732
 
 
733
static gchar *current_locale = NULL;
 
734
void
 
735
gc_locale_change(gchar *locale)
 
736
{
 
737
  if (!locale)
 
738
    return;
 
739
 
 
740
  if (strcmp(locale, "NULL") == 0){
 
741
    gc_locale_reset();
 
742
    return;
 
743
  }
 
744
 
 
745
  current_locale = g_strdup(gc_locale_get());
 
746
 
 
747
  gc_locale_set(locale);
 
748
}
 
749
 
 
750
void
 
751
gc_locale_reset()
 
752
{
 
753
  if (current_locale == NULL)
 
754
    return;
 
755
 
 
756
  gc_locale_change(current_locale);
 
757
 
 
758
  g_free(current_locale);
 
759
  current_locale = NULL;
 
760
}
 
761
 
 
762
 
 
763
/** \brief Search the given file for each locale and returns the locale list
 
764
 *
 
765
 * \param file: the file to search. In order to work, you need to provide a
 
766
 *              filename that includes a $LOCALE in it like:
 
767
 *              sounds/$LOCALE/colors/blue.ogg
 
768
 *
 
769
 * \return a list of locale
 
770
 */
 
771
GList*
 
772
gc_locale_gets_asset_list(const gchar *filename)
 
773
{
 
774
  GList *locales, *list, *locales_asset = NULL;
 
775
  gchar *abs_filename;
 
776
 
 
777
  locales = gc_locale_gets_list();
 
778
 
 
779
  for (list = locales; list != NULL; list = list->next)
 
780
    { 
 
781
      gchar **tmp;
 
782
 
 
783
      /* Check there is a $LOCALE to replace */
 
784
      if((tmp = g_strsplit(filename, "$LOCALE", -1)))
 
785
        {
 
786
          gchar locale[6];
 
787
          gchar *filename2;
 
788
 
 
789
          /* try with the locale */
 
790
          g_strlcpy(locale, list->data, sizeof(locale));
 
791
          filename2 = g_strjoinv(locale, tmp);
 
792
          g_warning("trying locale file '%s'\n", filename2);
 
793
          abs_filename = gc_file_find_absolute(filename2);
 
794
          g_free(filename2);
 
795
 
 
796
          g_strfreev(tmp);
 
797
        }
 
798
      else
 
799
        {
 
800
          abs_filename = gc_file_find_absolute(filename);
 
801
        }
 
802
 
 
803
      if(abs_filename)
 
804
        /* It would be cleaner to provide the real locale name but then we need a way
 
805
         * to get back the locale code from it's name and from the boards
 
806
         *
 
807
         * locales_asset = g_list_append(locales_asset, gc_locale_get_name(list->data));
 
808
         *
 
809
         */
 
810
        locales_asset = g_list_append(locales_asset, list->data);
 
811
 
 
812
    }
 
813
  
 
814
 
 
815
  return locales_asset;
 
816
}
 
817
 
 
818
/* key = "locale_sound" */
 
819
GtkComboBox *gc_board_config_combo_locales_asset(const gchar *label,
 
820
                                          gchar *init,
 
821
                                          const gchar *file)
 
822
{
 
823
 
 
824
  GtkWidget *combobox;
 
825
  GtkWidget *hbox = gtk_hbox_new (FALSE, 8);
 
826
  GList *list, *strings;
 
827
  GtkWidget *label_combo;
 
828
  gint init_index = 0;
 
829
 
 
830
  strings = gc_locale_gets_asset_list(file);
 
831
 
 
832
  strings = g_list_prepend( strings, _("Default"));
 
833
 
 
834
  if (init)
 
835
    {
 
836
      init_index =  g_list_position(strings,
 
837
                                    g_list_find_custom(strings,
 
838
                                                       (gconstpointer)init,
 
839
                                                       (GCompareFunc) my_strcmp));
 
840
    }
 
841
 
 
842
  if (init_index < 0)
 
843
    init_index=0;
 
844
  
 
845
  gtk_widget_show(hbox);
 
846
  
 
847
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
848
                      hbox,
 
849
                      FALSE,
 
850
                      FALSE,
 
851
                      0);
 
852
 
 
853
  /* Label */
 
854
  label_combo = gtk_label_new ((gchar *)NULL);
 
855
  gtk_widget_show(label_combo);
 
856
  gtk_box_pack_start (GTK_BOX(hbox),
 
857
                      label_combo,
 
858
                      FALSE,
 
859
                      FALSE,
 
860
                      0);
 
861
 
 
862
  gtk_label_set_justify (GTK_LABEL(label_combo),
 
863
                         GTK_JUSTIFY_RIGHT);
 
864
 
 
865
  gtk_label_set_markup (GTK_LABEL(label_combo),
 
866
                        label);
 
867
 
 
868
  combobox = gtk_combo_box_new_text();
 
869
 
 
870
  gtk_widget_show(combobox);
 
871
 
 
872
  gtk_box_pack_start (GTK_BOX(hbox),
 
873
                      combobox,
 
874
                      FALSE,
 
875
                      FALSE,
 
876
                      0);
 
877
 
 
878
 
 
879
  for (list = strings; list != NULL; list = list->next)
 
880
    gtk_combo_box_append_text(GTK_COMBO_BOX(combobox),
 
881
                              list->data);
 
882
 
 
883
  if (g_list_length(strings) > COMBOBOX_COL_MAX)
 
884
    gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combobox),
 
885
                                 g_list_length(strings) / COMBOBOX_COL_MAX +1 );
 
886
  
 
887
  gtk_combo_box_set_active (GTK_COMBO_BOX(combobox),
 
888
                            init_index);
 
889
  
 
890
  g_signal_connect(G_OBJECT(combobox),
 
891
                   "changed",
 
892
                   G_CALLBACK(gc_board_config_combo_locales_changed),
 
893
                   "locale_sound");
 
894
 
 
895
  return GTK_COMBO_BOX(combobox);
 
896
 
 
897
}
 
898
 
 
899
/****************************************/
 
900
/* TextView                             */
 
901
 
 
902
typedef struct {
 
903
  gchar *key;
 
904
  GcomprisTextCallback callback;
 
905
  GtkLabel *feedback;
 
906
  GtkTextBuffer *TextBuffer;
 
907
} user_param_type;
 
908
 
 
909
static void *
 
910
_textview_destroy (GtkButton *button,
 
911
                   gpointer user_data)
 
912
{
 
913
  g_free(((user_param_type *)user_data)->key);
 
914
  g_free(user_data);
 
915
 
 
916
  return NULL;
 
917
}
 
918
 
 
919
 
 
920
static void *
 
921
_textbuffer_changed (GtkTextBuffer *buffer,
 
922
                     gpointer user_data)
 
923
{
 
924
  gtk_widget_set_sensitive        (GTK_WIDGET(user_data),
 
925
                                   TRUE);
 
926
 
 
927
  return NULL;
 
928
}
 
929
 
 
930
static void *
 
931
_textview_yes (GtkButton *button,
 
932
               gpointer user_data)
 
933
{
 
934
 
 
935
  user_param_type *params= (user_param_type *) user_data;
 
936
 
 
937
  gchar *key = params->key;
 
938
  GcomprisTextCallback validate = params->callback;
 
939
  GtkLabel *label = params->feedback;
 
940
  GtkTextBuffer *text_buffer = params->TextBuffer;
 
941
 
 
942
  GtkTextIter start_iter;
 
943
  GtkTextIter end_iter;
 
944
 
 
945
  gtk_text_buffer_get_start_iter  (text_buffer,
 
946
                                   &start_iter);
 
947
 
 
948
  gtk_text_buffer_get_end_iter  (text_buffer,
 
949
                                 &end_iter);
 
950
    
 
951
  /* has this to be freed ? */
 
952
  gchar *text = gtk_text_buffer_get_slice (text_buffer,
 
953
                                           &start_iter,
 
954
                                           &end_iter,
 
955
                                           TRUE);
 
956
 
 
957
  
 
958
 
 
959
  gchar *in_memoriam_text = g_strdup (text);
 
960
  gchar *in_memoriam_key = g_strdup (key);
 
961
 
 
962
  if (validate( key, text, label)){
 
963
    g_hash_table_replace ( hash_conf, (gpointer) in_memoriam_key, (gpointer) in_memoriam_text);
 
964
    gtk_widget_set_sensitive        (GTK_WIDGET(button),
 
965
                                     FALSE);
 
966
  }
 
967
  else {
 
968
    g_free (in_memoriam_text);
 
969
    g_free (in_memoriam_key);
 
970
  }
 
971
  g_free(text);
 
972
 
 
973
  return NULL;
 
974
}
 
975
 
 
976
GtkTextView *
 
977
gc_board_config_textview(const gchar *label, 
 
978
                  gchar *key,
 
979
                  const gchar*description, 
 
980
                  gchar *init_text, 
 
981
                  GcomprisTextCallback validate)
 
982
{
 
983
  GtkWidget*frame =  gtk_frame_new ("GCompris text tool");
 
984
  gtk_widget_show(frame);
 
985
 
 
986
  gtk_box_pack_start (GTK_BOX(main_conf_box),
 
987
                      frame,
 
988
                      FALSE,
 
989
                      FALSE,
 
990
                      8);
 
991
  
 
992
 
 
993
  
 
994
  /* Main vbox for all our widegt */
 
995
  GtkWidget *textVbox = gtk_vbox_new ( FALSE, 8);
 
996
  gtk_widget_show(textVbox);
 
997
 
 
998
  gtk_container_add(GTK_CONTAINER(frame),
 
999
                    textVbox);
 
1000
  /* Title */
 
1001
  GtkWidget *title = gtk_label_new ((gchar *)NULL);
 
1002
  gtk_widget_show(title);
 
1003
 
 
1004
  gtk_box_pack_start (GTK_BOX(textVbox),
 
1005
                      title,
 
1006
                      FALSE,
 
1007
                      FALSE,
 
1008
                      8);
 
1009
 
 
1010
  gtk_label_set_justify (GTK_LABEL(title),
 
1011
                         GTK_JUSTIFY_CENTER);
 
1012
  
 
1013
  gchar *title_text = g_strdup(label);
 
1014
  gtk_label_set_markup (GTK_LABEL(title),
 
1015
                        (const gchar *)title_text);
 
1016
 
 
1017
  GtkWidget *separator = gtk_hseparator_new ();
 
1018
 
 
1019
  gtk_widget_show(separator);
 
1020
 
 
1021
  gtk_box_pack_start (GTK_BOX(textVbox),
 
1022
                      separator,
 
1023
                      FALSE,
 
1024
                      FALSE,
 
1025
                      0);
 
1026
 
 
1027
  /* Description */
 
1028
  GtkWidget *desc = gtk_label_new ((gchar *)NULL);
 
1029
  gtk_widget_show(desc);
 
1030
 
 
1031
  gtk_box_pack_start (GTK_BOX(textVbox),
 
1032
                      desc,
 
1033
                      FALSE,
 
1034
                      FALSE,
 
1035
                      0);
 
1036
 
 
1037
  //gtk_label_set_justify (GTK_LABEL(title),
 
1038
  //             GTK_JUSTIFY_CENTER);
 
1039
 
 
1040
  gtk_label_set_line_wrap(GTK_LABEL(desc), TRUE);
 
1041
 
 
1042
  gchar *desc_text = g_strdup(description);
 
1043
  gtk_label_set_markup (GTK_LABEL(desc),
 
1044
                        (const gchar *)desc_text);
 
1045
 
 
1046
  GtkWidget *scroll = gtk_scrolled_window_new ( NULL, NULL);
 
1047
 
 
1048
  
 
1049
  gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW(scroll),
 
1050
                                   GTK_POLICY_AUTOMATIC,
 
1051
                                   GTK_POLICY_AUTOMATIC);
 
1052
 
 
1053
  gtk_widget_set_size_request     (scroll,
 
1054
                                   -1,
 
1055
                                   100);
 
1056
 
 
1057
  gtk_widget_show( scroll);
 
1058
 
 
1059
  gtk_box_pack_start (GTK_BOX(textVbox),
 
1060
                      scroll,
 
1061
                      FALSE,
 
1062
                      FALSE,
 
1063
                      0);
 
1064
 
 
1065
  /* TextView */
 
1066
  GtkWidget *textView = gtk_text_view_new ();
 
1067
  gtk_widget_show(textView);
 
1068
 
 
1069
  gtk_container_add (GTK_CONTAINER(scroll),
 
1070
                     textView);
 
1071
 
 
1072
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textView), GTK_WRAP_WORD_CHAR);
 
1073
 
 
1074
 
 
1075
  GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textView));
 
1076
 
 
1077
  gtk_text_buffer_set_text (buffer, g_strdup(init_text), -1);
 
1078
 
 
1079
 
 
1080
  /* hbox for feedback and validation button */
 
1081
  GtkWidget *validationHbox = gtk_vbox_new ( FALSE, 8);
 
1082
  gtk_widget_show(validationHbox);
 
1083
 
 
1084
  gtk_box_pack_start (GTK_BOX(textVbox),
 
1085
                      validationHbox,
 
1086
                      FALSE,
 
1087
                      FALSE,
 
1088
                      0);
 
1089
 
 
1090
  /* Feedback */
 
1091
  GtkWidget *feedback = gtk_label_new ((gchar *)NULL);
 
1092
  gtk_widget_show(feedback);
 
1093
 
 
1094
  gtk_box_pack_start (GTK_BOX(validationHbox),
 
1095
                      feedback,
 
1096
                      FALSE,
 
1097
                      FALSE,
 
1098
                      0);
 
1099
  
 
1100
  gtk_label_set_justify (GTK_LABEL(title),
 
1101
                         GTK_JUSTIFY_FILL);
 
1102
  
 
1103
  gtk_label_set_line_wrap(GTK_LABEL(feedback), TRUE);
 
1104
  
 
1105
  user_param_type *user_param = g_malloc0(sizeof(user_param_type));
 
1106
 
 
1107
  user_param->key = g_strdup(key);
 
1108
  user_param->callback = validate;
 
1109
  user_param->feedback = GTK_LABEL(feedback);
 
1110
  user_param->TextBuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(textView));
 
1111
 
 
1112
 
 
1113
  /* vbox for feedback and validation button */
 
1114
  GtkWidget *validationVbox = gtk_hbox_new ( FALSE, 8);
 
1115
  gtk_widget_show(validationVbox);
 
1116
 
 
1117
  gtk_box_pack_end (GTK_BOX(validationHbox),
 
1118
                    validationVbox,
 
1119
                    FALSE,
 
1120
                    FALSE,
 
1121
                    0);
 
1122
 
 
1123
 
 
1124
  /* Validate button */
 
1125
  GtkWidget *button =  gtk_button_new_from_stock (GTK_STOCK_YES);
 
1126
  gtk_widget_show(button);
 
1127
  gtk_box_pack_end (GTK_BOX(validationVbox),
 
1128
                    button,
 
1129
                    FALSE,
 
1130
                    FALSE,
 
1131
                    0);
 
1132
 
 
1133
  g_signal_connect(G_OBJECT(button), 
 
1134
                   "clicked",
 
1135
                   G_CALLBACK(_textview_yes),
 
1136
                   (gpointer) user_param);
 
1137
 
 
1138
 
 
1139
  g_signal_connect(G_OBJECT(button), 
 
1140
                   "destroy",
 
1141
                   G_CALLBACK(_textview_destroy),
 
1142
                   (gpointer) user_param);
 
1143
 
 
1144
  g_signal_connect(G_OBJECT(user_param->TextBuffer), 
 
1145
                   "changed",
 
1146
                   G_CALLBACK(_textbuffer_changed),
 
1147
                   (gpointer) button);
 
1148
 
 
1149
  gtk_widget_set_sensitive (button,
 
1150
                            FALSE);
 
1151
 
 
1152
  return GTK_TEXT_VIEW(textView);
 
1153
}