]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkfilechooserdefault.c
Free volumes not actually put into the shortcut list.
[~andy/gtk] / gtk / gtkfilechooserdefault.c
index d8ccb35be59f63b78800b395a822b3a09c819e2c..8987297667fd8402043ffd0074b524b2b8bfa938 100644 (file)
@@ -147,8 +147,10 @@ struct _GtkFileChooserDefault
   guint settings_signal_id;
   int icon_size;
 
+#if 0
   GdkDragContext *shortcuts_drag_context;
   GSource *shortcuts_drag_outside_idle;
+#endif
 
   /* Flags */
 
@@ -161,13 +163,17 @@ struct _GtkFileChooserDefault
   guint changing_folder : 1;
   guint shortcuts_current_folder_active : 1;
   guint shortcuts_current_folder_is_volume : 1;
+
+#if 0
   guint shortcuts_drag_outside : 1;
+#endif
 };
 
 /* Signal IDs */
 enum {
   LOCATION_POPUP,
   UP_FOLDER,
+  DOWN_FOLDER,
   HOME_FOLDER,
   LAST_SIGNAL
 };
@@ -306,6 +312,7 @@ static void           gtk_file_chooser_default_initial_focus          (GtkFileCh
 
 static void location_popup_handler (GtkFileChooserDefault *impl);
 static void up_folder_handler      (GtkFileChooserDefault *impl);
+static void down_folder_handler    (GtkFileChooserDefault *impl);
 static void home_folder_handler    (GtkFileChooserDefault *impl);
 static void update_appearance      (GtkFileChooserDefault *impl);
 
@@ -486,6 +493,14 @@ gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
                             NULL, NULL,
                             _gtk_marshal_VOID__VOID,
                             G_TYPE_NONE, 0);
+  signals[DOWN_FOLDER] =
+    _gtk_binding_signal_new ("down-folder",
+                            G_OBJECT_CLASS_TYPE (class),
+                            G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                            G_CALLBACK (down_folder_handler),
+                            NULL, NULL,
+                            _gtk_marshal_VOID__VOID,
+                            G_TYPE_NONE, 0);
   signals[HOME_FOLDER] =
     _gtk_binding_signal_new ("home-folder",
                             G_OBJECT_CLASS_TYPE (class),
@@ -511,6 +526,15 @@ gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
                                "up-folder",
                                0);
 
+  gtk_binding_entry_add_signal (binding_set,
+                               GDK_Down, GDK_MOD1_MASK,
+                               "down-folder",
+                               0);
+  gtk_binding_entry_add_signal (binding_set,
+                               GDK_KP_Down, GDK_MOD1_MASK,
+                               "down-folder",
+                               0);
+
   gtk_binding_entry_add_signal (binding_set,
                                GDK_Home, GDK_MOD1_MASK,
                                "home-folder",
@@ -862,14 +886,42 @@ shortcuts_reload_icons (GtkFileChooserDefault *impl)
   } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter));
 }
 
-/* Clears the selection in the shortcuts tree */
+/* If a shortcut corresponds to the current folder, selects it */
 static void
-shortcuts_unselect_all (GtkFileChooserDefault *impl)
+shortcuts_find_current_folder (GtkFileChooserDefault *impl)
 {
   GtkTreeSelection *selection;
+  int pos;
+  GtkTreePath *path;
 
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
-  gtk_tree_selection_unselect_all (selection);
+
+  pos = shortcut_find_position (impl, impl->current_folder);
+  if (pos == -1)
+    {
+      gtk_tree_selection_unselect_all (selection);
+      return;
+    }
+
+  path = gtk_tree_path_new_from_indices (pos, -1);
+  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_path_free (path);
+}
+
+/* Returns whether a path is a folder */
+static gboolean
+check_is_folder (GtkFileSystem *file_system, const GtkFilePath *path, GError **error)
+{
+  GtkFileFolder *folder;
+
+  folder = gtk_file_system_get_folder (file_system, path,
+                                      GTK_FILE_INFO_DISPLAY_NAME,
+                                      error);
+  if (!folder)
+    return FALSE;
+
+  g_object_unref (folder);
+  return TRUE;
 }
 
 /* Convenience function to get the display name and icon info for a path */
