YAPatch for filesel, and a Q



Here's the newest patch for gtk_filesel.  It adds having the file list
automatically scroll to the last file selected when the dialog is opened,
and the entry being replaced with a GtkCombo with 5 elements of history.

Further we're thinking of making the history persistent.  Does GTK have any
standard way of doing persistence?

-Lars

-- 
Lars Clausen (http://shasta.cs.uiuc.edu/~lrclause) | Hårdgrim of Numenor
"I do not agree with a word that you say, but I    | Retainer of Sir Kegg
will defend to the death your right to say it."    |   of Westfield
    --Evelyn Beatrice Hall paraphrasing Voltaire   | Chaos Berserker of Khorne

===File ~/src/GTK/gtk_filesel_history.diff==================
diff -bBru gtk+-1.2.8-orig/gtk/gtkfilesel.c gtk+-1.2.8/gtk/gtkfilesel.c
--- gtk+-1.2.8-orig/gtk/gtkfilesel.c	Wed Oct 18 15:05:25 2000
+++ gtk+-1.2.8/gtk/gtkfilesel.c	Mon Oct 30 18:33:13 2000
@@ -55,6 +55,7 @@
 #include "gtkclist.h"
 #include "gtkdialog.h"
 #include "gtkintl.h"
+#include "gtkcombo.h"
 
 #define DIR_LIST_WIDTH   180
 #define DIR_LIST_HEIGHT  180
@@ -322,6 +323,7 @@
 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 (GtkWidget *widget, gpointer data);
 
 
 
@@ -368,6 +370,29 @@
 }
 
 static void
