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 CONFIG_VARIABLE(plist) \
27 minput_config_variable (current_lang, current_name, current_variable, \
39 /* type of current variable: Minteger, Msymbol, or Mtext */
42 /* widget showing and controlling current variable */
46 enum WidgetType wtype;
64 static MSymbol current_lang, current_name, current_variable;
67 update_status (struct ControllerInfo *ci)
73 plist = CURRENT_VALUE;
74 /* plist == (value [valid-value ...]) */
75 key = mplist_key (plist);
76 value = mplist_value (plist);
78 if (ci->wtype == ENTRY_WIDGET)
81 gtk_entry_set_text (GTK_ENTRY (ci->widget),
82 msymbol_name ((MSymbol) value));
83 else if (key == Mtext)
84 /* Fixme : Assuming the return value is in UTF-8 */
85 gtk_entry_set_text (GTK_ENTRY (ci->widget),
86 mtext_data ((MText *) value,
87 NULL, NULL, NULL, NULL));
88 else /* key == Minteger */
91 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
92 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
95 else if (ci->wtype == COMBO_BOX_WIDGET)
99 for (i = 0, plist = mplist_next (plist);
100 plist && mplist_key (plist) == key;
101 i++, plist = mplist_next (plist))
102 if (mplist_value (plist) == value)
104 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), i);
106 else /* ci->wtype == SPIN_BUTTON_WIDGET */
107 gtk_spin_button_set_value (GTK_SPIN_BUTTON (ci->widget),
108 (gdouble) (int) value);
110 status = CURRENT_STATUS;
111 if (status == Mconfigured)
113 gtk_widget_set_sensitive (ci->default_, TRUE);
114 gtk_widget_set_sensitive (ci->revert, TRUE);
115 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : modified"));
117 else if (status == Mcustomized)
119 gtk_widget_set_sensitive (ci->default_, TRUE);
120 gtk_widget_set_sensitive (ci->revert, FALSE);
121 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : customized"));
125 gtk_widget_set_sensitive (ci->default_, FALSE);
126 gtk_widget_set_sensitive (ci->revert, FALSE);
127 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : default"));
132 config_with_entry (struct ControllerInfo *ci)
134 const gchar *text = gtk_entry_get_text (GTK_ENTRY (ci->widget));
135 MPlist *plist = mplist ();
138 if (ci->vtype == Msymbol)
140 mplist_add (plist, Msymbol, msymbol (text));
141 CONFIG_VARIABLE (plist);
143 else if (ci->vtype == Mtext)
147 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
148 mplist_add (plist, Mtext, mt);
149 CONFIG_VARIABLE (plist);
150 m17n_object_unref (mt);
152 else /* ci->vtype == Minteger */
157 if (sscanf (text, "%d", &i) == 1)
159 mplist_add (plist, Minteger, (void *) i);
160 CONFIG_VARIABLE (plist);
166 msg = gtk_message_dialog_new (GTK_WINDOW
167 (gtk_widget_get_toplevel (ci->widget)),
168 GTK_DIALOG_DESTROY_WITH_PARENT,
171 _("The value must be an integer."));
172 gtk_dialog_run (GTK_DIALOG (msg));
173 gtk_widget_destroy (msg);
179 m17n_object_unref (plist);
184 config_with_combo (struct ControllerInfo *ci)
186 gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (ci->widget));
187 MPlist *plist = mplist ();
189 if (ci->vtype == Msymbol)
191 mplist_add (plist, Msymbol, msymbol (text));
192 CONFIG_VARIABLE (plist);
194 else if (ci->vtype == Mtext)
198 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
199 mplist_add (plist, Mtext, mt);
200 CONFIG_VARIABLE (plist);
201 m17n_object_unref (mt);
203 else /* ci->vtype == Minteger */
207 sscanf (text, "%d", &i);
208 mplist_add (plist, Minteger, (void *) i);
209 CONFIG_VARIABLE (plist);
211 m17n_object_unref (plist);
216 config_with_spin (struct ControllerInfo *ci)
218 MPlist *plist = mplist ();
221 i = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ci->widget));
222 mplist_add (plist, Minteger, (void *) i);
223 CONFIG_VARIABLE (plist);
224 m17n_object_unref (plist);
228 ok_cb (GtkButton *button, gpointer data)
230 struct ControllerInfo *ci = data;
232 if (! strcmp (gtk_label_get_text (GTK_LABEL (ci->status)),
233 "Status : modified"))
235 if (ci->wtype == ENTRY_WIDGET)
237 if (config_with_entry (ci))
238 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
243 else if (ci->wtype == COMBO_BOX_WIDGET)
245 config_with_combo (ci);
246 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
249 else /* ci->wtype == SPIN_BUTTON */
251 config_with_spin (ci);
252 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
255 else /* default or customized */
256 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
260 default_cb (GtkButton *button, gpointer data)
262 MPlist *empty = mplist ();
263 struct ControllerInfo *ci = data;
265 CONFIG_VARIABLE (empty);
266 m17n_object_unref (empty);
271 revert_cb (GtkButton *button, gpointer data)
273 struct ControllerInfo *ci = data;
275 CONFIG_VARIABLE (NULL);
280 changed_cb (GtkEntry *entry, gpointer data)
282 struct ControllerInfo *ci = data;
284 gtk_widget_set_sensitive (ci->default_, TRUE);
285 gtk_widget_set_sensitive (ci->revert, TRUE);
286 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : modified"));
290 value_changed_cb (GtkWidget *widget, gpointer data)
292 struct ControllerInfo *ci = data;
294 gtk_widget_set_sensitive (ci->default_, TRUE);
295 gtk_widget_set_sensitive (ci->revert, TRUE);
296 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : modified"));
309 set_value_status (GtkListStore *store, GtkTreeIter *iter)
313 gchar *value_str, *status_str, buf[32];
315 status = CURRENT_STATUS;
316 if (status == Mconfigured)
317 status_str = _("modified");
318 else if (status == Mcustomized)
319 status_str = _("customized");
321 status_str = _("default");
323 plist = CURRENT_VALUE;
324 /* plist == (value [valid-value ...]) */
325 if (mplist_key (plist) == Msymbol)
326 value_str = msymbol_name ((MSymbol) mplist_value (plist));
327 else if (mplist_key (plist) == Mtext)
328 /* Fixme : Assuming the return value is in UTF-8 */
329 value_str = mtext_data ((MText *) mplist_value (plist),
330 NULL, NULL, NULL, NULL);
333 g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist));
337 gtk_list_store_set (store, iter,
338 VCOL_VALUE, value_str,
339 VCOL_STATUS, status_str,
344 create_widget (struct ControllerInfo *ci)
349 plist = CURRENT_VALUE;
350 /* plist == (value [valid-value ...]) */
351 ci->vtype = mplist_key (plist);
352 value = mplist_value (plist);
353 plist = mplist_next (plist);
355 if (ci->vtype == Msymbol)
357 if (plist && mplist_key (plist) == Msymbol)
361 ci->widget = gtk_combo_box_new_text ();
362 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
363 G_CALLBACK (value_changed_cb), ci);
364 ci->wtype = COMBO_BOX_WIDGET;
365 for (i = 0; plist && mplist_key (plist) == Msymbol;
366 plist = mplist_next (plist), i++)
368 if (mplist_value (plist) == value)
370 gtk_combo_box_append_text
371 (GTK_COMBO_BOX (ci->widget),
372 msymbol_name ((MSymbol) mplist_value (plist)));
374 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
378 ci->widget = gtk_entry_new ();
379 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
380 G_CALLBACK (changed_cb), ci);
381 ci->wtype = ENTRY_WIDGET;
382 gtk_entry_set_text (GTK_ENTRY (ci->widget), msymbol_name (value));
383 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
386 else if (ci->vtype == Mtext)
388 if (plist && mplist_key (plist) == Mtext)
392 ci->widget = gtk_combo_box_new_text ();
393 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
394 G_CALLBACK (value_changed_cb), ci);
395 ci->wtype = COMBO_BOX_WIDGET;
396 for (i = 0; plist && mplist_key (plist) == Mtext;
397 plist = mplist_next (plist), i++)
399 if (! mtext_cmp ((MText *) mplist_value (plist),
402 /* Fixme : Assuming the return value is in UTF-8 */
403 gtk_combo_box_append_text
404 (GTK_COMBO_BOX (ci->widget),
405 mtext_data ((MText *) mplist_value (plist),
406 NULL, NULL, NULL, NULL));
408 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
412 ci->widget = gtk_entry_new ();
413 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
414 G_CALLBACK (changed_cb), ci);
415 ci->wtype = ENTRY_WIDGET;
416 /* Fixme : Assuming the return value is in UTF-8 */
417 gtk_entry_set_text (GTK_ENTRY (ci->widget),
418 mtext_data (value, NULL, NULL, NULL, NULL));
419 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
422 else /* ci->vtype == Minteger */
424 if (plist && mplist_key (plist) == Minteger)
428 ci->widget = gtk_combo_box_new_text ();
429 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
430 G_CALLBACK (value_changed_cb), ci);
431 ci->wtype = COMBO_BOX_WIDGET;
432 for (i = 0; plist && mplist_key (plist) == Minteger;
433 plist = mplist_next (plist), i++)
437 if (mplist_value (plist) == value)
439 g_snprintf (buf, sizeof (buf), "%d",
440 (gint) mplist_value (plist));
441 gtk_combo_box_append_text (GTK_COMBO_BOX (ci->widget), buf);
443 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
445 else if (plist && mplist_key (plist) == Mplist)
448 gdouble lower, upper;
450 plist = mplist_value (plist);
451 lower = (gdouble) (int) mplist_value (plist);
452 upper = (gdouble) (int) mplist_value (mplist_next (plist));
453 adj = gtk_adjustment_new ((gdouble) (int) value, lower, upper,
455 ci->widget = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0);
456 g_signal_connect (GTK_OBJECT (ci->widget), "value-changed",
457 G_CALLBACK (value_changed_cb), ci);
458 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
459 G_CALLBACK (changed_cb), ci);
460 ci->wtype = SPIN_BUTTON_WIDGET;
461 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ci->widget), TRUE);
462 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (ci->widget),
469 ci->widget = gtk_entry_new ();
470 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
471 G_CALLBACK (changed_cb), ci);
472 ci->wtype = ENTRY_WIDGET;
473 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
474 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
475 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
483 activated_cb (GtkTreeView *parent, GtkTreePath *path,
484 GtkTreeViewColumn *col, gpointer data)
488 GtkWidget *hbox, *vbox;
489 struct ControllerInfo ci;
492 model = gtk_tree_view_get_model (parent);
493 if (! gtk_tree_model_get_iter (model, &iter, path))
495 gtk_tree_model_get (model, &iter, VCOL_VARIABLE, &variable, -1);
496 current_variable = msymbol (variable);
498 ci.dialog = (gtk_dialog_new_with_buttons
500 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))),
501 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
504 ci.default_ = gtk_button_new_from_stock (_("_Default"));
505 g_signal_connect (G_OBJECT (ci.default_), "clicked",
506 G_CALLBACK (default_cb), &ci);
508 ci.revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED);
509 g_signal_connect (G_OBJECT (ci.revert), "clicked",
510 G_CALLBACK (revert_cb), &ci);
512 ci.status = gtk_label_new (NULL);
514 ci.ok = gtk_button_new_from_stock (GTK_STOCK_OK);
515 g_signal_connect (G_OBJECT (ci.ok), "clicked",
516 G_CALLBACK (ok_cb), &ci);
518 vbox = gtk_vbox_new (FALSE, 12);
519 gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
520 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->vbox), vbox);
522 gtk_container_add (GTK_CONTAINER (vbox), create_widget (&ci));
524 hbox = gtk_hbutton_box_new ();
525 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
526 gtk_box_set_spacing (GTK_BOX (hbox), 6);
527 gtk_container_add (GTK_CONTAINER (hbox), ci.default_);
528 gtk_container_add (GTK_CONTAINER (hbox), ci.revert);
529 gtk_container_add (GTK_CONTAINER (vbox), hbox);
531 hbox = gtk_hbox_new (FALSE, 6);
532 gtk_box_pack_start (GTK_BOX (hbox), ci.status, FALSE, FALSE, 6);
533 gtk_container_add (GTK_CONTAINER (vbox), hbox);
535 hbox = gtk_hbutton_box_new ();
536 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
537 gtk_box_set_spacing (GTK_BOX (hbox), 6);
538 gtk_container_add (GTK_CONTAINER (hbox), ci.ok);
539 gtk_container_add (GTK_CONTAINER (vbox), hbox);
542 gtk_widget_show_all (ci.dialog);
543 gtk_dialog_run (GTK_DIALOG (ci.dialog));
544 gtk_tree_model_get_iter (model, &iter, path);
545 set_value_status (GTK_LIST_STORE (model), &iter);
546 gtk_widget_destroy (ci.dialog);
550 create_variable_list (MSymbol lang, MSymbol name)
554 GtkCellRenderer *renderer;
560 plist = minput_get_variable (lang, name, Mnil);
562 return gtk_label_new (_("No customizable variables."));
565 * plist == ((variable description status value [valid-value ...])
566 * (variable description status value [valid-value ...])
570 store = gtk_list_store_new (NUM_VCOLS,
574 for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist))
578 MSymbol variable, value, status;
582 pl = mplist_value (plist);
583 /* pl == (variable description status value [valid-value ...]) */
584 current_variable = mplist_value (pl);
586 pl = mplist_next (pl);
587 /* pl == (description status value [valid-value ...]) */
588 if (mplist_key (pl) == Mtext)
589 /* Fixme : Assuming the return value is in UTF-8 */
590 desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL);
594 pl = mplist_next (pl);
595 /* pl == (status value [valid-value ...]) */
596 status = mplist_value (pl);
597 gtk_list_store_append (store, &iter);
598 gtk_list_store_set (store, &iter,
599 VCOL_VARIABLE, msymbol_name (current_variable),
601 set_value_status (store, &iter);
603 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
604 g_object_unref (G_OBJECT (store));
605 renderer = gtk_cell_renderer_text_new ();
606 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
613 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
620 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
627 g_signal_connect (G_OBJECT (view), "row-activated",
628 G_CALLBACK (activated_cb), NULL);