@@ -887,19 +939,17 @@ get_file_info (GtkFileSystem *file_system, const GtkFilePath *path, gboolean nam
 
   parent_folder = gtk_file_system_get_folder (file_system, parent_path ? parent_path : path,
                                              GTK_FILE_INFO_DISPLAY_NAME
-#if 0
-                                             | GTK_FILE_INFO_ICON
-#endif
                                              | (name_only ? 0 : GTK_FILE_INFO_IS_FOLDER),
                                              error);
-  gtk_file_path_free (parent_path);
-
   if (!parent_folder)
-    return NULL;
+    goto out;
 
-  info = gtk_file_folder_get_info (parent_folder, path, error);
+  info = gtk_file_folder_get_info (parent_folder, parent_path ? path : NULL, error);
   g_object_unref (parent_folder);
 
+ out:
+
+  gtk_file_path_free (parent_path);
   return info;
 }
 
@@ -930,18 +980,21 @@ shortcuts_insert_path (GtkFileChooserDefault *impl,
     }
   else
     {
-      /* Always check to make sure that the directory exists. */
-      GtkFileInfo *info = get_file_info (impl->file_system, path, FALSE, error);
-
-      if (info == NULL)
+      if (!check_is_folder (impl->file_system, path, error))
        return FALSE;
 
       if (label)
        label_copy = g_strdup (label);
       else
-       label_copy = g_strdup (gtk_file_info_get_display_name (info));
+       {
+         GtkFileInfo *info = get_file_info (impl->file_system, path, TRUE, error);
 
-      gtk_file_info_free (info);
+         if (!info)
+           return FALSE;
+
+         label_copy = g_strdup (gtk_file_info_get_display_name (info));
+         gtk_file_info_free (info);
+       }
 
       data = gtk_file_path_copy (path);
       pixbuf = gtk_file_system_render_icon (impl->file_system, path, GTK_WIDGET (impl),
@@ -1028,6 +1081,10 @@ shortcuts_append_paths (GtkFileChooserDefault *impl,
       path = paths->data;
       error = NULL;
 
+      if (impl->local_only &&
+         !gtk_file_system_path_is_local (impl->file_system, path))
+       continue;
+
       /* NULL GError, but we don't really want to show error boxes here */
       if (shortcuts_insert_path (impl, start_row + num_inserted, FALSE, NULL, path, NULL, TRUE, NULL))
        num_inserted++;
@@ -1141,6 +1198,10 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl)
   int start_row;
   GSList *list, *l;
   int n;
+  gboolean old_changing_folders;
+
+  old_changing_folders = impl->changing_folder;
+  impl->changing_folder = TRUE;
 
   start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
   shortcuts_remove_rows (impl, start_row, impl->num_volumes, volume_remove_cb);
@@ -1155,8 +1216,24 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl)
       GtkFileSystemVolume *volume;
 
       volume = l->data;
-      shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, FALSE, NULL);
-      n++;
+
+      if (impl->local_only)
+       {
+         GtkFilePath *base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+         gboolean is_local = gtk_file_system_path_is_local (impl->file_system, base_path);
+         gtk_file_path_free (base_path);
+
+         if (!is_local)
+           {
+             gtk_file_system_volume_free (impl->file_system, volume);
+             continue;
+           }
+       }
+
+      if (shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, FALSE, NULL))
+       n++;
+      else
+       gtk_file_system_volume_free (impl->file_system, volume);
     }
 
   impl->num_volumes = n;
@@ -1164,6 +1241,8 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl)
 
   if (impl->shortcuts_filter_model)
     gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
+
+  impl->changing_folder = old_changing_folders;
 }
 
 /* Used from shortcuts_remove_rows() */
@@ -1200,6 +1279,10 @@ static void
 shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
 {
   GSList *bookmarks;
+  gboolean old_changing_folders;
+
+  old_changing_folders = impl->changing_folder;
+  impl->changing_folder = TRUE;
 
   if (impl->num_bookmarks > 0)
     {
@@ -1220,6 +1303,8 @@ shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
     }
   if (impl->shortcuts_filter_model)
     gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
+
+  impl->changing_folder = old_changing_folders;
 }
 
 /* Appends a separator and a row to the shortcuts list for the current folder */