+gtk_file_selection_file_chosen( GtkWidget *widget, gpointer data) {
+  GtkFileSelection *filesel = GTK_FILE_SELECTION(widget);
+  gchar *filename = gtk_file_selection_get_filename(filesel);
+  GList *elem = NULL;
+
+  if ((elem = g_list_find_custom(filesel->last_selected_files, 
+				 filename, strcmp)) != NULL) {
+    filesel->last_selected_files = g_list_remove_link(filesel->last_selected_files, elem);
+    g_free(elem->data);
+    g_list_free(elem);
+  }
+
+  filesel->last_selected_files = g_list_prepend(filesel->last_selected_files, g_strdup(filename));
+  if (g_list_length(filesel->last_selected_files) >
+      GTK_FILE_SELECTION_VISUAL_HISTORY_LENGTH) {
+    GList *last = g_list_last(filesel->last_selected_files);
+    filesel->last_selected_files = g_list_remove_link(filesel->last_selected_files, last);
+    g_free(last->data);
+    g_list_free(last);
+  }
+}
+
+static void
 gtk_file_selection_init (GtkFileSelection *filesel)
 {
   GtkWidget *entry_vbox;
@@ -488,7 +513,10 @@
   gtk_box_pack_start (GTK_BOX (entry_vbox), label, FALSE, FALSE, 0);
   gtk_widget_show (label);
 
-  filesel->selection_entry = gtk_entry_new ();
+  filesel->selection_combo = gtk_combo_new();
+  gtk_combo_disable_activate(GTK_COMBO(filesel->selection_combo));
+
+  filesel->selection_entry = GTK_COMBO(filesel->selection_combo)->entry;
   gtk_signal_connect (GTK_OBJECT (filesel->selection_entry), "key_press_event",
 		      (GtkSignalFunc) gtk_file_selection_key_press, filesel);
   gtk_signal_connect_object (GTK_OBJECT (filesel->selection_entry), "focus_in_event",
@@ -497,8 +525,11 @@
   gtk_signal_connect_object (GTK_OBJECT (filesel->selection_entry), "activate",
                              (GtkSignalFunc) gtk_button_clicked,
                              GTK_OBJECT (filesel->ok_button));
-  gtk_box_pack_start (GTK_BOX (entry_vbox), filesel->selection_entry, TRUE, TRUE, 0);
-  gtk_widget_show (filesel->selection_entry);
+  gtk_signal_connect_object (GTK_OBJECT (filesel->ok_button), "clicked",
+			     (GtkSignalFunc) gtk_file_selection_file_chosen,
+			     GTK_OBJECT(filesel));
+  gtk_box_pack_start (GTK_BOX (entry_vbox), filesel->selection_combo, TRUE, TRUE, 0);
+  gtk_widget_show (filesel->selection_combo);
 
   if (!cmpl_state_okay (filesel->cmpl_state))
     {
@@ -567,6 +598,17 @@
       gtk_widget_show (filesel->fileop_ren_file);
     }
 
+  if (!filesel->fileop_home)
+    {
+      filesel->fileop_home = gtk_button_new_with_label (_("Home"));
+      gtk_signal_connect (GTK_OBJECT (filesel->fileop_home), "clicked",
+			  (GtkSignalFunc) gtk_file_selection_home, 
+			  (gpointer) filesel);
+      gtk_box_pack_start (GTK_BOX (filesel->button_area), 
+			  filesel->fileop_home, TRUE, TRUE, 0);
+      gtk_widget_show (filesel->fileop_home);
+    }
+
   gtk_widget_queue_resize(GTK_WIDGET(filesel));
 }
 
@@ -576,6 +618,11 @@
   g_return_if_fail (filesel != NULL);
   g_return_if_fail (GTK_IS_FILE_SELECTION (filesel));
     
+  if (filesel->fileop_home)
+    {
+      gtk_widget_destroy (filesel->fileop_home);
+      filesel->fileop_home = NULL;
+    }
   if (filesel->fileop_ren_file) 
     {
       gtk_widget_destroy (filesel->fileop_ren_file);
@@ -1082,6 +1129,28 @@
 }
 
 
+static void
+gtk_file_selection_home (GtkWidget *widget, gpointer data)
+{
+  GtkFileSelection *fs = data;
+  char *home_dir = getenv("HOME");
+
+  g_return_if_fail (fs != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
+
+  if (home_dir == NULL) {
+    /* Pop up error dialog */
+    gtk_file_selection_fileop_error (fs, "No home directory found.");
+    return;
+  }
+
+  home_dir = g_strconcat(home_dir, "/", NULL);
+
+  gtk_file_selection_populate (fs, home_dir, FALSE);
+
+  g_free(home_dir); /* Does gtk_file_selection_populate keep it? */
+}
+
 static gint
 gtk_file_selection_key_press (GtkWidget   *widget,
 			      GdkEventKey *event,
@@ -1248,7 +1317,7 @@
       else
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
 
-      g_free (filename);
+      g_free(filename);
     }
 }
 
@@ -1281,16 +1350,40 @@
 	    break;
 	  
 	  default:
+	    /*
 	    gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+	    */
 	    break;
 	  }
       else
+	gtk_file_selection_populate (fs, filename, FALSE);
+	/*
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+	*/
 
       g_free (filename);
     }
 }
 
+static gint
+gtk_file_selection_find_last_row(GtkFileSelection *fs) {
+  gchar *name = fs->last_selected_files->data;
+  GList *rows = GTK_CLIST(fs->file_list)->row_list;
+  int i = 0;
+  
+  name = g_basename(name);
+
+  for (; rows != NULL; rows = g_list_next(rows)) {
+    GtkCListRow *row = GTK_CLIST_ROW(rows);
+
+    if (!strcmp(name, row->cell->u.text))
+      return i;
+    i++;
+  }
+
+  return -1;
+}
+
 static void
 gtk_file_selection_populate (GtkFileSelection *fs,
 			     gchar            *rel_path,
@@ -1431,8 +1524,33 @@
     }
   else
     {
+      if (fs->selection_entry) {
+	gchar * basename;
+	basename = g_basename(gtk_entry_get_text(GTK_ENTRY(fs->selection_entry)));
+	if (basename == NULL) {
+	  g_print("NULL basename");
+	} else if (basename != gtk_entry_get_text(GTK_ENTRY(fs->selection_entry))) {
+	  basename = strdup(basename);
+	  gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), basename);
+	  g_free(basename);
+	}
+
+	if (fs->last_selected_files) {
+	  gint row;
+	  row = gtk_file_selection_find_last_row(fs);
+	  if (row != -1) {
+	    gtk_clist_moveto(GTK_CLIST(fs->file_list),
+			     row, 0, .5, 0.0);
+	  }
+	  gtk_combo_set_popdown_strings(GTK_COMBO(fs->selection_combo),
+					fs->last_selected_files);
+	}
+      }
+     
+      /*
       if (fs->selection_entry)
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), "");
+      */
     }
 
   if (!did_recurse)
