]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkfilechooserdefault.c
Updated Slovenian translation
[~andy/gtk] / gtk / gtkfilechooserdefault.c
index 50e3810a69642fcf408f9bae3ba8673119868718..b70af42160e6682c6e51badc36996373f00a555b 100644 (file)
@@ -34,6 +34,7 @@
 #include "gtkexpander.h"
 #include "gtkfilechooserprivate.h"
 #include "gtkfilechooserdefault.h"
+#include "gtkfilechooserdialog.h"
 #include "gtkfilechooserembed.h"
 #include "gtkfilechooserentry.h"
 #include "gtkfilechoosersettings.h"
@@ -203,7 +204,8 @@ enum {
   SEARCH_MODEL_COL_FILE,
   SEARCH_MODEL_COL_DISPLAY_NAME,
   SEARCH_MODEL_COL_COLLATION_KEY,
-  SEARCH_MODEL_COL_STAT,
+  SEARCH_MODEL_COL_MTIME,
+  SEARCH_MODEL_COL_SIZE,
   SEARCH_MODEL_COL_CANCELLABLE,
   SEARCH_MODEL_COL_PIXBUF,
   SEARCH_MODEL_COL_MIME_TYPE,
@@ -273,6 +275,7 @@ static void     gtk_file_chooser_default_get_property (GObject               *ob
                                                       GParamSpec            *pspec);
 static void     gtk_file_chooser_default_dispose      (GObject               *object);
 static void     gtk_file_chooser_default_show_all       (GtkWidget             *widget);
+static void     gtk_file_chooser_default_realize        (GtkWidget             *widget);
 static void     gtk_file_chooser_default_map            (GtkWidget             *widget);
 static void     gtk_file_chooser_default_unmap          (GtkWidget             *widget);
 static void     gtk_file_chooser_default_hierarchy_changed (GtkWidget          *widget,
@@ -407,13 +410,11 @@ static void list_name_data_func (GtkTreeViewColumn *tree_column,
                                 GtkTreeModel      *tree_model,
                                 GtkTreeIter       *iter,
                                 gpointer           data);
-#if 0
 static void list_size_data_func (GtkTreeViewColumn *tree_column,
                                 GtkCellRenderer   *cell,
                                 GtkTreeModel      *tree_model,
                                 GtkTreeIter       *iter,
                                 gpointer           data);
-#endif
 static void list_mtime_data_func (GtkTreeViewColumn *tree_column,
                                  GtkCellRenderer   *cell,
                                  GtkTreeModel      *tree_model,
@@ -432,6 +433,8 @@ static void location_switch_to_path_bar (GtkFileChooserDefault *impl);
 
 static void     search_stop_searching        (GtkFileChooserDefault *impl,
                                               gboolean               remove_query);
+static void     search_clear_model_row       (GtkTreeModel          *model,
+                                              GtkTreeIter           *iter);
 static void     search_clear_model           (GtkFileChooserDefault *impl, 
                                              gboolean               remove_from_treeview);
 static gboolean search_should_respond        (GtkFileChooserDefault *impl);
@@ -454,6 +457,7 @@ static void     recent_get_valid_child_iter  (GtkFileChooserDefault *impl,
                                               GtkTreeIter           *child_iter,
                                               GtkTreeIter           *iter);
 static void     set_file_system_backend      (GtkFileChooserDefault *impl);
+static void     unset_file_system_backend    (GtkFileChooserDefault *impl);
 
 
 
@@ -562,6 +566,7 @@ _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
   gobject_class->dispose = gtk_file_chooser_default_dispose;
 
   widget_class->show_all = gtk_file_chooser_default_show_all;
+  widget_class->realize = gtk_file_chooser_default_realize;
   widget_class->map = gtk_file_chooser_default_map;
   widget_class->unmap = gtk_file_chooser_default_unmap;
   widget_class->hierarchy_changed = gtk_file_chooser_default_hierarchy_changed;
@@ -792,6 +797,7 @@ _gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
   impl->use_preview_label = TRUE;
   impl->select_multiple = FALSE;
   impl->show_hidden = FALSE;
+  impl->show_size_column = FALSE;
   impl->icon_size = FALLBACK_ICON_SIZE;
   impl->load_state = LOAD_EMPTY;
   impl->reload_state = RELOAD_EMPTY;
@@ -921,6 +927,8 @@ gtk_file_chooser_default_finalize (GObject *object)
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
   GSList *l;
 
+  unset_file_system_backend (impl);
+
   if (impl->shortcuts_pane_filter_model)
     g_object_unref (impl->shortcuts_pane_filter_model);
 
@@ -929,8 +937,6 @@ gtk_file_chooser_default_finalize (GObject *object)
 
   shortcuts_free (impl);
 
-  g_object_unref (impl->file_system);
-
   g_free (impl->browse_files_last_selected_name);
 
   for (l = impl->filters; l; l = l->next)
@@ -990,7 +996,7 @@ error_message_with_parent (GtkWindow  *parent,
   gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            "%s", detail);
 
-  if (parent->group)
+  if (parent && parent->group)
     gtk_window_group_add_window (parent->group, GTK_WINDOW (dialog));
 
   gtk_dialog_run (GTK_DIALOG (dialog));
@@ -1153,9 +1159,6 @@ change_folder_and_display_error (GtkFileChooserDefault *impl,
 static void
 emit_default_size_changed (GtkFileChooserDefault *impl)
 {
-  if (!GTK_WIDGET_MAPPED (impl))
-    return;
-
   profile_msg ("    emit default-size-changed start", NULL);
   g_signal_emit_by_name (impl, "default-size-changed");
   profile_msg ("    emit default-size-changed end", NULL);
@@ -1189,7 +1192,8 @@ update_preview_widget_visibility (GtkFileChooserDefault *impl)
   else
     gtk_widget_hide (impl->preview_box);
 
-  emit_default_size_changed (impl);
+  if (!GTK_WIDGET_MAPPED (impl))
+    emit_default_size_changed (impl);
 }
 
 static void
@@ -1916,6 +1920,15 @@ shortcuts_append_desktop (GtkFileChooserDefault *impl)
   profile_start ("start", NULL);
 
   name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
+  /* "To disable a directory, point it to the homedir."
+   * See http://freedesktop.org/wiki/Software/xdg-user-dirs
+   **/
+  if (!g_strcmp0 (name, g_get_home_dir ()))
+    {
+      profile_end ("end", NULL);
+      return;
+    }
+
   file = g_file_new_for_path (name);
   shortcuts_insert_file (impl, -1, SHORTCUT_TYPE_FILE, NULL, file, _("Desktop"), FALSE, SHORTCUTS_DESKTOP);
   impl->has_desktop = TRUE;
@@ -1936,7 +1949,7 @@ shortcuts_append_bookmarks (GtkFileChooserDefault *impl,
 {
   int start_row;
   int num_inserted;
-  const gchar *label;
+  gchar *label;
 
   profile_start ("start", NULL);
 
@@ -1958,6 +1971,8 @@ shortcuts_append_bookmarks (GtkFileChooserDefault *impl,
       label = _gtk_file_system_get_bookmark_label (impl->file_system, file);
 
       shortcuts_insert_file (impl, start_row + num_inserted, SHORTCUT_TYPE_FILE, NULL, file, label, TRUE, SHORTCUTS_BOOKMARKS);
+      g_free (label);
+
       num_inserted++;
     }
 
@@ -2069,10 +2084,17 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl)
          if (_gtk_file_system_volume_is_mounted (volume))
            {
              GFile *base_file;
+              gboolean base_is_native = TRUE;
 
              base_file = _gtk_file_system_volume_get_root (volume);
-             if (base_file != NULL && !g_file_is_native (base_file))
-               continue;
+              if (base_file != NULL)
+                {
+                  base_is_native = g_file_is_native (base_file);
+                  g_object_unref (base_file);
+                }
+
+              if (!base_is_native)
+                continue;
            }
        }
 
@@ -2174,6 +2196,7 @@ shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
 
   bookmarks = _gtk_file_system_list_bookmarks (impl->file_system);
   shortcuts_append_bookmarks (impl, bookmarks);
+  g_slist_foreach (bookmarks, (GFunc) g_object_unref, NULL);
   g_slist_free (bookmarks);
 
   if (impl->num_bookmarks == 0)
@@ -2407,7 +2430,7 @@ edited_idle_cb (GtkFileChooserDefault *impl)
        {
          GError *error = NULL;
 
-         if (!g_file_make_directory (file, NULL, &error))
+         if (g_file_make_directory (file, NULL, &error))
            change_folder_and_display_error (impl, file, FALSE);
          else
            error_creating_folder_dialog (impl, file, error);
@@ -2758,7 +2781,7 @@ selection_check_foreach_cb (GtkTreeModel *model,
     case OPERATION_MODE_BROWSE:
       gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
       info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
-      is_folder = info ? (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) : FALSE;
+      is_folder = info ? (_gtk_file_info_consider_as_directory (info)) : FALSE;
       break;
 
     case OPERATION_MODE_SEARCH:
@@ -3851,7 +3874,7 @@ shortcuts_list_create (GtkFileChooserDefault *impl)
 
   swin = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
-                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+                                 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
                                       GTK_SHADOW_IN);
   gtk_widget_show (swin);
@@ -3936,6 +3959,7 @@ shortcuts_list_create (GtkFileChooserDefault *impl)
                                       NULL);
 
   renderer = gtk_cell_renderer_text_new ();
+  g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
   g_signal_connect (renderer, "edited", 
                    G_CALLBACK (shortcuts_edited), impl);
   g_signal_connect (renderer, "editing-canceled", 
@@ -4090,6 +4114,18 @@ show_hidden_toggled_cb (GtkCheckMenuItem      *item,
                NULL);
 }
 
+/* Callback used when the "Show Size Column" menu item is toggled */
+static void
+show_size_column_toggled_cb (GtkCheckMenuItem *item,
+                             GtkFileChooserDefault *impl)
+{
+  impl->show_size_column = gtk_check_menu_item_get_active (item);
+
+  if (impl->list_size_column)
+    gtk_tree_view_column_set_visible (impl->list_size_column,
+                                      impl->show_size_column);
+}
+
 /* Shows an error dialog about not being able to select a dragged file */
 static void
 error_selecting_dragged_file_dialog (GtkFileChooserDefault *impl,
@@ -4152,8 +4188,7 @@ file_list_drag_data_received_get_info_cb (GCancellable *cancellable,
 
   if ((data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
        data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) &&
-      data->uris[1] == 0 && !error &&
-      g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+      data->uris[1] == 0 && !error && _gtk_file_info_consider_as_directory (info))
     change_folder_and_display_error (data->impl, data->file, FALSE);
   else
     {
@@ -4197,10 +4232,13 @@ file_list_drag_data_received_cb (GtkWidget          *widget,
 
   impl = GTK_FILE_CHOOSER_DEFAULT (data);
   chooser = GTK_FILE_CHOOSER (data);
-  
+
   /* Allow only drags from other widgets; see bug #533891. */
   if (gtk_drag_get_source_widget (context) == widget)
-    return;
+    {
+      g_signal_stop_emission_by_name (widget, "drag-data-received");
+      return;
+    }
 
   /* Parse the text/uri-list string, navigate to the first one */
   uris = gtk_selection_data_get_uris (selection_data);
@@ -4290,6 +4328,13 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
                    G_CALLBACK (show_hidden_toggled_cb), impl);
   gtk_widget_show (item);
   gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
+
+  item = gtk_check_menu_item_new_with_mnemonic (_("Show _Size Column"));
+  impl->browse_files_popup_menu_size_column_item = item;
+  g_signal_connect (item, "toggled",
+                    G_CALLBACK (show_size_column_toggled_cb), impl);
+  gtk_widget_show (item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
 }
 
 /* Updates the popup menu for the file list, creating it if necessary */
@@ -4304,12 +4349,21 @@ file_list_update_popup_menu (GtkFileChooserDefault *impl)
    * bookmarks_check_add_sensitivity()
    */
 
+  /* 'Show Hidden Files' */
   g_signal_handlers_block_by_func (impl->browse_files_popup_menu_hidden_files_item,
                                   G_CALLBACK (show_hidden_toggled_cb), impl);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (impl->browse_files_popup_menu_hidden_files_item),
                                  impl->show_hidden);
   g_signal_handlers_unblock_by_func (impl->browse_files_popup_menu_hidden_files_item,
                                     G_CALLBACK (show_hidden_toggled_cb), impl);
+
+  /* 'Show Size Column' */
+  g_signal_handlers_block_by_func (impl->browse_files_popup_menu_size_column_item,
+                                  G_CALLBACK (show_size_column_toggled_cb), impl);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (impl->browse_files_popup_menu_size_column_item),
+                                 impl->show_size_column);
+  g_signal_handlers_unblock_by_func (impl->browse_files_popup_menu_size_column_item,
+                                    G_CALLBACK (show_size_column_toggled_cb), impl);
 }
 
 static void
@@ -4403,19 +4457,21 @@ list_button_press_event_cb (GtkWidget             *widget,
 static void
 file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
 {
-  int name_id, mtime_id;
+  int name_id, mtime_id, size_id;
 
-  name_id = mtime_id = 0;
+  name_id = mtime_id = size_id = 0;
 
   switch (impl->operation_mode)
     {
     case OPERATION_MODE_BROWSE:
       name_id = FILE_LIST_COL_NAME;
       mtime_id = FILE_LIST_COL_MTIME;
+      size_id = FILE_LIST_COL_SIZE;
       break;
     case OPERATION_MODE_SEARCH:
       name_id = SEARCH_MODEL_COL_FILE;
-      mtime_id = SEARCH_MODEL_COL_STAT;
+      mtime_id = SEARCH_MODEL_COL_MTIME;
+      size_id = SEARCH_MODEL_COL_SIZE;
       break;
     case OPERATION_MODE_RECENT:
       name_id = RECENT_MODEL_COL_FILE;
@@ -4425,6 +4481,7 @@ file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
 
   gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
   gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
+  gtk_tree_view_column_set_sort_column_id (impl->list_size_column, size_id);
 }
 
 static gboolean
@@ -4597,7 +4654,7 @@ create_file_list (GtkFileChooserDefault *impl)
                                           list_name_data_func, impl, NULL);
 
   gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column);
-#if 0
+
   /* Size column */
 
   column = gtk_tree_view_column_new ();
@@ -4609,7 +4666,7 @@ create_file_list (GtkFileChooserDefault *impl)
                                           list_size_data_func, impl, NULL);
   gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
   gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
-#endif
+  impl->list_size_column = column;
 
   /* Modification time column */
 
@@ -4848,6 +4905,7 @@ save_widgets_create (GtkFileChooserDefault *impl)
   impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
   _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
                                           impl->file_system);
+  _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only);
   gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
   gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
   gtk_table_attach (GTK_TABLE (table), impl->location_entry,
@@ -5287,13 +5345,17 @@ set_local_only (GtkFileChooserDefault *impl,
     {
       impl->local_only = local_only;
 
+      if (impl->location_entry)
+       _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), local_only);
+
       if (impl->shortcuts_model && impl->file_system)
        {
          shortcuts_add_volumes (impl);
          shortcuts_add_bookmarks (impl);
        }
 
-      if (local_only && !g_file_is_native (impl->current_folder))
+      if (local_only && impl->current_folder &&
+           !g_file_is_native (impl->current_folder))
        {
          /* If we are pointing to a non-local folder, make an effort to change
           * back to a local folder, but it's really up to the app to not cause
@@ -5366,6 +5428,17 @@ set_file_system_backend (GtkFileChooserDefault *impl)
   profile_end ("end", NULL);
 }
 
+static void
+unset_file_system_backend (GtkFileChooserDefault *impl)
+{
+  g_signal_handlers_disconnect_by_func (impl->file_system,
+                                       G_CALLBACK (volumes_bookmarks_changed_cb), impl);
+
+  g_object_unref (impl->file_system);
+
+  impl->file_system = NULL;
+}
+
 /* This function is basically a do_all function.
  *
  * It sets the visibility on all the widgets based on the current state, and
@@ -5887,18 +5960,6 @@ gtk_file_chooser_default_size_allocate (GtkWidget     *widget,
   impl = GTK_FILE_CHOOSER_DEFAULT (widget);
 
   GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation);
-
-  impl->default_width = allocation->width;
-  impl->default_height = allocation->height;
-
-  if (impl->preview_widget_active &&
-      impl->preview_widget &&
-      GTK_WIDGET_DRAWABLE (impl->preview_widget))
-    impl->default_width -= impl->preview_widget->allocation.width + PREVIEW_HBOX_SPACING;
-
-  if (impl->extra_widget &&
-      GTK_WIDGET_DRAWABLE (impl->extra_widget))
-    impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height;
 }
 
 static gboolean
@@ -5918,7 +5979,7 @@ get_is_file_filtered (GtkFileChooserDefault *impl,
   needed = gtk_file_filter_get_needed (impl->current_filter);
 
   filter_info.display_name = g_file_info_get_display_name (file_info);
-  filter_info.mime_type = g_file_info_get_content_type (file_info);
+  filter_info.mime_type = g_content_type_get_mime_type (g_file_info_get_content_type (file_info));
 
   if (needed & GTK_FILE_FILTER_FILENAME)
     {
@@ -5940,10 +6001,9 @@ get_is_file_filtered (GtkFileChooserDefault *impl,
 
   result = gtk_file_filter_filter (impl->current_filter, &filter_info);
 
-  if (filter_info.filename)
-    g_free ((gchar *)filter_info.filename);
-  if (filter_info.uri)
-    g_free ((gchar *)filter_info.uri);
+  g_free ((gchar *)filter_info.filename);
+  g_free ((gchar *)filter_info.uri);
+  g_free ((gchar *)filter_info.mime_type);
 
   return !result;
 }
@@ -5955,20 +6015,53 @@ settings_load (GtkFileChooserDefault *impl)
   LocationMode location_mode;
   gboolean show_hidden;
   gboolean expand_folders;
+  gboolean show_size_column;
 
   settings = _gtk_file_chooser_settings_new ();
 
   location_mode = _gtk_file_chooser_settings_get_location_mode (settings);
   show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
   expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
+  show_size_column = _gtk_file_chooser_settings_get_show_size_column (settings);
 
   g_object_unref (settings);
 
   location_mode_set (impl, location_mode, TRUE);
+
   gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden);
+
   impl->expand_folders = expand_folders;
   if (impl->save_expander)
     gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders);
+
+  impl->show_size_column = show_size_column;
+  if (impl->list_size_column)
+    gtk_tree_view_column_set_visible (impl->list_size_column, show_size_column);
+}
+
+static void
+save_dialog_geometry (GtkFileChooserDefault *impl, GtkFileChooserSettings *settings)
+{
+  GtkWindow *toplevel;
+  int x, y, width, height;
+
+  /* We don't save the geometry in non-expanded "save" mode, so that the "little
+   * dialog" won't make future Open dialogs too small.
+   */
+  if (!(impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
+       || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+       || impl->expand_folders))
+    return;
+
+  toplevel = get_toplevel (GTK_WIDGET (impl));
+
+  if (!(toplevel && GTK_IS_FILE_CHOOSER_DIALOG (toplevel)))
+    return;
+
+  gtk_window_get_position (toplevel, &x, &y);
+  gtk_window_get_size (toplevel, &width, &height);
+
+  _gtk_file_chooser_settings_set_geometry (settings, x, y, width, height);
 }
 
 static void
@@ -5981,6 +6074,9 @@ settings_save (GtkFileChooserDefault *impl)
   _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode);
   _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
   _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
+  _gtk_file_chooser_settings_set_show_size_column (settings, impl->show_size_column);
+
+  save_dialog_geometry (impl, settings);
 
   /* NULL GError */
   _gtk_file_chooser_settings_save (settings, NULL);
@@ -5988,6 +6084,20 @@ settings_save (GtkFileChooserDefault *impl)
   g_object_unref (settings);
 }
 
