8 #define _(String) dgettext (PACKAGE, String)
10 #define CURRENT_VALUE \
15 (minput_get_variable \
16 (current_lang, current_name, current_variable))))))
18 #define CURRENT_STATUS \
23 (minput_get_variable \
24 (current_lang, current_name, current_variable))))))
26 #define CURRENT_DESCRIPTION \
31 (minput_get_variable \
32 (current_lang, current_name, current_variable)))), \
33 NULL, NULL, NULL, NULL))
35 #define CONFIG_VARIABLE(plist) \
36 minput_config_variable (current_lang, current_name, current_variable, \
48 /* type of current variable: Minteger, Msymbol, or Mtext */
51 /* widget showing and controlling current variable */
55 enum WidgetType wtype;
57 /* whether minput_config_variable () should be called on ok button */
73 static MSymbol current_lang, current_name, current_variable;
76 update_widget (struct ControllerInfo *ci)
82 plist = CURRENT_VALUE;
83 /* plist == (value [valid-value ...]) */
84 key = mplist_key (plist);
85 value = mplist_value (plist);
87 if (ci->wtype == ENTRY_WIDGET)
90 gtk_entry_set_text (GTK_ENTRY (ci->widget),
91 msymbol_name ((MSymbol) value));
92 else if (key == Mtext)
93 /* Fixme : Assuming the return value is in UTF-8 */
94 gtk_entry_set_text (GTK_ENTRY (ci->widget),
95 mtext_data ((MText *) value,
96 NULL, NULL, NULL, NULL));
97 else /* key == Minteger */
100 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
101 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
104 else if (ci->wtype == COMBO_BOX_WIDGET)
108 for (i = 0, plist = mplist_next (plist);
109 plist && mplist_key (plist) == key;
110 i++, plist = mplist_next (plist))
111 if (mplist_value (plist) == value)
113 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), i);
115 else /* ci->wtype == SPIN_BUTTON_WIDGET */
116 gtk_spin_button_set_value (GTK_SPIN_BUTTON (ci->widget),
117 (gdouble) (int) value);
121 default_cb (GtkButton *button, gpointer data)
123 MPlist *empty = mplist ();
124 struct ControllerInfo *ci = data;
126 CONFIG_VARIABLE (empty);
127 m17n_object_unref (empty);
129 gtk_widget_set_sensitive (ci->default_, FALSE);
130 if (CURRENT_STATUS == Mconfigured)
132 gtk_widget_set_sensitive (ci->revert, TRUE);
133 gtk_label_set_text (GTK_LABEL (ci->status), _("modified"));
137 gtk_widget_set_sensitive (ci->revert, FALSE);
138 gtk_label_set_text (GTK_LABEL (ci->status), _("default"));
140 ci->need_config = FALSE;
144 revert_cb (GtkButton *button, gpointer data)
146 struct ControllerInfo *ci = data;
148 CONFIG_VARIABLE (NULL);
150 gtk_widget_set_sensitive (ci->revert, FALSE);
151 if (CURRENT_STATUS == Mnil)
153 gtk_widget_set_sensitive (ci->default_, FALSE);
154 gtk_label_set_text (GTK_LABEL (ci->status), _("default"));
158 gtk_widget_set_sensitive (ci->default_, TRUE);
159 gtk_label_set_text (GTK_LABEL (ci->status), _("customized"));
161 ci->need_config = FALSE;
165 config_with_entry (struct ControllerInfo *ci)
167 const gchar *text = gtk_entry_get_text (GTK_ENTRY (ci->widget));
168 MPlist *plist = mplist ();
171 if (ci->vtype == Msymbol)
173 mplist_add (plist, Msymbol, msymbol (text));
174 CONFIG_VARIABLE (plist);
176 else if (ci->vtype == Mtext)
180 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
181 mplist_add (plist, Mtext, mt);
182 CONFIG_VARIABLE (plist);
183 m17n_object_unref (mt);
185 else /* ci->vtype == Minteger */
190 if (sscanf (text, "%d", &i) == 1)
192 mplist_add (plist, Minteger, (void *) i);
193 CONFIG_VARIABLE (plist);
199 msg = gtk_message_dialog_new (GTK_WINDOW
200 (gtk_widget_get_toplevel (ci->dialog)),
201 GTK_DIALOG_DESTROY_WITH_PARENT,
204 _("The value must be an integer."));
205 gtk_dialog_run (GTK_DIALOG (msg));
206 gtk_widget_destroy (msg);
211 m17n_object_unref (plist);
216 config_with_combo (struct ControllerInfo *ci)
218 gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (ci->widget));
219 MPlist *plist = mplist ();
221 if (ci->vtype == Msymbol)
223 mplist_add (plist, Msymbol, msymbol (text));
224 CONFIG_VARIABLE (plist);
226 else if (ci->vtype == Mtext)
230 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
231 mplist_add (plist, Mtext, mt);
232 CONFIG_VARIABLE (plist);
233 m17n_object_unref (mt);
235 else /* ci->vtype == Minteger */
239 sscanf (text, "%d", &i);
240 mplist_add (plist, Minteger, (void *) i);
241 CONFIG_VARIABLE (plist);
243 m17n_object_unref (plist);
248 config_with_spin (struct ControllerInfo *ci)
252 i = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ci->widget));
253 MPlist *plist = mplist ();
255 mplist_add (plist, Minteger, (void *) i);
256 CONFIG_VARIABLE (plist);
257 m17n_object_unref (plist);
262 ok_cb (GtkButton *button, gpointer data)
264 struct ControllerInfo *ci = data;
268 if (ci->wtype == ENTRY_WIDGET)
270 if (config_with_entry (ci))
271 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
273 revert_cb (NULL, ci);
276 else if (ci->wtype == COMBO_BOX_WIDGET)
278 config_with_combo (ci); /* always returns true */
279 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
282 else /* ci->wtype == SPIN_BUTTON */
284 config_with_spin (ci); /* always returns true */
285 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
289 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
293 changed_cb (GtkEntry *entry, gpointer data)
295 struct ControllerInfo *ci = data;
297 gtk_widget_set_sensitive (ci->default_, TRUE);
298 gtk_widget_set_sensitive (ci->revert, TRUE);
299 gtk_label_set_text (GTK_LABEL (ci->status), _("modified"));
300 ci->need_config = TRUE;
312 set_value_status (GtkListStore *store, GtkTreeIter *iter)
316 gchar *value_str, *status_str, buf[32];
318 status = CURRENT_STATUS;
319 if (status == Mconfigured)
320 status_str = _("modified");
321 else if (status == Mcustomized)
322 status_str = _("customized");
324 status_str = _("default");
326 plist = CURRENT_VALUE;
327 /* plist == (value [valid-value ...]) */
328 if (mplist_key (plist) == Msymbol)
329 value_str = msymbol_name ((MSymbol) mplist_value (plist));
330 else if (mplist_key (plist) == Mtext)
331 /* Fixme : Assuming the return value is in UTF-8 */
332 value_str = mtext_data ((MText *) mplist_value (plist),
333 NULL, NULL, NULL, NULL);
336 g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist));
340 gtk_list_store_set (store, iter,
341 VCOL_VALUE, value_str,
342 VCOL_STATUS, status_str,
347 create_widget (struct ControllerInfo *ci)
352 plist = CURRENT_VALUE;
353 /* plist == (value [valid-value ...]) */
354 ci->vtype = mplist_key (plist);
355 value = mplist_value (plist);
356 plist = mplist_next (plist);
358 if (ci->vtype == Msymbol)
360 if (plist && mplist_key (plist) == Msymbol)
364 ci->widget = gtk_combo_box_new_text ();
365 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
366 G_CALLBACK (changed_cb), ci);
367 ci->wtype = COMBO_BOX_WIDGET;
368 for (i = 0; plist && mplist_key (plist) == Msymbol;
369 plist = mplist_next (plist), i++)
371 if (mplist_value (plist) == value)
373 gtk_combo_box_append_text
374 (GTK_COMBO_BOX (ci->widget),
375 msymbol_name ((MSymbol) mplist_value (plist)));
377 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
381 ci->widget = gtk_entry_new ();
382 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
383 G_CALLBACK (changed_cb), ci);
384 g_signal_connect (GTK_OBJECT (ci->widget), "activate",
385 G_CALLBACK (ok_cb), ci);
386 ci->wtype = ENTRY_WIDGET;
387 gtk_entry_set_text (GTK_ENTRY (ci->widget), msymbol_name (value));
388 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
391 else if (ci->vtype == Mtext)
393 if (plist && mplist_key (plist) == Mtext)
397 ci->widget = gtk_combo_box_new_text ();
398 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
399 G_CALLBACK (changed_cb), ci);
400 ci->wtype = COMBO_BOX_WIDGET;
401 for (i = 0; plist && mplist_key (plist) == Mtext;
402 plist = mplist_next (plist), i++)
404 if (! mtext_cmp ((MText *) mplist_value (plist),
407 /* Fixme : Assuming the return value is in UTF-8 */
408 gtk_combo_box_append_text
409 (GTK_COMBO_BOX (ci->widget),
410 mtext_data ((MText *) mplist_value (plist),
411 NULL, NULL, NULL, NULL));
413 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
417 ci->widget = gtk_entry_new ();
418 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
419 G_CALLBACK (changed_cb), ci);
420 g_signal_connect (GTK_OBJECT (ci->widget), "activate",
421 G_CALLBACK (ok_cb), ci);
422 ci->wtype = ENTRY_WIDGET;
423 /* Fixme : Assuming the return value is in UTF-8 */
424 gtk_entry_set_text (GTK_ENTRY (ci->widget),
425 mtext_data (value, NULL, NULL, NULL, NULL));
426 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
429 else /* ci->vtype == Minteger */
431 if (plist && mplist_key (plist) == Minteger)
435 ci->widget = gtk_combo_box_new_text ();
436 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
437 G_CALLBACK (changed_cb), ci);
438 ci->wtype = COMBO_BOX_WIDGET;
439 for (i = 0; plist && mplist_key (plist) == Minteger;
440 plist = mplist_next (plist), i++)
444 if (mplist_value (plist) == value)
446 g_snprintf (buf, sizeof (buf), "%d",
447 (gint) mplist_value (plist));
448 gtk_combo_box_append_text (GTK_COMBO_BOX (ci->widget), buf);
450 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
452 else if (plist && mplist_key (plist) == Mplist)
455 gdouble lower, upper;
457 plist = mplist_value (plist);
458 lower = (gdouble) (int) mplist_value (plist);
459 upper = (gdouble) (int) mplist_value (mplist_next (plist));
460 adj = gtk_adjustment_new ((gdouble) (int) value, lower, upper,
462 ci->widget = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0);
463 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
464 G_CALLBACK (changed_cb), ci);
465 ci->wtype = SPIN_BUTTON_WIDGET;
466 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ci->widget), TRUE);
467 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (ci->widget),
474 ci->widget = gtk_entry_new ();
475 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
476 G_CALLBACK (changed_cb), ci);
477 g_signal_connect (GTK_OBJECT (ci->widget), "activate",
478 G_CALLBACK (ok_cb), ci);
479 ci->wtype = ENTRY_WIDGET;
480 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
481 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
482 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
490 help_cb (GtkButton *button, gpointer data)
492 struct ControllerInfo *ci = data;
495 msg = gtk_message_dialog_new (GTK_WINDOW
496 (gtk_widget_get_toplevel (ci->dialog)),
497 GTK_DIALOG_DESTROY_WITH_PARENT,
500 CURRENT_DESCRIPTION);
501 gtk_dialog_run (GTK_DIALOG (msg));
502 gtk_widget_destroy (msg);
506 row_activated_cb (GtkTreeView *parent, GtkTreePath *path,
507 GtkTreeViewColumn *col, gpointer data)
511 GtkWidget *label, *ok, *help, *hbox, *vbox;
513 struct ControllerInfo ci;
516 model = gtk_tree_view_get_model (parent);
517 if (! gtk_tree_model_get_iter (model, &iter, path))
519 gtk_tree_model_get (model, &iter, VCOL_VARIABLE, &variable, -1);
520 current_variable = msymbol (variable);
522 ci.dialog = (gtk_dialog_new_with_buttons
524 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))),
525 GTK_DIALOG_DESTROY_WITH_PARENT,
528 ci.default_ = gtk_button_new_from_stock (_("_Default"));
529 g_signal_connect (G_OBJECT (ci.default_), "clicked",
530 G_CALLBACK (default_cb), &ci);
532 ci.revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED);
533 g_signal_connect (G_OBJECT (ci.revert), "clicked",
534 G_CALLBACK (revert_cb), &ci);
536 label = gtk_label_new (_("Status : "));
537 ci.status = gtk_label_new (NULL);
539 ok = gtk_button_new_from_stock (GTK_STOCK_OK);
540 g_signal_connect (G_OBJECT (ok), "clicked",
541 G_CALLBACK (ok_cb), &ci);
543 help = gtk_button_new_from_stock (GTK_STOCK_HELP);
544 g_signal_connect (G_OBJECT (help), "clicked",
545 G_CALLBACK (help_cb), &ci);
547 vbox = gtk_vbox_new (FALSE, 12);
548 gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
549 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->vbox), vbox);
551 gtk_container_add (GTK_CONTAINER (vbox), create_widget (&ci));
553 hbox = gtk_hbutton_box_new ();
554 gtk_box_set_spacing (GTK_BOX (hbox), 6);
555 gtk_container_add (GTK_CONTAINER (hbox), ci.default_);
556 gtk_container_add (GTK_CONTAINER (hbox), ci.revert);
557 gtk_container_add (GTK_CONTAINER (vbox), hbox);
559 hbox = gtk_hbox_new (FALSE, 6);
560 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
561 gtk_box_pack_start (GTK_BOX (hbox), ci.status, FALSE, FALSE, 0);
562 gtk_container_add (GTK_CONTAINER (vbox), hbox);
564 gtk_button_box_set_layout
565 (GTK_BUTTON_BOX (GTK_DIALOG (ci.dialog)->action_area),
567 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->action_area),
569 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->action_area),
572 status = CURRENT_STATUS;
573 if (status == Mconfigured)
575 gtk_widget_set_sensitive (ci.default_, TRUE);
576 gtk_widget_set_sensitive (ci.revert, TRUE);
577 gtk_label_set_text (GTK_LABEL (ci.status), _("modified"));
579 else if (status == Mcustomized)
581 gtk_widget_set_sensitive (ci.default_, TRUE);
582 gtk_widget_set_sensitive (ci.revert, FALSE);
583 gtk_label_set_text (GTK_LABEL (ci.status), _("customized"));
587 gtk_widget_set_sensitive (ci.default_, FALSE);
588 gtk_widget_set_sensitive (ci.revert, FALSE);
589 gtk_label_set_text (GTK_LABEL (ci.status), _("default"));
592 ci.need_config = FALSE;
594 gtk_widget_show_all (ci.dialog);
595 gtk_dialog_run (GTK_DIALOG (ci.dialog));
596 gtk_tree_model_get_iter (model, &iter, path);
597 set_value_status (GTK_LIST_STORE (model), &iter);
598 gtk_widget_destroy (ci.dialog);
602 create_variable_list (MSymbol lang, MSymbol name)
606 GtkCellRenderer *renderer;
612 plist = minput_get_variable (lang, name, Mnil);
614 return gtk_label_new (_("No customizable variables."));
617 * plist == ((variable description status value [valid-value ...])
618 * (variable description status value [valid-value ...])
622 store = gtk_list_store_new (NUM_VCOLS,
626 for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist))
630 MSymbol variable, value, status;
634 pl = mplist_value (plist);
635 /* pl == (variable description status value [valid-value ...]) */
636 current_variable = mplist_value (pl);
638 pl = mplist_next (pl);
639 /* pl == (description status value [valid-value ...]) */
640 if (mplist_key (pl) == Mtext)
641 /* Fixme : Assuming the return value is in UTF-8 */
642 desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL);
646 pl = mplist_next (pl);
647 /* pl == (status value [valid-value ...]) */
648 status = mplist_value (pl);
649 gtk_list_store_append (store, &iter);
650 gtk_list_store_set (store, &iter,
651 VCOL_VARIABLE, msymbol_name (current_variable),
653 set_value_status (store, &iter);
655 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
656 g_object_unref (G_OBJECT (store));
657 renderer = gtk_cell_renderer_text_new ();
658 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
665 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
672 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
679 g_signal_connect (G_OBJECT (view), "row-activated",
680 G_CALLBACK (row_activated_cb), NULL);