From: ntakahas Date: Mon, 23 Apr 2007 05:40:24 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: REL-0-9-0~26 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=109d4545d235e1ccdb1ae3c008d226414d662831;p=m17n%2Fm17n-im-config.git *** empty log message *** --- diff --git a/src/command.c b/src/command.c index 1575c97..0751916 100644 --- a/src/command.c +++ b/src/command.c @@ -1,22 +1,53 @@ #include #include #include +#include #include #include #include -#include +#include + +#define _(String) dgettext (PACKAGE, String) + +#define CURRENT_BINDINGS \ + (mplist_next \ + (mplist_next \ + (mplist_next \ + (mplist_value \ + (minput_get_command \ + (current_lang, current_name, current_command)))))) + +#define CURRENT_STATUS \ + (mplist_value \ + (mplist_next \ + (mplist_next \ + (mplist_value \ + (minput_get_command \ + (current_lang, current_name, current_command)))))) + +#define CONFIG_COMMAND(plist) \ + minput_config_command (current_lang, current_name, current_command, \ + (plist)) +static unsigned modifier_state = 0; +static MPlist *entry_keyseq; static MSymbol current_lang, current_name, current_command; -static MPlist * -get_command_bindings (MSymbol lang, MSymbol name, MSymbol command) +struct BindingWidgets { - return (mplist_next - (mplist_next - (mplist_next - (mplist_value - (minput_get_command (lang, name, command)))))); -} + GtkWidget *entry; + GtkWidget *clear; + GtkWidget *add; + GtkWidget *view; + GtkWidget *delete; +}; + +enum KeyMaskBit { + META_MASK_BIT = 1, + ALT_MASK_BIT = META_MASK_BIT << 1, + SUPER_MASK_BIT = ALT_MASK_BIT << 1, + HYPER_MASK_BIT = SUPER_MASK_BIT << 1 +}; static int keyseq_equal (MPlist *pl1, MPlist *pl2) @@ -34,95 +65,6 @@ keyseq_equal (MPlist *pl1, MPlist *pl2) } static void -keyseq_render_function (GtkTreeViewColumn *column, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data) -{ - MPlist *keyseq, *pl; - gint n; - gchar buf[1024]; - - gtk_tree_model_get (model, iter, 0, &keyseq, -1); - for (pl = keyseq, n = 0; - pl && mplist_key (pl) == Msymbol; - pl = mplist_next (pl)) - n += strlen (msymbol_name ((MSymbol) mplist_value (pl))) + 1; - if (n < sizeof (buf)) - { - buf[0] = '\0'; - for (pl = keyseq; - pl && mplist_key (pl) == Msymbol; - pl = mplist_next (pl)) - { - strcat (buf, msymbol_name ((MSymbol) mplist_value (pl))); - strcat (buf, " "); - } - g_object_set (renderer, "foreground-set", FALSE, NULL); - } - else - { - g_snprintf (buf, sizeof (buf), "Too long to display"); - g_object_set (renderer, "foreground", "Red", "foreground-set", TRUE, - NULL); - } - g_object_set (renderer, "text", buf, NULL); -} - -static void -delete_cb (GtkButton *button, GtkWidget *view) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - MPlist *keyseq, *old, *new, *pl; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, 0, &keyseq, -1); - - old = get_command_bindings (current_lang, current_name, current_command); - new = mplist (); - for (pl = old; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl)) - if (! keyseq_equal (mplist_value (pl), keyseq)) - mplist_add (new, Mplist, mplist_value (pl)); - minput_config_command (current_lang, current_name, current_command, new); - m17n_object_unref (new); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - } -} - - -static void -delete_keyseq (GtkWidget *view, MSymbol lang, MSymbol name, MSymbol command) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - MPlist *keyseq, *old, *new, *pl; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, 0, &keyseq, -1); - old = get_command_bindings (lang, name, command); - new = mplist (); - for (pl = old; - pl && mplist_key (pl) == Mplist; - pl = mplist_next (pl)) - if (! keyseq_equal (mplist_value (pl), keyseq)) - mplist_add (new, Mplist, mplist_value (pl)); - minput_config_command (lang, name, command, new); - m17n_object_unref (new); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - } -} - -static MPlist *entry_keyseq; - -static void update_entry (GtkEntry *entry) { if (mplist_key (entry_keyseq) == Mnil) @@ -145,23 +87,34 @@ update_entry (GtkEntry *entry) } } -enum KeyMaskBit { - META_MASK_BIT = 1, - ALT_MASK_BIT = META_MASK_BIT << 1, - SUPER_MASK_BIT = ALT_MASK_BIT << 1, - HYPER_MASK_BIT = SUPER_MASK_BIT << 1 -}; +static void +update_binding_store (GtkWidget *view) +{ + GtkListStore *store; + GtkTreeIter iter; + MPlist *pl; -static unsigned modifier_state = 0; + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); + gtk_list_store_clear (store); + + for (pl = CURRENT_BINDINGS; + pl && mplist_key (pl) == Mplist; + pl = mplist_next (pl)) + { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, mplist_value (pl), -1); + } +} gboolean -key_pressed (GtkEntry *entry, GdkEventKey *event, gpointer data) +key_pressed_cb (GtkEntry *entry, GdkEventKey *event, gpointer data) { guint c; MText *mt; char buf[32]; char *name; int nbytes, i; + struct BindingWidgets *bw = data; c = gdk_keyval_to_unicode (event->keyval); if (c == 0) @@ -211,11 +164,13 @@ key_pressed (GtkEntry *entry, GdkEventKey *event, gpointer data) buf[i + nbytes] = 0; mplist_add (entry_keyseq, Msymbol, msymbol (buf)); update_entry (entry); + gtk_widget_set_sensitive (bw->clear, TRUE); + gtk_widget_set_sensitive (bw->add, TRUE); return TRUE; } gboolean -key_released (GtkEntry *entry, GdkEventKey *event, gpointer data) +key_released_cb (GtkEntry *entry, GdkEventKey *event, gpointer data) { guint c; @@ -238,25 +193,31 @@ key_released (GtkEntry *entry, GdkEventKey *event, gpointer data) } static void -clear_cb (GtkButton *button, GtkWidget *entry) +clear_cb (GtkButton *button, gpointer data) { + struct BindingWidgets *bw = data; + mplist_set (entry_keyseq, Mnil, NULL); - gtk_widget_grab_focus (entry); - update_entry (GTK_ENTRY (entry)); + gtk_widget_grab_focus (bw->entry); + update_entry (GTK_ENTRY (bw->entry)); + gtk_widget_set_sensitive (bw->clear, FALSE); + gtk_widget_set_sensitive (bw->add, FALSE); } static void -add_cb (GtkButton *button, GtkListStore *store) +add_cb (GtkButton *button, gpointer data) { - MPlist *old, *new, *pl, *last; + MPlist *new, *pl, *last; + GtkListStore *store; GtkTreeIter iter; - GtkWidget *view; + struct BindingWidgets *bw = data; if (mplist_length (entry_keyseq) == 0) return; - old = get_command_bindings (current_lang, current_name, current_command); new = mplist (); - for (pl = old; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl)) + for (pl = CURRENT_BINDINGS; + pl && mplist_key (pl) == Mplist; + pl = mplist_next (pl)) { if (! keyseq_equal (mplist_value (pl), entry_keyseq)) mplist_add (new, Mplist, mplist_value (pl)); @@ -268,144 +229,342 @@ add_cb (GtkButton *button, GtkListStore *store) } } mplist_add (new, Mplist, entry_keyseq); - minput_config_command (current_lang, current_name, current_command, new); + CONFIG_COMMAND (new); m17n_object_unref (new); /* We cannot use ENTRY_KEYSEQ for gtk_list_store_set (). We must use a pointer to the internally copied one. */ - new = get_command_bindings (current_lang, current_name, current_command); - for (pl = new; pl && mplist_key (pl) == Mplist; - last = pl, pl = mplist_next (pl)) + new = CURRENT_BINDINGS; + for (pl = new; + pl && mplist_key (pl) == Mplist; + last = pl, pl = mplist_next (pl)); + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (bw->view))); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, mplist_value (last), -1); - view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + update_binding_store (bw->view); + clear_cb (NULL, bw); + gtk_widget_set_sensitive (bw->clear, FALSE); + gtk_widget_set_sensitive (bw->add, FALSE); +} + +static GtkWidget * +create_adding_section (struct BindingWidgets *bw) +{ + GtkWidget *label, *hbox, *vbox; + + label = gtk_label_new (_("New key binding:")); + + entry_keyseq = mplist (); + bw->entry = gtk_entry_new (); + g_signal_connect (G_OBJECT (bw->entry), "key-press-event", + G_CALLBACK (key_pressed_cb), bw); + g_signal_connect (G_OBJECT (bw->entry), "key-release-event", + G_CALLBACK (key_released_cb), bw); + + bw->clear = gtk_button_new_from_stock (GTK_STOCK_CLEAR); + gtk_widget_set_sensitive (bw->clear, FALSE); + g_signal_connect (G_OBJECT (bw->clear), "clicked", + G_CALLBACK (clear_cb), bw); + + bw->add = gtk_button_new_from_stock (GTK_STOCK_ADD); + gtk_widget_set_sensitive (bw->add, FALSE); + g_signal_connect (G_OBJECT (bw->add), "clicked", + G_CALLBACK (add_cb), bw); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + gtk_container_add (GTK_CONTAINER (vbox), bw->entry); + + hbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing (GTK_BOX (hbox), 6); + gtk_container_add (GTK_CONTAINER (hbox), bw->clear); + gtk_container_add (GTK_CONTAINER (hbox), bw->add); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + return vbox; } static void -command_cb (GtkButton *button, GtkWidget *frame) +selection_cb (GtkTreeSelection *selection, gpointer data) { - GtkWidget *dialog, *view, *scrolled; - GtkWidget *delete, *entry, *add, *clear; - GtkListStore *store; - GtkTreeIter iter; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - MPlist *bindings, *pl, *cmd; - gint response; + struct BindingWidgets *bw = data; - current_lang = g_object_get_data (G_OBJECT (button), "mim_lang"); - current_name = g_object_get_data (G_OBJECT (button), "mim_name"); - current_command = g_object_get_data (G_OBJECT (button), "mim_command"); - bindings = get_command_bindings (current_lang, current_name, current_command); + gtk_widget_set_sensitive + (bw->delete, + gtk_tree_selection_count_selected_rows (selection) ? TRUE : FALSE); +} - dialog = (gtk_dialog_new_with_buttons - (msymbol_name (current_command), - GTK_WINDOW (gtk_widget_get_toplevel (frame)), - GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_OK, GTK_RESPONSE_OK, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL)); +static void +keyseq_render_function (GtkTreeViewColumn *column, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + MPlist *keyseq, *pl; + gint n; + gchar buf[1024]; - store = gtk_list_store_new (1, G_TYPE_POINTER); - for (pl = bindings; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl)) + gtk_tree_model_get (model, iter, 0, &keyseq, -1); + for (pl = keyseq, n = 0; + pl && mplist_key (pl) == Msymbol; + pl = mplist_next (pl)) + n += strlen (msymbol_name ((MSymbol) mplist_value (pl))) + 1; + if (n < sizeof (buf)) { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, mplist_value (pl), -1); + buf[0] = '\0'; + for (pl = keyseq; + pl && mplist_key (pl) == Msymbol; + pl = mplist_next (pl)) + { + strcat (buf, msymbol_name ((MSymbol) mplist_value (pl))); + strcat (buf, " "); + } + g_object_set (renderer, "foreground-set", FALSE, NULL); } - view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + else + { + g_snprintf (buf, sizeof (buf), _("Too long to display")); + g_object_set (renderer, "foreground", "Red", "foreground-set", TRUE, + NULL); + } + g_object_set (renderer, "text", buf, NULL); +} + +static void * +default_cb (GtkButton *button, gpointer data) +{ + MPlist *empty = mplist (); + struct BindingWidgets *bw = data; + + CONFIG_COMMAND (empty); + m17n_object_unref (empty); + update_binding_store (bw->view); +} + +static void * +revert_cb (GtkButton *button, gpointer data) +{ + struct BindingWidgets *bw = data; + + CONFIG_COMMAND (NULL); + update_binding_store (bw->view); +} + +static void +delete_cb (GtkButton *button, gpointer data) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + MPlist *keyseq, *new, *pl; + struct BindingWidgets *bw = data; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (bw->view)); + if (! gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + gtk_tree_model_get (model, &iter, 0, &keyseq, -1); + new = mplist (); + for (pl = CURRENT_BINDINGS; + pl && mplist_key (pl) == Mplist; + pl = mplist_next (pl)) + if (! keyseq_equal (mplist_value (pl), keyseq)) + mplist_add (new, Mplist, mplist_value (pl)); + CONFIG_COMMAND (new); + m17n_object_unref (new); + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + update_binding_store (bw->view); + gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); +} + +static GtkWidget * +create_deleting_section (struct BindingWidgets *bw) +{ + GtkListStore *store; + GtkWidget *scrolled, *default_, *revert, *delete, *hbox, *vbox; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkTreeIter iter; + GtkTreeSelection *selection; + MPlist *pl; + + store = gtk_list_store_new (1, G_TYPE_POINTER); + bw->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); g_object_unref (G_OBJECT (store)); + update_binding_store (bw->view); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(bw->view)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (selection_cb), bw); + + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), + bw->view); + column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, "Current bindings"); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + gtk_tree_view_column_set_title (column, _("Current Key Bindings")); + gtk_tree_view_append_column (GTK_TREE_VIEW (bw->view), column); + renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_cell_data_func (column, renderer, keyseq_render_function, NULL, NULL); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view); - delete = gtk_button_new_from_stock (GTK_STOCK_DELETE); - g_signal_connect (G_OBJECT (delete), "clicked", - G_CALLBACK (delete_cb), view); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), delete); + default_ = gtk_button_new_from_stock (_("_Default")); + g_signal_connect (G_OBJECT (default_), "clicked", + G_CALLBACK (default_cb), bw); - entry_keyseq = mplist (); + revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED); + g_signal_connect (G_OBJECT (revert), "clicked", + G_CALLBACK (revert_cb), bw); - entry = gtk_entry_new (); - g_signal_connect (G_OBJECT (entry), "key-press-event", - G_CALLBACK (key_pressed), NULL); - g_signal_connect (G_OBJECT (entry), "key-release-event", - G_CALLBACK (key_released), NULL); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), entry); + bw->delete = gtk_button_new_from_stock (GTK_STOCK_DELETE); + gtk_widget_set_sensitive (bw->delete, FALSE); + g_signal_connect (G_OBJECT (bw->delete), "clicked", + G_CALLBACK (delete_cb), bw); - clear = gtk_button_new_from_stock (GTK_STOCK_CLEAR); - g_signal_connect (G_OBJECT (clear), "clicked", - G_CALLBACK (clear_cb), entry); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), clear); + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); - add = gtk_button_new_from_stock (GTK_STOCK_ADD); - g_signal_connect (G_OBJECT (add), "clicked", - G_CALLBACK (add_cb), store); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), add); + gtk_container_add (GTK_CONTAINER (vbox), scrolled); + + hbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing (GTK_BOX (hbox), 6); + gtk_container_add (GTK_CONTAINER (hbox), default_); + gtk_container_add (GTK_CONTAINER (hbox), revert); + gtk_container_add (GTK_CONTAINER (hbox), bw->delete); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + return vbox; +} + +static void +set_status (GtkListStore *store, GtkTreeIter *iter) +{ + MSymbol status; + gchar *status_str; + + status = CURRENT_STATUS; + if (status == Mnil || status == Minherited) + status_str = _("default"); + else if (status == Mcustomized) + status_str = _("customized"); + else + status_str = _("modified"); + gtk_list_store_set (store, iter, 1, status_str, -1); +} + +static void +activated_cb (GtkTreeView *parent, GtkTreePath *path, + GtkTreeViewColumn *col, gpointer data) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *dialog; + struct BindingWidgets bw; + gchar *command; + + model = gtk_tree_view_get_model (parent); + if (! gtk_tree_model_get_iter (model, &iter, path)) + return; + gtk_tree_model_get (model, &iter, 0, &command, -1); + current_command = msymbol (command); + + dialog = (gtk_dialog_new_with_buttons + (command, + GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL)); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), + create_adding_section (&bw)); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), + create_deleting_section (&bw)); gtk_widget_show_all (dialog); - response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_tree_model_get_iter (model, &iter, path); + set_status (GTK_LIST_STORE (model), &iter); gtk_widget_destroy (dialog); - m17n_object_unref (entry_keyseq); } -void -create_command_entries (GtkWidget *frame, GtkTooltips *tip, - MSymbol lang, MSymbol name) +GtkWidget * +create_command_entries (GtkTooltips *tip, MSymbol lang, MSymbol name) { - GtkWidget *vbox; + GtkListStore *store; + GtkWidget *view; + GtkCellRenderer *renderer; MPlist *plist; - plist = minput_get_command (lang, name, Mnil); - if (! plist) - { - GtkWidget *message; - - message = gtk_label_new ("No commands for this method"); - gtk_container_add (GTK_CONTAINER (frame), message); - return; - } + current_lang = lang; + current_name = name; + plist = minput_get_command (lang, name, Mnil); /* * plist == ((command description status keyseq keyseq ...) * (command description status keyseq keyseq ...) * ...) */ - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (frame), vbox); + if (! plist) + return gtk_label_new (_("No commands for this method.")); + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist)) { - GtkWidget *button; + GtkTreeIter iter; MPlist *pl; - MSymbol command; + MSymbol command, status; gchar *desc; + gchar *status_str; pl = mplist_value (plist); /* pl == (command description status keyseq keyseq ...) */ - command = mplist_value (pl); - button = gtk_button_new_with_label (msymbol_name (command)); - gtk_container_add (GTK_CONTAINER (vbox), button); + current_command = command = mplist_value (pl); - pl = mplist_next (pl); + pl = mplist_next (pl); /* pl == (description status keyseq keyseq ...) */ if (mplist_key (pl) == Mtext) /* Fixme : Assuming the return value is in UTF-8 */ desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL); else desc = NULL; - gtk_tooltips_set_tip (tip, button, desc, NULL); - g_object_set_data (G_OBJECT (button), "mim_lang", lang); - g_object_set_data (G_OBJECT (button), "mim_name", name); - g_object_set_data (G_OBJECT (button), "mim_command", command); - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (command_cb), frame); + pl = mplist_next (pl); + /* pl == (status keyseq keyseq ...) */ + status = mplist_value (pl); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, msymbol_name (command), + -1); + set_status (store, &iter); } + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + g_object_unref (G_OBJECT (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + -1, + _("Name"), + renderer, + "text", 0, + NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + -1, + _("Status"), + renderer, + "text", 1, + NULL); + g_signal_connect (G_OBJECT (view), "row-activated", + G_CALLBACK (activated_cb), NULL); + return view; } - diff --git a/src/mim-config.c b/src/mim-config.c index 697a763..fff6c90 100644 --- a/src/mim-config.c +++ b/src/mim-config.c @@ -78,12 +78,14 @@ get_mim_status (MSymbol lang, MSymbol name) MPlist *p = mplist_value (plist); MSymbol status_symbol; - status = MIM_STATUS_DEFAULT; + if (status == MIM_STATUS_NO) + status = MIM_STATUS_DEFAULT; p = mplist_next (mplist_next (p)); status_symbol = mplist_value (p); - if (status_symbol != Mnil && status_symbol != Minherited) - return (status_symbol == Mcustomized - ? MIM_STATUS_CUSTOMIZED : MIM_STATUS_MODIFIED); + if (status_symbol == Mconfigured) + return MIM_STATUS_MODIFIED; + if (status_symbol == Mcustomized) + status = MIM_STATUS_CUSTOMIZED; } for (plist = minput_get_command (lang, name, Mnil); plist && mplist_key (plist) != Mnil; plist = mplist_next (plist)) @@ -91,12 +93,14 @@ get_mim_status (MSymbol lang, MSymbol name) MPlist *p = mplist_value (plist); MSymbol status_symbol; - status = MIM_STATUS_DEFAULT; + if (status == MIM_STATUS_NO) + status = MIM_STATUS_DEFAULT; p = mplist_next (mplist_next (p)); status_symbol = mplist_value (p); - if (status_symbol != Mnil && status_symbol != Minherited) - return (status_symbol == Mcustomized - ? MIM_STATUS_CUSTOMIZED : MIM_STATUS_MODIFIED); + if (status_symbol == Mconfigured) + return MIM_STATUS_MODIFIED; + if (status_symbol == Mcustomized) + status = MIM_STATUS_CUSTOMIZED; } return status; } @@ -158,41 +162,58 @@ tree_expanded_cb (GtkTreeView *tree, GtkTreeIter *parent, } } +extern GtkWidget *create_variable_entries (GtkTooltips *tip, MSymbol lang, + MSymbol name); +extern GtkWidget *create_command_entries (GtkTooltips *tip, MSymbol lang, + MSymbol name); + static void edit_im (GtkTreeView *tree, MSymbol lang, MSymbol name) { - GtkWidget *dialog, *frame, *table; + GtkWidget *dialog, *notebook, *scrolled, *vbox, *label; GtkTooltips *tip = gtk_tooltips_new (); gint response; MPlist *plist; dialog = (gtk_dialog_new_with_buttons - (msymbol_name (name), + (name == Mnil ? "global" : msymbol_name (name), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tree))), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, - _("Default"), 0, - GTK_STOCK_REVERT_TO_SAVED, GTK_RESPONSE_NO, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL)); + gtk_widget_set_size_request (dialog, 500, 300); + + notebook = gtk_notebook_new (); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), notebook); - frame = gtk_frame_new (_("Variables")); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, + /* Variables' page */ + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + label = gtk_label_new_with_mnemonic ("_Variables"); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolled, label); + vbox = gtk_vbox_new (FALSE, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), + vbox); + gtk_box_pack_start (GTK_BOX (vbox), + create_variable_entries (tip, lang, name), FALSE, FALSE, 0); - create_variable_entries (frame, tip, lang, name); - frame = gtk_frame_new (_("Commands")); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, + /* Commands' pages */ + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + label = gtk_label_new_with_mnemonic ("Co_mmands"); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolled, label); + vbox = gtk_vbox_new (FALSE, 0); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), + vbox); + gtk_box_pack_start (GTK_BOX (vbox), + create_command_entries (tip, lang, name), FALSE, FALSE, 0); - create_command_entries (frame, tip, lang, name); gtk_widget_show_all (dialog); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == 0) - printf ("Default\n"); - else if (response == GTK_RESPONSE_NO) - printf ("GTK_RESPONSE_NO\n"); - else if (response == GTK_RESPONSE_CANCEL) - printf ("GTK_RESPONSE_CANCEL\n"); + gtk_dialog_run (dialog); gtk_widget_destroy (dialog); } @@ -495,7 +516,7 @@ mim_config_new (GCallback func, gpointer data) renderer = gtk_cell_renderer_text_new (); column = (gtk_tree_view_column_new_with_attributes - (_("status"), renderer, "text", COL_STATUS_STR, NULL)); + (_("Status"), renderer, "text", COL_STATUS_STR, NULL)); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); g_signal_connect (G_OBJECT (tree), "row-expanded", diff --git a/src/variable.c b/src/variable.c index b8475da..cb6fe9d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,35 +1,74 @@ -#include -#include #include #include +#include +#include +#include +#include + +#define _(String) dgettext (PACKAGE, String) + +#define CURRENT_VALUE \ + (mplist_next \ + (mplist_next \ + (mplist_next \ + (mplist_value \ + (minput_get_variable \ + (current_lang, current_name, current_variable)))))) + +#define CURRENT_STATUS \ + (mplist_next \ + (mplist_next \ + (mplist_value \ + (minput_get_variable \ + (current_lang, current_name, current_variable))))) + +#define CONFIG_VARIABLE(plist) \ + minput_config_variable (current_lang, current_name, current_variable, \ + (plist)) + +enum WidgetType + { + ENTRY_WIDGET, + COMBO_BOX_WIDGET, + SPIN_BUTTON_WIDGET + }; + +struct ControllerInfo +{ + /* type of current variable: Minteger, Msymbol, or Mtext */ + MSymbol vtype; + + /* widget showing and controlling current variable */ + GtkWidget *widget; + + /* type of widget */ + enum WidgetType wtype; +}; + +static MSymbol current_lang, current_name, current_variable; static void -entry_cb (GtkWidget *entry, gpointer data) +entry_cb (GtkEntry *entry, gpointer data) { - const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry)); - MSymbol lang, name, variable, key; + const gchar *text = gtk_entry_get_text (entry); MPlist *plist = mplist (); + struct ControllerInfo *ci = data; - lang = g_object_get_data (G_OBJECT (entry), "mim_lang"); - name = g_object_get_data (G_OBJECT (entry), "mim_name"); - variable = g_object_get_data (G_OBJECT (entry), "mim_variable"); - key = g_object_get_data (G_OBJECT (entry), "mim_key"); - - if (key == Msymbol) + if (ci->vtype == Msymbol) { mplist_add (plist, Msymbol, msymbol (text)); - minput_config_variable (lang, name, variable, plist); + CONFIG_VARIABLE (plist); } - else if (key == Mtext) + else if (ci->vtype == Mtext) { MText *mt; mt = mtext_from_data (text, strlen (text), MTEXT_FORMAT_UTF_8); mplist_add (plist, Mtext, mt); - minput_config_variable (lang, name, variable, plist); + CONFIG_VARIABLE (plist); m17n_object_unref (mt); } - else if (key == Minteger) + else if (ci->vtype == Minteger) { int i; gchar buf[32]; @@ -37,13 +76,25 @@ entry_cb (GtkWidget *entry, gpointer data) if (sscanf (text, "%d", &i) == 1) { mplist_add (plist, Minteger, (void *) i); - minput_config_variable (lang, name, variable, plist); + CONFIG_VARIABLE (plist); } else { - printf ("Invalid value\n"); + GtkWidget *msg; + + msg = gtk_message_dialog_new (GTK_WINDOW + (gtk_widget_get_toplevel (ci->widget)), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("The value must be an integer.")); + gtk_dialog_run (GTK_DIALOG (msg)); + gtk_widget_destroy (msg); + /* revert current value */ + mplist_add (plist, Minteger, mplist_value (CURRENT_VALUE)); } - sprintf (buf, "%d", (int) mplist_value (plist)); + /* redraw the value to get rid of non-digits */ + g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist)); gtk_entry_set_text (GTK_ENTRY (entry), buf); gtk_editable_set_position (GTK_EDITABLE (entry), -1); } @@ -51,251 +102,449 @@ entry_cb (GtkWidget *entry, gpointer data) } static void -combo_cb (GtkWidget *combo, gpointer data) +combo_cb (GtkComboBox *combo, gpointer data) { - gchar *text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo)); - MSymbol lang, name, variable, key; + gchar *text = gtk_combo_box_get_active_text (combo); MPlist *plist = mplist (); + struct ControllerInfo *ci = data; - lang = g_object_get_data (G_OBJECT (combo), "mim_lang"); - name = g_object_get_data (G_OBJECT (combo), "mim_name"); - variable = g_object_get_data (G_OBJECT (combo), "mim_variable"); - key = g_object_get_data (G_OBJECT (combo), "mim_key"); - if (key == Msymbol) + if (ci->vtype == Msymbol) { mplist_add (plist, Msymbol, msymbol (text)); - minput_config_variable (lang, name, variable, plist); + CONFIG_VARIABLE (plist); } - else if (key == Mtext) + else if (ci->vtype == Mtext) { MText *mt; mt = mtext_from_data (text, strlen (text), MTEXT_FORMAT_UTF_8); mplist_add (plist, Mtext, mt); - minput_config_variable (lang, name, variable, plist); + CONFIG_VARIABLE (plist); m17n_object_unref (mt); } - else if (key == Minteger) + else if (ci->vtype == Minteger) { int i; - gchar buf[32]; - if (sscanf (text, "%d", &i) == 1) - { - mplist_add (plist, Minteger, (void *) i); - minput_config_variable (lang, name, variable, plist); - } - else - { - printf ("Invalid value\n"); - } + sscanf (text, "%d", &i); + mplist_add (plist, Minteger, (void *) i); + CONFIG_VARIABLE (plist); } m17n_object_unref (plist); } static void -spin_cb (GtkWidget *spin, gpointer data) +spin_cb (GtkSpinButton *spin, gpointer data) { - MSymbol lang, name, variable; MPlist *plist = mplist (); + struct ControllerInfo *ci = data; - lang = g_object_get_data (G_OBJECT (spin), "mim_lang"); - name = g_object_get_data (G_OBJECT (spin), "mim_name"); - variable = g_object_get_data (G_OBJECT (spin), "mim_variable"); - - mplist_add - (plist, Minteger, - (void *) gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin))); - minput_config_variable (lang, name, variable, plist); + mplist_add (plist, Minteger, + (void *) gtk_spin_button_get_value_as_int (spin)); + CONFIG_VARIABLE (plist); m17n_object_unref (plist); } -void -create_variable_entries (GtkWidget *frame, GtkTooltips *tip, - MSymbol lang, MSymbol name) +enum + { + VCOL_VARIABLE, + VCOL_VALUE, + VCOL_STATUS, + NUM_VCOLS + }; + +static void +set_value_status (GtkListStore *store, GtkTreeIter *iter) { - GtkWidget *table; MPlist *plist; - gint row; - - plist = minput_get_variable (lang, name, Mnil); - if (! plist) - { - GtkWidget *message; + MSymbol status; + gchar *value_str, *status_str, buf[32]; - message = gtk_label_new ("No variables for this method"); - gtk_container_add (GTK_CONTAINER (frame), message); - return; - } + plist = CURRENT_STATUS; + /* plist == (status value [valid-value ...]) */ + status = mplist_value (plist); + if (status == Mnil || status == Minherited) + status_str = _("default"); + else if (status == Mcustomized) + status_str = _("customized"); + else + status_str = _("modified"); - /* - * plist == ((variable description status value [valid-value ...]) - * (variable description status value [valid-value ...]) - * ...) - */ - table = gtk_table_new (2, mplist_length (plist), FALSE); - gtk_container_add (GTK_CONTAINER (frame), table); - - for (row = 0; plist && mplist_key (plist) == Mplist; - row++, plist = mplist_next (plist)) + plist = mplist_next (plist); + /* plist == (value [valid-value ...]) */ + if (mplist_key (plist) == Msymbol) + value_str = msymbol_name ((MSymbol) mplist_value (plist)); + else if (mplist_key (plist) == Mtext) + /* Fixme : Assuming the return value is in UTF-8 */ + value_str = mtext_data ((MText *) mplist_value (plist), + NULL, NULL, NULL, NULL); + else { - GtkWidget *label, *widget; - MPlist *pl, *data; - MSymbol variable, key; - void *value; - gchar *desc; + g_snprintf (buf, sizeof (buf), "%d", (gint) mplist_value (plist)); + value_str = buf; + } - pl = mplist_value (plist); - variable = mplist_value (pl); - label = gtk_label_new (msymbol_name (variable)); - gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, row, row + 1); + gtk_list_store_set (store, iter, + VCOL_VALUE, value_str, + VCOL_STATUS, status_str, + -1); +} - pl = mplist_next (pl); - if (mplist_key (pl) == Mtext) - /* Fixme : Assuming the return value is in UTF-8 */ - desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL); - else - desc = NULL; +static GtkWidget * +create_widget (struct ControllerInfo *ci) +{ + MPlist *plist; + void *value; - pl = mplist_next (mplist_next (pl)); /* ignore status */ - key = mplist_key (pl); - value = mplist_value (pl); - pl = mplist_next (pl); + plist = CURRENT_VALUE; + /* plist == (value [valid-value ...]) */ + ci->vtype = mplist_key (plist); + value = mplist_value (plist); + plist = mplist_next (plist); - if (key == Msymbol) + if (ci->vtype == Msymbol) + { + if (plist && mplist_key (plist) == Msymbol) { - if (mplist_key (pl) == Msymbol) - { - int i, nth = -1; - - widget = gtk_combo_box_new_text (); - for (i = 0; pl && mplist_key (pl) == Msymbol; - pl = mplist_next (pl), i++) - { - if (mplist_value (pl) == value) - nth = i; - gtk_combo_box_append_text (GTK_COMBO_BOX (widget), - msymbol_name (mplist_value (pl))); - } - if (nth != -1) - gtk_combo_box_set_active (GTK_COMBO_BOX (widget), nth); - g_signal_connect (G_OBJECT (widget), "changed", - G_CALLBACK (combo_cb), NULL); - } - else + gint i, nth = -1; + + ci->widget = gtk_combo_box_new_text (); + ci->wtype = COMBO_BOX_WIDGET; + for (i = 0; plist && mplist_key (plist) == Msymbol; + plist = mplist_next (plist), i++) { - widget = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (widget), msymbol_name (value)); - gtk_editable_set_editable (GTK_EDITABLE (widget), TRUE); - g_signal_connect (G_OBJECT (widget), "activate", - G_CALLBACK (entry_cb), NULL); + if (mplist_value (plist) == value) + nth = i; + gtk_combo_box_append_text + (GTK_COMBO_BOX (ci->widget), + msymbol_name ((MSymbol) mplist_value (plist))); } + if (nth != -1) + gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth); + g_signal_connect (G_OBJECT (ci->widget), "changed", + G_CALLBACK (combo_cb), ci); } - - else if (key == Mtext) + else { - if (mplist_key (pl) == Mtext) - { - int i, nth = -1; - - widget = gtk_combo_box_new_text (); - for (i = 0; pl && mplist_key (pl) == Mtext; - pl = mplist_next (pl), i++) - { - if (! mtext_cmp (mplist_value (pl), value)) - nth = i; - /* Fixme : Assuming the return value is in UTF-8 */ - gtk_combo_box_append_text - (GTK_COMBO_BOX (widget), - mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL)); - } - if (nth != -1) - gtk_combo_box_set_active (GTK_COMBO_BOX (widget), nth); - g_signal_connect (G_OBJECT (widget), "changed", - G_CALLBACK (combo_cb), NULL); - } - else + ci->widget = gtk_entry_new (); + ci->wtype = ENTRY_WIDGET; + gtk_entry_set_text (GTK_ENTRY (ci->widget), msymbol_name (value)); + gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE); + g_signal_connect (G_OBJECT (ci->widget), "activate", + G_CALLBACK (entry_cb), ci); + } + } + else if (ci->vtype == Mtext) + { + if (plist && mplist_key (plist) == Mtext) + { + gint i, nth = -1; + + ci->widget = gtk_combo_box_new_text (); + ci->wtype = COMBO_BOX_WIDGET; + for (i = 0; plist && mplist_key (plist) == Mtext; + plist = mplist_next (plist), i++) { - widget = gtk_entry_new (); + if (! mtext_cmp ((MText *) mplist_value (plist), + (MText *) value)) + nth = i; /* Fixme : Assuming the return value is in UTF-8 */ - gtk_entry_set_text (GTK_ENTRY (widget), - mtext_data (value, NULL, NULL, NULL, NULL)); - gtk_editable_set_editable (GTK_EDITABLE (widget), TRUE); - g_signal_connect (G_OBJECT (widget), "activate", - G_CALLBACK (entry_cb), NULL); + gtk_combo_box_append_text + (GTK_COMBO_BOX (ci->widget), + mtext_data ((MText *) mplist_value (plist), + NULL, NULL, NULL, NULL)); } + if (nth != -1) + gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth); + g_signal_connect (G_OBJECT (ci->widget), "changed", + G_CALLBACK (combo_cb), ci); } - - else if (key == Minteger) + else { - if (mplist_key (pl) == Minteger) - { - int i, nth = -1; - - widget = gtk_combo_box_new_text (); - for (i = 0; pl && mplist_key (pl) == Minteger; - pl = mplist_next (pl), i++) - { - gchar buf[32]; - - if (mplist_value (pl) == value) - nth = i; - snprintf (buf, 31, "%d", (int) mplist_value (pl)); - gtk_combo_box_append_text (GTK_COMBO_BOX (widget), buf); - } - if (nth != -1) - gtk_combo_box_set_active (GTK_COMBO_BOX (widget), nth); - g_signal_connect (G_OBJECT (widget), "changed", - G_CALLBACK (combo_cb), NULL); - } - else if (mplist_key (pl) == Mplist) - { - GtkAdjustment *adj; - gdouble lower, upper; - - pl = mplist_value (pl); - lower = (gdouble) (int) mplist_value (pl); - pl = mplist_next (pl); - upper = (gdouble) (int) mplist_value (pl); - adj = (GtkAdjustment *) - gtk_adjustment_new ((gdouble) (int) value, (gdouble) lower, - (gdouble) upper, 1.0, 10.0, 0); - widget = gtk_spin_button_new (adj, 0, 0); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE); - gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (widget), - GTK_UPDATE_IF_VALID); - g_signal_connect (G_OBJECT (widget), "value_changed", - G_CALLBACK (spin_cb), NULL); - } - else + ci->widget = gtk_entry_new (); + ci->wtype = ENTRY_WIDGET; + /* Fixme : Assuming the return value is in UTF-8 */ + gtk_entry_set_text (GTK_ENTRY (ci->widget), + mtext_data (value, NULL, NULL, NULL, NULL)); + gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE); + g_signal_connect (G_OBJECT (ci->widget), "activate", + G_CALLBACK (entry_cb), ci); + } + } + else if (ci->vtype == Minteger) + { + if (plist && mplist_key (plist) == Minteger) + { + gint i, nth = -1; + + ci->widget = gtk_combo_box_new_text (); + ci->wtype = COMBO_BOX_WIDGET; + for (i = 0; plist && mplist_key (plist) == Minteger; + plist = mplist_next (plist), i++) { gchar buf[32]; - widget = gtk_entry_new (); - snprintf (buf, 31, "%d", (int) value); - gtk_entry_set_text (GTK_ENTRY (widget), buf); - gtk_editable_set_editable (GTK_EDITABLE (widget), TRUE); - g_signal_connect (G_OBJECT (widget), "activate", - G_CALLBACK (entry_cb), NULL); + if (mplist_value (plist) == value) + nth = i; + g_snprintf (buf, sizeof (buf), "%d", + (gint) mplist_value (plist)); + gtk_combo_box_append_text (GTK_COMBO_BOX (ci->widget), buf); } + if (nth != -1) + gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), nth); + g_signal_connect (G_OBJECT (ci->widget), "changed", + G_CALLBACK (combo_cb), ci); } + else if (plist && mplist_key (plist) == Mplist) + { + GtkObject *adj; + gdouble lower, upper; + plist = mplist_value (plist); + lower = (gdouble) (int) mplist_value (plist); + upper = (gdouble) (int) mplist_value (mplist_next (plist)); + adj = gtk_adjustment_new ((gdouble) (int) value, lower, upper, + 1.0, 10.0, 0); + ci->widget = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0); + ci->wtype = SPIN_BUTTON_WIDGET; + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ci->widget), TRUE); + gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (ci->widget), + GTK_UPDATE_IF_VALID); + g_signal_connect (G_OBJECT (ci->widget), "value_changed", + G_CALLBACK (spin_cb), ci); + } else { - widget = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (widget), "???"); - gtk_editable_set_editable (GTK_EDITABLE (widget), TRUE); - g_signal_connect (G_OBJECT (widget), "activate", - G_CALLBACK (entry_cb), NULL); + gchar buf[32]; + + ci->widget = gtk_entry_new (); + ci->wtype = ENTRY_WIDGET; + g_snprintf (buf, sizeof (buf), "%d", (gint) value); + gtk_entry_set_text (GTK_ENTRY (ci->widget), buf); + gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE); + g_signal_connect (G_OBJECT (ci->widget), "activate", + G_CALLBACK (entry_cb), ci); } + } + else + { + ci->widget = gtk_entry_new (); + ci->wtype = ENTRY_WIDGET; + gtk_entry_set_text (GTK_ENTRY (ci->widget), "???"); + gtk_editable_set_editable (GTK_EDITABLE (ci->widget), TRUE); + g_signal_connect (G_OBJECT (ci->widget), "activate", + G_CALLBACK (entry_cb), ci); + } + return ci->widget; +} - gtk_tooltips_set_tip (tip, widget, desc, NULL); - g_object_set_data (G_OBJECT (widget), "mim_lang", lang); - g_object_set_data (G_OBJECT (widget), "mim_name", name); - g_object_set_data (G_OBJECT (widget), "mim_variable", variable); - g_object_set_data (G_OBJECT (widget), "mim_key", key); - gtk_table_attach_defaults (GTK_TABLE (table), widget, - 1, 2, row, row + 1); +static void +update_controller (struct ControllerInfo *ci) +{ + MPlist *plist; + MSymbol key; + void *value; + + plist = CURRENT_VALUE; + /* plist == (value [valid-value ...]) */ + key = mplist_key (plist); + value = mplist_value (plist); + + if (ci->wtype == ENTRY_WIDGET) + { + if (key == Msymbol) + gtk_entry_set_text (GTK_ENTRY (ci->widget), + msymbol_name ((MSymbol) value)); + else if (key == Mtext) + /* Fixme : Assuming the return value is in UTF-8 */ + gtk_entry_set_text (GTK_ENTRY (ci->widget), + mtext_data ((MText *) value, + NULL, NULL, NULL, NULL)); + else + { + gchar buf[32]; + g_snprintf (buf, sizeof (buf), "%d", (gint) value); + gtk_entry_set_text (GTK_ENTRY (ci->widget), buf); + } + } + else if (ci->wtype == COMBO_BOX_WIDGET) + { + gint i; + + for (i = 0, plist = mplist_next (plist); + plist && mplist_key (plist) == key; + i++, plist = mplist_next (plist)) + if (mplist_value (plist) == value) + break; + gtk_combo_box_set_active (GTK_COMBO_BOX (ci->widget), i); + } + else + gtk_spin_button_set_value (GTK_SPIN_BUTTON (ci->widget), + (gdouble) (int) value); +} + +static void * +default_cb (GtkButton *button, gpointer data) +{ + MPlist *empty = mplist (); + + CONFIG_VARIABLE (empty); + m17n_object_unref (empty); + update_controller ((struct ControllerInfo *) data); +} + +static void * +revert_cb (GtkButton *button, gpointer data) +{ + CONFIG_VARIABLE (NULL); + update_controller ((struct ControllerInfo *) data); +} + +static void * +apply_cb (GtkButton *button, gpointer data) +{ + struct ControllerInfo *ci = data; + + if (ci->wtype == ENTRY_WIDGET) + entry_cb (GTK_ENTRY (ci->widget), ci); +} + +static void +activated_cb (GtkTreeView *parent, GtkTreePath *path, + GtkTreeViewColumn *col, gpointer data) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *dialog, *default_, *revert, *apply, *hbox, *vbox; + struct ControllerInfo ci; + gchar *variable; + + model = gtk_tree_view_get_model (parent); + if (! gtk_tree_model_get_iter (model, &iter, path)) + return; + gtk_tree_model_get (model, &iter, VCOL_VARIABLE, &variable, -1); + current_variable = msymbol (variable); + + dialog = (gtk_dialog_new_with_buttons + (variable, + GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (parent))), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL)); + + default_ = gtk_button_new_from_stock (_("_Default")); + g_signal_connect (G_OBJECT (default_), "clicked", + G_CALLBACK (default_cb), &ci); + + revert = gtk_button_new_from_stock (GTK_STOCK_REVERT_TO_SAVED); + g_signal_connect (G_OBJECT (revert), "clicked", + G_CALLBACK (revert_cb), &ci); + + apply = gtk_button_new_from_stock (GTK_STOCK_APPLY); + g_signal_connect (G_OBJECT (apply), "clicked", + G_CALLBACK (apply_cb), &ci); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox); + + gtk_container_add (GTK_CONTAINER (vbox), create_widget (&ci)); + + hbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing (GTK_BOX (hbox), 6); + gtk_container_add (GTK_CONTAINER (hbox), default_); + gtk_container_add (GTK_CONTAINER (hbox), revert); + gtk_container_add (GTK_CONTAINER (hbox), apply); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + gtk_widget_show_all (dialog); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_tree_model_get_iter (model, &iter, path); + set_value_status (GTK_LIST_STORE (model), &iter); + gtk_widget_destroy (dialog); +} + +GtkWidget * +create_variable_entries (GtkTooltips *tip, MSymbol lang, MSymbol name) +{ + GtkListStore *store; + GtkWidget *view; + GtkCellRenderer *renderer; + MPlist *plist; + + current_lang = lang; + current_name = name; + + plist = minput_get_variable (lang, name, Mnil); + if (! plist) + return gtk_label_new (_("No variables for this method.")); + + /* + * plist == ((variable description status value [valid-value ...]) + * (variable description status value [valid-value ...]) + * ...) + */ + + store = gtk_list_store_new (NUM_VCOLS, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist)) + { + GtkTreeIter iter; + MPlist *pl; + MSymbol variable, value, status; + gchar *desc; + gchar *status_str; + + pl = mplist_value (plist); + /* pl == (variable description status value [valid-value ...]) */ + current_variable = mplist_value (pl); + + pl = mplist_next (pl); + /* pl == (description status value [valid-value ...]) */ + if (mplist_key (pl) == Mtext) + /* Fixme : Assuming the return value is in UTF-8 */ + desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL); + else + desc = NULL; + + pl = mplist_next (pl); + /* pl == (status value [valid-value ...]) */ + status = mplist_value (pl); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + VCOL_VARIABLE, msymbol_name (current_variable), + -1); + set_value_status (store, &iter); } + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + g_object_unref (G_OBJECT (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + -1, + _("Name"), + renderer, + "text", + VCOL_VARIABLE, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + -1, + _("Value"), + renderer, + "text", + VCOL_VALUE, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), + -1, + _("Status"), + renderer, + "text", + VCOL_STATUS, + NULL); + g_signal_connect (G_OBJECT (view), "row-activated", + G_CALLBACK (activated_cb), NULL); + return view; }