+/* GtkWidget::realize method */
+static void
+gtk_file_chooser_default_realize (GtkWidget *widget)
+{
+  GtkFileChooserDefault *impl;
+  char *current_working_dir;
+
+  impl = GTK_FILE_CHOOSER_DEFAULT (widget);
+
+  GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->realize (widget);
+
+  emit_default_size_changed (impl);
+}
+
 /* GtkWidget::map method */
 static void
 gtk_file_chooser_default_map (GtkWidget *widget)
@@ -6041,8 +6151,6 @@ gtk_file_chooser_default_map (GtkWidget *widget)
 
   settings_load (impl);
 
-  emit_default_size_changed (impl);
-
   profile_end ("end", NULL);
 }
 
@@ -6072,7 +6180,7 @@ list_model_filter_func (GtkFileSystemModel *model,
   if (!impl->current_filter)
     return TRUE;
 
-  if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+  if (_gtk_file_info_consider_as_directory (file_info))
     return TRUE;
 
   return !get_is_file_filtered (impl, file, file_info);
@@ -6109,12 +6217,12 @@ install_list_model_filter (GtkFileChooserDefault *impl)
   gboolean dir_a, dir_b;                                                                                      \
                                                                                                               \
   if (info_a)                                                                                                 \
-    dir_a = (g_file_info_get_file_type (info_a) == G_FILE_TYPE_DIRECTORY);                                    \
+    dir_a = _gtk_file_info_consider_as_directory (info_a);                                                    \
   else                                                                                                        \
     return impl->list_sort_ascending ? -1 : 1;                                                                \
                                                                                                               \
   if (info_b)                                                                                                 \
-    dir_b = (g_file_info_get_file_type (info_b) == G_FILE_TYPE_DIRECTORY);                                    \
+    dir_b = _gtk_file_info_consider_as_directory (info_b);                                                    \
   else                                                                                                        \
     return impl->list_sort_ascending ? 1 : -1;                                                                \
                                                                                                               \
@@ -6396,9 +6504,9 @@ show_and_select_files_finished_loading (GtkFolder *folder,
            have_hidden = g_file_info_get_is_hidden (info);
 
          if (!have_filtered)
-           have_filtered = (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY) &&
+           have_filtered = (! _gtk_file_info_consider_as_directory (info)) &&
                             get_is_file_filtered (data->impl, file, info);
-
+       
          g_object_unref (info);
 
          if (have_hidden && have_filtered)
@@ -6496,7 +6604,7 @@ show_and_select_files (GtkFileChooserDefault *impl,
 
   impl->show_and_select_files_cancellable =
     _gtk_file_system_get_folder (impl->file_system, parent_file,
-                                "standard::is-hidden,standard::type,standard::name",
+                                "standard::is-hidden,standard::type,standard::name,standard::content-type",
                                 show_and_select_files_get_folder_cb, info);
 
   profile_end ("end", NULL);
@@ -6731,7 +6839,7 @@ update_chooser_entry (GtkFileChooserDefault *impl)
              impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
            {
              /* We don't want the name to change when clicking on a folder... */
-             change_entry = (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY);
+             change_entry = (! _gtk_file_info_consider_as_directory (info));
            }
           else
            change_entry = TRUE; /* ... unless we are in SELECT_FOLDER mode */
@@ -6815,6 +6923,41 @@ struct UpdateCurrentFolderData
   GError *original_error;
 };
 
+static void
+update_current_folder_mount_enclosing_volume_cb (GCancellable        *cancellable,
+                                                 GtkFileSystemVolume *volume,
+                                                 const GError        *error,
+                                                 gpointer             user_data)
+{
+  gboolean cancelled = g_cancellable_is_cancelled (cancellable);
+  struct UpdateCurrentFolderData *data = user_data;
+  GtkFileChooserDefault *impl = data->impl;
+
+  if (cancellable != impl->update_current_folder_cancellable)
+    goto out;
+
+  impl->update_current_folder_cancellable = NULL;
+  set_busy_cursor (impl, FALSE);
+
+  if (cancelled)
+    goto out;
+
+  if (error)
+    {
+      error_changing_folder_dialog (data->impl, data->file, g_error_copy (error));
+      impl->reload_state = RELOAD_EMPTY;
+      goto out;
+    }
+
+  change_folder_and_display_error (impl, data->file, data->clear_entry);
+
+out:
+  g_object_unref (data->file);
+  g_free (data);
+
+  g_object_unref (cancellable);
+}
+
 static void
 update_current_folder_get_info_cb (GCancellable *cancellable,
                                   GFileInfo    *info,
@@ -6840,6 +6983,27 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
     {
       GFile *parent_file;
 
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED))
+        {
+          GMountOperation *mount_operation;
+          GtkWidget *toplevel;
+
+          g_object_unref (cancellable);
+          toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl));
+
+          mount_operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
+
+          set_busy_cursor (impl, TRUE);
+
+          impl->update_current_folder_cancellable =
+            _gtk_file_system_mount_enclosing_volume (impl->file_system, data->file,
+                                                     mount_operation,
+                                                     update_current_folder_mount_enclosing_volume_cb,
+                                                     data);
+
+          return;
+        }
+
       if (!data->original_file)
         {
          data->original_file = g_object_ref (data->file);
@@ -6871,8 +7035,13 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
        }
       else
         {
-         /* error and bail out */
-         error_changing_folder_dialog (impl, data->original_file, data->original_error);
+         /* Error and bail out, ignoring "not found" errors since they're useless:
+           * they only happen when a program defaults to a folder that has been (re)moved.
+           */
+          if (!g_error_matches (data->original_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+           error_changing_folder_dialog (impl, data->original_file, data->original_error);
+          else
+            g_error_free (data->original_error);
          g_object_unref (data->original_file);
 
          goto out;
@@ -6886,7 +7055,7 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
       g_object_unref (data->original_file);
     }
 
-  if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
+  if (! _gtk_file_info_consider_as_directory (info))
     goto out;
 
   if (!_gtk_path_bar_set_file (GTK_PATH_BAR (impl->browse_path_bar), data->file, data->keep_trail, NULL))
@@ -6898,10 +7067,10 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
        g_object_unref (impl->current_folder);
 
       impl->current_folder = g_object_ref (data->file);
-
-      impl->reload_state = RELOAD_HAS_FOLDER;
     }
 
+  impl->reload_state = RELOAD_HAS_FOLDER;
+
   /* Update the widgets that may trigger a folder change themselves.  */
 
   if (!impl->changing_folder)
@@ -7169,7 +7338,7 @@ maybe_select (GtkTreeModel *model,
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
   
   info = get_list_file_info (impl, iter);
-  is_folder = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+  is_folder = _gtk_file_info_consider_as_directory (info);
 
   if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
       (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
@@ -7567,7 +7736,7 @@ add_shortcut_get_info_cb (GCancellable *cancellable,
 
   data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, cancellable);
 
-  if (cancelled || error || g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
+  if (cancelled || error || (! _gtk_file_info_consider_as_directory (info)))
     goto out;
 
   pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
@@ -7811,6 +7980,20 @@ gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
       || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
       || impl->expand_folders)
     {
+      GtkFileChooserSettings *settings;
+      int x, y, width, height;
+
+      settings = _gtk_file_chooser_settings_new ();
+      _gtk_file_chooser_settings_get_geometry (settings, &x, &y, &width, &height);
+      g_object_unref (settings);
+
+      if (x >= 0 && y >= 0 && width > 0 && height > 0)
+       {
+         *default_width = width;
+         *default_height = height;
+         return;
+       }
+
       find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
 
       if (impl->preview_widget_active &&
@@ -8115,7 +8298,7 @@ save_entry_get_info_cb (GCancellable *cancellable,
   if (!info)
     parent_is_folder = FALSE;
   else
-    parent_is_folder = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+    parent_is_folder = _gtk_file_info_consider_as_directory (info);
 
   if (parent_is_folder)
     {
@@ -8185,7 +8368,7 @@ file_exists_get_info_cb (GCancellable *cancellable,
   if (cancelled)
     goto out;
 
-  file_exists_and_is_not_folder = info && (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY);
+  file_exists_and_is_not_folder = info && (! _gtk_file_info_consider_as_directory (info));
 
   if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
     /* user typed a filename; we are done */
@@ -8509,7 +8692,7 @@ search_selected_foreach_get_file_cb (GtkTreeModel *model,
   list = data;
 
   gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_FILE, &file, -1);
-  *list = g_slist_prepend (*list, file);
+  *list = g_slist_prepend (*list, g_object_ref (file));
 }
 
 /* Constructs a list of the selected paths in search mode */
@@ -8561,6 +8744,9 @@ search_hit_get_info_cb (GCancellable *cancellable,
   GtkTreeIter iter;
   GCancellable *model_cancellable;
   gboolean is_folder = FALSE;
+  GTimeVal mtime;
+  guint64 modification_time = 0;
+  goffset size;
   char *mime_type;
   char *display_name;
   struct SearchHitInsertRequest *request = data;
@@ -8592,13 +8778,17 @@ search_hit_get_info_cb (GCancellable *cancellable,
 
   if (!info)
     {
+      search_clear_model_row (GTK_TREE_MODEL (request->impl->search_model), &iter);
       gtk_list_store_remove (request->impl->search_model, &iter);
       goto out;
     }
 
   display_name = g_strdup (g_file_info_get_display_name (info));
-  mime_type = g_strdup (g_file_info_get_content_type (info));
-  is_folder = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+  mime_type = g_content_type_get_mime_type (g_file_info_get_content_type (info));
+  g_file_info_get_modification_time (info, &mtime);
+  modification_time = (guint64) mtime.tv_sec;
+  size = g_file_info_get_size (info);
+  is_folder = _gtk_file_info_consider_as_directory (info);
   pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
                                       request->impl->icon_size);
 
@@ -8607,6 +8797,8 @@ search_hit_get_info_cb (GCancellable *cancellable,
                       SEARCH_MODEL_COL_DISPLAY_NAME, display_name,
                       SEARCH_MODEL_COL_MIME_TYPE, mime_type,
                       SEARCH_MODEL_COL_IS_FOLDER, is_folder,
+                      SEARCH_MODEL_COL_MTIME, modification_time,
+                      SEARCH_MODEL_COL_SIZE, size,
                       -1);
 
   if (pixbuf)
@@ -8627,17 +8819,16 @@ search_add_hit (GtkFileChooserDefault *impl,
                gchar                 *uri)
 {
   GFile *file;
-  char *filename;
   char *tmp;
   char *collation_key;
-  struct stat statbuf;
-  struct stat *statbuf_copy;
   GtkTreeIter iter;
   GtkTreePath *p;
   GCancellable *cancellable;
   struct SearchHitInsertRequest *request;
 
   file = g_file_new_for_uri (uri);
+  if (!file)
+    return;
 
   if (!g_file_is_native (file))
     {
@@ -8645,18 +8836,6 @@ search_add_hit (GtkFileChooserDefault *impl,
       return;
     }
 
-  filename = g_file_get_path (file);
-
-  if (stat (filename, &statbuf) != 0)
-    {
-      g_object_unref (file);
-      g_free (filename);
-      return;
-    }
-
-  statbuf_copy = g_new (struct stat, 1);
-  *statbuf_copy = statbuf;
-
   tmp = g_file_get_parse_name (file);
   collation_key = g_utf8_collate_key_for_filename (tmp, -1);
   g_free (tmp);
@@ -8672,20 +8851,20 @@ search_add_hit (GtkFileChooserDefault *impl,
   gtk_tree_path_free (p);
 
   cancellable = _gtk_file_system_get_info (impl->file_system, file,
-                                          "standard::type,standard::icon,"
-                                          "standard::content-type,standard::display-name",
+                                          "standard::type,"
+                                           "standard::icon,"
+                                          "standard::content-type,"
+                                           "standard::display-name,"
+                                           "time::modified,"
+                                           "standard::size",
                                           search_hit_get_info_cb,
                                           request);
 
   gtk_list_store_set (impl->search_model, &iter,
                       SEARCH_MODEL_COL_FILE, file,
                       SEARCH_MODEL_COL_COLLATION_KEY, collation_key,
-                      SEARCH_MODEL_COL_STAT, statbuf_copy,
                       SEARCH_MODEL_COL_CANCELLABLE, cancellable,
                       -1);
-
-  g_object_unref (file);
-  g_free (filename);
 }
 
 /* Callback used from GtkSearchEngine when we get new hits */
@@ -8752,6 +8931,35 @@ search_engine_error_cb (GtkSearchEngine *engine,
   set_busy_cursor (impl, FALSE);
 }
 
+static void
+search_clear_model_row (GtkTreeModel *model,
+                        GtkTreeIter  *iter)
+{
+  GFile *file;
+  gchar *display_name;
+  gchar *collation_key;
+  GCancellable *cancellable;
+  gchar *mime_type;
+
+  gtk_tree_model_get (model, iter,
+                      SEARCH_MODEL_COL_FILE, &file,
+                      SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
+                      SEARCH_MODEL_COL_COLLATION_KEY, &collation_key,
+                      SEARCH_MODEL_COL_CANCELLABLE, &cancellable,
+                      SEARCH_MODEL_COL_MIME_TYPE, &mime_type,
+                      -1);
+
+  if (file)
+    g_object_unref (file);
+
+  g_free (display_name);
+  g_free (collation_key);
+  g_free (mime_type);
+           
+  if (cancellable)
+    g_cancellable_cancel (cancellable);
+}
+
 /* Frees the data in the search_model */
 static void
 search_clear_model (GtkFileChooserDefault *impl, 
@@ -8768,14 +8976,7 @@ search_clear_model (GtkFileChooserDefault *impl,
   if (gtk_tree_model_get_iter_first (model, &iter))
     do
       {
-       GCancellable *cancellable;
-
-       gtk_tree_model_get (model, &iter,
-                            SEARCH_MODEL_COL_CANCELLABLE, &cancellable,
-                           -1);
-
-        if (cancellable)
-         g_cancellable_cancel (cancellable);
+        search_clear_model_row (model, &iter);
       }
     while (gtk_tree_model_iter_next (model, &iter));
 
@@ -8879,6 +9080,41 @@ search_column_path_sort_func (GtkTreeModel *model,
   return strcmp (collation_key_a, collation_key_b);
 }
 
+/* Sort callback from the size column */
+static gint
+search_column_size_sort_func (GtkTreeModel *model,
+                              GtkTreeIter  *a,
+                              GtkTreeIter  *b,
+                              gpointer      user_data)
+{
+  GtkFileChooserDefault *impl = user_data;
+  GtkTreeIter child_a, child_b;
+  gboolean is_folder_a, is_folder_b;
+  goffset size_a, size_b;
+
+  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
+  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
+
+  gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
+                      SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
+                      SEARCH_MODEL_COL_SIZE, &size_a,
+                      -1);
+  gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
+                      SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
+                      SEARCH_MODEL_COL_SIZE, &size_b,
+                      -1);
+  
+  if (is_folder_a != is_folder_b)
+    return is_folder_a ? 1 : -1;
+
+  if (size_a < size_b)
+    return -1;
+  else if (size_a > size_b)
+    return 1;
+  else
+    return 0;
+}
+
 /* Sort callback from the modification time column */
 static gint
 search_column_mtime_sort_func (GtkTreeModel *model,
@@ -8888,38 +9124,27 @@ search_column_mtime_sort_func (GtkTreeModel *model,
 {
   GtkFileChooserDefault *impl = user_data;
   GtkTreeIter child_a, child_b;
-  const struct stat *statbuf_a, *statbuf_b;
   gboolean is_folder_a, is_folder_b;
+  guint64 mtime_a, mtime_b;
 
   gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
   gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
 
-  /* Note that although we store a whole struct stat in the model, we only
-   * compare the mtime here.  If we add another column relative to a struct stat
-   * (e.g. a file size column), we'll want another sort callback similar to this
-   * one as well.
-   */
   gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
                       SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
-                      SEARCH_MODEL_COL_STAT, &statbuf_a,
+                      SEARCH_MODEL_COL_MTIME, &mtime_a,
                       -1);
   gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
                       SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
-                      SEARCH_MODEL_COL_STAT, &statbuf_b,
+                      SEARCH_MODEL_COL_MTIME, &mtime_b,
                       -1);
   
-  if (!statbuf_a)
-    return 1;
-
-  if (!statbuf_b)
-    return -1;
-
   if (is_folder_a != is_folder_b)
     return is_folder_a ? 1 : -1;
 
-  if (statbuf_a->st_mtime < statbuf_b->st_mtime)
+  if (mtime_a < mtime_b)
     return -1;
-  else if (statbuf_a->st_mtime > statbuf_b->st_mtime)
+  else if (mtime_a > mtime_b)
     return 1;
   else
     return 0;
@@ -9019,7 +9244,8 @@ search_setup_model (GtkFileChooserDefault *impl)
    *   as a pointer not as a G_TYPE_STRING
    * SEARCH_MODEL_COL_COLLATION_KEY - collation key for the filename, stored
    *   as a pointer not as a G_TYPE_STRING
-   * SEARCH_MODEL_COL_STAT - pointer to a struct stat
+   * SEARCH_MODEL_COL_MTIME - G_TYPE_UINT64 for the modification time
+   * SEARCH_MODEL_COL_SIZE - G_TYPE_INT64 for the size
    * SEARCH_MODEL_COL_CANCELLABLE - cancellable used when getting the hit's info
    * SEARCH_MODEL_COL_PIXBUF - GdkPixbuf for the hit's icon
    * SEARCH_MODEL_COL_MIME_TYPE - a string with the hit's MIME type
@@ -9029,14 +9255,15 @@ search_setup_model (GtkFileChooserDefault *impl)
    * of this file.
    */
   impl->search_model = gtk_list_store_new (SEARCH_MODEL_COL_NUM_COLUMNS,
-                                          G_TYPE_POINTER,
-                                          G_TYPE_POINTER,
-                                          G_TYPE_POINTER,
-                                          G_TYPE_POINTER,
-                                           G_TYPE_POINTER,
-                                           GDK_TYPE_PIXBUF,
-                                           G_TYPE_POINTER,
-                                           G_TYPE_BOOLEAN);
+                                          G_TYPE_POINTER, /* file */
+                                          G_TYPE_POINTER, /* display-name */
+                                          G_TYPE_POINTER, /* collation-key */
+                                          G_TYPE_UINT64, /* mtime */
+                                           G_TYPE_INT64, /* size */
+                                           G_TYPE_POINTER, /* cancellable */
+                                           GDK_TYPE_PIXBUF, /* pixbuf */
+                                           G_TYPE_POINTER, /* mime-type */
+                                           G_TYPE_BOOLEAN /*is-folder */);
   
   impl->search_model_filter =
     GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL));
@@ -9051,11 +9278,15 @@ search_setup_model (GtkFileChooserDefault *impl)
                                   search_column_path_sort_func,
                                   impl, NULL);
   gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
-                                  SEARCH_MODEL_COL_STAT,
+                                  SEARCH_MODEL_COL_MTIME,
                                   search_column_mtime_sort_func,
                                   impl, NULL);
+  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
+                                  SEARCH_MODEL_COL_SIZE,
+                                  search_column_size_sort_func,
+                                  impl, NULL);
   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model_sort),
-                                       SEARCH_MODEL_COL_STAT,
+                                       SEARCH_MODEL_COL_MTIME,
                                        GTK_SORT_DESCENDING);
 
   /* EB: setting the model here will make the hits list update feel
@@ -9348,6 +9579,8 @@ recent_switch_to_browse_mode (GtkFileChooserDefault *impl)
        gtk_widget_show (impl->location_entry_box);
     }
 
+  gtk_tree_view_column_set_visible (impl->list_size_column, impl->show_size_column);
+
   impl->operation_mode = OPERATION_MODE_BROWSE;
 
   file_list_set_sort_column_ids (impl);
@@ -9645,7 +9878,7 @@ recent_item_get_info_cb (GCancellable *cancellable,
       goto out;
     }
 
-  is_folder = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+  is_folder = _gtk_file_info_consider_as_directory (info);
 
   gtk_list_store_set (request->impl->recent_model, &iter,
                       RECENT_MODEL_COL_IS_FOLDER, is_folder,
@@ -9911,6 +10144,10 @@ recent_activate (GtkFileChooserDefault *impl)
     }
 
   recent_hide_entry (impl);
+
+  /* hide the file size column if it's visible */
+  gtk_tree_view_column_set_visible (impl->list_size_column, FALSE);
+
   file_list_set_sort_column_ids (impl);
   recent_start_loading (impl);
 }
@@ -10161,12 +10398,16 @@ shortcuts_activate_volume (GtkFileChooserDefault *impl,
 
   if (!_gtk_file_system_volume_is_mounted (volume))
     {
-      set_busy_cursor (impl, TRUE);
+      GtkMountOperation *mount_op;
 
+      set_busy_cursor (impl, TRUE);
+   
+      mount_op = gtk_mount_operation_new (get_toplevel (GTK_WIDGET (impl)));
       impl->shortcuts_activate_iter_cancellable =
-        _gtk_file_system_mount_volume (impl->file_system, volume, NULL,
+        _gtk_file_system_mount_volume (impl->file_system, volume, mount_op,
                                       shortcuts_activate_volume_mount_cb,
                                       g_object_ref (impl));
+      g_object_unref (mount_op);
     }
   else
     {
@@ -10205,7 +10446,7 @@ shortcuts_activate_get_info_cb (GCancellable *cancellable,
   if (cancelled)
     goto out;
 
-  if (!error && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+  if (!error && _gtk_file_info_consider_as_directory (info))
     change_folder_and_display_error (data->impl, data->file, FALSE);
   else
     gtk_file_chooser_default_select_file (GTK_FILE_CHOOSER (data->impl),
@@ -10427,7 +10668,7 @@ list_select_func  (GtkTreeSelection  *selection,
 
             gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
             info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
-            if (info && g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
+            if (info && (! _gtk_file_info_consider_as_directory (info)))
               return FALSE;
           }
           break;
@@ -10539,11 +10780,28 @@ list_row_activated (GtkTreeView           *tree_view,
         info = _gtk_file_system_model_get_info (impl->browse_files_model,
                                                 &child_iter);
 
-        if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+        if (_gtk_file_info_consider_as_directory (info))
           {
-           GFile *file;
+           GFile *file, *target_file;
+           const gchar *target_uri;
 
             file = _gtk_file_system_model_get_file (impl->browse_files_model, &child_iter);
+            if (g_file_info_get_file_type (info) == G_FILE_TYPE_MOUNTABLE ||
+                g_file_info_get_file_type (info) == G_FILE_TYPE_SHORTCUT) 
+              {
+                target_uri = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
+                if (target_uri)
+                  {
+                    target_file = g_file_new_for_uri (target_uri);
+                    if (target_file)
+                      {
+                        g_object_unref (file);
+                        file = target_file;
+                      }
+                  }  
+              }
+            
+            
             change_folder_and_display_error (impl, file, FALSE);
             return;
           }
@@ -10671,7 +10929,7 @@ list_icon_data_func (GtkTreeViewColumn *tree_column,
         if (info &&
             (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
              impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
-          sensitive = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+          sensitive = _gtk_file_info_consider_as_directory (info);
       }
       break;
     }
@@ -10775,7 +11033,7 @@ list_name_data_func (GtkTreeViewColumn *tree_column,
   if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
       impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
     {
-      sensitive = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+      sensitive = _gtk_file_info_consider_as_directory (info);
     }
 
   g_object_set (cell,
@@ -10785,7 +11043,6 @@ list_name_data_func (GtkTreeViewColumn *tree_column,
                NULL);
 }
 
-#if 0
 static void
 list_size_data_func (GtkTreeViewColumn *tree_column,
                     GtkCellRenderer   *cell,
@@ -10794,12 +11051,47 @@ list_size_data_func (GtkTreeViewColumn *tree_column,
                     gpointer           data)
 {
   GtkFileChooserDefault *impl = data;
-  GFileInfo *info = get_list_file_info (impl, iter);
-  gint64 size;
+  GFileInfo *info;
+  goffset size;
   gchar *str;
   gboolean sensitive = TRUE;
 
-  if (!info || g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+  if (impl->operation_mode == OPERATION_MODE_RECENT)
+    return;
+
+  if (impl->operation_mode == OPERATION_MODE_SEARCH)
+    {
+      GtkTreeIter child_iter;
+      gboolean is_folder = FALSE;
+
+      search_get_valid_child_iter (impl, &child_iter, iter);
+      gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
+                          SEARCH_MODEL_COL_SIZE, &size,
+                          SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
+                         -1);
+
+      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
+          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
+        sensitive = is_folder ? TRUE : FALSE;
+
+      if (!is_folder)
+        str = g_format_size_for_display (size);
+      else
+        str = NULL;
+
+      g_object_set (cell,
+                    "text", str,
+                    "sensitive", sensitive,
+                    NULL);
+
+      g_free (str);
+
+      return;
+    }
+
+  info = get_list_file_info (impl, iter);
+
+  if (!info || _gtk_file_info_consider_as_directory (info))
     {
       g_object_set (cell,
                    "text", NULL,
@@ -10808,18 +11100,9 @@ list_size_data_func (GtkTreeViewColumn *tree_column,
       return;
     }
 
-  size = gtk_file_info_get_size (info);
-#if 0
-  if (size < (gint64)1024)
-    str = g_strdup_printf (g_dngettext (GETTEXT_DOMAIN, "%d byte", "%d bytes", (gint)size), (gint)size);
-  else if (size < (gint64)1024*1024)
-    str = g_strdup_printf (_("%.1f KB"), size / (1024.));
-  else if (size < (gint64)1024*1024*1024)
-    str = g_strdup_printf (_("%.1f MB"), size / (1024.*1024.));
-  else
-    str = g_strdup_printf (_("%.1f GB"), size / (1024.*1024.*1024.));
-#endif
-  str = g_strdup_printf ("%" G_GINT64_FORMAT, size);
+  size = g_file_info_get_size (info);
+  str = g_format_size_for_display (size);
+
   if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
       impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
     sensitive = FALSE;
@@ -10832,7 +11115,6 @@ list_size_data_func (GtkTreeViewColumn *tree_column,
 
   g_free (str);
 }
-#endif
 
 /* Tree column data callback for the file list; fetches the mtime of a file */
 static void
@@ -10858,19 +11140,16 @@ list_mtime_data_func (GtkTreeViewColumn *tree_column,
   if (impl->operation_mode == OPERATION_MODE_SEARCH)
     {
       GtkTreeIter child_iter;
-      struct stat *statbuf;
+      guint64 mtime;
       gboolean is_folder;
 
       search_get_valid_child_iter (impl, &child_iter, iter);
       gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
-                          SEARCH_MODEL_COL_STAT, &statbuf,
+                          SEARCH_MODEL_COL_MTIME, &mtime,
                           SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
                          -1);
-      if (statbuf)
-        time_mtime = statbuf->st_mtime;
-      else
-        time_mtime = 0;
 
+      time_mtime = (time_t) mtime;
 
       if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
           impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
@@ -10916,7 +11195,7 @@ list_mtime_data_func (GtkTreeViewColumn *tree_column,
 
       if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-       sensitive = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+       sensitive = _gtk_file_info_consider_as_directory (info);
     }
 
   if (G_UNLIKELY (time_mtime == 0))