1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2004-2005 Takuro Ashie
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "scim_anthy_table_editor.h"
28 #include "scim_anthy_intl.h"
36 static void scim_anthy_table_editor_class_init (ScimAnthyTableEditorClass *klass);
37 static void scim_anthy_table_editor_init (ScimAnthyTableEditor *object);
38 static void scim_anthy_table_editor_dispose (GObject *object);
40 static void scim_anthy_table_editor_add_entry (ScimAnthyTableEditor *editor);
41 static void scim_anthy_table_editor_remove_entry (ScimAnthyTableEditor *editor);
43 static gint compare_string (GtkTreeModel *model,
48 static void on_table_view_selection_changed (GtkTreeSelection *selection,
50 static void on_add_button_clicked (GtkButton *button,
52 static void on_remove_button_clicked (GtkButton *button,
54 static void on_entry_activate (GtkEntry *entry,
56 static void on_entry_changed (GtkEditable *editable,
58 static void on_sequence_entry_insert_text (GtkEditable *editable,
64 static guint editor_signals[LAST_SIGNAL] = { 0 };
65 static GtkDialogClass *parent_class = NULL;
68 scim_anthy_table_editor_get_type (void)
70 static GType type = 0;
73 static const GTypeInfo info = {
74 sizeof (ScimAnthyTableEditorClass),
76 NULL, /* base_finalize */
77 (GClassInitFunc) scim_anthy_table_editor_class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (ScimAnthyTableEditor),
82 (GInstanceInitFunc) scim_anthy_table_editor_init,
85 type = g_type_register_static (GTK_TYPE_DIALOG,
86 "ScimAnthyTableEditor",
87 &info, (GTypeFlags) 0);
94 scim_anthy_table_editor_class_init (ScimAnthyTableEditorClass *klass)
96 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
97 //GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
99 parent_class = (GtkDialogClass *) g_type_class_peek_parent (klass);
101 editor_signals[ADD_ENTRY_SIGNAL] =
102 g_signal_new ("add-entry",
103 G_TYPE_FROM_CLASS (klass),
105 G_STRUCT_OFFSET (ScimAnthyTableEditorClass, add_entry),
107 g_cclosure_marshal_VOID__VOID,
109 editor_signals[REMOVE_ENTRY_SIGNAL] =
110 g_signal_new ("remove-entry",
111 G_TYPE_FROM_CLASS (klass),
113 G_STRUCT_OFFSET (ScimAnthyTableEditorClass, remove_entry),
115 g_cclosure_marshal_VOID__VOID,
118 gobject_class->dispose = scim_anthy_table_editor_dispose;
119 klass->add_entry = scim_anthy_table_editor_add_entry;
120 klass->remove_entry = scim_anthy_table_editor_remove_entry;
124 scim_anthy_table_editor_init (ScimAnthyTableEditor *editor)
126 gtk_dialog_add_buttons (GTK_DIALOG (editor),
127 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
130 gtk_window_set_default_size (GTK_WINDOW (editor), 350, 250);
131 gtk_window_set_position (GTK_WINDOW (editor),
132 GTK_WIN_POS_CENTER_ON_PARENT);
135 GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
136 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
137 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editor)->vbox), hbox,
139 gtk_widget_show (hbox);
142 GtkWidget *scrwin = gtk_scrolled_window_new (NULL, NULL);
143 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrwin),
145 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrwin),
146 GTK_POLICY_AUTOMATIC,
147 GTK_POLICY_AUTOMATIC);
148 gtk_box_pack_start (GTK_BOX (hbox), scrwin, TRUE, TRUE, 0);
149 gtk_widget_show (scrwin);
151 GtkWidget *treeview = gtk_tree_view_new ();
152 editor->treeview = treeview;
153 gtk_container_add (GTK_CONTAINER (scrwin), treeview);
154 gtk_widget_show (treeview);
156 GtkTreeSelection *selection;
157 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
158 g_signal_connect (G_OBJECT (selection), "changed",
159 G_CALLBACK (on_table_view_selection_changed), editor);
161 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
162 gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (treeview), TRUE);
165 GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
166 editor->button_area = vbox;
167 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 5);
168 gtk_widget_show (vbox);
170 editor->entries = NULL;
174 scim_anthy_table_editor_dispose (GObject *object)
176 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (object);
178 if (editor->entries) {
179 g_list_free (editor->entries);
180 editor->entries = NULL;
183 if (G_OBJECT_CLASS(parent_class)->dispose)
184 G_OBJECT_CLASS(parent_class)->dispose(object);
188 scim_anthy_table_editor_new (void)
190 return GTK_WIDGET(g_object_new (SCIM_ANTHY_TYPE_TABLE_EDITOR,
195 scim_anthy_table_editor_set_columns (ScimAnthyTableEditor *editor,
198 g_return_if_fail (SCIM_ANTHY_IS_TABLE_EDITOR (editor));
204 for (n_cols = 0; titles[n_cols]; n_cols++);
209 for (gint i = 0; i < n_cols; i++)
210 types[i] = G_TYPE_STRING;
212 GtkListStore *store = gtk_list_store_newv (n_cols, types);
213 gtk_tree_view_set_model (GTK_TREE_VIEW (editor->treeview),
214 GTK_TREE_MODEL (store));
217 for (int i = 0; i < n_cols; i++) {
218 GtkCellRenderer *cell;
219 GtkTreeViewColumn *column;
220 cell = gtk_cell_renderer_text_new ();
221 column = gtk_tree_view_column_new_with_attributes (titles[i], cell,
224 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
225 gtk_tree_view_column_set_fixed_width (column, 80);
226 gtk_tree_view_column_set_resizable(column, TRUE);
227 gtk_tree_view_append_column(GTK_TREE_VIEW(editor->treeview), column);
229 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), i,
231 GINT_TO_POINTER (i), NULL);
232 gtk_tree_view_column_set_sort_column_id (column, i);
236 for (int i = 0; i < n_cols; i++) {
237 GtkWidget *label = gtk_label_new_with_mnemonic (titles[i]);
238 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
239 gtk_box_pack_start (GTK_BOX (editor->button_area), label, FALSE, FALSE, 2);
240 gtk_widget_show (label);
242 GtkWidget *entry = gtk_entry_new ();
243 gtk_box_pack_start (GTK_BOX (editor->button_area), entry,
245 gtk_widget_set_size_request (entry, 80, -1);
246 g_signal_connect (G_OBJECT (entry), "activate",
247 G_CALLBACK (on_entry_activate), editor);
248 g_signal_connect (G_OBJECT (entry), "changed",
249 G_CALLBACK (on_entry_changed), editor);
251 g_signal_connect (G_OBJECT (entry), "insert-text",
252 G_CALLBACK (on_sequence_entry_insert_text),
254 gtk_widget_show (entry);
255 gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
257 editor->entries = g_list_append (editor->entries, entry);
261 GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_ADD);
262 editor->add_button = button;
263 gtk_box_pack_start (GTK_BOX (editor->button_area), button, FALSE, FALSE, 5);
264 g_signal_connect (G_OBJECT (button), "clicked",
265 G_CALLBACK (on_add_button_clicked), editor);
266 gtk_widget_set_sensitive (button, FALSE);
267 gtk_widget_show (button);
269 button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
270 editor->remove_button = button;
271 gtk_box_pack_start (GTK_BOX (editor->button_area), button, FALSE, FALSE, 5);
272 g_signal_connect (G_OBJECT (button), "clicked",
273 G_CALLBACK (on_remove_button_clicked), editor);
274 gtk_widget_set_sensitive (button, FALSE);
275 gtk_widget_show (button);
278 g_object_unref (store);
282 scim_anthy_table_editor_get_nth_text (ScimAnthyTableEditor *editor, guint nth)
284 g_return_val_if_fail (SCIM_ANTHY_IS_TABLE_EDITOR (editor), "");
286 GtkEntry *entry = GTK_ENTRY (g_list_nth_data (editor->entries, nth));
290 return gtk_entry_get_text (entry);
294 scim_anthy_table_editor_add_entry (ScimAnthyTableEditor *editor)
296 GtkTreeView *treeview = GTK_TREE_VIEW (editor->treeview);
297 GtkTreeModel *model = gtk_tree_view_get_model (treeview);
303 const gchar *sequence;
304 sequence = scim_anthy_table_editor_get_nth_text (editor, 0);
309 for (go_next = gtk_tree_model_get_iter_first (model, &iter);
311 go_next = gtk_tree_model_iter_next (model, &iter))
314 gtk_tree_model_get (model, &iter,
317 if (seq && !strcmp (sequence, seq)) {
326 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
330 for (i = 0, node = editor->entries;
332 i++, node = g_list_next (node))
334 const char *text = gtk_entry_get_text (GTK_ENTRY (node->data));
335 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
340 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
341 gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
342 gtk_tree_path_free (path);
346 scim_anthy_table_editor_remove_entry (ScimAnthyTableEditor *editor)
348 GtkTreeView *treeview = GTK_TREE_VIEW (editor->treeview);
349 GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
350 GtkTreeModel *model = NULL;
351 GtkTreeIter iter, next;
352 gboolean selected, success;
354 selected = gtk_tree_selection_get_selected (selection, &model, &iter);
358 gchar *sequence = NULL;
359 gtk_tree_model_get (model, &iter,
364 success = gtk_tree_model_iter_next (model, &next);
365 GtkTreePath *path = NULL;
367 path = gtk_tree_model_get_path (model, &next);
369 path = gtk_tree_model_get_path (model, &iter);
371 success = gtk_tree_path_prev (path);
375 gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
377 gtk_tree_path_free (path);
379 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
385 compare_string (GtkTreeModel *model,
390 gint n_cols, column, cur_column = GPOINTER_TO_INT (user_data);
393 n_cols = gtk_tree_model_get_n_columns (model);
395 if (cur_column < n_cols) {
396 gchar *seq1 = NULL, *seq2 = NULL;
397 gtk_tree_model_get (model, a,
400 gtk_tree_model_get (model, b,
405 } else if (seq1 && !seq2) {
407 } else if (seq1 && seq2) {
408 ret = strcmp (seq1, seq2);
416 for (column = 0; ret == 0 && column < n_cols; column++) {
417 gchar *seq1 = NULL, *seq2 = NULL;
419 if (cur_column == column)
422 gtk_tree_model_get (model, a,
425 gtk_tree_model_get (model, b,
430 } else if (seq1 && !seq2) {
432 } else if (!seq1 && !seq2) {
433 ret = strcmp (seq1, seq2);
445 on_table_view_selection_changed (GtkTreeSelection *selection, gpointer data)
447 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (data);
448 GtkTreeModel *model = NULL;
453 selected = gtk_tree_selection_get_selected (selection, &model, &iter);
455 if (editor->remove_button) {
457 gtk_widget_set_sensitive (editor->remove_button, true);
459 gtk_widget_set_sensitive (editor->remove_button, false);
467 for (i = 0, node = editor->entries;
469 i++, node = g_list_next (node))
472 gtk_tree_model_get (model, &iter,
475 gtk_entry_set_text (GTK_ENTRY (node->data), str);
479 for (node = editor->entries; node; node = g_list_next (node))
480 gtk_entry_set_text (GTK_ENTRY (node->data), "");
485 on_add_button_clicked (GtkButton *button, gpointer data)
487 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (data);
488 g_signal_emit (editor, editor_signals[ADD_ENTRY_SIGNAL], 0);
492 on_remove_button_clicked (GtkButton *button, gpointer data)
494 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (data);
495 g_signal_emit (editor, editor_signals[REMOVE_ENTRY_SIGNAL], 0);
499 on_entry_activate (GtkEntry *entry, gpointer data)
501 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (data);
502 g_signal_emit (editor, editor_signals[ADD_ENTRY_SIGNAL], 0);
506 on_entry_changed (GtkEditable *editable, gpointer data)
508 ScimAnthyTableEditor *editor = SCIM_ANTHY_TABLE_EDITOR (data);
511 if (!editor->entries || !editor->entries->data)
514 seq = gtk_entry_get_text (GTK_ENTRY (editor->entries->data));
515 gtk_widget_set_sensitive (editor->add_button,
520 on_sequence_entry_insert_text (GtkEditable *editable,
526 for (int i = 0; i < length; i++) {
527 if (!isascii (text[i]) || isspace (text[i])) {
528 g_signal_stop_emission_by_name (editable, "insert_text");