@@ -1545,42 +1630,30 @@ shortcuts_add_bookmark_from_path (GtkFileChooserDefault *impl,
                                  const GtkFilePath     *path,
                                  int                    pos)
 {
-  GtkFileInfo *info;
   GError *error;
-  gboolean result;
 
   if (shortcut_find_position (impl, path) != -1)
     return FALSE;
 
-  result = FALSE;
-
+  /* FIXME: this check really belongs in gtk_file_system_insert_bookmark.  */
   error = NULL;
-  info = get_file_info (impl->file_system, path, FALSE, &error);
-
-  if (!info)
-    error_getting_info_dialog (impl, path, error);
-  else if (!gtk_file_info_get_is_folder (info))
+  if (!check_is_folder (impl->file_system, path, &error))
     {
-      char *msg;
-      char *uri;
-
-      uri = gtk_file_system_path_to_uri (impl->file_system, path);
-      msg = g_strdup_printf (_("Could not add bookmark for %s because it is not a folder."),
-                            uri);
-      error_message (impl, msg);
-      g_free (uri);
-      g_free (msg);
+      error_dialog (impl,
+                   _("Could not add bookmark for %s because it is not a folder."),
+                   path,
+                   error);
+      return FALSE;
     }
-  else
+
+  error = NULL;
+  if (!gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
     {
-      error = NULL;
-      if (gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
-       result = TRUE;
-      else
-       error_could_not_add_bookmark_dialog (impl, path, error);
+      error_could_not_add_bookmark_dialog (impl, path, error);
+      return FALSE;
     }
 
-  return result;
+  return TRUE;
 }
 
 static void
@@ -1792,9 +1865,12 @@ shortcuts_drag_begin_cb (GtkWidget             *widget,
                         GdkDragContext        *context,
                         GtkFileChooserDefault *impl)
 {
+#if 0
   impl->shortcuts_drag_context = g_object_ref (context);
+#endif
 }
 
+#if 0
 /* Removes the idle handler for outside drags */
 static void
 shortcuts_cancel_drag_outside_idle (GtkFileChooserDefault *impl)
@@ -1805,6 +1881,7 @@ shortcuts_cancel_drag_outside_idle (GtkFileChooserDefault *impl)
   g_source_destroy (impl->shortcuts_drag_outside_idle);
   impl->shortcuts_drag_outside_idle = NULL;
 }
+#endif
 
 /* GtkWidget::drag-end handler for the shortcuts list. */
 static void
@@ -1812,6 +1889,7 @@ shortcuts_drag_end_cb (GtkWidget             *widget,
                       GdkDragContext        *context,
                       GtkFileChooserDefault *impl)
 {
+#if 0
   g_object_unref (impl->shortcuts_drag_context);
 
   shortcuts_cancel_drag_outside_idle (impl);
@@ -1822,6 +1900,7 @@ shortcuts_drag_end_cb (GtkWidget             *widget,
   gtk_button_clicked (GTK_BUTTON (impl->browse_shortcuts_remove_button));
 
   impl->shortcuts_drag_outside = FALSE;
+#endif
 }
 
 /* GtkWidget::drag-data-delete handler for the shortcuts list. */
@@ -1833,6 +1912,7 @@ shortcuts_drag_data_delete_cb (GtkWidget             *widget,
   g_signal_stop_emission_by_name (widget, "drag-data-delete");
 }
 
+#if 0
 /* Creates a suitable drag cursor to indicate that the selected bookmark will be
  * deleted or not.
  */
@@ -1991,7 +2071,8 @@ shortcuts_drag_outside_idle_cb (GtkFileChooserDefault *impl)
   shortcuts_cancel_drag_outside_idle (impl);
   return FALSE;
 }
-                        
+#endif
+
 /* GtkWidget::drag-leave handler for the shortcuts list.  We unhighlight the
  * drop position.
  */
@@ -2001,6 +2082,7 @@ shortcuts_drag_leave_cb (GtkWidget             *widget,
                         guint                  time_,
                         GtkFileChooserDefault *impl)
 {
+#if 0
   if (gtk_drag_get_source_widget (context) == widget && !impl->shortcuts_drag_outside_idle)
     {
       impl->shortcuts_drag_outside_idle = g_idle_source_new ();
@@ -2009,6 +2091,7 @@ shortcuts_drag_leave_cb (GtkWidget             *widget,
                                                   G_OBJECT (impl)));
       g_source_attach (impl->shortcuts_drag_outside_idle, NULL);
     }
+#endif
 
   gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
                                   NULL,
@@ -2091,6 +2174,7 @@ shortcuts_drag_motion_cb (GtkWidget             *widget,
   GtkTreeViewDropPosition pos;
   GdkDragAction action;
 
+#if 0
   if (gtk_drag_get_source_widget (context) == widget)
     {
       shortcuts_cancel_drag_outside_idle (impl);
@@ -2101,6 +2185,7 @@ shortcuts_drag_motion_cb (GtkWidget             *widget,
          impl->shortcuts_drag_outside = FALSE;
        }
     }
+#endif
 
   if (context->suggested_action == GDK_ACTION_COPY || (context->actions & GDK_ACTION_COPY) != 0)
     action = GDK_ACTION_COPY;
@@ -2138,7 +2223,9 @@ shortcuts_drag_drop_cb (GtkWidget             *widget,
                        guint                  time_,
                        GtkFileChooserDefault *impl)
 {
+#if 0
   shortcuts_cancel_drag_outside_idle (impl);
+#endif
 
   g_signal_stop_emission_by_name (widget, "drag-drop");
   return TRUE;
@@ -2810,6 +2897,8 @@ browse_widgets_create (GtkFileChooserDefault *impl)
   widget = file_pane_create (impl, size_group);
   gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
 
+  g_object_unref (size_group);
+
   /* Alignment to hold custom widget */
   impl->browse_extra_align = gtk_alignment_new (0.0, .5, 1.0, 1.0);
   gtk_box_pack_start (GTK_BOX (vbox), impl->browse_extra_align, FALSE, FALSE, 0);
@@ -2870,6 +2959,37 @@ set_extra_widget (GtkFileChooserDefault *impl,
   impl->extra_widget = extra_widget;
 }
 
+static void
+set_local_only (GtkFileChooserDefault *impl,
+               gboolean               local_only)
+{
+  if (local_only != impl->local_only)
+    {
+      impl->local_only = local_only;
+
+      if (impl->shortcuts_model && impl->file_system)
+       {
+         shortcuts_add_volumes (impl);
+         shortcuts_add_bookmarks (impl);
+       }
+
+      if (local_only &&
+         !gtk_file_system_path_is_local (impl->file_system, 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
+          * such a situation, so we ignore errors.
+          */
+         const gchar *home = g_get_home_dir ();
+         GtkFilePath *home_path = gtk_file_system_filename_to_path (impl->file_system, home);
+
+         _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL);
+
+         gtk_file_path_free (home_path);
+       }
+    }
+}
+
 static void
 volumes_changed_cb (GtkFileSystem         *file_system,
                    GtkFileChooserDefault *impl)
@@ -3028,8 +3148,7 @@ update_appearance (GtkFileChooserDefault *impl)
        _gtk_file_system_model_set_show_files (impl->browse_files_model, TRUE);
     }
 
-  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
-      || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
     gtk_widget_hide (impl->browse_new_folder_button);
   else
     gtk_widget_show (impl->browse_new_folder_button);
@@ -3121,7 +3240,7 @@ gtk_file_chooser_default_set_property (GObject      *object,
       set_current_filter (impl, g_value_get_object (value));
       break;
     case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
-      impl->local_only = g_value_get_boolean (value);
+      set_local_only (impl, g_value_get_boolean (value));
       break;
     case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
       set_preview_widget (impl, g_value_get_object (value));
@@ -3301,11 +3420,14 @@ check_icon_theme (GtkFileChooserDefault *impl)
   if (impl->settings_signal_id)
     return;
 
-  settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
-  impl->settings_signal_id = g_signal_connect (settings, "notify",
-                                              G_CALLBACK (settings_notify_cb), impl);
+  if (gtk_widget_has_screen (GTK_WIDGET (impl)))
+    {
+      settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
+      impl->settings_signal_id = g_signal_connect (settings, "notify",
+                                                  G_CALLBACK (settings_notify_cb), impl);
 
-  change_icon_theme (impl);
+      change_icon_theme (impl);
+    }
 }
 
 static void
@@ -3561,13 +3683,21 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser    *chooser,
                                             GError           **error)
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
-  GtkFileInfo *info;
 
   /* Test validity of path here.  */
-  info = get_file_info (impl->file_system, path, FALSE, error);
-  if (!info)
+  if (!check_is_folder (impl->file_system, path, error))
     return FALSE;
-  gtk_file_info_free (info);
+
+  if (impl->local_only &&
+      !gtk_file_system_path_is_local (impl->file_system, path))
+    {
+      g_set_error (error,
+                  GTK_FILE_SYSTEM_ERROR,
+                  GTK_FILE_SYSTEM_ERROR_FAILED,
+                  _("Can't change to folder because it isn't local"));
+
+      return FALSE;
+    }
 
   if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), path, error))
     return FALSE;
