Index: gtk/gtkfilechooserentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserentry.c,v
retrieving revision 1.24
diff -u -u -r1.24 gtkfilechooserentry.c
--- gtk/gtkfilechooserentry.c	17 Sep 2004 18:13:26 -0000	1.24
+++ gtk/gtkfilechooserentry.c	2 Oct 2004 18:42:44 -0000
@@ -34,6 +34,10 @@
 #define GTK_IS_FILE_CHOOSER_ENTRY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_CHOOSER_ENTRY))
 #define GTK_FILE_CHOOSER_ENTRY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_ENTRY, GtkFileChooserEntryClass))
 
+
+#define FALLBACK_ICON_SIZE 20
+
+
 struct _GtkFileChooserEntryClass
 {
   GtkEntryClass parent_class;
@@ -57,6 +61,9 @@
 
   GtkListStore *completion_store;
 
+  gulong settings_signal_id;
+  gint icon_size;
+
   guint has_completion : 1;
   guint in_change      : 1;
   guint eat_tabs       : 1;
@@ -76,6 +83,10 @@
 static void     gtk_file_chooser_entry_finalize       (GObject          *object);
 static gboolean gtk_file_chooser_entry_focus          (GtkWidget        *widget,
 						       GtkDirectionType  direction);
+static void     gtk_file_chooser_entry_screen_changed (GtkWidget        *widget,
+						       GdkScreen        *old_screen);
+static void     gtk_file_chooser_entry_style_set      (GtkWidget        *widget,
+						       GtkStyle         *old_style);
 static void     gtk_file_chooser_entry_activate       (GtkEntry         *entry);
 static void     gtk_file_chooser_entry_changed        (GtkEditable      *editable);
 static void     gtk_file_chooser_entry_do_insert_text (GtkEditable *editable,
@@ -93,6 +104,13 @@
 					   const char          *key,
 					   GtkTreeIter         *iter,
 					   gpointer             data);
+static void     mime_icon_cell_data_func  (GtkCellLayout       *layout,
+					   GtkCellRenderer     *cell,
+					   GtkTreeModel        *model,
+					   GtkTreeIter         *iter,
+					   gpointer             user_data);
+static void     remove_settings_signal    (GtkFileChooserEntry *chooser_entry,
+					   GdkScreen           *screen);
 static void     files_added_cb            (GtkFileSystem       *file_system,
 					   GSList              *added_uris,
 					   GtkFileChooserEntry *chooser_entry);
@@ -157,6 +175,8 @@
   gobject_class->finalize = gtk_file_chooser_entry_finalize;
 
   widget_class->focus = gtk_file_chooser_entry_focus;
+  widget_class->screen_changed = gtk_file_chooser_entry_screen_changed;
+  widget_class->style_set = gtk_file_chooser_entry_style_set;
 
   entry_class->activate = gtk_file_chooser_entry_activate;
 }
@@ -183,12 +203,19 @@
 				       chooser_entry,
 				       NULL);
 
+  cell = gtk_cell_renderer_pixbuf_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp),
+			      cell, FALSE);
+  gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comp),
+				      cell, mime_icon_cell_data_func,
+				      chooser_entry, NULL);
+
   cell = gtk_cell_renderer_text_new ();
   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp),
                               cell, TRUE);
   gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (comp),
                                  cell,
-                                 "text", 0);
+                                 "text", DISPLAY_NAME_COLUMN);
 
   g_signal_connect (comp, "match-selected",
 		    G_CALLBACK (match_selected_callback), chooser_entry);
@@ -207,6 +234,9 @@
 {
   GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object);
 
+  remove_settings_signal (chooser_entry,
+			  gtk_widget_get_screen (GTK_WIDGET (object)));
+
   if (chooser_entry->completion_store)
     g_object_unref (chooser_entry->completion_store);
 
@@ -515,7 +545,6 @@
     }
 }
 
-
 static void
 update_current_folder_files (GtkFileChooserEntry *chooser_entry,
 			     GSList              *added_uris)
@@ -676,6 +705,154 @@
     return GTK_WIDGET_CLASS (parent_class)->focus (widget, direction);
 }
 
