void uim_cand_win_vertical_gtk_set_index(UIMCandWinVerticalGtk *vertical_cwin, gint index) { UIMCandWinGtk *cwin; UIMCandWinVerticalGtkClass *vertical_cwin_class; UIMCandWinGtkClass *cwin_class; g_return_if_fail(UIM_IS_CAND_WIN_VERTICAL_GTK(vertical_cwin)); cwin = UIM_CAND_WIN_GTK(vertical_cwin); /* call parent method */ vertical_cwin_class = UIM_CAND_WIN_VERTICAL_GTK_GET_CLASS(vertical_cwin); cwin_class = g_type_class_peek_parent(vertical_cwin_class); cwin_class->set_index(cwin, index); if (cwin->candidate_index >= 0) { GtkTreePath *path; gint pos = index; if (cwin->display_limit) pos = cwin->candidate_index % cwin->display_limit; path = gtk_tree_path_new_from_indices(pos, -1); gtk_tree_view_set_cursor(GTK_TREE_VIEW(cwin->view), path, NULL, FALSE); gtk_tree_path_free(path); } else { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(cwin->view)); gtk_tree_selection_unselect_all(selection); uim_cand_win_gtk_update_label(cwin); } }
static gboolean tree_selection_change(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data) { UIMCandWinVerticalGtk *vertical_cwin = UIM_CAND_WIN_VERTICAL_GTK(data); UIMCandWinGtk *cwin = UIM_CAND_WIN_GTK(vertical_cwin); gint *indicies; gint idx; if (!cwin) return TRUE; if (cwin->block_index_selection) return TRUE; indicies = gtk_tree_path_get_indices(path); g_return_val_if_fail(indicies, TRUE); idx = *indicies + cwin->display_limit * cwin->page_index; if (!path_currently_selected && cwin->candidate_index != idx) { if (cwin->candidate_index >= 0) { cwin->candidate_index = idx; /* if emit "index-changed" here and IM deactivates this candwin, * activates new candwin and selects a candidate on new candwin * from index-changed callback, SEGV occurs in gtk because gtk tries to * select on old candwin after return of this tree_selection_change(). * To avoid SEGV, instead of emitting before selection change by gtk, * emit after selection changed by gtk. */ cwin->index_changed = TRUE; } uim_cand_win_gtk_update_label(cwin); if (cwin->candidate_index < 0) return FALSE; else return TRUE; } else { uim_cand_win_gtk_update_label(cwin); return TRUE; } }
void uim_cand_win_gtk_set_candidates(UIMCandWinGtk *cwin, guint display_limit, GSList *candidates) { gint i, nr_stores = 1; g_return_if_fail(UIM_IS_CAND_WIN_GTK(cwin)); if (cwin->stores == NULL) cwin->stores = g_ptr_array_new(); /* remove old data */ if (cwin->page_index >= 0 && cwin->page_index < (int) cwin->stores->len) { /* Remove data from current page to shrink the window */ if (cwin->stores->pdata[cwin->page_index]) gtk_list_store_clear(cwin->stores->pdata[cwin->page_index]); } for (i = cwin->stores->len - 1; i >= 0; i--) { GtkListStore *store = g_ptr_array_remove_index(cwin->stores, i); if (store) g_object_unref(G_OBJECT(store)); } cwin->candidate_index = -1; cwin->nr_candidates = g_slist_length(candidates); cwin->display_limit = display_limit; cwin->sub_window.active = FALSE; if (candidates == NULL) return; /* calculate number of GtkListStores to create */ if (display_limit) { nr_stores = cwin->nr_candidates / display_limit; if (cwin->nr_candidates > display_limit * nr_stores) nr_stores++; } /* create GtkListStores, and set candidates */ for (i = 0; i < nr_stores; i++) { GtkListStore *store = gtk_list_store_new(NR_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GSList *node; guint j; g_ptr_array_add(cwin->stores, store); /* set candidates */ for (j = i * display_limit, node = g_slist_nth(candidates, j); display_limit ? j < display_limit * (i + 1) : j < cwin->nr_candidates; j++, node = g_slist_next(node)) { GtkTreeIter ti; if (node) { uim_candidate cand = node->data; gtk_list_store_append(store, &ti); gtk_list_store_set(store, &ti, COLUMN_HEADING, uim_candidate_get_heading_label(cand), COLUMN_CANDIDATE, uim_candidate_get_cand_str(cand), COLUMN_ANNOTATION, uim_candidate_get_annotation_str(cand), TERMINATOR); } else { #if 0 /* * 2004-07-22 Takuro Ashie <*****@*****.**> * * FIXME!: * I think we shoudn't set any data for empty row. * It may cause incorrect action. */ gtk_list_store_append(store, &ti); gtk_list_store_set(store, &ti, COLUMN_HEADING, "", COLUMN_CANDIDATE, "", COLUMN_ANNOTATION, NULL, TERMINATOR); #endif } } } if (cwin->nr_candidates <= cwin->display_limit) { gtk_widget_set_sensitive(GTK_WIDGET(cwin->prev_page_button), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(cwin->next_page_button), FALSE); } else { gtk_widget_set_sensitive(GTK_WIDGET(cwin->prev_page_button), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(cwin->next_page_button), TRUE); } uim_cand_win_gtk_set_page(cwin, 0); uim_cand_win_gtk_update_label(cwin); }
void uim_cand_win_horizontal_gtk_set_index(UIMCandWinHorizontalGtk *horizontal_cwin, gint index) { gint new_page, prev_index; UIMCandWinGtk *cwin; g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(horizontal_cwin)); cwin = UIM_CAND_WIN_GTK(horizontal_cwin); prev_index = cwin->candidate_index; if (index >= (gint) cwin->nr_candidates) cwin->candidate_index = 0; else cwin->candidate_index = index; if (cwin->candidate_index >= 0 && cwin->display_limit) new_page = cwin->candidate_index / cwin->display_limit; else new_page = cwin->page_index; if (cwin->page_index != new_page) uim_cand_win_gtk_set_page(cwin, new_page); if (cwin->candidate_index >= 0) { gint pos; struct index_button *idxbutton, *prev_selected; GtkWidget *label; if (cwin->display_limit) pos = cwin->candidate_index % cwin->display_limit; else pos = cwin->candidate_index; idxbutton = g_ptr_array_index(horizontal_cwin->buttons, pos); prev_selected = (gpointer)horizontal_cwin->selected; if (prev_selected && prev_index != cwin->candidate_index) { label = gtk_bin_get_child(GTK_BIN(prev_selected->button)); gtk_widget_queue_draw(label); } label = gtk_bin_get_child(GTK_BIN(idxbutton->button)); gtk_widget_queue_draw(label); horizontal_cwin->selected = idxbutton; /* show subwin */ if (cwin->stores->pdata[new_page]) { char *annotation = NULL; GtkTreeModel *model = GTK_TREE_MODEL(cwin->stores->pdata[new_page]); GtkTreeIter iter; gtk_tree_model_iter_nth_child(model, &iter, NULL, pos); gtk_tree_model_get(model, &iter, COLUMN_ANNOTATION, &annotation, -1); if (annotation && *annotation) { if (!cwin->sub_window.window) uim_cand_win_gtk_create_sub_window(cwin); gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(cwin->sub_window.text_view)), annotation, -1); uim_cand_win_gtk_layout_sub_window(cwin); gtk_widget_show(cwin->sub_window.window); cwin->sub_window.active = TRUE; } else { if (cwin->sub_window.window) { gtk_widget_hide(cwin->sub_window.window); cwin->sub_window.active = FALSE; } } free(annotation); } } else { horizontal_cwin->selected = NULL; if (cwin->sub_window.window) { gtk_widget_hide(cwin->sub_window.window); cwin->sub_window.active = FALSE; } } uim_cand_win_gtk_update_label(cwin); }