@@ -3596,7 +3726,7 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser    *chooser,
 
   /* Refresh controls */
 
-  shortcuts_unselect_all (impl);
+  shortcuts_find_current_folder (impl);
 
   g_signal_emit_by_name (impl, "current-folder-changed", 0);
 
@@ -3622,7 +3752,8 @@ gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser,
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
 
-  g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE);
+  g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+                   || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
 
   gtk_entry_set_text (GTK_ENTRY (impl->save_file_name_entry), name);
 }
@@ -3777,6 +3908,8 @@ get_paths_foreach (GtkTreeModel *model,
   gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter);
 
   file_path = _gtk_file_system_model_get_path (GTK_FILE_SYSTEM_MODEL (fs_model), &sel_iter);
+  if (!file_path)
+    return; /* We are on the editable row */
 
   if (!info->path_from_entry
       || gtk_file_path_compare (info->path_from_entry, file_path) != 0)
@@ -3947,6 +4080,10 @@ gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser    *chooser,
   gboolean result;
   int pos;
 
+  /* Test validity of path here.  */
+  if (!check_is_folder (impl->file_system, path, error))
+    return FALSE;
+
   pos = shortcuts_get_pos_for_shortcut_folder (impl, impl->num_shortcuts);
 
   result = shortcuts_insert_path (impl, pos, FALSE, NULL, path, NULL, FALSE, error);