+/* Removes the settings signal handler.  It's safe to call multiple times */
+static void
+remove_settings_signal (GtkFileChooserEntry *entry,
+			GdkScreen           *screen)
+{
+  if (entry->settings_signal_id)
+    {
+      GtkSettings *settings;
+
+      settings = gtk_settings_get_for_screen (screen);
+      g_signal_handler_disconnect (settings,
+				   entry->settings_signal_id);
+      entry->settings_signal_id = 0;
+    }
+}
+
+static void
+mime_icon_cell_data_func (GtkCellLayout   *layout,
+			  GtkCellRenderer *cell,
+			  GtkTreeModel    *model,
+			  GtkTreeIter     *iter,
+			  gpointer         user_data)
+{
+  GdkPixbuf *pixbuf;
+  GtkFileChooserEntry *chooser_entry;
+  GtkFilePath *path;
+
+  chooser_entry = GTK_FILE_CHOOSER_ENTRY (user_data);
+  gtk_tree_model_get (model, iter, PATH_COLUMN, &path, -1);
+
+  if (path)
+    {
+      GSList *volumes;
+  
+      volumes = gtk_file_system_list_volumes (chooser_entry->file_system);
+      pixbuf = NULL;
+      while (volumes && !pixbuf)
+	{
+	  GtkFilePath *base_path;
+
+	  base_path = gtk_file_system_volume_get_base_path (chooser_entry->file_system,
+							    volumes->data);
+
+	  if (gtk_file_path_compare (base_path, path) == 0)
+	    pixbuf = gtk_file_system_volume_render_icon (chooser_entry->file_system,
+							 volumes->data,
+							 GTK_WIDGET (chooser_entry),
+							 chooser_entry->icon_size,
+							 NULL);
+
+	  volumes = g_slist_remove_link (volumes, volumes);
+	}
+      g_slist_free (volumes);
+
+      if (!pixbuf)
+	pixbuf = gtk_file_system_render_icon (chooser_entry->file_system, path,
+					      GTK_WIDGET (chooser_entry),
+					      chooser_entry->icon_size, NULL);
+      gtk_file_path_free (path);
+    }
+  else
+    pixbuf = NULL;
+
+  g_object_set (cell, "pixbuf", pixbuf, NULL);
+  
+  if (pixbuf)
+    g_object_unref (pixbuf);
+}
+
+/* Changes the icons wherever it is needed */
+static void
+change_icon_theme (GtkFileChooserEntry *chooser_entry)
+{
+  GtkSettings *settings;
+  gint width, height;
+
+  settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser_entry)));
+
+  if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_SMALL_TOOLBAR, &width, &height))
+    chooser_entry->icon_size = MAX (width, height);
+  else
+    chooser_entry->icon_size = FALLBACK_ICON_SIZE;
+}
+
+/* Callback used when a GtkSettings value changes */
+static void
+settings_notify_cb (GObject             *object,
+		    GParamSpec          *pspec,
+		    GtkFileChooserEntry *chooser_entry)
+{
+  const char *name;
+
+  name = g_param_spec_get_name (pspec);
+
+  if (strcmp (name, "gtk-icon-theme-name") == 0
+      || strcmp (name, "gtk-icon-sizes") == 0)
+    change_icon_theme (chooser_entry);
+}
+
+/* Installs a signal handler for GtkSettings so that we can monitor changes in
+ * the icon theme.
+ */
+static void
+check_icon_theme (GtkFileChooserEntry *chooser_entry)
+{
+  GtkSettings *settings;
+
+  if (chooser_entry->settings_signal_id)
+    return;
+
+  if (gtk_widget_has_screen (GTK_WIDGET (chooser_entry)))
+    {
+      settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser_entry)));
+      chooser_entry->settings_signal_id = g_signal_connect (settings, "notify",
+							    G_CALLBACK (settings_notify_cb),
+							    chooser_entry);
+
+      change_icon_theme (chooser_entry);
+    }
+}
+
+
+static void
+gtk_file_chooser_entry_screen_changed (GtkWidget *widget,
+				       GdkScreen *old_screen)
+{
+  GtkFileChooserEntry *chooser_entry;
+
+  chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget);
+
+  if (GTK_WIDGET_CLASS (parent_class)->screen_changed)
+    (*GTK_WIDGET_CLASS (parent_class)->screen_changed) (widget, old_screen);
+
+  remove_settings_signal (chooser_entry, old_screen);
+  check_icon_theme (chooser_entry);
+}
+
+static void
+gtk_file_chooser_entry_style_set (GtkWidget *widget,
+				  GtkStyle  *old_style)
+{
+  if (GTK_WIDGET_CLASS (parent_class)->style_set)
+    (*GTK_WIDGET_CLASS (parent_class)->style_set) (widget, old_style);
+
+  if (gtk_widget_has_screen (widget))
+    change_icon_theme (GTK_FILE_CHOOSER_ENTRY (widget));
+}
+
 static void
 gtk_file_chooser_entry_activate (GtkEntry *entry)
 {
@@ -720,9 +897,9 @@
 	  if (chooser_entry->completion_store)
 	    {
 	      gtk_list_store_clear (GTK_LIST_STORE (chooser_entry->completion_store));
-	      /* FIXME: Uncomment this line and get rid of the _clear above
-	       * after #137211 is fixed */
-	      /* gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);*/
+              /* FIXME: Uncomment this line and get rid of the _clear above
+               * after #137211 is fixed */
+              /* gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);*/
 	      g_object_unref (chooser_entry->completion_store);
 	      chooser_entry->completion_store = NULL;
 	    }
