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;
48 /* whether minput_config_variable () should be called on ok button */
67 static MSymbol current_lang, current_name, current_variable;
70 update_widget (struct ControllerInfo *ci)
76 plist = CURRENT_VALUE;
77 /* plist == (value [valid-value ...]) */
78 key = mplist_key (plist);
79 value = mplist_value (plist);
81 if (ci->wtype == ENTRY_WIDGET)
84 gtk_entry_set_text (GTK_ENTRY (ci->widget),
85 msymbol_name ((MSymbol) value));
86 else if (key == Mtext)
87 /* Fixme : Assuming the return value is in UTF-8 */
88 gtk_entry_set_text (GTK_ENTRY (ci->widget),
89 mtext_data ((MText *) value,
90 NULL, NULL, NULL, NULL));
91 else /* key == Minteger */
94 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
95 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
98 else if (ci->wtype == COMBO_BOX_WIDGET)
102 for (i = 0, plist = mplist_next (plist);
103 plist && mplist_key (plist) == key;
104 i++, plist = mplist_next (plist))
105 if (mplist_value (plist) == value)
107 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), i);
109 else /* ci->wtype == SPIN_BUTTON_WIDGET */
110 gtk_spin_button_set_value (GTK_SPIN_BUTTON (ci->widget),
111 (gdouble) (int) value);
115 default_cb (GtkButton *button, gpointer data)
117 MPlist *empty = mplist ();
118 struct ControllerInfo *ci = data;
120 CONFIG_VARIABLE (empty);
121 m17n_object_unref (empty);
123 gtk_widget_set_sensitive (ci->default_, FALSE);
124 if (CURRENT_STATUS == Mconfigured)
126 gtk_widget_set_sensitive (ci->revert, TRUE);
127 gtk_label_set_text (GTK_LABEL (ci->status), _("modified"));
131 gtk_widget_set_sensitive (ci->revert, FALSE);
132 gtk_label_set_text (GTK_LABEL (ci->status), _("default"));
134 ci->need_config = FALSE;
138 revert_cb (GtkButton *button, gpointer data)
140 struct ControllerInfo *ci = data;
142 CONFIG_VARIABLE (NULL);
144 gtk_widget_set_sensitive (ci->revert, FALSE);
145 if (CURRENT_STATUS == Mnil)
147 gtk_widget_set_sensitive (ci->default_, FALSE);
148 gtk_label_set_text (GTK_LABEL (ci->status), _("default"));
152 gtk_widget_set_sensitive (ci->default_, TRUE);
153 gtk_label_set_text (GTK_LABEL (ci->status), _("customized"));
155 ci->need_config = FALSE;
159 config_with_entry (struct ControllerInfo *ci)
161 const gchar *text = gtk_entry_get_text (GTK_ENTRY (ci->widget));
162 MPlist *plist = mplist ();
165 if (ci->vtype == Msymbol)
167 mplist_add (plist, Msymbol, msymbol (text));
168 CONFIG_VARIABLE (plist);
170 else if (ci->vtype == Mtext)
174 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
175 mplist_add (plist, Mtext, mt);
176 CONFIG_VARIABLE (plist);
177 m17n_object_unref (mt);
179 else /* ci->vtype == Minteger */
184 if (sscanf (text, "%d", &i) == 1)
186 mplist_add (plist, Minteger, (void *) i);
187 CONFIG_VARIABLE (plist);
193 msg = gtk_message_dialog_new (GTK_WINDOW
194 (gtk_widget_get_toplevel (ci->widget)),
195 GTK_DIALOG_DESTROY_WITH_PARENT,
198 _("The value must be an integer."));
199 gtk_dialog_run (GTK_DIALOG (msg));
200 gtk_widget_destroy (msg);
205 m17n_object_unref (plist);
210 config_with_combo (struct ControllerInfo *ci)
212 gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (ci->widget));
213 MPlist *plist = mplist ();
215 if (ci->vtype == Msymbol)
217 mplist_add (plist, Msymbol, msymbol (text));
218 CONFIG_VARIABLE (plist);
220 else if (ci->vtype == Mtext)
224 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
225 mplist_add (plist, Mtext, mt);
226 CONFIG_VARIABLE (plist);
227 m17n_object_unref (mt);
229 else /* ci->vtype == Minteger */
233 sscanf (text, "%d", &i);
234 mplist_add (plist, Minteger, (void *) i);
235 CONFIG_VARIABLE (plist);
237 m17n_object_unref (plist);
242 config_with_spin (struct ControllerInfo *ci)
246 i = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ci->widget));
247 MPlist *plist = mplist ();
249 mplist_add (plist, Minteger, (void *) i);
250 CONFIG_VARIABLE (plist);
251 m17n_object_unref (plist);
256 ok_cb (GtkButton *button, gpointer data)
258 struct ControllerInfo *ci = data;
262 if (ci->wtype == ENTRY_WIDGET)
264 if (config_with_entry (ci))
265 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
267 revert_cb (NULL, ci);
270 else if (ci->wtype == COMBO_BOX_WIDGET)
272 config_with_combo (ci); /* always returns true */
273 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
276 else /* ci->wtype == SPIN_BUTTON */
278 config_with_spin (ci); /* always returns true */
279 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
283 gtk_dialog_response (GTK_DIALOG (ci->dialog), GTK_RESPONSE_OK);
287 changed_cb (GtkEntry *entry, gpointer data)
289 struct ControllerInfo *ci = data;
291 gtk_widget_set_sensitive (ci->default_, TRUE);
292 gtk_widget_set_sensitive (ci->revert, TRUE);
293 gtk_label_set_text (GTK_LABEL (ci->status), _("modified"));
294 ci->need_config = TRUE;
306 set_value_status (GtkListStore *store, GtkTreeIter *iter)
310 gchar *value_str, *status_str, buf[32];
312 status = CURRENT_STATUS;
313 if (status == Mconfigured)
314 status_str = _("modified");
315 else if (status == Mcustomized)
316 status_str = _("customized");
318 status_str = _("default");
320 plist = CURRENT_VALUE;
321 /* plist == (value [valid-value ...]) */
322 if (mplist_key (plist) == Msymbol)
323 value_str = msymbol_name ((MSymbol) mplist_value (plist));
324 else if (mplist_key (plist) == Mtext)
325 /* Fixme : Assuming the return value is in UTF-8 */
326 value_str = mtext_data ((MText *) mplist_value (plist),
327 NULL, NULL, NULL, NULL);
330 g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist));
334 gtk_list_store_set (store, iter,
335 VCOL_VALUE, value_str,
336 VCOL_STATUS, status_str,
341 create_widget (struct ControllerInfo *ci)
346 plist = CURRENT_VALUE;
347 /* plist == (value [valid-value ...]) */
348 ci->vtype = mplist_key (plist);
349 value = mplist_value (plist);
350 plist = mplist_next (plist);
352 if (ci->vtype == Msymbol)
354 if (plist && mplist_key (plist) == Msymbol)
358 ci->widget = gtk_combo_box_new_text ();
359 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
360 G_CALLBACK (changed_cb), ci);
361 ci->wtype = COMBO_BOX_WIDGET;
362 for (i = 0; plist && mplist_key (plist) == Msymbol;
363 plist = mplist_next (plist), i++)
365 if (mplist_value (plist) == value)
367 gtk_combo_box_append_text
368 (GTK_COMBO_BOX (ci->widget),
369 msymbol_name ((MSymbol) mplist_value (plist)));
371 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
375 ci->widget = gtk_entry_new ();
376 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
377 G_CALLBACK (changed_cb), ci);
378 ci->wtype = ENTRY_WIDGET;
379 gtk_entry_set_text (GTK_ENTRY (ci->widget), msymbol_name (value));
380 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
383 else if (ci->vtype == Mtext)
385 if (plist && mplist_key (plist) == Mtext)
389 ci->widget = gtk_combo_box_new_text ();
390 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
391 G_CALLBACK (changed_cb), ci);
392 ci->wtype = COMBO_BOX_WIDGET;
393 for (i = 0; plist && mplist_key (plist) == Mtext;
394 plist = mplist_next (plist), i++)
396 if (! mtext_cmp ((MText *) mplist_value (plist),
399 /* Fixme : Assuming the return value is in UTF-8 */
400 gtk_combo_box_append_text
401 (GTK_COMBO_BOX (ci->widget),
402 mtext_data ((MText *) mplist_value (plist),
403 NULL, NULL, NULL, NULL));
405 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
409 ci->widget = gtk_entry_new ();
410 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
411 G_CALLBACK (changed_cb), ci);
412 ci->wtype = ENTRY_WIDGET;
413 /* Fixme : Assuming the return value is in UTF-8 */
414 gtk_entry_set_text (GTK_ENTRY (ci->widget),
415 mtext_data (value, NULL, NULL, NULL, NULL));
416 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
419 else /* ci->vtype == Minteger */
421 if (plist && mplist_key (plist) == Minteger)
425 ci->widget = gtk_combo_box_new_text ();
426 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
427 G_CALLBACK (changed_cb), ci);
428 ci->wtype = COMBO_BOX_WIDGET;
429 for (i = 0; plist && mplist_key (plist) == Minteger;
430 plist = mplist_next (plist), i++)
434 if (mplist_value (plist) == value)
436 g_snprintf (buf, sizeof (buf), "%d",
437 (gint) mplist_value (plist));
438 gtk_combo_box_append_text (GTK_COMBO_BOX (ci->widget), buf);
440 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
442 else if (plist && mplist_key (plist) == Mplist)
445 gdouble lower, upper;
447 plist = mplist_value (plist);
448 lower = (gdouble) (int) mplist_value (plist);
449 upper = (gdouble) (int) mplist_value (mplist_next (plist));
450 adj = gtk_adjustment_new ((gdouble) (int) value, lower, upper,
452 ci->widget = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0);
453 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
454 G_CALLBACK (changed_cb), ci);
455 ci->wtype = SPIN_BUTTON_WIDGET;
456 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ci->widget), TRUE);
457 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (ci->widget),
464 ci->widget = gtk_entry_new ();
465 g_signal_connect (GTK_OBJECT (ci->widget), "changed",
466 G_CALLBACK (changed_cb), ci);
467 ci->wtype = ENTRY_WIDGET;
468 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
469 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
470 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
478 activated_cb (GtkTreeView *parent, GtkTreePath *path,
479 GtkTreeViewColumn *col, gpointer data)
483 GtkWidget *label, *hbox, *vbox;
485 struct ControllerInfo ci;
488 model = gtk_tree_view_get_model (parent);
489 if (! gtk_tree_model_get_iter (model, &iter, path))
491 gtk_tree_model_get (model, &iter, VCOL_VARIABLE, &variable, -1);
492 current_variable = msymbol (variable);
494 ci.dialog = (gtk_dialog_new_with_buttons
496 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))),
497 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
500 ci.default_ = gtk_button_new_from_stock (_("_Default"));
501 g_signal_connect (G_OBJECT (ci.default_), "clicked",
502 G_CALLBACK (default_cb), &ci);
504 ci.revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED);
505 g_signal_connect (G_OBJECT (ci.revert), "clicked",
506 G_CALLBACK (revert_cb), &ci);
508 label = gtk_label_new (_("Status : "));
509 ci.status = gtk_label_new (NULL);
511 ci.ok = gtk_button_new_from_stock (GTK_STOCK_OK);
512 g_signal_connect (G_OBJECT (ci.ok), "clicked",
513 G_CALLBACK (ok_cb), &ci);
515 vbox = gtk_vbox_new (FALSE, 12);
516 gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
517 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->vbox), vbox);
519 gtk_container_add (GTK_CONTAINER (vbox), create_widget (&ci));
521 hbox = gtk_hbutton_box_new ();
522 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
523 gtk_box_set_spacing (GTK_BOX (hbox), 6);
524 gtk_container_add (GTK_CONTAINER (hbox), ci.default_);
525 gtk_container_add (GTK_CONTAINER (hbox), ci.revert);
526 gtk_container_add (GTK_CONTAINER (vbox), hbox);
528 hbox = gtk_hbox_new (FALSE, 6);
529 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
530 gtk_box_pack_start (GTK_BOX (hbox), ci.status, FALSE, FALSE, 0);
531 gtk_container_add (GTK_CONTAINER (vbox), hbox);
533 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ci.dialog)->action_area),
536 status = CURRENT_STATUS;
537 if (status == Mconfigured)
539 gtk_widget_set_sensitive (ci.default_, TRUE);
540 gtk_widget_set_sensitive (ci.revert, TRUE);
541 gtk_label_set_text (GTK_LABEL (ci.status), _("modified"));
543 else if (status == Mcustomized)
545 gtk_widget_set_sensitive (ci.default_, TRUE);
546 gtk_widget_set_sensitive (ci.revert, FALSE);
547 gtk_label_set_text (GTK_LABEL (ci.status), _("customized"));
551 gtk_widget_set_sensitive (ci.default_, FALSE);
552 gtk_widget_set_sensitive (ci.revert, FALSE);
553 gtk_label_set_text (GTK_LABEL (ci.status), _("default"));
556 ci.need_config = FALSE;
558 gtk_widget_show_all (ci.dialog);
559 gtk_dialog_run (GTK_DIALOG (ci.dialog));
560 gtk_tree_model_get_iter (model, &iter, path);
561 set_value_status (GTK_LIST_STORE (model), &iter);
562 gtk_widget_destroy (ci.dialog);
566 create_variable_list (MSymbol lang, MSymbol name)
570 GtkCellRenderer *renderer;
576 plist = minput_get_variable (lang, name, Mnil);
578 return gtk_label_new (_("No customizable variables."));
581 * plist == ((variable description status value [valid-value ...])
582 * (variable description status value [valid-value ...])
586 store = gtk_list_store_new (NUM_VCOLS,
590 for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist))
594 MSymbol variable, value, status;
598 pl = mplist_value (plist);
599 /* pl == (variable description status value [valid-value ...]) */
600 current_variable = mplist_value (pl);
602 pl = mplist_next (pl);
603 /* pl == (description status value [valid-value ...]) */
604 if (mplist_key (pl) == Mtext)
605 /* Fixme : Assuming the return value is in UTF-8 */
606 desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL);
610 pl = mplist_next (pl);
611 /* pl == (status value [valid-value ...]) */
612 status = mplist_value (pl);
613 gtk_list_store_append (store, &iter);
614 gtk_list_store_set (store, &iter,
615 VCOL_VARIABLE, msymbol_name (current_variable),
617 set_value_status (store, &iter);
619 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
620 g_object_unref (G_OBJECT (store));
621 renderer = gtk_cell_renderer_text_new ();
622 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
629 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
636 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
643 g_signal_connect (G_OBJECT (view), "row-activated",
644 G_CALLBACK (activated_cb), NULL);