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,

Reply via email to