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



commit a4a2d7618250407fa78cb5cd3184b7d20a11a7e8
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Jan 21 12:37:35 2011 -0600

    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>

 gtk/gtkfilechooserdefault.c |   63 ++++++++++++++++++++++++++++++++----------
 1 files changed, 48 insertions(+), 15 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 2a5adf9..8ffd758 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -993,6 +993,21 @@ error_creating_folder_over_existing_file_dialog (GtkFileChooserDefault *impl,
 		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
  * the same name is already there.
  */
@@ -8200,7 +8215,11 @@ name_entry_get_parent_info_cb (GCancellable *cancellable,
 
   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)
 	    {
@@ -8224,28 +8243,40 @@ name_entry_get_parent_info_cb (GCancellable *cancellable,
       else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_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
 	   * "/blah/nonexistent" you *will* want a folder created.
 	   */
 
 	  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);
 
-	  if (!error)
+	  if (!mkdir_error)
 	    g_signal_emit_by_name (data->impl, "response-requested");
 	  else
-	    error_creating_folder_dialog (data->impl, data->file, error);
+	    error_creating_folder_dialog (data->impl, data->file, mkdir_error);
         }
       else
 	g_assert_not_reached ();
     }
   else
     {
-      /* This will display an error, which is what we want */
-      change_folder_and_display_error (data->impl, data->parent_file, FALSE);
+      if (info)
+	{
+	  /* 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:
@@ -8267,7 +8298,7 @@ file_exists_get_info_cb (GCancellable *cancellable,
   gboolean cancelled = g_cancellable_is_cancelled (cancellable);
   gboolean file_exists;
   gboolean is_folder;
-  gboolean needs_file_type_check = FALSE;
+  gboolean needs_parent_check = FALSE;
   struct FileExistsData *data = user_data;
 
   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);
       else
 	{
-	  /* user typed a filename; we are done */
-	  g_signal_emit_by_name (data->impl, "response-requested");
+	  if (file_exists)
+	    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)
@@ -8305,14 +8338,14 @@ file_exists_get_info_cb (GCancellable *cancellable,
         }
       else
         {
-          needs_file_type_check = TRUE;
+          needs_parent_check = TRUE;
         }
     }
   else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
     {
       if (!file_exists)
         {
-	  needs_file_type_check = TRUE;
+	  needs_parent_check = TRUE;
         }
       else
 	{
@@ -8330,15 +8363,15 @@ file_exists_get_info_cb (GCancellable *cancellable,
       if (is_folder)
 	change_folder_and_display_error (data->impl, data->file, TRUE);
       else
-	needs_file_type_check = TRUE;
+	needs_parent_check = TRUE;
     }
   else
     {
       g_assert_not_reached();
     }
 
-  if (needs_file_type_check) {
-    /* check that everything up to the last component exists */
+  if (needs_parent_check) {
+    /* 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_ownership_taken = TRUE;



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