bgo#639531 - [filechooser] Handle the case where the user types a nonexistent_subfolder/file.txt

The logic was to try to switch to that nonexistent folder and thus get
an error message presented.  However, no such message actually appears,
as the file chooser tries to switch to the closest parent folder that
actually exists, without bringing up an error message --- this is done
to cope with the case of the file chooser being started with a folder
that doesn't exist anymore.

Now, we just bring up an error message directly when we detect that
the user types a subfolder name that doesn't exist.

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
This commit is contained in:
Federico Mena Quintero 2011-01-21 12:37:35 -06:00
parent 84bf984f85
commit a4a2d76182

View File

@ -993,6 +993,21 @@ error_creating_folder_over_existing_file_dialog (GtkFileChooserDefault *impl,
file, error); file, error);
} }
static void
error_with_file_under_nonfolder (GtkFileChooserDefault *impl,
GFile *parent_file)
{
GError *error;
error = NULL;
g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
_("You need to choose a valid filename."));
error_dialog (impl,
_("Cannot create a file under %s as it is not a folder"),
parent_file, error);
}
/* Shows an error about not being able to select a folder because a file with /* Shows an error about not being able to select a folder because a file with
* the same name is already there. * the same name is already there.
*/ */
@ -8200,7 +8215,11 @@ name_entry_get_parent_info_cb (GCancellable *cancellable,
if (parent_is_folder) if (parent_is_folder)
{ {
if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
{
g_signal_emit_by_name (data->impl, "response-requested"); /* even if the file doesn't exist, apps can make good use of that (e.g. Emacs) */
}
else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
{ {
if (data->file_exists_and_is_not_folder) if (data->file_exists_and_is_not_folder)
{ {
@ -8224,28 +8243,40 @@ name_entry_get_parent_info_cb (GCancellable *cancellable,
else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|| data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) || data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
{ {
GError *error = NULL; GError *mkdir_error = NULL;
/* In both cases (SELECT_FOLDER and CREATE_FOLDER), if you type /* In both cases (SELECT_FOLDER and CREATE_FOLDER), if you type
* "/blah/nonexistent" you *will* want a folder created. * "/blah/nonexistent" you *will* want a folder created.
*/ */
set_busy_cursor (data->impl, TRUE); set_busy_cursor (data->impl, TRUE);
g_file_make_directory (data->file, NULL, &error); g_file_make_directory (data->file, NULL, &mkdir_error);
set_busy_cursor (data->impl, FALSE); set_busy_cursor (data->impl, FALSE);
if (!error) if (!mkdir_error)
g_signal_emit_by_name (data->impl, "response-requested"); g_signal_emit_by_name (data->impl, "response-requested");
else else
error_creating_folder_dialog (data->impl, data->file, error); error_creating_folder_dialog (data->impl, data->file, mkdir_error);
} }
else else
g_assert_not_reached (); g_assert_not_reached ();
} }
else else
{ {
/* This will display an error, which is what we want */ if (info)
change_folder_and_display_error (data->impl, data->parent_file, FALSE); {
/* The parent exists, but it's not a folder! Someone probably typed existing_file.txt/subfile.txt */
error_with_file_under_nonfolder (data->impl, data->parent_file);
}
else
{
GError *error_copy;
/* The parent folder is not readable for some reason */
error_copy = g_error_copy (error);
error_changing_folder_dialog (data->impl, data->parent_file, error_copy);
}
} }
out: out:
@ -8267,7 +8298,7 @@ file_exists_get_info_cb (GCancellable *cancellable,
gboolean cancelled = g_cancellable_is_cancelled (cancellable); gboolean cancelled = g_cancellable_is_cancelled (cancellable);
gboolean file_exists; gboolean file_exists;
gboolean is_folder; gboolean is_folder;
gboolean needs_file_type_check = FALSE; gboolean needs_parent_check = FALSE;
struct FileExistsData *data = user_data; struct FileExistsData *data = user_data;
if (cancellable != data->impl->file_exists_get_info_cancellable) if (cancellable != data->impl->file_exists_get_info_cancellable)
@ -8289,8 +8320,10 @@ file_exists_get_info_cb (GCancellable *cancellable,
change_folder_and_display_error (data->impl, data->file, TRUE); change_folder_and_display_error (data->impl, data->file, TRUE);
else else
{ {
/* user typed a filename; we are done */ if (file_exists)
g_signal_emit_by_name (data->impl, "response-requested"); g_signal_emit_by_name (data->impl, "response-requested"); /* user typed an existing filename; we are done */
else
needs_parent_check = TRUE; /* file doesn't exist; see if its parent exists */
} }
} }
else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
@ -8305,14 +8338,14 @@ file_exists_get_info_cb (GCancellable *cancellable,
} }
else else
{ {
needs_file_type_check = TRUE; needs_parent_check = TRUE;
} }
} }
else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
{ {
if (!file_exists) if (!file_exists)
{ {
needs_file_type_check = TRUE; needs_parent_check = TRUE;
} }
else else
{ {
@ -8330,15 +8363,15 @@ file_exists_get_info_cb (GCancellable *cancellable,
if (is_folder) if (is_folder)
change_folder_and_display_error (data->impl, data->file, TRUE); change_folder_and_display_error (data->impl, data->file, TRUE);
else else
needs_file_type_check = TRUE; needs_parent_check = TRUE;
} }
else else
{ {
g_assert_not_reached(); g_assert_not_reached();
} }
if (needs_file_type_check) { if (needs_parent_check) {
/* check that everything up to the last component exists */ /* check that everything up to the last path component exists (i.e. the parent) */
data->file_exists_and_is_not_folder = file_exists && !is_folder; data->file_exists_and_is_not_folder = file_exists && !is_folder;
data_ownership_taken = TRUE; data_ownership_taken = TRUE;