Tree-viewization of GtkFileSelection



In the same vein as the previous patch, here's one to switch
GtkFileSelection over. I am considerably more hesitant about this one
since:

 - People _do_ poke around in the internals of GtkFileselection
   a lot, including a lot of fooling around with the lists.

 - My consistent position on GtkFileSelection has been that
   we won't touch it all, we'll keep even the most hacky
   existing code working, and then we'll fix it the right
   way for 2.2.

On the other hand, it looks pretty darn lame to have GtkCList sticking
around in our standard dialogs, and GtkCList is probably going to be a
problem from an accessibility standpoint.

Regards,
                                        Owen

Index: gtkfilesel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilesel.c,v
retrieving revision 1.95
diff -u -p -r1.95 gtkfilesel.c
--- gtkfilesel.c	2002/01/17 01:37:06	1.95
+++ gtkfilesel.c	2002/01/17 06:26:10
@@ -49,22 +49,23 @@
 
 #include "gdk/gdkkeysyms.h"
 #include "gtkbutton.h"
+#include "gtkcellrenderertext.h"
 #include "gtkentry.h"
 #include "gtkfilesel.h"
 #include "gtkhbox.h"
 #include "gtkhbbox.h"
 #include "gtklabel.h"
-#include "gtklist.h"
-#include "gtklistitem.h"
+#include "gtkliststore.h"
 #include "gtkmain.h"
 #include "gtkscrolledwindow.h"
 #include "gtkstock.h"
 #include "gtksignal.h"
+#include "gtktreeselection.h"
+#include "gtktreeview.h"
 #include "gtkvbox.h"
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
 #include "gtkoptionmenu.h"
-#include "gtkclist.h"
 #include "gtkdialog.h"
 #include "gtkmessagedialog.h"
 #include "gtkintl.h"
@@ -233,6 +234,14 @@ enum {
   PROP_FILENAME
 };
 
+enum {
+  DIR_COLUMN
+};
+
+enum {
+  FILE_COLUMN
+};
+
 /* File completion functions which would be external, were they used
  * outside of this file.
  */
@@ -367,17 +376,16 @@ static gint gtk_file_selection_insert_te
 					      gint                  *position,
 					      gpointer               user_data);
 
-static void gtk_file_selection_file_button (GtkWidget *widget,
-					    gint row, 
-					    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_file_activate (GtkTreeView       *tree_view,
+					      GtkTreePath       *path,
+					      GtkTreeViewColumn *column,
+					      gpointer           user_data);
+static void gtk_file_selection_file_changed  (GtkTreeSelection  *selection,
+					      gpointer           user_data);
+static void gtk_file_selection_dir_activate  (GtkTreeView       *tree_view,
+					      GtkTreePath       *path,
+					      GtkTreeViewColumn *column,
+					      gpointer           user_data);
 
 static void gtk_file_selection_populate      (GtkFileSelection      *fs,
 					      gchar                 *rel_path,
@@ -599,10 +607,10 @@ gtk_file_selection_init (GtkFileSelectio
   GtkWidget *scrolled_win;
   GtkWidget *eventbox;
   GtkDialog *dialog;
-  
-  char *dir_title [2];
-  char *file_title [2];
 
+  GtkListStore *model;
+  GtkTreeViewColumn *column;
+  
   dialog = GTK_DIALOG (filesel);
 
   filesel->cmpl_state = cmpl_init_state ();
@@ -636,19 +644,28 @@ gtk_file_selection_init (GtkFileSelectio
   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 list */
 
-  /* The directories clist */
-  dir_title[0] = _("Directories");
-  dir_title[1] = NULL;
-  filesel->dir_list = gtk_clist_new_with_titles (1, (gchar**) dir_title);
+  model = gtk_list_store_new (1, G_TYPE_STRING);
+  filesel->dir_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+  g_object_unref (model);
+
+  column = gtk_tree_view_column_new_with_attributes (_("Directories"),
+						     gtk_cell_renderer_text_new (),
+						     "text", DIR_COLUMN,
+						     NULL);
+  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (filesel->dir_list), column);
+
   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_set_column_auto_resize (GTK_CLIST (filesel->dir_list), 0, TRUE);
-  gtk_clist_column_titles_passive (GTK_CLIST (filesel->dir_list));
+  g_signal_connect (filesel->dir_list, "row_activated",
+		    G_CALLBACK (gtk_file_selection_dir_activate), filesel);
+
+  /*  gtk_clist_column_titles_passive (GTK_CLIST (filesel->dir_list)); */
 
   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);  
   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);
@@ -656,19 +673,29 @@ gtk_file_selection_init (GtkFileSelectio
   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 list */
+  model = gtk_list_store_new (1, G_TYPE_STRING);
+  filesel->file_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+  g_object_unref (model);
+
+  column = gtk_tree_view_column_new_with_attributes (_("Files"),
+						     gtk_cell_renderer_text_new (),
+						     "text", FILE_COLUMN,
+						     NULL);
+  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (filesel->file_list), column);
 
-  /* 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);
-  gtk_signal_connect (GTK_OBJECT (filesel->file_list), "select_row",
-		      (GtkSignalFunc) gtk_file_selection_file_button, 
-		      (gpointer) filesel);
-  gtk_clist_set_column_auto_resize (GTK_CLIST (filesel->file_list), 0, TRUE);
-  gtk_clist_column_titles_passive (GTK_CLIST (filesel->file_list));
+  g_signal_connect (filesel->file_list, "row_activated",
+		    G_CALLBACK (gtk_file_selection_file_activate), filesel);
+  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (filesel->file_list)), "changed",
+		    G_CALLBACK (gtk_file_selection_file_changed), filesel);
 
+  /* gtk_clist_column_titles_passive (GTK_CLIST (filesel->file_list)); */
+
   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
   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);
