2 Scim-Unikey Input Method
4 Copyright (C) 2008-2009 Ubuntu-VN <http://www.ubuntu-vn.org>
5 Author: Le Quoc Tuan <mr.lequoctuan@gmail.com>
6 Home: http://scim-unikey.googlecode.com
7 License: GNU LESSER GENERAL PUBLIC LICENSE v2.1
10 #define Uses_SCIM_CONFIG_BASE
13 #define _(String) dgettext(PACKAGE_NAME,String)
20 #include "scim_unikey_const.h"
21 #include "scim_unikey_utils.h"
24 #include "scimkeyselection.h"
28 #define scim_module_init unikey_setup_LTX_scim_module_init
29 #define scim_module_exit unikey_setup_LTX_scim_module_exit
31 #define scim_setup_module_create_ui unikey_setup_LTX_scim_setup_module_create_ui
32 #define scim_setup_module_get_category unikey_setup_LTX_scim_setup_module_get_category
33 #define scim_setup_module_get_name unikey_setup_LTX_scim_setup_module_get_name
34 #define scim_setup_module_get_description unikey_setup_LTX_scim_setup_module_get_description
35 #define scim_setup_module_load_config unikey_setup_LTX_scim_setup_module_load_config
36 #define scim_setup_module_save_config unikey_setup_LTX_scim_setup_module_save_config
37 #define scim_setup_module_query_changed unikey_setup_LTX_scim_setup_module_query_changed
39 static bool __have_changed = false;
41 static bool __unikey_preedit = SCIM_IMENGINE_UNIKEY_PREEDIT_DEF;
42 static bool __unikey_freemarking = SCIM_IMENGINE_UNIKEY_FREEMARKING_DEF;
43 static bool __unikey_modernstyle = SCIM_IMENGINE_UNIKEY_MODERNSTYLE_DEF;
44 static bool __unikey_macroenabled = SCIM_IMENGINE_UNIKEY_MACROENABLED_DEF;
45 static bool __unikey_spellcheckenabled = SCIM_IMENGINE_UNIKEY_SPELLCHECKENABLED_DEF;
46 static bool __unikey_autononvnrestore = SCIM_IMENGINE_UNIKEY_AUTONONVNRESTORE_DEF;
47 static bool __unikey_codertelex = SCIM_IMENGINE_UNIKEY_CODERTELEX_DEF;
48 static bool __unikey_processwatwordbegin = SCIM_IMENGINE_UNIKEY_PROCESSWATWORDBEGIN_DEF;
50 static GtkTooltips *__widget_tooltips = 0;
51 static GtkWidget *__widget_preedit = 0;
52 static GtkWidget *__widget_preedit_skey = 0;
53 static GtkWidget *__widget_freemarking = 0;
54 static GtkWidget *__widget_modernstyle = 0;
55 static GtkWidget *__widget_macroenabled = 0;
56 static GtkWidget *__widget_spellcheckenabled = 0;
57 static GtkWidget *__widget_autononvnrestore = 0;
58 static GtkWidget *__widget_codertelex = 0;
59 static GtkWidget *__widget_processwatwordbegin = 0;
60 static CMacroTable __macStore;
62 static GtkWidget* create_setup_window();
63 static void load_config(const ConfigPointer &config);
64 static void save_config(const ConfigPointer &config);
65 static bool query_changed();
67 static void setup_widget_value();
68 static GtkListStore* create_and_fill_list_store();
70 static void on_default_toggle_button_toggled(GtkToggleButton *togglebutton, gpointer user_data);
71 static void on_macrotable_button_clicked(GtkButton *button, gpointer user_data);
72 static void on_key_edited (GtkCellRendererText *celltext, const gchar *string_path, const gchar *new_text, gpointer data);
73 static void on_replace_edited (GtkCellRendererText *celltext, const gchar *string_path, const gchar *new_text, gpointer data);
74 static void on_end_macro_table(GtkListStore *liststore);
75 static void on_del_macro_clicked(GtkButton *button, gpointer user_data);
76 static void on_delall_macro_clicked(GtkButton *button, gpointer user_data);
77 static gboolean iter_2_macro(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
78 static void on_hotkey_button_clicked(GtkButton *button, gpointer user_data);
82 void scim_module_init(void)
86 void scim_module_exit(void)
90 GtkWidget * scim_setup_module_create_ui (void)
92 return create_setup_window();
95 String scim_setup_module_get_category (void)
97 return String("IMEngine");
100 String scim_setup_module_get_name(void)
102 return String(_("Unikey Setup"));
105 String scim_setup_module_get_description(void)
107 return String("Setup scim-unikey v" SCIM_UNIKEY_VERSION " IMEngine.");
110 void scim_setup_module_load_config(const ConfigPointer &config)
115 void scim_setup_module_save_config(const ConfigPointer &config)
120 bool scim_setup_module_query_changed()
122 return query_changed();
126 static GtkWidget* create_setup_window()
128 static GtkWidget *window = 0;
131 gtk_window_set_default_icon_from_file(SCIM_ICONDIR SCIM_UNIKEY_ICON_FILENAME, NULL);
132 __widget_tooltips = gtk_tooltips_new();
134 // Create the toplevel box.
135 window = gtk_hbox_new(false, 0);
138 GtkWidget *vbox0 = gtk_vbox_new(false, 0);
139 gtk_box_pack_start(GTK_BOX(window), vbox0, false, false, 0);
141 // create Common Frame
142 GtkWidget *fr = gtk_frame_new(_("Unikey option"));
143 gtk_box_pack_start(GTK_BOX(vbox0), fr, false, false, 0);
145 GtkWidget *vbox = gtk_vbox_new(false, 5);
146 gtk_container_add(GTK_CONTAINER(fr), vbox);
147 gtk_container_set_border_width(GTK_CONTAINER(fr), 5);
149 // create spellcheck checkbox
150 __widget_spellcheckenabled = gtk_check_button_new_with_label(_("Enable spell check"));
151 gtk_box_pack_start(GTK_BOX(vbox), __widget_spellcheckenabled, false, false, 0);
152 gtk_container_set_border_width(GTK_CONTAINER(__widget_spellcheckenabled), 5);
153 g_signal_connect(__widget_spellcheckenabled, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_spellcheckenabled);
155 gtk_tooltips_set_tip (__widget_tooltips, __widget_spellcheckenabled,
156 _("If enable, you can decrease mistake when typing"), NULL);
158 // create autononvnrestore checkbox
159 __widget_autononvnrestore = gtk_check_button_new_with_label(_("Auto restore keys with invalid words"));
160 gtk_box_pack_start(GTK_BOX(vbox), __widget_autononvnrestore, false, false, 0);
161 gtk_container_set_border_width(GTK_CONTAINER(__widget_autononvnrestore), 5);
162 g_signal_connect(__widget_autononvnrestore, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_autononvnrestore);
164 gtk_tooltips_set_tip (__widget_tooltips, __widget_autononvnrestore,
165 _("When typing a word not in Vietnamese,\n"
166 "it will auto restore keystroke into orginal"), NULL);
168 // create modernstyle checkbox
169 __widget_modernstyle = gtk_check_button_new_with_label(_("Use oà, uý (instead of òa, úy)"));
170 gtk_box_pack_start(GTK_BOX(vbox), __widget_modernstyle, false, false, 0);
171 gtk_container_set_border_width(GTK_CONTAINER(__widget_modernstyle), 5);
172 g_signal_connect(__widget_modernstyle, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_modernstyle);
174 // create freemarking checkbox
175 __widget_freemarking = gtk_check_button_new_with_label(_("Allow type with more freedom"));
176 gtk_box_pack_start(GTK_BOX(vbox), __widget_freemarking, false, false, 0);
177 gtk_container_set_border_width(GTK_CONTAINER(__widget_freemarking), 5);
178 g_signal_connect(__widget_freemarking, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_freemarking);
181 // create preedit frame
183 GtkWidget *prefr = gtk_frame_new(_("Typing mode"));
184 gtk_container_set_border_width(GTK_CONTAINER(prefr), 5);
185 gtk_box_pack_start(GTK_BOX(vbox0), prefr, false, false, 0);
187 vbox = gtk_vbox_new(false, 5);
188 gtk_container_add(GTK_CONTAINER(prefr), vbox);
190 // create preedit switch key
191 GtkWidget *psbox = gtk_hbox_new(false, 0);
192 gtk_box_pack_start(GTK_BOX(vbox), psbox, false, false, 0);
194 GtkWidget *lpskey = gtk_label_new(_("Mode switch key:"));
195 gtk_box_pack_start(GTK_BOX(psbox), lpskey, false, false, 5);
197 __widget_preedit_skey = gtk_entry_new();
198 gtk_entry_set_editable(GTK_ENTRY(__widget_preedit_skey), false);
199 gtk_box_pack_start(GTK_BOX(psbox), __widget_preedit_skey, true, false, 0);
201 GtkWidget *bpskey = gtk_button_new_with_label("...");
202 gtk_box_pack_start(GTK_BOX(psbox), bpskey, true, true, 0);
203 gtk_container_set_border_width(GTK_CONTAINER(bpskey), 5);
204 g_signal_connect(bpskey, "clicked", G_CALLBACK(on_hotkey_button_clicked), __widget_preedit_skey);
207 // create preedit checkbox
208 __widget_preedit = gtk_check_button_new_with_label(_("Preedit is default"));
209 gtk_box_pack_start(GTK_BOX(vbox), __widget_preedit, false, false, 0);
210 gtk_container_set_border_width(GTK_CONTAINER(__widget_preedit), 5);
211 g_signal_connect(__widget_preedit, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_preedit);
213 gtk_tooltips_set_tip (__widget_tooltips, __widget_preedit,
214 _("This option is best for most application\n"
215 "But you may don't like it because it have an underline when typing"), NULL);
220 vbox = gtk_vbox_new(false, 0);
221 gtk_box_pack_start(GTK_BOX(window), vbox, true, true, 0);
224 fr = gtk_frame_new(_("Macro option"));
225 gtk_box_pack_start(GTK_BOX(vbox), fr, false, true, 0);
226 gtk_container_set_border_width(GTK_CONTAINER(fr), 5);
229 GtkWidget *fr2 = gtk_frame_new(_("Telex option"));
230 gtk_box_pack_start(GTK_BOX(vbox), fr2, false, false, 0);
231 gtk_container_set_border_width(GTK_CONTAINER(fr2), 5);
233 vbox = gtk_vbox_new(false, 5);
234 gtk_container_add(GTK_CONTAINER(fr), vbox);
236 // create macroenabled checkbox
237 __widget_macroenabled = gtk_check_button_new_with_label(_("Enable Macro"));
238 gtk_box_pack_start(GTK_BOX(vbox), __widget_macroenabled, false, false, 0);
239 gtk_container_set_border_width(GTK_CONTAINER(__widget_macroenabled), 5);
240 g_signal_connect(__widget_macroenabled, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_macroenabled);
242 // create macroedit button
243 GtkWidget* __widget_macrotable = gtk_button_new_with_label(_("Macro Table"));
244 gtk_box_pack_start(GTK_BOX(vbox), __widget_macrotable, false, false, 0);
245 gtk_container_set_border_width(GTK_CONTAINER(__widget_macrotable), 5);
246 g_signal_connect(__widget_macrotable, "clicked", G_CALLBACK(on_macrotable_button_clicked), NULL);
248 gtk_tooltips_set_tip (__widget_tooltips, __widget_macrotable,
249 _("Edit the macro table for Macro function"), NULL);
253 vbox = gtk_vbox_new(false, 5);
254 gtk_container_add(GTK_CONTAINER(fr2), vbox);
256 // create process w at word begin checkbox
257 __widget_processwatwordbegin = gtk_check_button_new_with_label(_("Process W at word begin"));
258 gtk_box_pack_start(GTK_BOX(vbox), __widget_processwatwordbegin, false, false, 0);
259 gtk_container_set_border_width(GTK_CONTAINER(__widget_processwatwordbegin), 5);
260 g_signal_connect(__widget_processwatwordbegin, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_processwatwordbegin);
262 gtk_tooltips_set_tip (__widget_tooltips, __widget_processwatwordbegin,
263 _("If enable, type W at begin\n"
264 "of word will change to Ư."), NULL);
266 // create coder telex checkbox
267 __widget_codertelex = gtk_check_button_new_with_label(_("Not use [,],{,} on Telex"));
268 gtk_box_pack_start(GTK_BOX(vbox), __widget_codertelex, false, false, 0);
269 gtk_container_set_border_width(GTK_CONTAINER(__widget_codertelex), 5);
270 g_signal_connect(__widget_codertelex, "toggled", G_CALLBACK(on_default_toggle_button_toggled), &__unikey_codertelex);
272 gtk_tooltips_set_tip (__widget_tooltips, __widget_codertelex,
273 _("Not use [,],{,} for map on Telex"), NULL);
276 setup_widget_value();
277 gtk_widget_show_all(window);
282 static void setup_widget_value()
284 if (__widget_preedit)
285 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_preedit), __unikey_preedit);
287 if (__widget_spellcheckenabled)
288 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_spellcheckenabled), __unikey_spellcheckenabled);
290 if (__widget_autononvnrestore)
291 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_autononvnrestore), __unikey_autononvnrestore);
293 if (__widget_modernstyle)
294 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_modernstyle), __unikey_modernstyle);
296 if (__widget_freemarking)
297 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_freemarking), __unikey_freemarking);
299 if (__widget_macroenabled)
300 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_macroenabled), __unikey_macroenabled);
302 if (__widget_codertelex)
303 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_codertelex), __unikey_codertelex);
305 if (__widget_processwatwordbegin)
306 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(__widget_processwatwordbegin), __unikey_processwatwordbegin);
309 static void load_config(const ConfigPointer &config)
314 t = config->read(SCIM_IMENGINE_UNIKEY_PREEDIT, &__unikey_preedit);
315 if (!t) __unikey_preedit = SCIM_IMENGINE_UNIKEY_PREEDIT_DEF;
318 t = config->read(SCIM_IMENGINE_UNIKEY_PREEDIT_SWITCH_KEY, &s);
319 gtk_entry_set_text(GTK_ENTRY(__widget_preedit_skey), t?s.c_str():SCIM_IMENGINE_UNIKEY_PREEDIT_SWITCH_KEY_DEF);
321 t = config->read(SCIM_IMENGINE_UNIKEY_FREEMARKING, &__unikey_freemarking);
322 if (!t) __unikey_freemarking = SCIM_IMENGINE_UNIKEY_FREEMARKING_DEF;
324 t = config->read(SCIM_IMENGINE_UNIKEY_MODERNSTYLE, &__unikey_modernstyle);
325 if (!t) __unikey_modernstyle = SCIM_IMENGINE_UNIKEY_MODERNSTYLE_DEF;
327 t = config->read(SCIM_IMENGINE_UNIKEY_MACROENABLED, &__unikey_macroenabled);
328 if (!t) __unikey_macroenabled = SCIM_IMENGINE_UNIKEY_MACROENABLED_DEF;
330 t = config->read(SCIM_IMENGINE_UNIKEY_SPELLCHECKENABLED, &__unikey_spellcheckenabled);
331 if (!t) __unikey_spellcheckenabled = SCIM_IMENGINE_UNIKEY_SPELLCHECKENABLED_DEF;
333 t = config->read(SCIM_IMENGINE_UNIKEY_AUTONONVNRESTORE, &__unikey_autononvnrestore);
334 if (!t) __unikey_autononvnrestore = SCIM_IMENGINE_UNIKEY_AUTONONVNRESTORE_DEF;
336 t = config->read(SCIM_IMENGINE_UNIKEY_CODERTELEX, &__unikey_codertelex);
337 if (!t) __unikey_codertelex = SCIM_IMENGINE_UNIKEY_CODERTELEX_DEF;
339 t = config->read(SCIM_IMENGINE_UNIKEY_PROCESSWATWORDBEGIN, &__unikey_processwatwordbegin);
340 if (!t) __unikey_processwatwordbegin = SCIM_IMENGINE_UNIKEY_PROCESSWATWORDBEGIN_DEF;
343 __macStore.loadFromFile(getMacroFile());
345 setup_widget_value();
346 __have_changed = false;
350 static void save_config(const ConfigPointer &config)
354 config->write(SCIM_IMENGINE_UNIKEY_PREEDIT, __unikey_preedit);
355 String s = String(gtk_entry_get_text(GTK_ENTRY(__widget_preedit_skey)));
356 config->write(SCIM_IMENGINE_UNIKEY_PREEDIT_SWITCH_KEY, s);
357 config->write(SCIM_IMENGINE_UNIKEY_FREEMARKING, __unikey_freemarking);
358 config->write(SCIM_IMENGINE_UNIKEY_MODERNSTYLE, __unikey_modernstyle);
359 config->write(SCIM_IMENGINE_UNIKEY_MACROENABLED, __unikey_macroenabled);
360 config->write(SCIM_IMENGINE_UNIKEY_SPELLCHECKENABLED, __unikey_spellcheckenabled);
361 config->write(SCIM_IMENGINE_UNIKEY_AUTONONVNRESTORE, __unikey_autononvnrestore);
362 config->write(SCIM_IMENGINE_UNIKEY_AUTONONVNRESTORE, __unikey_autononvnrestore);
363 config->write(SCIM_IMENGINE_UNIKEY_CODERTELEX, __unikey_codertelex);
364 config->write(SCIM_IMENGINE_UNIKEY_PROCESSWATWORDBEGIN, __unikey_processwatwordbegin);
366 s = String(getMacroFile());
367 FILE *f = fopen(s.c_str(), "wt");
370 s = s.substr(0, s.rfind('/'));
371 int tmp=system((String("mkdir ") + s).c_str());
376 __macStore.writeToFile(getMacroFile());
378 __have_changed = false;
382 static bool query_changed()
384 return __have_changed;
387 static void on_default_toggle_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
389 bool *toggle = static_cast<bool*> (user_data);
393 *toggle = gtk_toggle_button_get_active (togglebutton);
394 __have_changed = true;
398 enum {COL_KEY = 0, COL_REPLACE, NUM_COLS};
400 static void on_macrotable_button_clicked(GtkButton *button, gpointer user_data)
405 GtkTreeViewColumn *col;
406 GtkWidget *contentarea;
407 GtkWidget *hbox, *vbox;
408 GtkCellRenderer *renderer;
410 // create main dialog
411 dialog = gtk_dialog_new();
412 gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 300);
413 gtk_window_set_title(GTK_WINDOW(dialog), _("Macro table definition"));
414 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
415 GTK_STOCK_OK, GTK_RESPONSE_OK,
416 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
419 //contentarea = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // only for GTK >= 2.14
420 contentarea = GTK_DIALOG(dialog)->vbox;
422 hbox = gtk_hbox_new (false, 5);
423 gtk_container_add(GTK_CONTAINER(contentarea), hbox);
425 // create scroll window and tree view
426 model = GTK_TREE_MODEL(create_and_fill_list_store());
428 treeview = gtk_tree_view_new_with_model (model);
430 GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
431 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
433 gtk_box_pack_start(GTK_BOX(hbox), scroll, true, true, 0);
434 gtk_container_add(GTK_CONTAINER(scroll), treeview);
437 renderer = gtk_cell_renderer_text_new();
438 g_object_set(renderer, "editable", true, NULL);
439 g_object_set(renderer, "width-chars", MAX_MACRO_KEY_LEN+4, NULL);
440 g_signal_connect(renderer, "edited", G_CALLBACK(on_key_edited), model);
441 col = gtk_tree_view_column_new_with_attributes(_("Word"), renderer, "text", COL_KEY, NULL);
442 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), col);
444 // create replace column
445 renderer = gtk_cell_renderer_text_new();
446 g_object_set(renderer, "editable", true, NULL);
447 //g_object_set(renderer, "width-chars", MAX_MACRO_KEY_LEN*3, NULL);
448 g_signal_connect(renderer, "edited", G_CALLBACK(on_replace_edited), model);
449 col = gtk_tree_view_column_new_with_attributes(_("Replace with"), renderer, "text", COL_REPLACE, NULL);
450 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), col);
452 vbox = gtk_vbox_new (false, 0);
453 gtk_box_pack_end(GTK_BOX(hbox), vbox, false, false, 6);
456 GtkWidget* btDel = gtk_button_new_with_label (_("Delete"));
457 gtk_box_pack_start(GTK_BOX(vbox), btDel, false, true, 3);
458 g_signal_connect(btDel, "clicked", G_CALLBACK(on_del_macro_clicked), treeview);
460 // create DelAll button
461 GtkWidget *btDelAll = gtk_button_new_with_label (_("Delete All"));
462 gtk_box_pack_start(GTK_BOX(vbox), btDelAll, false, true, 3);
463 g_signal_connect(btDelAll, "clicked", G_CALLBACK(on_delall_macro_clicked), model);
465 gtk_widget_show_all(dialog);
466 gint result = gtk_dialog_run(GTK_DIALOG(dialog));
469 if (result == GTK_RESPONSE_OK)
472 gtk_tree_model_foreach(model, iter_2_macro, NULL);
474 __have_changed = true;
477 g_object_unref(model);
478 gtk_widget_destroy(dialog);
481 static void on_end_macro_table(GtkListStore *liststore)
487 n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(liststore), NULL);
490 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(liststore), &iter, NULL, n-1);
494 gtk_list_store_append(liststore, &iter);
495 gtk_list_store_set(liststore, &iter, COL_KEY, "...", COL_REPLACE, "...", -1);
499 gtk_tree_model_get(GTK_TREE_MODEL(liststore), &iter, COL_KEY, &lastkey, -1);
500 if (strcmp(lastkey, "...") || n==0)
502 gtk_list_store_append(liststore, &iter);
503 gtk_list_store_set(liststore, &iter, COL_KEY, "...", COL_REPLACE, "...", -1);
507 static void on_del_macro_clicked(GtkButton *button, gpointer user_data)
509 GtkTreeView *treeview;
510 GtkListStore *liststore;
511 GtkTreeSelection*tselect;
515 treeview = GTK_TREE_VIEW(user_data);
516 tselect = gtk_tree_view_get_selection(treeview);
518 if (gtk_tree_selection_get_selected(tselect, NULL, &iter))
520 liststore = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
521 gtk_tree_model_get(GTK_TREE_MODEL(liststore), &iter, COL_KEY, &lastkey, -1);
522 if (strcmp(lastkey, "..."))
523 gtk_list_store_remove(liststore, &iter);
527 static void on_delall_macro_clicked(GtkButton *button, gpointer user_data)
529 GtkListStore *liststore;
532 liststore = GTK_LIST_STORE(user_data);
534 gtk_list_store_clear(liststore);
535 on_end_macro_table(liststore);
538 static GtkListStore* create_and_fill_list_store()
540 GtkListStore* liststore;
543 char key[MAX_MACRO_KEY_LEN*3], replace[MAX_MACRO_TEXT_LEN*3];
545 int i, inLen, maxOutLen, ret;
547 liststore = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);
549 // add key and replace to liststore
550 for (int i=0 ; i < __macStore.getCount() ; i++)
552 p = (UKBYTE *)__macStore.getKey(i);
554 maxOutLen = sizeof(key);
555 ret = VnConvert(CONV_CHARSET_VNSTANDARD, CONV_CHARSET_UNIUTF8,
556 (UKBYTE *) p, (UKBYTE *)key,
561 p = (UKBYTE *)__macStore.getText(i);
563 maxOutLen = sizeof(replace);
564 ret = VnConvert(CONV_CHARSET_VNSTANDARD, CONV_CHARSET_UNIUTF8,
565 p, (UKBYTE *)replace,
570 gtk_list_store_append(liststore, &iter);
571 gtk_list_store_set(liststore, &iter, COL_KEY, key, COL_REPLACE, replace, -1);
574 on_end_macro_table(liststore);
578 static void on_key_edited (GtkCellRendererText *celltext, const gchar *string_path, const gchar *new_text, gpointer data)
582 gchar *curkey, *oldkey, *oldreplace;
585 model = GTK_TREE_MODEL (data);
587 if (!strcmp(new_text, "..."))
590 b = gtk_tree_model_get_iter_first(model, &iter);
593 gtk_tree_model_get(model, &iter, COL_KEY, &curkey, -1);
594 if (!strcasecmp(curkey, new_text))
597 b = gtk_tree_model_iter_next(model, &iter);
599 gtk_tree_model_get_iter_from_string(model, &iter, string_path);
600 gtk_tree_model_get(model, &iter, COL_KEY, &oldkey, COL_REPLACE, &oldreplace, -1);
602 gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_KEY, new_text, -1);
603 if (!strcmp(oldkey, "..."))
604 gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_REPLACE, _("(replace text)"));
606 on_end_macro_table(GTK_LIST_STORE(model));
609 static void on_replace_edited (GtkCellRendererText *celltext, const gchar *string_path, const gchar *new_text, gpointer data)
615 model = GTK_TREE_MODEL (data);
616 gtk_tree_model_get_iter_from_string(model, &iter, string_path);
618 gtk_tree_model_get(model, &iter, COL_KEY, &oldkey, -1);
619 if (strcmp(oldkey, "..."))
620 gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_REPLACE, new_text, -1);
623 static gboolean iter_2_macro(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
625 gchar *key, *replace;
630 if (!gtk_tree_model_iter_next(model, &c))
632 gtk_tree_model_get(model, iter, COL_KEY, &key, COL_REPLACE, &replace, -1);
634 __macStore.addItem(key, replace, CONV_CHARSET_XUTF8);
639 static void on_hotkey_button_clicked (GtkButton *button, gpointer data)
641 GtkWidget *wid = (GtkWidget*)data;
643 GtkWidget *dialog = scim_key_selection_dialog_new("Edit hotkey");
645 const gchar *hotkeys = gtk_entry_get_text(GTK_ENTRY(wid));
649 scim_key_selection_dialog_set_keys(
650 SCIM_KEY_SELECTION_DIALOG(dialog), hotkeys);
653 r = gtk_dialog_run(GTK_DIALOG(dialog));
655 if (r == GTK_RESPONSE_OK)
657 const gchar *newkeys = scim_key_selection_dialog_get_keys(SCIM_KEY_SELECTION_DIALOG(dialog));
658 gtk_entry_set_text(GTK_ENTRY(wid), newkeys?newkeys:"");
659 __have_changed = true;
662 gtk_widget_destroy(dialog);