6 #include <gdk/gdkkeysyms.h>
9 static MSymbol current_lang, current_name, current_command;
12 get_command_bindings (MSymbol lang, MSymbol name, MSymbol command)
18 (minput_get_command (lang, name, command))))));
22 keyseq_equal (MPlist *pl1, MPlist *pl2)
24 if (mplist_length (pl1) != mplist_length (pl2))
26 while (pl1 && mplist_key (pl1) == Msymbol)
28 if (mplist_value (pl1) != mplist_value (pl2))
30 pl1 = mplist_next (pl1);
31 pl2 = mplist_next (pl2);
37 keyseq_render_function (GtkTreeViewColumn *column,
38 GtkCellRenderer *renderer,
47 gtk_tree_model_get (model, iter, 0, &keyseq, -1);
48 for (pl = keyseq, n = 0;
49 pl && mplist_key (pl) == Msymbol;
50 pl = mplist_next (pl))
51 n += strlen (msymbol_name ((MSymbol) mplist_value (pl))) + 1;
56 pl && mplist_key (pl) == Msymbol;
57 pl = mplist_next (pl))
59 strcat (buf, msymbol_name ((MSymbol) mplist_value (pl)));
62 g_object_set (renderer, "foreground-set", FALSE, NULL);
66 g_snprintf (buf, sizeof (buf), "Too long to display");
67 g_object_set (renderer, "foreground", "Red", "foreground-set", TRUE,
70 g_object_set (renderer, "text", buf, NULL);
74 delete_cb (GtkButton *button, GtkWidget *view)
76 GtkTreeSelection *selection;
79 MPlist *keyseq, *old, *new, *pl;
81 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
82 if (gtk_tree_selection_get_selected (selection, &model, &iter))
84 gtk_tree_model_get (model, &iter, 0, &keyseq, -1);
86 old = get_command_bindings (current_lang, current_name, current_command);
88 for (pl = old; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl))
89 if (! keyseq_equal (mplist_value (pl), keyseq))
90 mplist_add (new, Mplist, mplist_value (pl));
91 minput_config_command (current_lang, current_name, current_command, new);
92 m17n_object_unref (new);
93 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
99 delete_keyseq (GtkWidget *view, MSymbol lang, MSymbol name, MSymbol command)
101 GtkTreeSelection *selection;
104 MPlist *keyseq, *old, *new, *pl;
106 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
107 if (gtk_tree_selection_get_selected (selection, &model, &iter))
109 gtk_tree_model_get (model, &iter, 0, &keyseq, -1);
110 old = get_command_bindings (lang, name, command);
113 pl && mplist_key (pl) == Mplist;
114 pl = mplist_next (pl))
115 if (! keyseq_equal (mplist_value (pl), keyseq))
116 mplist_add (new, Mplist, mplist_value (pl));
117 minput_config_command (lang, name, command, new);
118 m17n_object_unref (new);
119 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
123 static MPlist *entry_keyseq;
126 update_entry (GtkEntry *entry)
128 if (mplist_key (entry_keyseq) == Mnil)
129 gtk_entry_set_text (entry, "");
135 name = msymbol_name ((MSymbol) mplist_value (entry_keyseq));
136 gtk_entry_set_text (entry, name);
137 for (p = mplist_next (entry_keyseq); mplist_key (p) != Mnil;
140 name = msymbol_name ((MSymbol) mplist_value (p));
141 gtk_entry_append_text (entry, " ");
142 gtk_entry_append_text (entry, name);
144 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
150 ALT_MASK_BIT = META_MASK_BIT << 1,
151 SUPER_MASK_BIT = ALT_MASK_BIT << 1,
152 HYPER_MASK_BIT = SUPER_MASK_BIT << 1
155 static unsigned modifier_state = 0;
158 key_pressed (GtkEntry *entry, GdkEventKey *event, gpointer data)
166 c = gdk_keyval_to_unicode (event->keyval);
169 switch (event->keyval)
171 case GDK_Meta_L: case GDK_Meta_R:
172 modifier_state |= META_MASK_BIT; return TRUE;
173 case GDK_Alt_L: case GDK_Alt_R:
174 modifier_state |= ALT_MASK_BIT; return TRUE;
175 case GDK_Super_L: case GDK_Super_R:
176 modifier_state |= SUPER_MASK_BIT; return TRUE;
177 case GDK_Hyper_L: case GDK_Hyper_R:
178 modifier_state |= HYPER_MASK_BIT; return TRUE;
180 if (event->keyval >= GDK_Shift_L && event->keyval <= GDK_Shift_Lock)
183 name = gdk_keyval_name (event->keyval);
186 nbytes = strlen (name);
192 mtext_cat_char (mt, c);
193 nbytes = mconv_encode_buffer (msymbol ("utf-8"), mt,
194 (unsigned char *) name, 32);
195 m17n_object_unref (mt);
198 if (c == 0 && event->state & GDK_SHIFT_MASK)
199 buf[i++] = 'S', buf[i++] = '-';
200 if (event->state & GDK_CONTROL_MASK)
201 buf[i++] = 'C', buf[i++] = '-';
202 if (modifier_state & META_MASK_BIT)
203 buf[i++] = 'M', buf[i++] = '-';
204 if (modifier_state & ALT_MASK_BIT)
205 buf[i++] = 'A', buf[i++] = '-';
206 if (modifier_state & SUPER_MASK_BIT)
207 buf[i++] = 's', buf[i++] = '-';
208 if (modifier_state & HYPER_MASK_BIT)
209 buf[i++] = 'H', buf[i++] = '-';
210 strncpy (buf + i, name, nbytes);
212 mplist_add (entry_keyseq, Msymbol, msymbol (buf));
213 update_entry (entry);
218 key_released (GtkEntry *entry, GdkEventKey *event, gpointer data)
222 c = gdk_keyval_to_unicode (event->keyval);
225 switch (event->keyval)
227 case GDK_Meta_L: case GDK_Meta_R:
228 modifier_state &= ~META_MASK_BIT; break;
229 case GDK_Alt_L: case GDK_Alt_R:
230 modifier_state &= ~ALT_MASK_BIT; break;
231 case GDK_Super_L: case GDK_Super_R:
232 modifier_state &= ~SUPER_MASK_BIT; break;
233 case GDK_Hyper_L: case GDK_Hyper_R:
234 modifier_state &= ~HYPER_MASK_BIT; break;
241 clear_cb (GtkButton *button, GtkWidget *entry)
243 mplist_set (entry_keyseq, Mnil, NULL);
244 gtk_widget_grab_focus (entry);
245 update_entry (GTK_ENTRY (entry));
249 add_cb (GtkButton *button, GtkListStore *store)
251 MPlist *old, *new, *pl, *last;
255 if (mplist_length (entry_keyseq) == 0)
257 old = get_command_bindings (current_lang, current_name, current_command);
259 for (pl = old; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl))
261 if (! keyseq_equal (mplist_value (pl), entry_keyseq))
262 mplist_add (new, Mplist, mplist_value (pl));
265 /* entry_keyseq is already registered. */
266 m17n_object_unref (new);
270 mplist_add (new, Mplist, entry_keyseq);
271 minput_config_command (current_lang, current_name, current_command, new);
272 m17n_object_unref (new);
274 /* We cannot use ENTRY_KEYSEQ for gtk_list_store_set (). We must
275 use a pointer to the internally copied one. */
276 new = get_command_bindings (current_lang, current_name, current_command);
277 for (pl = new; pl && mplist_key (pl) == Mplist;
278 last = pl, pl = mplist_next (pl))
279 gtk_list_store_append (store, &iter);
280 gtk_list_store_set (store, &iter, 0, mplist_value (last), -1);
281 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
285 command_cb (GtkButton *button, GtkWidget *frame)
287 GtkWidget *dialog, *view, *scrolled;
288 GtkWidget *delete, *entry, *add, *clear;
291 GtkTreeViewColumn *column;
292 GtkCellRenderer *renderer;
293 MPlist *bindings, *pl, *cmd;
296 current_lang = g_object_get_data (G_OBJECT (button), "mim_lang");
297 current_name = g_object_get_data (G_OBJECT (button), "mim_name");
298 current_command = g_object_get_data (G_OBJECT (button), "mim_command");
299 bindings = get_command_bindings (current_lang, current_name, current_command);
301 dialog = (gtk_dialog_new_with_buttons
302 (msymbol_name (current_command),
303 GTK_WINDOW (gtk_widget_get_toplevel (frame)),
304 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
305 GTK_STOCK_OK, GTK_RESPONSE_OK,
306 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
309 store = gtk_list_store_new (1, G_TYPE_POINTER);
310 for (pl = bindings; pl && mplist_key (pl) == Mplist; pl = mplist_next (pl))
312 gtk_list_store_append (store, &iter);
313 gtk_list_store_set (store, &iter, 0, mplist_value (pl), -1);
315 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
316 g_object_unref (G_OBJECT (store));
317 column = gtk_tree_view_column_new ();
318 gtk_tree_view_column_set_title (column, "Current bindings");
319 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
320 renderer = gtk_cell_renderer_text_new ();
321 gtk_tree_view_column_pack_start (column, renderer, TRUE);
322 gtk_tree_view_column_set_cell_data_func
323 (column, renderer, keyseq_render_function, NULL, NULL);
324 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view);
326 delete = gtk_button_new_from_stock (GTK_STOCK_DELETE);
327 g_signal_connect (G_OBJECT (delete), "clicked",
328 G_CALLBACK (delete_cb), view);
329 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), delete);
331 entry_keyseq = mplist ();
333 entry = gtk_entry_new ();
334 g_signal_connect (G_OBJECT (entry), "key-press-event",
335 G_CALLBACK (key_pressed), NULL);
336 g_signal_connect (G_OBJECT (entry), "key-release-event",
337 G_CALLBACK (key_released), NULL);
338 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), entry);
340 clear = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
341 g_signal_connect (G_OBJECT (clear), "clicked",
342 G_CALLBACK (clear_cb), entry);
343 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), clear);
345 add = gtk_button_new_from_stock (GTK_STOCK_ADD);
346 g_signal_connect (G_OBJECT (add), "clicked",
347 G_CALLBACK (add_cb), store);
348 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), add);
350 gtk_widget_show_all (dialog);
351 response = gtk_dialog_run (GTK_DIALOG (dialog));
352 gtk_widget_destroy (dialog);
354 m17n_object_unref (entry_keyseq);
358 create_command_entries (GtkWidget *frame, GtkTooltips *tip,
359 MSymbol lang, MSymbol name)
364 plist = minput_get_command (lang, name, Mnil);
369 message = gtk_label_new ("No commands for this method");
370 gtk_container_add (GTK_CONTAINER (frame), message);
375 * plist == ((command description status keyseq keyseq ...)
376 * (command description status keyseq keyseq ...)
379 vbox = gtk_vbox_new (FALSE, 0);
380 gtk_container_add (GTK_CONTAINER (frame), vbox);
382 for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist))
389 pl = mplist_value (plist);
390 /* pl == (command description status keyseq keyseq ...) */
391 command = mplist_value (pl);
392 button = gtk_button_new_with_label (msymbol_name (command));
393 gtk_container_add (GTK_CONTAINER (vbox), button);
395 pl = mplist_next (pl);
396 /* pl == (description status keyseq keyseq ...) */
397 if (mplist_key (pl) == Mtext)
398 /* Fixme : Assuming the return value is in UTF-8 */
399 desc = mtext_data (mplist_value (pl), NULL, NULL, NULL, NULL);
402 gtk_tooltips_set_tip (tip, button, desc, NULL);
404 g_object_set_data (G_OBJECT (button), "mim_lang", lang);
405 g_object_set_data (G_OBJECT (button), "mim_name", name);
406 g_object_set_data (G_OBJECT (button), "mim_command", command);
407 g_signal_connect (G_OBJECT (button), "clicked",
408 G_CALLBACK (command_cb), frame);
410 m17n_object_unref (plist);