@@ -1792,24 +1819,9 @@ gtk_file_selection_update_history_menu (
   g_free (current_dir);
 }
 
-static void
-gtk_file_selection_file_button (GtkWidget      *widget,
-				gint            row, 
-				gint            column, 
-				GdkEventButton *bevent,
-				gpointer        user_data)
+static gchar *
+get_real_filename (gchar *filename)
 {
-  GtkFileSelection *fs = NULL;
-  gchar *filename, *temp = NULL;
-  
-  g_return_if_fail (GTK_IS_CLIST (widget));
-
-  fs = user_data;
-  g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
-  
-  gtk_clist_get_text (GTK_CLIST (fs->file_list), row, 0, &temp);
-  filename = g_strdup (temp);
-
 #ifdef G_WITH_CYGWIN
   /* Check to see if the selection was a drive selector */
   if (isalpha (filename[0]) && (filename[1] == ':'))
@@ -1817,62 +1829,82 @@ gtk_file_selection_file_button (GtkWidge
       /* It is... map it to a CYGWIN32 drive */
       gchar *temp_filename = g_strdup_printf ("//%c/", tolower (filename[0]));
       g_free(filename);
-      filename = temp_filename;
+      return temp_filename;
     }
+#else
+  return filename;
 #endif /* G_WITH_CYGWIN */
+}
 
-  if (filename)
-    {
-      if (bevent)
-	switch (bevent->type)
-	  {
-	  case GDK_2BUTTON_PRESS:
-	    gtk_button_clicked (GTK_BUTTON (fs->ok_button));
-	    break;
-	    
-	  default:
-	    gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
-	    break;
-	  }
-      else
-	gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+static void
+gtk_file_selection_file_activate (GtkTreeView       *tree_view,
+				  GtkTreePath       *path,
+				  GtkTreeViewColumn *column,
+				  gpointer           user_data)
+{
+  GtkFileSelection *fs = GTK_FILE_SELECTION (user_data);
+  GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+  GtkTreeIter iter;  
+  gchar *filename;
+  
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_tree_model_get (model, &iter, FILE_COLUMN, &filename, -1);
+  filename = get_real_filename (filename);
 
-      g_free (filename);
-    }
+  gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+  gtk_button_clicked (GTK_BUTTON (fs->ok_button));
+
+  g_free (filename);
 }
 
 static void
-gtk_file_selection_dir_button (GtkWidget      *widget,
-			       gint            row, 
-			       gint            column, 
-			       GdkEventButton *bevent,
-			       gpointer        user_data)
+gtk_file_selection_file_changed (GtkTreeSelection *selection,
+				 gpointer          user_data)
 {
-  GtkFileSelection *fs = NULL;
-  gchar *filename = NULL;
+  GtkFileSelection *fs = GTK_FILE_SELECTION (user_data);
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  
+  if (gtk_tree_selection_get_selected (selection, &model, &iter))
+    {
+      gchar *filename;
+      
+      gtk_tree_model_get (model, &iter, FILE_COLUMN, &filename, -1);
+      filename = get_real_filename (filename);
 
-  g_return_if_fail (GTK_IS_CLIST (widget));
+      gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
 
-  fs = GTK_FILE_SELECTION (user_data);
-  g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
+      g_free (filename);
+    }
+}
 
-  gtk_clist_get_text (GTK_CLIST (fs->dir_list), row, 0, &filename);
+static void
+gtk_file_selection_dir_activate (GtkTreeView       *tree_view,
+				 GtkTreePath       *path,
+				 GtkTreeViewColumn *column,
+				 gpointer           user_data)
+{
+  GtkFileSelection *fs = GTK_FILE_SELECTION (user_data);
+  GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+  GtkTreeIter iter;
+  gchar *filename;
 
-  if (filename && bevent && bevent->type == GDK_2BUTTON_PRESS)
-    gtk_file_selection_populate (fs, filename, FALSE, FALSE);
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_tree_model_get (model, &iter, DIR_COLUMN, &filename, -1);
+  gtk_file_selection_populate (fs, filename, FALSE, FALSE);
+  g_free (filename);
 }
 
 #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
 
 static void
