[maemo-developers] how to get the current item of GtkEntryCompletion list when up arrows moves throuth items

From: bocheng at redflag-linux.com bocheng at redflag-linux.com
Date: Wed Mar 14 08:44:43 EET 2007
在 2007年3月13日 星期二 17:12,bocheng at redflag-linux.com 写道:
I  modified gtkentry.c , it just works well ,below is the patch for it in gtk 
2.6.10


--- gtk+/gtk/gtkentry.c 2007-03-14 10:17:39.000000000 +0800
+++ new/gtk/gtkentry.c  2007-03-14 14:33:47.568511424 +0800
@@ -78,6 +78,9 @@
 typedef struct _GtkEntryPrivate GtkEntryPrivate;

 #define GTK_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), 
GTK_TYPE_ENTRY, GtkEntryPrivate))
+typedef struct {GtkEntry * entry ;
+       GtkEntryCompletion * completion;}
+arg;

 struct _GtkEntryPrivate
 {
@@ -5727,7 +5730,7 @@
   if (keyval == GDK_Up || keyval == GDK_KP_Up)
     return TRUE;

-  if (keyval == GDK_Down || keyval == GDK_KP_Down)
+  if (keyval == GDK_Down || keyval == GDK_KP_Down||keyval == GDK_Tab||keyval 
== GDK_KP_Tab )
     return TRUE;

   if (keyval == GDK_Page_Up)
@@ -5745,7 +5748,7 @@
                                 gpointer     user_data)
 {
   gint matches, actions = 0;
-  GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
+  GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION 
(((arg*)user_data)->completion);

   if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
     return FALSE;
@@ -5766,87 +5769,118 @@
          else
            completion->priv->current_selected--;
         }