diff -bBru gtk+-1.2.8-orig/gtk/gtkfilesel.c.orig gtk+-1.2.8/gtk/gtkfilesel.c.orig
--- gtk+-1.2.8-orig/gtk/gtkfilesel.c.orig	Wed Oct 18 15:04:43 2000
+++ gtk+-1.2.8/gtk/gtkfilesel.c.orig	Mon Oct 30 15:32:04 2000
@@ -322,7 +322,6 @@
 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 (GtkWidget *widget, gpointer data);
 
 
 
@@ -369,6 +368,16 @@
 }
 
 static void
+gtk_file_selection_file_chosen( GtkWidget *widget, gpointer data) {
+  GtkFileSelection *filesel = GTK_FILE_SELECTION(widget);
+
+  g_print("Saving name\n");
+
+  filesel->last_selected_file = gtk_file_selection_get_filename(filesel);
+  /* Also eventually put into history */
+}
+
+static void
 gtk_file_selection_init (GtkFileSelection *filesel)
 {
   GtkWidget *entry_vbox;
@@ -498,6 +507,9 @@
   gtk_signal_connect_object (GTK_OBJECT (filesel->selection_entry), "activate",
                              (GtkSignalFunc) gtk_button_clicked,
                              GTK_OBJECT (filesel->ok_button));
+  gtk_signal_connect_object (GTK_OBJECT (filesel->ok_button), "clicked",
+			     (GtkSignalFunc) gtk_file_selection_file_chosen,
+			     GTK_OBJECT(filesel));
   gtk_box_pack_start (GTK_BOX (entry_vbox), filesel->selection_entry, TRUE, TRUE, 0);
   gtk_widget_show (filesel->selection_entry);
 
@@ -568,17 +580,6 @@
       gtk_widget_show (filesel->fileop_ren_file);
     }
 
-  if (!filesel->fileop_home)
-    {
-      filesel->fileop_home = gtk_button_new_with_label (_("Home"));
-      gtk_signal_connect (GTK_OBJECT (filesel->fileop_home), "clicked",
-			  (GtkSignalFunc) gtk_file_selection_home, 
-			  (gpointer) filesel);
-      gtk_box_pack_start (GTK_BOX (filesel->button_area), 
-			  filesel->fileop_home, TRUE, TRUE, 0);
-      gtk_widget_show (filesel->fileop_home);
-    }
-
   gtk_widget_queue_resize(GTK_WIDGET(filesel));
 }
 
@@ -588,11 +589,6 @@
   g_return_if_fail (filesel != NULL);
   g_return_if_fail (GTK_IS_FILE_SELECTION (filesel));
     
-  if (filesel->fileop_home)
-    {
-      gtk_widget_destroy (filesel->fileop_home);
-      filesel->fileop_home = NULL;
-    }
   if (filesel->fileop_ren_file) 
     {
       gtk_widget_destroy (filesel->fileop_ren_file);
@@ -1099,28 +1095,6 @@
 }
 
 
