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;
61 static MSymbol current_lang, current_name, current_variable;
64 update_controller (struct ControllerInfo *ci)
70 status = CURRENT_STATUS;
71 if (status == Mconfigured)
73 gtk_widget_set_sensitive (ci->default_, TRUE);
74 gtk_widget_set_sensitive (ci->revert, TRUE);
75 gtk_widget_set_sensitive (ci->apply, FALSE);
76 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : modified"));
78 else if (status == Mcustomized)
80 gtk_widget_set_sensitive (ci->default_, TRUE);
81 gtk_widget_set_sensitive (ci->revert, FALSE);
82 gtk_widget_set_sensitive (ci->apply, FALSE);
83 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : customized"));
87 gtk_widget_set_sensitive (ci->default_, FALSE);
88 gtk_widget_set_sensitive (ci->revert, FALSE);
89 gtk_widget_set_sensitive (ci->apply, FALSE);
90 gtk_label_set_text (GTK_LABEL (ci->status), _("Status : default"));
93 plist = CURRENT_VALUE;
94 /* plist == (value [valid-value ...]) */
95 key = mplist_key (plist);
96 value = mplist_value (plist);
98 if (ci->wtype == ENTRY_WIDGET)
101 gtk_entry_set_text (GTK_ENTRY (ci->widget),
102 msymbol_name ((MSymbol) value));
103 else if (key == Mtext)
104 /* Fixme : Assuming the return value is in UTF-8 */
105 gtk_entry_set_text (GTK_ENTRY (ci->widget),
106 mtext_data ((MText *) value,
107 NULL, NULL, NULL, NULL));
111 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
112 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
115 else if (ci->wtype == COMBO_BOX_WIDGET)
119 for (i = 0, plist = mplist_next (plist);
120 plist && mplist_key (plist) == key;
121 i++, plist = mplist_next (plist))
122 if (mplist_value (plist) == value)
124 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), i);
127 gtk_spin_button_set_value (GTK_SPIN_BUTTON (ci->widget),
128 (gdouble) (int) value);
132 entry_cb (GtkEntry *entry, gpointer data)
134 const gchar *text = gtk_entry_get_text (entry);
135 MPlist *plist = mplist ();
136 struct ControllerInfo *ci = data;
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 if (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);
174 /* revert current value */
175 mplist_add (plist, Minteger, mplist_value (CURRENT_VALUE));
177 /* redraw the value to get rid of non-digits */
178 g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist));
179 gtk_entry_set_text (GTK_ENTRY (entry), buf);
180 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
182 m17n_object_unref (plist);
183 update_controller (ci);
187 combo_cb (GtkComboBox *combo, gpointer data)
189 gchar *text = gtk_combo_box_get_active_text (combo);
190 MPlist *plist = mplist ();
191 struct ControllerInfo *ci = data;
194 if (ci->vtype == Msymbol)
196 mplist_add (plist, Msymbol, msymbol (text));
197 CONFIG_VARIABLE (plist);
199 else if (ci->vtype == Mtext)
203 mt = mconv_decode_buffer (Mcoding_utf_8, text, strlen (text));
204 mplist_add (plist, Mtext, mt);
205 CONFIG_VARIABLE (plist);
206 m17n_object_unref (mt);
208 else if (ci->vtype == Minteger)
212 sscanf (text, "%d", &i);
213 mplist_add (plist, Minteger, (void *) i);
214 CONFIG_VARIABLE (plist);
216 m17n_object_unref (plist);
217 update_controller (ci);
221 spin_cb (GtkSpinButton *spin, gpointer data)
223 MPlist *plist = mplist ();
224 struct ControllerInfo *ci = data;
226 mplist_add (plist, Minteger,
227 (void *) gtk_spin_button_get_value_as_int (spin));
228 CONFIG_VARIABLE (plist);
229 m17n_object_unref (plist);
230 update_controller (ci);
242 set_value_status (GtkListStore *store, GtkTreeIter *iter)
246 gchar *value_str, *status_str, buf[32];
248 status = CURRENT_STATUS;
249 if (status == Mconfigured)
250 status_str = _("modified");
251 else if (status == Mcustomized)
252 status_str = _("customized");
254 status_str = _("default");
256 plist = CURRENT_VALUE;
257 /* plist == (value [valid-value ...]) */
258 if (mplist_key (plist) == Msymbol)
259 value_str = msymbol_name ((MSymbol) mplist_value (plist));
260 else if (mplist_key (plist) == Mtext)
261 /* Fixme : Assuming the return value is in UTF-8 */
262 value_str = mtext_data ((MText *) mplist_value (plist),
263 NULL, NULL, NULL, NULL);
266 g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist));
270 gtk_list_store_set (store, iter,
271 VCOL_VALUE, value_str,
272 VCOL_STATUS, status_str,
277 key_pressed_cb (GtkEntry *entry, GdkEventKey *event, gpointer data)
279 struct ControllerInfo *ci = data;
281 gtk_widget_set_sensitive (ci->default_, TRUE);
282 gtk_widget_set_sensitive (ci->revert, TRUE);
283 gtk_widget_set_sensitive (ci->apply, TRUE);
288 create_widget (struct ControllerInfo *ci)
293 plist = CURRENT_VALUE;
294 /* plist == (value [valid-value ...]) */
295 ci->vtype = mplist_key (plist);
296 value = mplist_value (plist);
297 plist = mplist_next (plist);
299 if (ci->vtype == Msymbol)
301 if (plist && mplist_key (plist) == Msymbol)
305 ci->widget = gtk_combo_box_new_text ();
306 ci->wtype = COMBO_BOX_WIDGET;
307 for (i = 0; plist && mplist_key (plist) == Msymbol;
308 plist = mplist_next (plist), i++)
310 if (mplist_value (plist) == value)
312 gtk_combo_box_append_text
313 (GTK_COMBO_BOX (ci->widget),
314 msymbol_name ((MSymbol) mplist_value (plist)));
317 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
318 g_signal_connect (G_OBJECT (ci->widget), "changed",
319 G_CALLBACK (combo_cb), ci);
323 ci->widget = gtk_entry_new ();
324 ci->wtype = ENTRY_WIDGET;
325 gtk_entry_set_text (GTK_ENTRY (ci->widget), msymbol_name (value));
326 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
327 g_signal_connect (G_OBJECT (ci->widget), "activate",
328 G_CALLBACK (entry_cb), ci);
329 g_signal_connect (G_OBJECT (ci->widget), "key-press-event",
330 G_CALLBACK (key_pressed_cb), ci);
333 else if (ci->vtype == Mtext)
335 if (plist && mplist_key (plist) == Mtext)
339 ci->widget = gtk_combo_box_new_text ();
340 ci->wtype = COMBO_BOX_WIDGET;
341 for (i = 0; plist && mplist_key (plist) == Mtext;
342 plist = mplist_next (plist), i++)
344 if (! mtext_cmp ((MText *) mplist_value (plist),
347 /* Fixme : Assuming the return value is in UTF-8 */
348 gtk_combo_box_append_text
349 (GTK_COMBO_BOX (ci->widget),
350 mtext_data ((MText *) mplist_value (plist),
351 NULL, NULL, NULL, NULL));
354 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
355 g_signal_connect (G_OBJECT (ci->widget), "changed",
356 G_CALLBACK (combo_cb), ci);
360 ci->widget = gtk_entry_new ();
361 ci->wtype = ENTRY_WIDGET;
362 /* Fixme : Assuming the return value is in UTF-8 */
363 gtk_entry_set_text (GTK_ENTRY (ci->widget),
364 mtext_data (value, NULL, NULL, NULL, NULL));
365 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
366 g_signal_connect (G_OBJECT (ci->widget), "activate",
367 G_CALLBACK (entry_cb), ci);
368 g_signal_connect (G_OBJECT (ci->widget), "key-press-event",
369 G_CALLBACK (key_pressed_cb), ci);
372 else if (ci->vtype == Minteger)
374 if (plist && mplist_key (plist) == Minteger)
378 ci->widget = gtk_combo_box_new_text ();
379 ci->wtype = COMBO_BOX_WIDGET;
380 for (i = 0; plist && mplist_key (plist) == Minteger;
381 plist = mplist_next (plist), i++)
385 if (mplist_value (plist) == value)
387 g_snprintf (buf, sizeof (buf), "%d",
388 (gint) mplist_value (plist));
389 gtk_combo_box_append_text (GTK_COMBO_BOX (ci->widget), buf);
392 gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth);
393 g_signal_connect (G_OBJECT (ci->widget), "changed",
394 G_CALLBACK (combo_cb), ci);
396 else if (plist && mplist_key (plist) == Mplist)
399 gdouble lower, upper;
401 plist = mplist_value (plist);
402 lower = (gdouble) (int) mplist_value (plist);
403 upper = (gdouble) (int) mplist_value (mplist_next (plist));
404 adj = gtk_adjustment_new ((gdouble) (int) value, lower, upper,
406 ci->widget = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0);
407 ci->wtype = SPIN_BUTTON_WIDGET;
408 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ci->widget), TRUE);
409 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (ci->widget),
410 GTK_UPDATE_IF_VALID);
411 g_signal_connect (G_OBJECT (ci->widget), "activate",
412 G_CALLBACK (entry_cb), ci);
413 g_signal_connect (G_OBJECT (ci->widget), "value_changed",
414 G_CALLBACK (spin_cb), ci);
415 g_signal_connect (G_OBJECT (ci->widget), "key-press-event",
416 G_CALLBACK (key_pressed_cb), ci);
422 ci->widget = gtk_entry_new ();
423 ci->wtype = ENTRY_WIDGET;
424 g_snprintf (buf, sizeof (buf), "%d", (gint) value);
425 gtk_entry_set_text (GTK_ENTRY (ci->widget), buf);
426 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
427 g_signal_connect (G_OBJECT (ci->widget), "activate",
428 G_CALLBACK (entry_cb), ci);
429 g_signal_connect (G_OBJECT (ci->widget), "key-press-event",
430 G_CALLBACK (key_pressed_cb), ci);
433 else /* should never come here */
435 ci->widget = gtk_entry_new ();
436 ci->wtype = ENTRY_WIDGET;
437 gtk_entry_set_text (GTK_ENTRY (ci->widget), "???");
438 gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE);
439 g_signal_connect (G_OBJECT (ci->widget), "activate",
440 G_CALLBACK (entry_cb), ci);
441 g_signal_connect (G_OBJECT (ci->widget), "key-press-event",
442 G_CALLBACK (key_pressed_cb), ci);
448 default_cb (GtkButton *button, gpointer data)
450 MPlist *empty = mplist ();
451 struct ControllerInfo *ci = data;
453 CONFIG_VARIABLE (empty);
454 m17n_object_unref (empty);
455 update_controller (ci);
459 revert_cb (GtkButton *button, gpointer data)
461 struct ControllerInfo *ci = data;
463 CONFIG_VARIABLE (NULL);
464 update_controller (ci);
468 apply_cb (GtkButton *button, gpointer data)
470 struct ControllerInfo *ci = data;
472 if (ci->wtype == ENTRY_WIDGET)
473 entry_cb (GTK_ENTRY (ci->widget), ci);
474 update_controller (ci);
478 activated_cb (GtkTreeView *parent, GtkTreePath *path,
479 GtkTreeViewColumn *col, gpointer data)
483 GtkWidget *dialog, *hbox, *vbox;
484 struct ControllerInfo ci;
487 model = gtk_tree_view_get_model (parent);
488 if (! gtk_tree_model_get_iter (model, &iter, path))
490 gtk_tree_model_get (model, &iter, VCOL_VARIABLE, &variable, -1);
491 current_variable = msymbol (variable);
493 dialog = (gtk_dialog_new_with_buttons
495 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))),
496 GTK_DIALOG_DESTROY_WITH_PARENT,
497 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
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 ci.apply = gtk_button_new_from_stock (GTK_STOCK_APPLY);
509 g_signal_connect (G_OBJECT (ci.apply), "clicked",
510 G_CALLBACK (apply_cb), &ci);
512 ci.status = gtk_label_new (NULL);
514 vbox = gtk_vbox_new (FALSE, 6);
515 gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
516 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
518 gtk_container_add (GTK_CONTAINER (vbox), create_widget (&ci));
520 hbox = gtk_hbutton_box_new ();
521 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
522 gtk_box_set_spacing (GTK_BOX (hbox), 6);
523 gtk_container_add (GTK_CONTAINER (hbox), ci.default_);
524 gtk_container_add (GTK_CONTAINER (hbox), ci.revert);
525 gtk_container_add (GTK_CONTAINER (hbox), ci.apply);
526 gtk_container_add (GTK_CONTAINER (vbox), hbox);
528 gtk_container_add (GTK_CONTAINER (vbox), ci.status);
530 update_controller (&ci);
531 gtk_widget_show_all (dialog);
532 gtk_dialog_run (GTK_DIALOG (dialog));
533 gtk_tree_model_get_iter (model, &iter, path);
534 set_value_status (GTK_LIST_STORE (model), &iter);
535 gtk_widget_destroy (dialog);
539 create_variable_list (GtkTooltips *tip, MSymbol lang, MSymbol name)
543 GtkCellRenderer *renderer;
549 plist = minput_get_variable (lang, name, Mnil);
551 return gtk_label_new (_("No customizable variables."));
554 * plist == ((variable description status value [valid-value ...])
555 * (variable description status value [valid-value ...])
559 store = gtk_list_store_new (NUM_VCOLS,
563 for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist))
567 MSymbol variable, value, status;
571 pl = mplist_value (plist);
572 /* pl == (variable description status value [valid-value ...]) */
573 current_variable = mplist_value (pl);
575 pl = mplist_next (pl);
576 /* pl == (description status value [valid-value ...]) */
577 if (mplist_key (pl) == Mtext)
578 /* Fixme : Assuming the return value is in UTF-8 */
579 desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL);
583 pl = mplist_next (pl);
584 /* pl == (status value [valid-value ...]) */
585 status = mplist_value (pl);
586 gtk_list_store_append (store, &iter);
587 gtk_list_store_set (store, &iter,
588 VCOL_VARIABLE, msymbol_name (current_variable),
590 set_value_status (store, &iter);
592 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
593 g_object_unref (G_OBJECT (store));
594 renderer = gtk_cell_renderer_text_new ();
595 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
602 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
609 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
616 g_signal_connect (G_OBJECT (view), "row-activated",
617 G_CALLBACK (activated_cb), NULL);