-      else if (event->keyval == GDK_Down || event->keyval == GDK_KP_Down)
-        {
-          if (completion->priv->current_selected < matches + actions - 1)
-           completion->priv->current_selected++;
-         else
-            completion->priv->current_selected = -1;
-        }
-      else if (event->keyval == GDK_Page_Up)
-       {
-         if (completion->priv->current_selected < 0)
-           completion->priv->current_selected = matches + actions - 1;
-         else if (completion->priv->current_selected == 0)
-           completion->priv->current_selected = -1;
-         else if (completion->priv->current_selected < matches)
-           {
-             completion->priv->current_selected -= 14;
-             if (completion->priv->current_selected < 0)
-               completion->priv->current_selected = 0;
-           }
-         else
-           {
-             completion->priv->current_selected -= 14;
-             if (completion->priv->current_selected < matches - 1)
-               completion->priv->current_selected = matches - 1;
-           }
-       }
-      else if (event->keyval == GDK_Page_Down)
-       {
-         if (completion->priv->current_selected < 0)
-           completion->priv->current_selected = 0;
-         else if (completion->priv->current_selected < matches - 1)
-           {
-             completion->priv->current_selected += 14;
-             if (completion->priv->current_selected > matches - 1)
-               completion->priv->current_selected = matches - 1;
-           }
-         else if (completion->priv->current_selected == matches + actions - 
1)
-           {
-             completion->priv->current_selected = -1;
-           }
-         else
-           {
-             completion->priv->current_selected += 14;
-             if (completion->priv->current_selected > matches + actions - 1)
-               completion->priv->current_selected = matches + actions - 1;
-           }
-       }
+      else if (event->keyval == GDK_Down ||event->keyval == GDK_KP_Down || 
event->keyval==GDK_Tab || event->keyval==GDK_KP_Tab||
event->keyval==GDK_ISO_Left_Tab)
+      {
+             if (completion->priv->current_selected < matches + actions - 1)
+                     completion->priv->current_selected++;
+             else
+                     completion->priv->current_selected = -1;
+             /* for coolfox*/
+             {
+                     GtkTreeIter iter;
+                     GtkTreeModel *model = NULL;
+                     GtkTreeSelection *sel;
+                     model= gtk_tree_view_get_model (GTK_TREE_VIEW 
(completion->priv->tree_view));
+
+                     gchar *str = NULL;
+                     if(completion->priv->current_selected==-1)
+                     {
+
+                             gtk_entry_set_text (GTK_ENTRY 
(((arg*)user_data)->entry), "\0");

-      if (completion->priv->current_selected < 0)
-        {
-          gtk_tree_selection_unselect_all (gtk_tree_view_get_selection 
(GTK_TREE_VIEW (completion->priv->tree_view)));
-          gtk_tree_selection_unselect_all (gtk_tree_view_get_selection 
(GTK_TREE_VIEW (completion->priv->action_view)));
-        }
-      else if (completion->priv->current_selected < matches)
-        {
-          gtk_tree_selection_unselect_all (gtk_tree_view_get_selection 
(GTK_TREE_VIEW (completion->priv->action_view)));

-          path = gtk_tree_path_new_from_indices 
(completion->priv->current_selected, -1);
-          gtk_tree_view_set_cursor (GTK_TREE_VIEW 
(completion->priv->tree_view),
-                                    path, NULL, FALSE);
-        }
-      else if (completion->priv->current_selected - matches >= 0)
-        {
-          gtk_tree_selection_unselect_all (gtk_tree_view_get_selection 
(GTK_TREE_VIEW (completion->priv->tree_view)));

-          path = gtk_tree_path_new_from_indices 
(completion->priv->current_selected - matches, -1);
-          gtk_tree_view_set_cursor (GTK_TREE_VIEW 
(completion->priv->action_view),
-                                    path, NULL, FALSE);
-        }
+                     }
+                     else{
+                             char index[10]={0};
+                             
sprintf(index,"%d",completion->priv->current_selected);
+                             
gtk_tree_model_get_iter_from_string(model,&iter,index);
+                             
printf("***%d\n",completion->priv->current_selected) ;
+                             gtk_tree_model_get (model, &iter,
+                                             completion->priv->text_column, 
&str,
+                                             -1);

-      gtk_tree_path_free (path);
+                             gtk_entry_set_text (GTK_ENTRY 
(((arg*)user_data)->entry), str);
+                     }
+             }

-      return TRUE;
-    }
+             /*end coolfox*/
+
+      }
+             else if (event->keyval == GDK_Page_Up)
+             {
+                     if (completion->priv->current_selected < 0)
+                             completion->priv->current_selected = matches + 
actions - 1;
+                     else if (completion->priv->current_selected == 0)
+                             completion->priv->current_selected = -1;
+                     else if (completion->priv->current_selected < matches)
+                     {
+                             completion->priv->current_selected -= 14;
+                             if (completion->priv->current_selected < 0)
+                                     completion->priv->current_selected = 0;
+                     }
+                     else
+                     {
+                             completion->priv->current_selected -= 14;
+                             if (completion->priv->current_selected < matches 
- 1)
+                                     completion->priv->current_selected = 
matches - 1;
+                     }
+             }
+             else if (event->keyval == GDK_Page_Down)
+             {
+                     if (completion->priv->current_selected < 0)
+                             completion->priv->current_selected = 0;
+                     else if (completion->priv->current_selected < matches - 
1)
+                     {
+                             completion->priv->current_selected += 14;
+                             if (completion->priv->current_selected > matches 
- 1)
+                                     completion->priv->current_selected = 
matches - 1;
+                     }
+                     else if (completion->priv->current_selected == matches + 
actions - 1)
+                     {
+                             completion->priv->current_selected = -1;
+                     }
+                     else
+                     {
+                             completion->priv->current_selected += 14;
+                             if (completion->priv->current_selected > matches 
+ actions - 1)
+                                     completion->priv->current_selected = 
matches + actions - 1;
+                     }
+             }
+
+             if (completion->priv->current_selected < 0)
+             {
+                     gtk_tree_selection_unselect_all 
(gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)));
+                     gtk_tree_selection_unselect_all 
(gtk_tree_view_get_selection (GTK_TREE_VIEW 
(completion->priv->action_view)));
+             }
+             else if (completion->priv->current_selected < matches)
+             {
+                     gtk_tree_selection_unselect_all 
(gtk_tree_view_get_selection (GTK_TREE_VIEW 
(completion->priv->action_view)));
+
+                     path = gtk_tree_path_new_from_indices 
(completion->priv->current_selected, -1);
+                     gtk_tree_view_set_cursor (GTK_TREE_VIEW 
(completion->priv->tree_view),
+                                     path, NULL, FALSE);
+             }
+             else if (completion->priv->current_selected - matches >= 0)
+             {
+                     gtk_tree_selection_unselect_all 
(gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)));
+
+                     path = gtk_tree_path_new_from_indices 
(completion->priv->current_selected - matches, -1);
+                     gtk_tree_view_set_cursor (GTK_TREE_VIEW 
(completion->priv->action_view),
+                                     path, NULL, FALSE);
+             }
+
+             gtk_tree_path_free (path);
+
+             return TRUE;
+      }
   else if (event->keyval == GDK_Escape)
     {
       _gtk_entry_completion_popdown (completion);

       return TRUE;
     }