-static void
-gtk_file_selection_home (GtkWidget *widget, gpointer data)
-{
-  GtkFileSelection *fs = data;
-  char *home_dir = getenv("HOME");
-
-  g_return_if_fail (fs != NULL);
-  g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
-
-  if (home_dir == NULL) {
-    /* Pop up error dialog */
-    gtk_file_selection_fileop_error (fs, "No home directory found.");
-    return;
-  }
-
-  home_dir = g_strconcat(home_dir, "/", NULL);
-
-  gtk_file_selection_populate (fs, home_dir, FALSE);
-
-  g_free(home_dir); /* Does gtk_file_selection_populate keep it? */
-}
-
 static gint
 gtk_file_selection_key_press (GtkWidget   *widget,
 			      GdkEventKey *event,
@@ -1287,7 +1261,9 @@
       else
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
 
-      g_free (filename);
+      fs->last_selected_file = gtk_clist_get_row_data(GTK_CLIST(fs->file_list), row);
+      
+      g_free(filename);
     }
 }
 
@@ -1320,11 +1296,16 @@
 	    break;
 	  
 	  default:
+	    /*
 	    gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+	    */
 	    break;
 	  }
       else
+	gtk_file_selection_populate (fs, filename, FALSE);
+	/*
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+	*/
 
       g_free (filename);
     }
@@ -1413,6 +1394,7 @@
 	      int width = gdk_string_width(fs->file_list->style->font,
 				           filename);
 	      row = gtk_clist_append (GTK_CLIST (fs->file_list), text);
+	      gtk_clist_set_row_data(GTK_CLIST(fs->file_list), row, text[0]);
 	      if(width > file_list_width)
 	        {
 	          file_list_width = width;
@@ -1470,8 +1452,33 @@
     }
   else
     {
+      if (fs->selection_entry) {
+	gchar * basename;
+	basename = g_basename(gtk_entry_get_text(GTK_ENTRY(fs->selection_entry)));
+	if (basename == NULL) {
+	  g_print("NULL basename");
+	} else if (basename != gtk_entry_get_text(GTK_ENTRY(fs->selection_entry))) {
+	  basename = strdup(basename);
+	  gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), basename);
+	  g_free(basename);
+	}
+
+	if (fs->last_selected_file) {
+	  gint row;
+	  row = gtk_clist_find_row_from_data(GTK_CLIST(fs->file_list),
+					     fs->last_selected_file);
+	  g_print("Last file was %s at %d\n", fs->last_selected_file, row);
+	  if (row != -1) {
+	    gtk_clist_moveto(GTK_CLIST(fs->file_list),
+			     row, 0, .5, 0.0);
+	  }
+	}
+      }
+     
+      /*
       if (fs->selection_entry)
 	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), "");
+      */
     }
 
   if (!did_recurse)
diff -bBru gtk+-1.2.8-orig/gtk/gtkfilesel.h gtk+-1.2.8/gtk/gtkfilesel.h
--- gtk+-1.2.8-orig/gtk/gtkfilesel.h	Wed Oct 18 15:05:25 2000
+++ gtk+-1.2.8/gtk/gtkfilesel.h	Mon Oct 30 18:24:33 2000
@@ -42,9 +42,9 @@
 #define GTK_FILE_SELECTION_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SELECTION, GtkFileSelectionClass))
 #define GTK_IS_FILE_SELECTION(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_FILE_SELECTION))
 #define GTK_IS_FILE_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SELECTION))
+#define GTK_FILE_SELECTION_VISUAL_HISTORY_LENGTH 5
 
-
-typedef struct _GtkFileSelection       GtkFileSelection;
+  typedef struct _GtkFileSelection       GtkFileSelection;
 typedef struct _GtkFileSelectionClass  GtkFileSelectionClass;
 
 struct _GtkFileSelection
@@ -74,6 +74,10 @@
   GtkWidget *button_area;
   GtkWidget *action_area;
   
+  GtkWidget *fileop_home;
+
+  GtkWidget *selection_combo;
+  GList     *last_selected_files;
 };
 
 struct _GtkFileSelectionClass
============================================================




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]