hi list the following is a message I sent earlier to Brian to share a patch I wrote for type-ahead file searching. I haven't heard back from him and not sure if he is still maintaining the project. Today I worked on this a little bit more and it now accepts more than one keys. I attached my patch in form of "svn diff" under the src/gtk directory. Can someone review&test it and see if there is any issue to add this to the upstream? I hope this will be useful to other people. please let me know, thanks. Qianqian -------- Original Message --------
hi Brian I would like to first thank you for creating gftp, it has been my favorite ftp client for many years. Just one thing I feel not very convenient: I can not type a key-stroke to quickly locate a folder or file from the file list, i.e. the so-called "type-ahead" function. I did some search this afternoon and figured out that gtk clist does not support search function as in treeviews. so, I added a little code in the gftp-gtk.c unit to manually scan and select an item in the key_press_event callback. It turned out worked nicely for my purposes. I think this function may also be useful for others, so I attached my patch (diff against v2.0.19 source). Please review it and let me know what you think. thanks you very much Qianqian |
Index: gftp-gtk.c =================================================================== --- gftp-gtk.c (revision 995) +++ gftp-gtk.c (working copy) @@ -730,6 +730,51 @@ list_doaction (wdata); return (FALSE); } + else + { /*simple type-ahead support in the file listbox - Qianqian Fang 03/08/2010 */ + int i; + static gint typeaheadtime=0; + static gchar typeaheadbuf[GFTP_TYPEAHEAD_BUF_LEN]={'\0'}; + gchar *text; + GtkWidget * lbox=GTK_CLIST ((wdata)->listbox); + gint startpos=0, rowcount=GTK_CLIST(lbox)->rows; + + if(GTK_CLIST(lbox)->selection) /*search starts from the selected item*/ + startpos=GPOINTER_TO_INT(GTK_CLIST(lbox)->selection->data)+1; + + if (strlen(gdk_keyval_name(event->keyval))==1) /*only simple keys*/ + { + + if(event->time-typeaheadtime>GFTP_TYPEAHEAD_MAX_WAIT) + { + strcpy(typeaheadbuf,gdk_keyval_name(event->keyval)); + typeaheadtime=event->time; + } + else + { + strcpy(typeaheadbuf+strlen(typeaheadbuf),gdk_keyval_name(event->keyval)); + if(GTK_CLIST(lbox)->selection) /*search starts from the selected item*/ + startpos=GPOINTER_TO_INT(GTK_CLIST(lbox)->selection->data); + } + typeaheadtime=event->time; + + gtk_clist_unselect_all (GTK_CLIST(lbox)); + for(i=0;i<rowcount;i++) + { + int idx=(i+startpos)%rowcount; /*wrap around and search the entire list*/ + gtk_clist_get_text (GTK_CLIST(lbox),idx,1,&text); + if(strstr(text,typeaheadbuf)==text)/*match string beginning*/ + { + gtk_clist_select_row(GTK_CLIST(lbox),idx,1); + if (gtk_clist_row_is_visible(GTK_CLIST(lbox),idx) == GTK_VISIBILITY_NONE) + gtk_clist_moveto(GTK_CLIST(lbox),idx, -1, 0.5, 0); + + /*g_print("row=%d %d %s %s\n",idx,i,text,gdk_keyval_name(event->keyval));*/ + break; + } + } + } + } return (TRUE); } Index: gftp-gtk.h =================================================================== --- gftp-gtk.h (revision 995) +++ gftp-gtk.h (working copy) @@ -33,6 +33,10 @@ #define GFTP_MENU_ITEM_WIN1 3 #define GFTP_MENU_ITEM_WIN2 4 +#define GFTP_TYPEAHEAD_BUF_LEN 32 +#define GFTP_TYPEAHEAD_MAX_WAIT 1000 /*wait for 1 second*/ + + #define IS_ONE_SELECTED(wdata) (GTK_CLIST ((wdata)->listbox)->selection && GTK_CLIST ((wdata)->listbox)->selection->next == NULL) #define IS_NONE_SELECTED(wdata) (GTK_CLIST ((wdata)->listbox)->selection == NULL) #define gftp_gtk_get_list_selection(wdata) (GTK_CLIST ((wdata)->listbox)->selection)