-win32_gtk_add_drives_to_dir_list (GtkWidget *the_dir_list)
+win32_gtk_add_drives_to_dir_list (GtkListStore *model)
 {
-  gchar *text[2], *textPtr;
+  gchar *textPtr;
   gchar buffer[128];
   char volumeNameBuf[128];
   char formatBuffer[128];
-
-  text[1] = NULL;
+  GtkTreeIter iter;
 
   /* Get the Drives string */
   GetLogicalDriveStrings (sizeof (buffer), buffer);
@@ -1898,8 +1930,8 @@ win32_gtk_add_drives_to_dir_list (GtkWid
 	  sprintf (formatBuffer, "%s (%s)", formatBuffer, volumeNameBuf);
 #endif
 	/* Add to the list */
-	text[0] = formatBuffer;
-	gtk_clist_append (GTK_CLIST (the_dir_list), text);
+	gtk_list_store_append (model, &iter);
+	gtk_list_store_set (model, &iter, DIR_COLUMN, formatBuffer, -1);
       }
     textPtr += (strlen (textPtr) + 1);
   }
@@ -1914,16 +1946,18 @@ gtk_file_selection_populate (GtkFileSele
 {
   CompletionState *cmpl_state;
   PossibleCompletion* poss;
+  GtkTreeIter iter;
+  GtkListStore *dir_model;
+  GtkListStore *file_model;
   gchar* filename;
   gchar* rem_path = rel_path;
   gchar* sel_text;
-  gchar* text[2];
   gint did_recurse = FALSE;
   gint possible_count = 0;
   gint selection_index = -1;
   
   g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
-  
+
   cmpl_state = (CompletionState*) fs->cmpl_state;
   poss = cmpl_completion_matches (rel_path, &rem_path, cmpl_state);
 
@@ -1935,19 +1969,18 @@ gtk_file_selection_populate (GtkFileSele
     }
 
   g_assert (cmpl_state->reference_dir);
+
+  dir_model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fs->dir_list)));
+  file_model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fs->file_list)));
 
-  gtk_clist_freeze (GTK_CLIST (fs->dir_list));
-  gtk_clist_clear (GTK_CLIST (fs->dir_list));
-  gtk_clist_freeze (GTK_CLIST (fs->file_list));
-  gtk_clist_clear (GTK_CLIST (fs->file_list));
-
-  /* Set the dir_list to include ./ and ../ */
-  text[1] = NULL;
-  text[0] = "." G_DIR_SEPARATOR_S;
-  gtk_clist_append (GTK_CLIST (fs->dir_list), text);
+  gtk_list_store_clear (dir_model);
+  gtk_list_store_clear (file_model);
 
-  text[0] = ".." G_DIR_SEPARATOR_S;
-  gtk_clist_append (GTK_CLIST (fs->dir_list), text);
+  /* Set the dir list to include ./ and ../ */
+  gtk_list_store_append (dir_model, &iter);
+  gtk_list_store_set (dir_model, &iter, DIR_COLUMN, "." G_DIR_SEPARATOR_S, -1);
+  gtk_list_store_append (dir_model, &iter);
+  gtk_list_store_set (dir_model, &iter, DIR_COLUMN, ".." G_DIR_SEPARATOR_S, -1);
 
   while (poss)
     {
@@ -1957,17 +1990,19 @@ gtk_file_selection_populate (GtkFileSele
 
           filename = cmpl_this_completion (poss);
 
-	  text[0] = filename;
-	  
           if (cmpl_is_directory (poss))
             {
               if (strcmp (filename, "." G_DIR_SEPARATOR_S) != 0 &&
                   strcmp (filename, ".." G_DIR_SEPARATOR_S) != 0)
-		gtk_clist_append (GTK_CLIST (fs->dir_list), text);
+		{
+		  gtk_list_store_append (dir_model, &iter);
+		  gtk_list_store_set (dir_model, &iter, DIR_COLUMN, filename, -1);
+		}
 	    }
           else
 	    {
-	      gtk_clist_append (GTK_CLIST (fs->file_list), text);
+	      gtk_list_store_append (file_model, &iter);
+	      gtk_list_store_set (file_model, &iter, DIR_COLUMN, filename, -1);
             }
 	}
 
@@ -1976,11 +2011,8 @@ gtk_file_selection_populate (GtkFileSele
 
 #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
   /* For Windows, add drives as potential selections */
-  win32_gtk_add_drives_to_dir_list (fs->dir_list);
+  win32_gtk_add_drives_to_dir_list (dir_model);
 #endif
-
-  gtk_clist_thaw (GTK_CLIST (fs->dir_list));
-  gtk_clist_thaw (GTK_CLIST (fs->file_list));
 
   /* File lists are set. */
 


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