comparison src/ui_tabcomp.c @ 1388:2496a345c452

Try to improve tab completion: when a key is pressed while tab completion menu is shown, the number of entries is reduced, dhowing all matching entries but the menu is no more closed after each key pressure. Number of possible entries in this menu was increased from 500 to 1000. Pressing TAB when path entry is empty now adds / (root directory).
author zas_
date Fri, 06 Mar 2009 22:34:38 +0000
parents b4e6fee484f7
children a3d3208b0c50
comparison
equal deleted inserted replaced
1387:6f31fa931d3f 1388:2496a345c452
40 40
41 /* define this to enable a pop-up menu that shows possible matches 41 /* define this to enable a pop-up menu that shows possible matches
42 * #define TAB_COMPLETION_ENABLE_POPUP_MENU 42 * #define TAB_COMPLETION_ENABLE_POPUP_MENU
43 */ 43 */
44 #define TAB_COMPLETION_ENABLE_POPUP_MENU 1 44 #define TAB_COMPLETION_ENABLE_POPUP_MENU 1
45 #define TAB_COMP_POPUP_MAX 500 45 #define TAB_COMP_POPUP_MAX 1000
46 46
47 #ifdef TAB_COMPLETION_ENABLE_POPUP_MENU 47 #ifdef TAB_COMPLETION_ENABLE_POPUP_MENU
48 #include "ui_menu.h" 48 #include "ui_menu.h"
49 #endif 49 #endif
50 50
76 76
77 FileDialog *fd; 77 FileDialog *fd;
78 gchar *fd_title; 78 gchar *fd_title;
79 gint fd_folders_only; 79 gint fd_folders_only;
80 GtkWidget *fd_button; 80 GtkWidget *fd_button;
81
82 guint choices;
81 }; 83 };
82 84
83 85
84 static void tab_completion_select_show(TabCompData *td); 86 static void tab_completion_select_show(TabCompData *td);
87 static gint tab_completion_do(TabCompData *td);
85 88
86 static void tab_completion_free_list(TabCompData *td) 89 static void tab_completion_free_list(TabCompData *td)
87 { 90 {
88 GList *list; 91 GList *list;
89 92
196 td->tab_func(text, td->tab_data); 199 td->tab_func(text, td->tab_data);
197 g_free(text); 200 g_free(text);
198 } 201 }
199 202
200 #ifdef TAB_COMPLETION_ENABLE_POPUP_MENU 203 #ifdef TAB_COMPLETION_ENABLE_POPUP_MENU
204 void tab_completion_iter_menu_items(GtkWidget *widget, gpointer data)
205 {
206 TabCompData *td = data;
207 GtkWidget *child;
208
209 if (!GTK_WIDGET_VISIBLE(widget)) return;
210
211 child = gtk_bin_get_child(GTK_BIN(widget));
212 if (GTK_IS_LABEL(child)) {
213 const gchar *text = gtk_label_get_text(GTK_LABEL(child));
214 const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(td->entry));
215 const gchar *prefix = filename_from_path(entry_text);
216 guint prefix_len = strlen(prefix);
217
218 if (strlen(text) < prefix_len || strncmp(text, prefix, prefix_len))
219 {
220 /* Hide menu items not matching */
221 gtk_widget_hide(widget);
222 }
223 else
224 {
225 /* Count how many choices are left in the menu */
226 td->choices++;
227 }
228 }
229 }
201 230
202 static gint tab_completion_popup_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) 231 static gint tab_completion_popup_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
203 { 232 {
204 TabCompData *td = data; 233 TabCompData *td = data;
205 234
214 243
215 buf[0] = event->keyval; 244 buf[0] = event->keyval;
216 buf[1] = '\0'; 245 buf[1] = '\0';
217 gtk_editable_insert_text(GTK_EDITABLE(td->entry), buf, 1, &p); 246 gtk_editable_insert_text(GTK_EDITABLE(td->entry), buf, 1, &p);
218 gtk_editable_set_position(GTK_EDITABLE(td->entry), -1); 247 gtk_editable_set_position(GTK_EDITABLE(td->entry), -1);
248
249 /* Reduce the number of entries in the menu */
250 td->choices = 0;
251 gtk_container_foreach(GTK_CONTAINER(widget), tab_completion_iter_menu_items, (gpointer) td);
252 if (td->choices > 1) return TRUE; /* multiple choices */
253 if (td->choices > 0) tab_completion_do(td); /* one choice */
219 } 254 }
220 255
221 /*close the menu */ 256 /* close the menu */
222 gtk_menu_popdown(GTK_MENU(widget)); 257 gtk_menu_popdown(GTK_MENU(widget));
223 /* doing this does not emit the "selection done" signal, unref it ourselves */ 258 /* doing this does not emit the "selection done" signal, unref it ourselves */
224 #if GTK_CHECK_VERSION(2,12,0) 259 #if GTK_CHECK_VERSION(2,12,0)
225 g_object_unref(widget); 260 g_object_unref(widget);
226 #else 261 #else
373 const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(td->entry)); 408 const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(td->entry));
374 const gchar *entry_file; 409 const gchar *entry_file;
375 gchar *entry_dir; 410 gchar *entry_dir;
376 gchar *ptr; 411 gchar *ptr;
377 gint home_exp = FALSE; 412 gint home_exp = FALSE;
413
414 if (entry_text[0] == '\0')
415 {
416 entry_dir = g_strdup(G_DIR_SEPARATOR_S); /* FIXME: root directory win32 */
417 gtk_entry_set_text(GTK_ENTRY(td->entry), entry_dir);
418 gtk_editable_set_position(GTK_EDITABLE(td->entry), strlen(entry_dir));
419 g_free(entry_dir);
420 return FALSE;
421 }
378 422
379 /* home dir expansion */ 423 /* home dir expansion */
380 if (entry_text[0] == '~') 424 if (entry_text[0] == '~')
381 { 425 {
382 entry_dir = expand_tilde(entry_text); 426 entry_dir = expand_tilde(entry_text);