-  else if (event->keyval == GDK_Tab ||
+ /* else if (event->keyval == GDK_Tab ||
           event->keyval == GDK_KP_Tab ||
           event->keyval == GDK_ISO_Left_Tab)
     {
@@ -5860,8 +5894,8 @@

       gtk_widget_child_focus (gtk_widget_get_toplevel (entry), dir);

-      return TRUE;
-    }
+      return TRUE;
+    }*/
   else if (event->keyval == GDK_ISO_Enter ||
            event->keyval == GDK_KP_Enter ||
           event->keyval == GDK_Return)
@@ -6039,13 +6073,16 @@
 connect_completion_signals (GtkEntry           *entry,
                            GtkEntryCompletion *completion)
 {
+       arg * pass =malloc(sizeof(arg));
+       pass->entry = entry;
+       pass->completion=completion;
   if (completion->priv->popup_completion)
     {
       completion->priv->changed_id =
        g_signal_connect (entry, "changed",
                          G_CALLBACK (gtk_entry_completion_changed), 
completion);
       g_signal_connect (entry, "key_press_event",
-                       G_CALLBACK (gtk_entry_completion_key_press), 
completion);
+                       G_CALLBACK (gtk_entry_completion_key_press), pass);
     }

   if (completion->priv->inline_completion)

 
> main purpose of the code below is  when putting some characters such as
> to ,oa,and so on, the list of completion will show all strings  that
> contains the characters ,but when I tip Tab  key on the keyboard , it moves
> through all the match items in the list ,But what signal should I  connect
> to show current string on the entry when  tipping Tab continuous in the
> matching list ?
> /* Entry Completion
> gcc entry_completion.c `pkg-config gtk+-2.0 --cflags --libs`
> */
>
> #include <gtk/gtk.h>
> #include <gdk/gdkkeysyms.h>
> gboolean match_selected_cb(GtkEntryCompletion *completion,
>                         GtkTreeModel * model , GtkTreeIter * iter,void *
> data)
>
> {
>         char * select = 0;
>         gtk_tree_model_get(model,iter,0,&select,-1);
>         gtk_entry_set_text(data,select);
> }
>
>
> gboolean  action_cb(GtkEntryCompletion* completion, int index,void * data)
> {
>         printf("SSSS %d\n",index);
>         return TRUE;
> }
> gboolean match_rule(GtkEntryCompletion* completion , const char *
> key,GtkTreeIter * iter  , void * usr_data)
> {
>         GtkTreeModel *model;
>
>         model = gtk_entry_completion_get_model (completion);
>         char * context = NULL ;
>         gtk_tree_model_get(model,iter,0,&context,-1);
>         if(strstr(context,key)) return TRUE;
>         else return FALSE;
> }
>
>
> static GtkWidget *window = NULL;
> GdkEvent* synthesize_gdk_event(GdkEventType evtType, GtkWidget *widget,
> guint keyVal)
> {
>         GdkEvent *evt = NULL;
>         GdkKeymapKey *keys;
>         gint n_keys;
>         GtkWidget *temp_widget;
>         guint16 hardware_keycode;
>
>         if (gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
>                                 keyVal, &keys, &n_keys))
>         {
>                 temp_widget = GTK_WIDGET(widget);
>                 hardware_keycode = keys[0].keycode;
>
>                 g_free (keys);
>                 evt = gdk_event_new (evtType);
>                 evt->key.window = g_object_ref(temp_widget->window);
>                 evt->key.hardware_keycode = hardware_keycode;
>
>                 /* these are optional but possibly nice to have */
>                 //toevt->key.keyval = gdk_unicode_to_keyval (keyVal);
>                 evt->key.keyval = keyVal;
>
>                 /* the rest are no-ops */
>                 evt->key.send_event = FALSE;   /* seems unused except for
> dnd */
>                 evt->key.time = GDK_CURRENT_TIME;
>         }
>
>         return evt;
> }
>
> tab_cb(GtkWidget *window, GdkEventKey *ev,gpointer data)
> {
>         if(ev->keyval == GDK_Tab)
>         {
>                 GdkEvent * fake = synthesize_gdk_event(GDK_KEY_PRESS,
> GTK_WIDGET(data), GDK_Down);
>         //      GdkEvent * fake1 = synthesize_gdk_event(GDK_KEY_PRESS,
> GTK_WIDGET(window), GDK_Return);
>                 gtk_main_do_event(fake);
>         //      gtk_main_do_event(fake1);
>                 return 1;
>         }
>
>
>         return 0;
>
> }
> /* Creates a tree model containing the completions */
> GtkTreeModel *
> create_completion_model (void)
> {
>         GtkListStore *store;
>         GtkTreeIter iter;
>
>         store = gtk_list_store_new (1, G_TYPE_STRING);
>
>         /* Append one word */
>         gtk_list_store_append (store, &iter);
>         gtk_list_store_set (store, &iter, 0, "GNOME", -1);
>
>         /* Append another word */
>         gtk_list_store_append (store, &iter);
>         gtk_list_store_set (store, &iter, 0, "total", -1);
>
>         /* And another word */
>         gtk_list_store_append (store, &iter);
>         gtk_list_store_set (store, &iter, 0, "totally", -1);
>
>         gtk_list_store_append (store, &iter);
>         gtk_list_store_set (store, &iter, 0, "totallly", -1);
>
>         gtk_list_store_append (store, &iter);
>         gtk_list_store_set (store, &iter, 0, "totalllly", -1);
>
>         return GTK_TREE_MODEL (store);
> }
>
>
> GtkWidget *
> do_entry_completion (GtkWidget *do_widget)
> {
>         GtkWidget *vbox;
>         GtkWidget *label;
>         GtkWidget *entry;
>         GtkEntryCompletion *completion;
>         GtkTreeModel *completion_model;
>
>         if (!window)
>         {
>                 window = gtk_dialog_new_with_buttons ("GtkEntryCompletion",
>                                 GTK_WINDOW (do_widget),
>                                 0,
>                                 GTK_STOCK_CLOSE,
>                                 GTK_RESPONSE_NONE,
>                                 NULL);
>                 gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
>
>                 g_signal_connect (window, "response",
>                                 G_CALLBACK (gtk_widget_destroy), NULL);
>                 g_signal_connect (window, "destroy",
>                                 G_CALLBACK (gtk_widget_destroyed),
> &window);
>
>                 vbox = gtk_vbox_new (FALSE, 5);
>                 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox),
> vbox, TRUE, TRUE, 0);
>                 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
>
>                 label = gtk_label_new (NULL);
>                 gtk_label_set_markup (GTK_LABEL (label), "Completion demo,
> try writing <b>total</b> or <b>gnome</b> for example.");
>                 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE,
> 0);
>
>                 /* Create our entry */
>                 entry = gtk_entry_new ();
>                 g_signal_connect(entry,"key_press_event",tab_cb,entry);
>                 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE,
> 0);
>
>                 /* Create the completion object */
>                 completion = gtk_entry_completion_new ();
>
>                 /* Assign the completion to the entry */
>                 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
>                 g_object_unref (completion);
>
>                 /* Create a tree model and use it as the completion model
> */ completion_model = create_completion_model ();
>                 gtk_entry_completion_set_model (completion,
> completion_model); g_object_unref (completion_model);
>                
> gtk_entry_completion_set_match_func(completion,match_rule,NULL,NULL);
> g_signal_connect (completion, "match_selected",
> G_CALLBACK (match_selected_cb),entry);
>         //      g_signal_connect (completion, "action_activated" ,
> G_CALLBACK (action_cb),entry);
>                 /* Use model column 0 as the text column */
>                 gtk_entry_completion_set_text_column (completion, 0);
>         }
>
>         if (!GTK_WIDGET_VISIBLE (window))
>                 gtk_widget_show_all (window);
>         else
>                 gtk_widget_destroy (window);
>
>         return window;
> }
>
> main(int argc,char ** argv)
> {
>         gtk_init(&argc,&argv);
>         GtkWidget * gg =do_entry_completion(NULL);
>         gtk_widget_show_all(gg);
>         gtk_main();
>         return 0;
> }

More information about the maemo-developers mailing list