@@ -4812,11 +4949,17 @@ update_from_entry (GtkFileChooserDefault *impl,
 
       if (!info)
        {
-#if 0
-         if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
-           return;
-#endif
-         error_getting_info_dialog (impl, subfolder_path, error);
+         if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+             || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
+           {
+             if (!change_folder_and_display_error (impl, folder_path))
+               goto out;
+
+             gtk_file_chooser_default_set_current_name (GTK_FILE_CHOOSER (impl), file_part);
+           }
+         else
+           error_getting_info_dialog (impl, subfolder_path, error);
+
          goto out;
        }
 
@@ -4859,6 +5002,7 @@ location_popup_handler (GtkFileChooserDefault *impl)
   GtkWidget *label;
   GtkWidget *entry;
   gboolean refocus;
+  char *title;
 
   /* Create dialog */
 
@@ -4866,7 +5010,19 @@ location_popup_handler (GtkFileChooserDefault *impl)
   if (!GTK_WIDGET_TOPLEVEL (toplevel))
     toplevel = NULL;
 
-  dialog = gtk_dialog_new_with_buttons (_("Open Location"),
+  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
+      || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+    {
+      title = _("Open Location");
+    }
+  else
+    {
+      g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+               || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
+      title = ""; /* FIXME: #137272, fix for 2.4.1 */
+    }
+
+  dialog = gtk_dialog_new_with_buttons (title,
                                        GTK_WINDOW (toplevel),
                                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -4898,7 +5054,17 @@ location_popup_handler (GtkFileChooserDefault *impl)
     {
       if (update_from_entry (impl, GTK_WINDOW (dialog), GTK_FILE_CHOOSER_ENTRY (entry)))
        {
-         gtk_widget_grab_focus (impl->browse_files_tree_view);
+         if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
+             || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+           {
+             gtk_widget_grab_focus (impl->browse_files_tree_view);
+           }
+         else
+           {
+             g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+                       || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
+             gtk_widget_grab_focus (impl->save_file_name_entry);
+           }
          refocus = FALSE;
        }
     }
@@ -4919,24 +5085,14 @@ location_popup_handler (GtkFileChooserDefault *impl)
 static void
 up_folder_handler (GtkFileChooserDefault *impl)
 {
-  GtkFilePath *parent_path;
-  GError *error;
+  _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
+}
 
-  error = NULL;
-  if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, &parent_path, &error))
-    {
-      if (parent_path) /* If we were on a root, parent_path will be NULL */
-       {
-         change_folder_and_display_error (impl, parent_path);
-         gtk_file_path_free (parent_path);
-       }
-    }
-  else
-    {
-      error_dialog (impl,
-                   _("Could not go to the parent folder of %s:\n%s"),
-                   impl->current_folder, error);
-    }
+/* Handler for the "down-folder" keybinding signal */
+static void
+down_folder_handler (GtkFileChooserDefault *impl)
+{
+  _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar));
 }
 
 /* Handler for the "home-folder" keybinding signal */