*** ../old/gtk+-1.2.8/gtk/gtkfilesel.h Sun Feb 13 01:59:45 2000 --- gtk/gtkfilesel.h Wed Jul 26 10:19:19 2000 *************** *** 57,69 **** --- 57,73 ---- GtkWidget *selection_text; GtkWidget *main_vbox; GtkWidget *ok_button; GtkWidget *cancel_button; GtkWidget *help_button; + + /* These are not used. Just fillers in the class structure */ GtkWidget *history_pulldown; GtkWidget *history_menu; GList *history_list; + /* ***************** */ + GtkWidget *fileop_dialog; GtkWidget *fileop_entry; gchar *fileop_file; gpointer cmpl_state; *************** *** 71,81 **** GtkWidget *fileop_del_file; GtkWidget *fileop_ren_file; GtkWidget *button_area; GtkWidget *action_area; ! }; struct _GtkFileSelectionClass { GtkWindowClass parent_class; --- 75,92 ---- GtkWidget *fileop_del_file; GtkWidget *fileop_ren_file; GtkWidget *button_area; GtkWidget *action_area; ! ! GtkWidget *history_combo; ! GList *prev_history; ! GList *next_history; ! GtkWidget *mask_entry; ! gchar *mask; ! gchar *saved_entry; ! }; struct _GtkFileSelectionClass { GtkWindowClass parent_class; *** ../old/gtk+-1.2.8/gtk/gtkfilesel.c Thu Jan 27 09:39:54 2000 --- gtk/gtkfilesel.c Wed Jul 26 10:19:19 2000 *************** *** 52,61 **** --- 52,63 ---- #include "gtkmenu.h" #include "gtkmenuitem.h" #include "gtkoptionmenu.h" #include "gtkclist.h" #include "gtkdialog.h" + #include "gtkcombo.h" + #include "gtkframe.h" #include "gtkintl.h" #define DIR_LIST_WIDTH 180 #define DIR_LIST_HEIGHT 180 #define FILE_LIST_WIDTH 180 *************** *** 150,159 **** --- 152,165 ---- */ gchar *text; gint is_a_completion; gint is_directory; + gint file_size; + gint file_time; + gint uid; + gint gid; /* Private fields */ gint text_alloc; }; *************** *** 304,318 **** gint column, GdkEventButton *bevent, gpointer user_data); static void gtk_file_selection_dir_button (GtkWidget *widget, ! gint row, ! gint column, GdkEventButton *bevent, gpointer data); static void gtk_file_selection_populate (GtkFileSelection *fs, gchar *rel_path, gint try_complete); static void gtk_file_selection_abort (GtkFileSelection *fs); --- 310,330 ---- gint column, GdkEventButton *bevent, gpointer user_data); static void gtk_file_selection_dir_button (GtkWidget *widget, ! gint row, ! gint column, GdkEventButton *bevent, gpointer data); + static void gtk_file_selection_undir_button (GtkWidget *widget, + gint row, + gint column, + GdkEventButton *bevent, + gpointer data); + static void gtk_file_selection_populate (GtkFileSelection *fs, gchar *rel_path, gint try_complete); static void gtk_file_selection_abort (GtkFileSelection *fs); *************** *** 321,337 **** --- 333,447 ---- static void gtk_file_selection_create_dir (GtkWidget *widget, gpointer data); static void gtk_file_selection_delete_file (GtkWidget *widget, gpointer data); static void gtk_file_selection_rename_file (GtkWidget *widget, gpointer data); + static gboolean gtk_file_selection_history_combo_callback (GtkWidget *widget, GdkEventKey *event, gpointer data); + static gboolean gtk_file_selection_history_combo_list_key_handler(GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); + static gboolean gtk_file_selection_history_combo_list_callback (GtkWidget *thelist, + GdkEventButton *event, + gpointer user_data); + static void gtk_file_selection_mask_entry_callback (GtkWidget *widget, gpointer data); + static void gtk_file_selection_create_dir (GtkWidget *widget, gpointer data); + static void gtk_file_selection_delete_file (GtkWidget *widget, gpointer data); + static void gtk_file_selection_rename_file (GtkWidget *widget, gpointer data); + static void gtk_file_selection_home_button (GtkWidget *widget, gpointer data); + static void gtk_file_selection_up_button (GtkWidget *widget, gpointer data); + static void gtk_file_selection_prev_button (GtkWidget *widget, gpointer data); + static void gtk_file_selection_next_button (GtkWidget *widget, gpointer data); + static void gtk_file_selection_refresh_button (GtkWidget *widget, gpointer data); + + static gint gtk_file_selection_match_char (gchar, gchar *mask); + static gint gtk_file_selection_match_mask (gchar *,gchar *); static GtkWindowClass *parent_class = NULL; /* Saves errno when something cmpl does fails. */ static gint cmpl_errno; + /* General notes: + * Make prev and next inactive if their respective * + * histories are empty. + * Add facilities for handling hidden files and * + * directories * + * Add an api to access the mask, and hidden files * + * check box? (prob not in 1.2.x series) * + */ + + /* Routine for applying mask to filenames * + * Need to be optimized to minimize recursion * + * help the for loop by looking for the next * + * instance of the mask character following * + * the '*'. ei *.c -- look for '.' * + * Also, swap all *? pairs (-> ?*), as that * + * will make it possible to look ahead (? * + * makes it very nondeterministic as in *?.c * + * which really is ?*.c * + * Allow multiply masks, separted by commas * + * Allow more flexible [] handling (ie [a-zA-Z] * + * * + */ + static gint gtk_file_selection_match_char (gchar text, gchar *mask){ + gchar *maskc; + gint x; + gint s; + + if (mask[0] == '[') + { + if (!strchr (mask,']')) return 0; + maskc = g_strdup(mask + 1); /* get the portion of mask inside []*/ + + (*(strchr (maskc,']'))) = 0; + s = strlen ((char *)maskc); + + for (x = 0; x < s; x++){ + if (text == maskc[x]) + { + g_free (maskc); + return s + 2; + } + } + g_free (maskc); + return 0; + } + + if (mask[0] == '?') return 1; + if (mask[0] == text) return 1; + + return 0; + } + + + static gint gtk_file_selection_match_mask (gchar *text, gchar *mask){ + + int mc; + int tc; + + tc = 0; mc = 0; + + if (mask[0] == 0 && text[0] == 0) return 1; + + if (mask[0] == '*') + { + for (tc = 0; tc <= strlen(text); tc++) + { + if (gtk_file_selection_match_mask (text + tc, mask + 1)) + return 1; + } + return 0; + } + mc = gtk_file_selection_match_char (text[0], mask); + + if(mc) + return gtk_file_selection_match_mask (text + 1, mask + mc); + else + return 0; + } + GtkType gtk_file_selection_get_type (void) { static GtkType file_selection_type = 0; *************** *** 372,389 **** --- 482,514 ---- { GtkWidget *entry_vbox; GtkWidget *label; GtkWidget *list_hbox; GtkWidget *confirm_area; + GtkWidget *vbox; + GtkWidget *hbox; GtkWidget *pulldown_hbox; GtkWidget *scrolled_win; + GtkWidget *mask_label; + GtkWidget *bigframe; + GtkWidget *label_lookingin; + GtkWidget *up_button; + GtkWidget *home_button; + GtkWidget *prev_button; + GtkWidget *next_button; + GtkWidget *refresh_button; char *dir_title [2]; char *file_title [2]; filesel->cmpl_state = cmpl_init_state (); + filesel->mask=NULL; + filesel->prev_history=NULL; + filesel->next_history=NULL; + filesel->saved_entry=NULL; + /* The dialog-sized vertical box */ filesel->main_vbox = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (filesel), 10); gtk_container_add (GTK_CONTAINER (filesel), filesel->main_vbox); gtk_widget_show (filesel->main_vbox); *************** *** 397,440 **** gtk_widget_show (filesel->button_area); gtk_file_selection_show_fileop_buttons(filesel); /* hbox for pulldown menu */ ! pulldown_hbox = gtk_hbox_new (TRUE, 5); gtk_box_pack_start (GTK_BOX (filesel->main_vbox), pulldown_hbox, FALSE, FALSE, 0); gtk_widget_show (pulldown_hbox); ! /* Pulldown menu */ ! filesel->history_pulldown = gtk_option_menu_new (); ! gtk_widget_show (filesel->history_pulldown); ! gtk_box_pack_start (GTK_BOX (pulldown_hbox), filesel->history_pulldown, ! FALSE, FALSE, 0); ! /* The horizontal box containing the directory and file listboxes */ list_hbox = gtk_hbox_new (FALSE, 5); ! gtk_box_pack_start (GTK_BOX (filesel->main_vbox), list_hbox, TRUE, TRUE, 0); gtk_widget_show (list_hbox); /* The directories clist */ dir_title[0] = _("Directories"); dir_title[1] = NULL; filesel->dir_list = gtk_clist_new_with_titles (1, (gchar**) dir_title); gtk_widget_set_usize (filesel->dir_list, DIR_LIST_WIDTH, DIR_LIST_HEIGHT); gtk_signal_connect (GTK_OBJECT (filesel->dir_list), "select_row", ! (GtkSignalFunc) gtk_file_selection_dir_button, (gpointer) filesel); gtk_clist_column_titles_passive (GTK_CLIST (filesel->dir_list)); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled_win), filesel->dir_list); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); ! gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5); ! gtk_box_pack_start (GTK_BOX (list_hbox), scrolled_win, TRUE, TRUE, 0); gtk_widget_show (filesel->dir_list); gtk_widget_show (scrolled_win); /* The files clist */ file_title[0] = _("Files"); file_title[1] = NULL; filesel->file_list = gtk_clist_new_with_titles (1, (gchar**) file_title); gtk_widget_set_usize (filesel->file_list, FILE_LIST_WIDTH, FILE_LIST_HEIGHT); --- 522,654 ---- gtk_widget_show (filesel->button_area); gtk_file_selection_show_fileop_buttons(filesel); /* hbox for pulldown menu */ ! pulldown_hbox = gtk_hbox_new (FALSE, 5); gtk_box_pack_start (GTK_BOX (filesel->main_vbox), pulldown_hbox, FALSE, FALSE, 0); gtk_widget_show (pulldown_hbox); ! /* The combo box that replaces the pulldown menu */ ! label_lookingin = gtk_label_new (_("Looking in:")); ! gtk_widget_show (label_lookingin); ! gtk_box_pack_start (GTK_BOX (pulldown_hbox), label_lookingin, FALSE, FALSE, 0); ! ! filesel->history_combo = gtk_combo_new(); ! gtk_widget_show(filesel->history_combo); ! gtk_combo_set_value_in_list(GTK_COMBO(filesel->history_combo),FALSE,FALSE); ! gtk_box_pack_start (GTK_BOX(pulldown_hbox),filesel->history_combo, ! TRUE,TRUE, 0); ! gtk_signal_connect(GTK_OBJECT(((GtkCombo *)filesel->history_combo)->entry),"key-press-event", ! (GtkSignalFunc) gtk_file_selection_history_combo_callback, ! (gpointer) filesel); ! ! gtk_signal_connect(GTK_OBJECT(((GtkCombo *)filesel->history_combo)->list),"button-press-event", ! (GtkSignalFunc) gtk_file_selection_history_combo_list_callback, ! (gpointer) filesel); ! ! gtk_signal_connect(GTK_OBJECT(((GtkCombo *)filesel->history_combo)->list),"key-press-event", ! (GtkSignalFunc) gtk_file_selection_history_combo_list_key_handler, ! (gpointer) filesel); ! ! /* frame to put the following hbox in */ ! bigframe = gtk_frame_new (NULL); ! gtk_widget_show (bigframe); ! gtk_box_pack_start (GTK_BOX (filesel->main_vbox), bigframe, TRUE, TRUE, 0); ! /* The horizontal box containing the directory and file listboxes */ list_hbox = gtk_hbox_new (FALSE, 5); ! gtk_container_add (GTK_CONTAINER(bigframe), list_hbox); ! gtk_container_set_border_width (GTK_CONTAINER (list_hbox), 5); gtk_widget_show (list_hbox); + /* vbox to put the buttons and directory listing in */ + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (list_hbox), vbox, FALSE, FALSE, 0); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + home_button = gtk_button_new_with_label (_("Home")); + gtk_widget_show (home_button); + gtk_signal_connect (GTK_OBJECT (home_button), "clicked", + (GtkSignalFunc) gtk_file_selection_home_button, + (gpointer) filesel); + gtk_box_pack_start (GTK_BOX (hbox), home_button, TRUE,TRUE, 0); + + prev_button = gtk_button_new_with_label (_("Prev")); + gtk_signal_connect (GTK_OBJECT (prev_button), "clicked", + (GtkSignalFunc) gtk_file_selection_prev_button, + (gpointer) filesel); + gtk_widget_show (prev_button); + gtk_box_pack_start (GTK_BOX (hbox), prev_button, TRUE,TRUE, 0); + + up_button = gtk_button_new_with_label (_("Up")); + gtk_signal_connect (GTK_OBJECT (up_button), "clicked", + (GtkSignalFunc) gtk_file_selection_up_button, + (gpointer) filesel); + gtk_widget_show (up_button); + gtk_box_pack_start (GTK_BOX (hbox), up_button, TRUE,TRUE, 0); + + next_button = gtk_button_new_with_label (_("Next")); + gtk_widget_show (next_button); + gtk_signal_connect (GTK_OBJECT (next_button), "clicked", + (GtkSignalFunc) gtk_file_selection_next_button, + (gpointer) filesel); + gtk_box_pack_start (GTK_BOX (hbox), next_button, TRUE,TRUE, 0); + + refresh_button = gtk_button_new_with_label (_("Refresh")); + gtk_widget_show (refresh_button); + gtk_signal_connect (GTK_OBJECT (refresh_button), "clicked", + (GtkSignalFunc) gtk_file_selection_refresh_button, + (gpointer) filesel); + gtk_box_pack_start (GTK_BOX (hbox), refresh_button, TRUE, TRUE, 0); + /* The directories clist */ dir_title[0] = _("Directories"); dir_title[1] = NULL; filesel->dir_list = gtk_clist_new_with_titles (1, (gchar**) dir_title); gtk_widget_set_usize (filesel->dir_list, DIR_LIST_WIDTH, DIR_LIST_HEIGHT); gtk_signal_connect (GTK_OBJECT (filesel->dir_list), "select_row", ! (GtkSignalFunc) gtk_file_selection_dir_button, ! (gpointer) filesel); ! gtk_signal_connect (GTK_OBJECT (filesel->dir_list), "unselect_row", ! (GtkSignalFunc) gtk_file_selection_undir_button, (gpointer) filesel); gtk_clist_column_titles_passive (GTK_CLIST (filesel->dir_list)); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled_win), filesel->dir_list); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); ! gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE,TRUE, 5); gtk_widget_show (filesel->dir_list); gtk_widget_show (scrolled_win); + /* vbox area for mask entry and files clist */ + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (list_hbox), vbox, TRUE, TRUE, 0); + + hbox = gtk_hbox_new (FALSE, 5); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + mask_label = gtk_label_new (_("Mask:")); + gtk_widget_show (mask_label); + gtk_box_pack_start (GTK_BOX (hbox), mask_label, FALSE, FALSE, 0); + + filesel->mask_entry = gtk_entry_new (); + gtk_widget_show (filesel->mask_entry); + gtk_signal_connect(GTK_OBJECT(filesel->mask_entry),"activate", + (GtkSignalFunc) gtk_file_selection_mask_entry_callback, + (gpointer) filesel); + gtk_box_pack_start (GTK_BOX (hbox),filesel->mask_entry, TRUE, TRUE, 0); + + /* The files clist */ file_title[0] = _("Files"); file_title[1] = NULL; filesel->file_list = gtk_clist_new_with_titles (1, (gchar**) file_title); gtk_widget_set_usize (filesel->file_list, FILE_LIST_WIDTH, FILE_LIST_HEIGHT); *************** *** 445,456 **** scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled_win), filesel->file_list); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); ! gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5); ! gtk_box_pack_start (GTK_BOX (list_hbox), scrolled_win, TRUE, TRUE, 0); gtk_widget_show (filesel->file_list); gtk_widget_show (scrolled_win); /* action area for packing buttons into. */ filesel->action_area = gtk_hbox_new (TRUE, 0); --- 659,669 ---- scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled_win), filesel->file_list); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); ! gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 5); gtk_widget_show (filesel->file_list); gtk_widget_show (scrolled_win); /* action area for packing buttons into. */ filesel->action_area = gtk_hbox_new (TRUE, 0); *************** *** 653,698 **** void gtk_file_selection_complete (GtkFileSelection *filesel, const gchar *pattern) { g_return_if_fail (filesel != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (filesel)); g_return_if_fail (pattern != NULL); if (filesel->selection_entry) gtk_entry_set_text (GTK_ENTRY (filesel->selection_entry), pattern); ! gtk_file_selection_populate (filesel, (gchar*) pattern, TRUE); } static void gtk_file_selection_destroy (GtkObject *object) { GtkFileSelection *filesel; GList *list; - HistoryCallbackArg *callback_arg; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (object)); filesel = GTK_FILE_SELECTION (object); if (filesel->fileop_dialog) ! gtk_widget_destroy (filesel->fileop_dialog); ! if (filesel->history_list) { ! list = filesel->history_list; while (list) ! { ! callback_arg = list->data; ! g_free (callback_arg->directory); ! g_free (callback_arg); list = list->next; ! } ! g_list_free (filesel->history_list); ! filesel->history_list = NULL; } cmpl_free_state (filesel->cmpl_state); filesel->cmpl_state = NULL; --- 866,949 ---- void gtk_file_selection_complete (GtkFileSelection *filesel, const gchar *pattern) { + gchar *new_pattern; + gint x; + g_return_if_fail (filesel != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (filesel)); g_return_if_fail (pattern != NULL); if (filesel->selection_entry) gtk_entry_set_text (GTK_ENTRY (filesel->selection_entry), pattern); ! ! if(strchr(pattern,'*') || strchr(pattern,'?')) ! { ! for(x=strlen(pattern);x>=0;x--) ! { ! if(pattern[x]=='/') break; ! } ! gtk_entry_set_text(GTK_ENTRY(filesel->mask_entry),g_strdup(pattern+x+1)); ! ! if(filesel->mask) g_free(filesel->mask); ! ! filesel->mask=g_strdup(pattern+x+1); ! new_pattern=g_strdup(pattern); ! new_pattern[x+1]=0; ! gtk_file_selection_populate (filesel, (gchar*) new_pattern, TRUE); ! g_free(new_pattern); ! } ! else ! { ! gtk_file_selection_populate (filesel, (gchar*) pattern, TRUE); ! } } static void gtk_file_selection_destroy (GtkObject *object) { GtkFileSelection *filesel; GList *list; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (object)); filesel = GTK_FILE_SELECTION (object); if (filesel->fileop_dialog) ! gtk_widget_destroy (filesel->fileop_dialog); ! if (filesel->next_history) { ! list = filesel->next_history; while (list) ! { ! g_free (list->data); list = list->next; ! } ! } ! g_list_free (filesel->next_history); ! filesel->next_history = NULL; ! ! if (filesel->prev_history) ! { ! list = filesel->prev_history; ! while (list) ! { ! g_free (list->data); ! list = list->next; ! } ! } ! g_list_free (filesel->prev_history); ! filesel->prev_history = NULL; ! ! if (filesel->mask) ! { ! g_free (filesel->mask); ! filesel->mask = NULL; } cmpl_free_state (filesel->cmpl_state); filesel->cmpl_state = NULL; *************** *** 1091,1103 **** char *text; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (event != NULL, FALSE); if (event->keyval == GDK_Tab) { - fs = GTK_FILE_SELECTION (user_data); text = gtk_entry_get_text (GTK_ENTRY (fs->selection_entry)); text = g_strdup (text); gtk_file_selection_populate (fs, text, TRUE); --- 1342,1355 ---- char *text; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (event != NULL, FALSE); + fs = GTK_FILE_SELECTION (user_data); + if (event->keyval == GDK_Tab) { text = gtk_entry_get_text (GTK_ENTRY (fs->selection_entry)); text = g_strdup (text); gtk_file_selection_populate (fs, text, TRUE); *************** *** 1106,1217 **** gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event"); return TRUE; } return FALSE; } static void ! gtk_file_selection_history_callback (GtkWidget *widget, gpointer data) ! { GtkFileSelection *fs = data; - HistoryCallbackArg *callback_arg; GList *list; g_return_if_fail (fs != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! list = fs->history_list; ! ! while (list) { ! callback_arg = list->data; ! ! if (callback_arg->menu_item == widget) ! { ! gtk_file_selection_populate (fs, callback_arg->directory, FALSE); ! break; ! } ! ! list = list->next; ! } } ! static void ! gtk_file_selection_update_history_menu (GtkFileSelection *fs, ! gchar *current_directory) ! { ! HistoryCallbackArg *callback_arg; ! GtkWidget *menu_item; GList *list; ! gchar *current_dir; ! gint dir_len; ! gint i; ! g_return_if_fail (fs != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); - g_return_if_fail (current_directory != NULL); - - list = fs->history_list; ! if (fs->history_menu) { ! while (list) { ! callback_arg = list->data; ! g_free (callback_arg->directory); ! g_free (callback_arg); ! list = list->next; ! } ! g_list_free (fs->history_list); ! fs->history_list = NULL; - gtk_widget_destroy (fs->history_menu); } ! ! fs->history_menu = gtk_menu_new(); ! current_dir = g_strdup (current_directory); ! dir_len = strlen (current_dir); ! for (i = dir_len; i >= 0; i--) { ! /* the i == dir_len is to catch the full path for the first ! * entry. */ ! if ( (current_dir[i] == '/') || (i == dir_len)) ! { ! /* another small hack to catch the full path */ ! if (i != dir_len) ! current_dir[i + 1] = '\0'; ! menu_item = gtk_menu_item_new_with_label (current_dir); ! ! callback_arg = g_new (HistoryCallbackArg, 1); ! callback_arg->menu_item = menu_item; ! ! /* since the autocompletion gets confused if you don't ! * supply a trailing '/' on a dir entry, set the full ! * (current) path to "" which just refreshes the filesel */ ! if (dir_len == i) { ! callback_arg->directory = g_strdup (""); ! } else { ! callback_arg->directory = g_strdup (current_dir); ! } ! ! fs->history_list = g_list_append (fs->history_list, callback_arg); ! ! gtk_signal_connect (GTK_OBJECT (menu_item), "activate", ! (GtkSignalFunc) gtk_file_selection_history_callback, ! (gpointer) fs); ! gtk_menu_append (GTK_MENU (fs->history_menu), menu_item); ! gtk_widget_show (menu_item); } } ! gtk_option_menu_set_menu (GTK_OPTION_MENU (fs->history_pulldown), ! fs->history_menu); g_free (current_dir); } static void gtk_file_selection_file_button (GtkWidget *widget, --- 1358,1617 ---- gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event"); return TRUE; } + if (fs->saved_entry) + { + gtk_clist_unselect_all ((GtkCList *) (fs->dir_list)); + gtk_entry_set_text(GTK_ENTRY(fs->selection_entry),fs->saved_entry); + g_free (fs->saved_entry); + fs->saved_entry = NULL; + } + return FALSE; } + static void + gtk_file_selection_home_button (GtkWidget *widget, gpointer data){ + GList *list; + + GtkFileSelection *fs=data; + + list = fs->next_history; + if (list) + { + g_free (list->data); + list = list->next; + } + g_list_free (fs->next_history); + fs->next_history = NULL; + + gtk_file_selection_populate (fs,"~/",FALSE); + } static void ! gtk_file_selection_up_button (GtkWidget *widget, gpointer data){ GtkFileSelection *fs = data; GList *list; g_return_if_fail (fs != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! list = fs->next_history; ! if (list) ! { ! g_free (list->data); ! list = list->next; ! } ! g_list_free (fs->next_history); ! fs->next_history = NULL; ! ! gtk_file_selection_populate (fs, "../", FALSE); /*change directories. */ ! } ! static void ! gtk_file_selection_prev_button (GtkWidget *widget, gpointer data){ ! GtkFileSelection *fs = data; GList *list; ! GList *first; ! gchar *path; ! g_return_if_fail (fs != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! list = fs->prev_history; ! ! if (list && g_list_length(list) > 1) { ! first = list; /* get first element */ ! list = list->next; /* pop off current directory */ ! ! list->prev = NULL; /* make this the new head. */ ! ! fs->prev_history = list; /* update prev_history list */ ! fs->next_history = g_list_prepend(fs->next_history,first->data); /* put it on next_history */ ! ! first->next = NULL; /* orphan the old first node */ ! g_list_free (first); /* free the node (data is now in use by next_history) */ ! ! ! ! path = g_malloc(strlen(list->data)+4); /* plenty of space */ ! strcpy(path,list->data); /* get the 2nd path in the history */ ! strcat(path,"/"); /* append a '/' */ ! gtk_file_selection_populate (fs, path, FALSE); /* change directories. */ ! g_free (path); ! } ! } ! ! static void ! gtk_file_selection_next_button (GtkWidget *widget, gpointer data){ ! GtkFileSelection *fs = data; ! GList *list; ! GList *first; ! gchar *path; ! ! g_return_if_fail (fs != NULL); ! g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! ! list = fs->next_history; ! ! if (list && g_list_length(list) > 0) ! { ! first = list; /*get first element*/ ! list = list->next; /*pop off current directory*/ ! ! if (list) ! list->prev = NULL; ! ! fs->next_history = list; /*update prev_history list*/ ! ! path = g_malloc(strlen(first->data)+4); /*plenty of space*/ ! strcpy(path,first->data); ! strcat(path,"/"); /*append a / */ ! gtk_file_selection_populate (fs, path, FALSE); /*change directories.*/ ! g_free(path); ! ! first->next = NULL; /* orphan the old first node */ ! g_list_free (first); /* free the node (data is now in use by next_history) */ } ! } ! void static ! gtk_file_selection_refresh_button (GtkWidget *widget, gpointer data){ ! GtkFileSelection *fs = data; ! g_return_if_fail (fs != NULL); ! g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! ! gtk_file_selection_populate (fs,"",FALSE); ! } ! static void ! gtk_file_selection_mask_entry_callback (GtkWidget *widget, gpointer data){ ! GtkFileSelection *fs = data; ! ! if(fs->mask) ! g_free (fs->mask); ! ! fs->mask = g_strdup(gtk_entry_get_text (GTK_ENTRY(fs->mask_entry))); ! ! if (strlen(fs->mask) == 0) { ! g_free (fs->mask); ! fs->mask = NULL; ! } ! ! gtk_file_selection_refresh_button (widget,data); ! } ! ! static gboolean gtk_file_selection_history_combo_list_key_handler(GtkWidget *widget, ! GdkEventKey *event, ! gpointer user_data) ! { ! /* ! g_print("Key pressed! \n"); ! */ ! ! return TRUE; ! } ! ! static gboolean gtk_file_selection_history_combo_list_callback (GtkWidget *thelist, ! GdkEventButton *event, ! gpointer user_data) ! { ! ! GtkFileSelection *fs = user_data; ! GList *list; ! gchar *path; ! ! list = fs->next_history; ! if(list) ! { ! g_free (list->data); ! list = list->next; ! } ! g_list_free (fs->next_history); ! fs->next_history = NULL; ! ! path = g_malloc(strlen(gtk_entry_get_text(GTK_ENTRY (((GtkCombo *)fs->history_combo)->entry)))+4); ! strcpy (path,gtk_entry_get_text(GTK_ENTRY( ((GtkCombo *)fs->history_combo)->entry))); ! strcat (path,"/"); ! ! gtk_file_selection_populate (fs,path,TRUE); ! ! g_free (path); ! ! return TRUE; ! } ! ! static gboolean ! gtk_file_selection_history_combo_callback (GtkWidget *widget, GdkEventKey *event, gpointer data) ! { ! GtkEntry *entry=(GtkEntry *)widget; ! GtkFileSelection *fs=data; ! GList *list; ! gchar *path; ! ! g_return_val_if_fail (fs != NULL,FALSE); ! g_return_val_if_fail (GTK_IS_FILE_SELECTION (fs),FALSE); ! ! ! if (event->keyval == GDK_Return) ! { ! list = fs->next_history; ! if (list) ! { ! g_free (list->data); ! list = list->next; } + g_list_free (fs->next_history); + fs->next_history = NULL; + + path = g_malloc(strlen(gtk_entry_get_text(entry))+4); + strcpy (path,gtk_entry_get_text(entry)); + strcat (path,"/"); + gtk_file_selection_populate (fs,path,TRUE); + g_free (path); + gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event"); + return TRUE; } + else + { + return FALSE; + } + + } + + static void + gtk_file_selection_update_history_menu (GtkFileSelection *fs, + gchar *current_directory) + { + gchar *current_dir; ! g_return_if_fail (fs != NULL); ! g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); ! g_return_if_fail (current_directory != NULL); ! ! current_dir = g_strdup (current_directory); ! ! if(fs->prev_history) ! { ! if (strcmp((fs->prev_history)->data,current_dir)) ! { /*if this item isn't on the top of the list */ ! fs->prev_history = g_list_prepend(fs->prev_history,g_strdup(current_dir)); ! } ! } else { ! fs->prev_history = g_list_prepend(fs->prev_history,g_strdup(current_dir)); ! } ! ! gtk_combo_set_popdown_strings (GTK_COMBO (fs->history_combo),fs->prev_history); ! g_free (current_dir); } static void gtk_file_selection_file_button (GtkWidget *widget, *************** *** 1245,1255 **** gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); break; } else gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); ! g_free (filename); } } static void --- 1645,1655 ---- gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); break; } else gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); ! g_free (filename); } } static void *************** *** 1257,1266 **** --- 1657,1667 ---- gint row, gint column, GdkEventButton *bevent, gpointer user_data) { + GList *list; GtkFileSelection *fs = NULL; gchar *filename, *temp = NULL; g_return_if_fail (GTK_IS_CLIST (widget)); *************** *** 1275,1293 **** { if (bevent) switch (bevent->type) { case GDK_2BUTTON_PRESS: gtk_file_selection_populate (fs, filename, FALSE); break; ! default: ! gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); break; } else gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); g_free (filename); } } --- 1676,1758 ---- { if (bevent) switch (bevent->type) { case GDK_2BUTTON_PRESS: + list = fs->next_history; + if (list) + { + g_free (list->data); + list = list->next; + } + g_list_free (fs->next_history); + fs->next_history = NULL; + gtk_file_selection_populate (fs, filename, FALSE); + gtk_entry_set_text(GTK_ENTRY(fs->selection_entry),fs->saved_entry); + g_free (fs->saved_entry); + fs->saved_entry = NULL; break; ! default: ! /* here we need to add the "filename" to the beginning of what's already ! in the entry. Save what's in the entry, then restore it on the double click ! */ ! if (fs->saved_entry) g_free (fs->saved_entry); ! fs->saved_entry=g_strdup(gtk_entry_get_text(GTK_ENTRY (fs->selection_entry))); ! ! temp=g_strconcat(filename,fs->saved_entry,NULL); ! gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), temp); ! g_free (temp); ! break; } else gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); + + g_free (filename); + } + } + + static void + gtk_file_selection_undir_button (GtkWidget *widget, + gint row, + gint column, + GdkEventButton *bevent, + gpointer user_data) + { + GtkFileSelection *fs = NULL; + gchar *filename, *temp = NULL; + + g_return_if_fail (GTK_IS_CLIST (widget)); + + fs = GTK_FILE_SELECTION (user_data); + g_return_if_fail (fs != NULL); + g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); + + gtk_clist_get_text (GTK_CLIST (fs->dir_list), row, 0, &temp); + filename = g_strdup (temp); + + if (filename) + { + if (bevent) + switch (bevent->type) + { + default: + /* here we need to add the "filename" to the beginning of what's already + in the entry. Save what's in the entry, then restore it on the double click + */ + if (fs->saved_entry) + { + gtk_entry_set_text (GTK_ENTRY (fs->selection_entry),fs->saved_entry); + g_free (fs->saved_entry); + fs->saved_entry = NULL; + } + break; + } + else + gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); //????? g_free (filename); } } *************** *** 1344,1388 **** gtk_clist_set_column_width(GTK_CLIST(fs->file_list),0,file_list_width); while (poss) { if (cmpl_is_a_completion (poss)) ! { ! possible_count += 1; ! ! filename = cmpl_this_completion (poss); text[0] = filename; ! if (cmpl_is_directory (poss)) ! { ! if (strcmp (filename, "./") != 0 && ! strcmp (filename, "../") != 0) { int width = gdk_string_width(fs->dir_list->style->font, filename); row = gtk_clist_append (GTK_CLIST (fs->dir_list), text); if(width > dir_list_width) { dir_list_width = width; gtk_clist_set_column_width(GTK_CLIST(fs->dir_list),0, width); } ! } } ! else { ! int width = gdk_string_width(fs->file_list->style->font, ! filename); ! row = gtk_clist_append (GTK_CLIST (fs->file_list), text); ! if(width > file_list_width) ! { ! file_list_width = width; ! gtk_clist_set_column_width(GTK_CLIST(fs->file_list),0, ! width); ! } ! } } poss = cmpl_next_completion (cmpl_state); } --- 1809,1871 ---- gtk_clist_set_column_width(GTK_CLIST(fs->file_list),0,file_list_width); while (poss) { if (cmpl_is_a_completion (poss)) ! { ! possible_count += 1; ! ! filename = cmpl_this_completion (poss); text[0] = filename; ! if (cmpl_is_directory (poss)) ! { ! if (strcmp (filename, "./") != 0 && ! strcmp (filename, "../") != 0) { int width = gdk_string_width(fs->dir_list->style->font, filename); row = gtk_clist_append (GTK_CLIST (fs->dir_list), text); if(width > dir_list_width) { dir_list_width = width; gtk_clist_set_column_width(GTK_CLIST(fs->dir_list),0, width); } ! } } ! else { ! if(fs->mask) ! { ! if (gtk_file_selection_match_mask(filename,fs->mask)) ! { ! int width = gdk_string_width(fs->file_list->style->font, ! filename); ! row = gtk_clist_append (GTK_CLIST (fs->file_list), text); ! if(width > file_list_width) ! { ! file_list_width = width; ! gtk_clist_set_column_width(GTK_CLIST(fs->file_list),0, ! width); ! } ! } ! } ! else ! { ! int width = gdk_string_width(fs->file_list->style->font, ! filename); ! row = gtk_clist_append (GTK_CLIST (fs->file_list), text); ! if(width > file_list_width) ! { ! file_list_width = width; ! gtk_clist_set_column_width(GTK_CLIST(fs->file_list),0, ! width); ! } ! } ! } } poss = cmpl_next_completion (cmpl_state); } *************** *** 1430,1440 **** } } else { if (fs->selection_entry) ! gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), ""); } if (!did_recurse) { if (fs->selection_entry) --- 1913,1925 ---- } } else { if (fs->selection_entry) ! /* Here we need to take the old filename and keep it!*/ ! /*gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), "");*/ ! ; } if (!did_recurse) { if (fs->selection_entry) *************** *** 1448,1462 **** gtk_label_set_text (GTK_LABEL (fs->selection_text), sel_text); g_free (sel_text); } ! if (fs->history_pulldown) ! { ! gtk_file_selection_update_history_menu (fs, cmpl_reference_position (cmpl_state)); ! } ! } } static void gtk_file_selection_abort (GtkFileSelection *fs) --- 1933,1944 ---- gtk_label_set_text (GTK_LABEL (fs->selection_text), sel_text); g_free (sel_text); } ! gtk_file_selection_update_history_menu (fs, cmpl_reference_position (cmpl_state)); ! } } static void gtk_file_selection_abort (GtkFileSelection *fs) *************** *** 2758,2762 **** --- 3240,3306 ---- if(err == CMPL_ERRNO_TOO_LONG) return "Name too long"; else return g_strerror (err); } + + + /* Testing area */ + #ifdef TORRIE_DEBUG + + /* Get the selected filename and print it to the console */ + void file_ok_sel( GtkWidget *w, + GtkFileSelection *fs ) + { + g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs))); + } + + void destroy( GtkWidget *widget, + gpointer data ) + { + gtk_main_quit (); + } + + int main( int argc, + char *argv[] ) + { + GtkWidget *filew; + + gtk_init (&argc, &argv); + + /* Create a new file selection widget */ + filew = gtk_file_selection_new ("Michael's Glorious File Selector"); + // gtk_file_selection_complete(GTK_FILE_SELECTION(filew),"bob"); + + + gtk_signal_connect (GTK_OBJECT (filew), "destroy", + (GtkSignalFunc) destroy, &filew); + /* Connect the ok_button to file_ok_sel function */ + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), + "clicked", (GtkSignalFunc) file_ok_sel, filew ); + + /* Connect the cancel_button to destroy the widget */ + gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION + (filew)->cancel_button), + "clicked", (GtkSignalFunc) gtk_widget_destroy, + GTK_OBJECT (filew)); + + + gtk_widget_show(filew); + + /* + g_print("%d",gtk_file_selection_match_mask("mask.c","m*.c")); + g_print("%d",gtk_file_selection_match_mask("mask.c","m???.c")); + g_print("%d",gtk_file_selection_match_mask("mask.c","m??*.c")); + g_print("%d",gtk_file_selection_match_mask("mask.cout","m*.c")); + g_print("%d",gtk_file_selection_match_mask("mask.cout","m*.c???")); + g_print("%d",gtk_file_selection_match_mask("mask.cout","m*.c*")); + g_print("%d",gtk_file_selection_match_mask("mask.cout","n*.c???")); + g_print("%d",gtk_file_selection_match_mask("mask.c","[mn]*")); + g_print("%d",gtk_file_selection_match_mask("COPYING","*.xpm")); + */ + gtk_main (); + + return 0; + } + /* example-end */ + #endif