Author: ek.kato
Date: Mon Sep 22 23:41:23 2008
New Revision: 5577
Modified:
trunk/gtk/gtk-im-uim.c
trunk/gtk/gtk-im-uim.h
trunk/gtk/uim-cand-win-gtk.c
trunk/gtk/uim-cand-win-gtk.h
Log:
* gtk/gtk-im-uim.h : Define IM_UIM_USE_NEW_PAGE_HANDLING for
optimized candidates handling.
* gtk/gtk-im.uim.c
- (get_page_candidates) : New. Return list of candidates for
the page.
- (free_candiadtes) : New.
- (cand_activate_cb) : Set candidates for the first page for
IM_UIM_USE_NEW_PAGE_HANDLING.
- (cand_select_cb) : Set candidates for the updated page for
IM_UIM_USE_NEW_PAGE_HANDLING.
- (cand_shift_page_cb) : Ditto.
* gtk/uim-cand-win-gtk.h
* gtk/uim-cand-win-gtk.c
- (uim_cand_win_gtk_dispose) : Add sanity check.
- (uim_cand_win_gtk_set_nr_candidates) : New. Initialize
candidates window condition.
- (uim_cand_win_gtk_set_candidates) : Add sanity check.
- (uim_cand_win_gtk_set_page_candidates) : New. Set caniddates
for the selected page.
- (uim_cand_win_gtk_set_page) : Simplify.
- (uim_cand_win_gtk_query_new_page_by_cand_select) : New.
- (uim_cand_win_gtk_query_new_page_by_shift_page) : New.
Modified: trunk/gtk/gtk-im-uim.c
==============================================================================
--- trunk/gtk/gtk-im-uim.c (original)
+++ trunk/gtk/gtk-im-uim.c Mon Sep 22 23:41:23 2008
@@ -647,16 +647,53 @@
}
}
+#if IM_UIM_USE_NEW_PAGE_HANDLING
+static GSList *
+get_page_candidates(IMUIMContext *uic,
+ guint page,
+ guint nr,
+ guint display_limit)
+{
+ gint i, page_nr, start;
+ GSList *list = NULL;
+
+ start = page * display_limit;
+ if ((nr - start) > display_limit)
+ page_nr = display_limit;
+ else
+ page_nr = nr - start;
+
+ for (i = start; i < (start + page_nr); i++) {
+ uim_candidate cand = uim_get_candidate(uic->uc, i,
+ display_limit ? (int)(i % display_limit) : i);
+ list = g_slist_prepend(list, cand);
+ }
+ list = g_slist_reverse(list);
+
+ return list;
+}
+
+static void
+free_candidates(GSList *candidates)
+{
+ g_slist_foreach(candidates, (GFunc)uim_candidate_free, NULL);
+ g_slist_free(candidates);
+}
+#endif /* IM_UIM_USE_NEW_PAGE_HANDLING */
+
static void
cand_activate_cb(void *ptr, int nr, int display_limit)
{
IMUIMContext *uic = (IMUIMContext *)ptr;
GSList *list = NULL;
+#if !IM_UIM_USE_NEW_PAGE_HANDLING
uim_candidate cand;
gint i;
+#endif
uic->cwin_is_active = TRUE;
+#if !IM_UIM_USE_NEW_PAGE_HANDLING
for (i = 0; i < nr; i++) {
cand = uim_get_candidate(uic->uc, i, display_limit ? i %
display_limit : i);
list = g_slist_prepend(list, cand);
@@ -667,6 +704,16 @@
g_slist_foreach(list, (GFunc)uim_candidate_free, NULL);
g_slist_free(list);
+#else
+ list = get_page_candidates(uic, 0, nr, display_limit);
+
+ uim_cand_win_gtk_set_nr_candidates(uic->cwin, nr, display_limit);
+ uic->cwin->candidate_index = -1; /* Don't select any candidate at first
*/
+ uim_cand_win_gtk_set_page_candidates(uic->cwin, 0, list);
+ uim_cand_win_gtk_set_page(uic->cwin, 0);
+
+ free_candidates(list);
+#endif /* IM_UIM_USE_NEW_PAGE_HANDLING */
layout_candwin(uic);
gtk_widget_show(GTK_WIDGET(uic->cwin));
@@ -683,9 +730,22 @@
cand_select_cb(void *ptr, int index)
{
IMUIMContext *uic = (IMUIMContext *)ptr;
+#if IM_UIM_USE_NEW_PAGE_HANDLING
+ guint new_page;
+#endif
layout_candwin(uic);
+#if IM_UIM_USE_NEW_PAGE_HANDLING
+ new_page = uim_cand_win_gtk_query_new_page_by_cand_select(uic->cwin,
index);
+ if (!uic->cwin->stores->pdata[new_page]) {
+ guint nr = uic->cwin->nr_candidates;
+ guint display_limit = uic->cwin->display_limit;
+ GSList *list = get_page_candidates(uic, new_page, nr, display_limit);
+ uim_cand_win_gtk_set_page_candidates(uic->cwin, new_page, list);
+ free_candidates(list);
+ }
+#endif /* IM_UIM_USE_NEW_PAGE_HANDLING */
g_signal_handlers_block_by_func(uic->cwin,
(gpointer)(uintptr_t)index_changed_cb, uic);
uim_cand_win_gtk_set_index(uic->cwin, index);
g_signal_handlers_unblock_by_func(uic->cwin,
(gpointer)(uintptr_t)index_changed_cb, uic);
@@ -695,11 +755,25 @@
cand_shift_page_cb(void *ptr, int direction)
{
IMUIMContext *uic = (IMUIMContext *)ptr;
+#if IM_UIM_USE_NEW_PAGE_HANDLING
+ guint new_page;
+#endif
layout_candwin(uic);
g_signal_handlers_block_by_func(uic->cwin,
(gpointer)(uintptr_t)index_changed_cb, uic);
+#if IM_UIM_USE_NEW_PAGE_HANDLING
+ new_page = uim_cand_win_gtk_query_new_page_by_shift_page(uic->cwin,
+ direction);
+ if (!uic->cwin->stores->pdata[new_page]) {
+ guint nr = uic->cwin->nr_candidates;
+ guint display_limit = uic->cwin->display_limit;
+ GSList *list = get_page_candidates(uic, new_page, nr, display_limit);
+ uim_cand_win_gtk_set_page_candidates(uic->cwin, new_page, list);
+ free_candidates(list);
+ }
+#endif /* IM_UIM_USE_NEW_PAGE_HANDLING */
uim_cand_win_gtk_shift_page(uic->cwin, direction);
if (uic->cwin->candidate_index != -1)
uim_set_candidate_index(uic->uc, uic->cwin->candidate_index);
Modified: trunk/gtk/gtk-im-uim.h
==============================================================================
--- trunk/gtk/gtk-im-uim.h (original)
+++ trunk/gtk/gtk-im-uim.h Mon Sep 22 23:41:23 2008
@@ -54,6 +54,9 @@
#define IM_UIM_USE_SNOOPER 0
#define IM_UIM_USE_TOPLEVEL 1
+/* enable per page candidates handling */
+#define IM_UIM_USE_NEW_PAGE_HANDLING 1
+
typedef struct _IMUIMContext {
struct _GtkIMContext parent;
struct _GtkIMContext *slave;
Modified: trunk/gtk/uim-cand-win-gtk.c
==============================================================================
--- trunk/gtk/uim-cand-win-gtk.c (original)
+++ trunk/gtk/uim-cand-win-gtk.c Mon Sep 22 23:41:23 2008
@@ -259,8 +259,10 @@
if (cwin->stores) {
guint i;
- for (i = 0; i < cwin->stores->len; i++)
- g_object_unref(G_OBJECT(cwin->stores->pdata[i]));
+ for (i = 0; i < cwin->stores->len; i++) {
+ if (cwin->stores->pdata[i])
+ g_object_unref(G_OBJECT(cwin->stores->pdata[i]));
+ }
g_ptr_array_free(cwin->stores, TRUE);
cwin->stores = NULL;
}
@@ -460,6 +462,44 @@
}
void
+uim_cand_win_gtk_set_nr_candidates(UIMCandWinGtk *cwin,
+ guint nr,
+ guint display_limit)
+{
+ gint i, nr_stores = 1;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_GTK(cwin));
+
+ cwin->nr_candidates = nr;
+ cwin->display_limit = display_limit;
+
+ 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 (G_OBJECT(store))
+ g_object_unref(G_OBJECT(store));
+ }
+ /* calculate number of GtkListStores to create */
+ if (display_limit) {
+ nr_stores = nr / display_limit;
+ if (cwin->nr_candidates > display_limit * nr_stores)
+ nr_stores++;
+ }
+
+ /* setup dummy array */
+ for (i = 0; i < nr_stores; i++)
+ g_ptr_array_add(cwin->stores, NULL);
+}
+
+void
uim_cand_win_gtk_set_candidates(UIMCandWinGtk *cwin,
guint display_limit,
GSList *candidates)
@@ -474,11 +514,13 @@
/* remove old data */
if (cwin->page_index >= 0 && cwin->page_index < (int) cwin->stores->len)
{
/* Remove data from current page to shrink the window */
- gtk_list_store_clear(cwin->stores->pdata[cwin->page_index]);
+ 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);
- g_object_unref(G_OBJECT(store));
+ if (store)
+ g_object_unref(G_OBJECT(store));
}
cwin->candidate_index = -1;
@@ -549,6 +591,50 @@
}
void
+uim_cand_win_gtk_set_page_candidates(UIMCandWinGtk *cwin,
+ guint page,
+ GSList *candidates)
+{
+ GtkListStore *store;
+ GSList *node;
+ gint j, len;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_GTK(cwin));
+
+ if (candidates == NULL)
+ return;
+
+ cwin->sub_window.active = FALSE;
+ len = g_slist_length(candidates);
+
+ /* create GtkListStores, and set candidates */
+ store = gtk_list_store_new(NR_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ cwin->stores->pdata[page] = store;
+
+ /* set candidates */
+ for (j = 0, node = g_slist_nth(candidates, j);
+ j < len;
+ 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, NULL,
/*uim_candidate_get_annotation(cand),*/
+ TERMINATOR);
+ }
+ }
+}
+
+void
uim_cand_win_gtk_clear_candidates(UIMCandWinGtk *cwin)
{
uim_cand_win_gtk_set_candidates(cwin, 0, NULL);
@@ -638,19 +724,15 @@
len = cwin->stores->len;
g_return_if_fail(len);
- if (page < 0) {
- gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
- GTK_TREE_MODEL(cwin->stores->pdata[len - 1]));
+ if (page < 0)
new_page = len - 1;
- } else if (page >= (gint) len) {
- gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
- GTK_TREE_MODEL(cwin->stores->pdata[0]));
+ else if (page >= (gint) len)
new_page = 0;
- } else {
- gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
- GTK_TREE_MODEL(cwin->stores->pdata[page]));
+ else
new_page = page;
- }
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
+ GTK_TREE_MODEL(cwin->stores->pdata[new_page]));
cwin->page_index = new_page;
@@ -691,6 +773,50 @@
} else {
uim_cand_win_gtk_set_page(cwin, cwin->page_index - 1);
}
+}
+
+guint
+uim_cand_win_gtk_query_new_page_by_cand_select(UIMCandWinGtk *cwin, gint
index)
+{
+ guint new_page;
+
+ g_return_val_if_fail(UIM_IS_CAND_WIN_GTK(cwin), 0);
+
+ if (index >= (gint)cwin->nr_candidates)
+ index = 0;
+
+ if (index >= 0 && cwin->display_limit)
+ new_page = index / cwin->display_limit;
+ else
+ new_page = cwin->page_index;
+
+ return new_page;
+}
+
+guint
+uim_cand_win_gtk_query_new_page_by_shift_page(UIMCandWinGtk *cwin,
+ gboolean forward)
+{
+ gint index;
+ guint new_page, len;
+
+ g_return_val_if_fail(UIM_IS_CAND_WIN_GTK(cwin), 0);
+
+ len = cwin->stores->len;
+
+ if (forward)
+ index = cwin->page_index + 1;
+ else
+ index = cwin->page_index - 1;
+
+ if (index < 0)
+ new_page = len - 1;
+ else if (index >= (gint)len)
+ new_page = 0;
+ else
+ new_page = index;
+
+ return new_page;
}
void
Modified: trunk/gtk/uim-cand-win-gtk.h
==============================================================================
--- trunk/gtk/uim-cand-win-gtk.h (original)
+++ trunk/gtk/uim-cand-win-gtk.h Mon Sep 22 23:41:23 2008
@@ -96,6 +96,12 @@
void uim_cand_win_gtk_set_candidates (UIMCandWinGtk *cwin,
guint disp_limit,
GSList *candidates);
+void uim_cand_win_gtk_set_page_candidates (UIMCandWinGtk *cwin,
+ guint page,
+ GSList *candidates);
+void uim_cand_win_gtk_set_nr_candidates (UIMCandWinGtk *cwin,
+ guint nr,
+ guint disp_limit);
void uim_cand_win_gtk_clear_candidates (UIMCandWinGtk *cwin);
guint uim_cand_win_gtk_get_nr_candidates (UIMCandWinGtk *cwin);
gint uim_cand_win_gtk_get_index (UIMCandWinGtk *cwin);
@@ -107,6 +113,12 @@
void uim_cand_win_gtk_set_page (UIMCandWinGtk *cwin,
gint page);
void uim_cand_win_gtk_shift_page (UIMCandWinGtk *cwin,
+ gboolean forward);
+guint uim_cand_win_gtk_query_new_page_by_cand_select
+ (UIMCandWinGtk *cwin,
+ gint index);
+guint uim_cand_win_gtk_query_new_page_by_shift_page
+ (UIMCandWinGtk *cwin,
gboolean forward);
void uim_cand_win_gtk_set_scrollable (UIMCandWinGtk *cwin,