From 2dd7cf4926bdc2edc8d27e81b86178efd091c433 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Fri, 23 Jan 2009 00:53:23 +0000 Subject: [PATCH] Return an error code when refreshing the entry from the user's input 2009-01-22 Federico Mena Quintero Return an error code when refreshing the entry from the user's input. We use this in the completion code to know when completion can't happen due to (for example) having a non-local URI in a file chooser that is local_only=TRUE. Also, we start maintaining an invariant that chooser_entry->current_folder_file != NULL implies that: * what the user entered is valid * we are loading that folder (chooser_entry->load_folder_cancellable != NULL) * or we are done loading that folder, or we have a handle to it at least (chooser_entry->current_folder != NULL) The invariant also says that all of the above are NULL (and chooser_entry->current_folder_file == NULL) implies that the user typed something invalid. This makes _gtk_file_chooser_entry_get_current_folder() not able to return an invalid folder. * gtk/gtkfilechooserentry.c (RefreshStatus): New enum. (refresh_current_folder_and_file_part): Return a RefreshStatus. We filter out incomplete hostnames here (typing "sftp://incompl[tab]" will error out), as well as completely unparsable input. Signed-off-by: Federico Mena Quintero svn path=/trunk/; revision=22177 --- ChangeLog | 29 +++++++++++++++++++++++++++++ gtk/gtkfilechooserentry.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6dc099e56..c23efb033d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2009-01-22 Federico Mena Quintero + + Return an error code when refreshing the entry from the user's + input. We use this in the completion code to know when completion + can't happen due to (for example) having a non-local URI in a file + chooser that is local_only=TRUE. + + Also, we start maintaining an invariant that + chooser_entry->current_folder_file != NULL implies that: + + * what the user entered is valid + + * we are loading that folder (chooser_entry->load_folder_cancellable != NULL) + + * or we are done loading that folder, or we have a handle + to it at least (chooser_entry->current_folder != NULL) + + The invariant also says that all of the above are NULL (and + chooser_entry->current_folder_file == NULL) implies that the user + typed something invalid. This makes + _gtk_file_chooser_entry_get_current_folder() not able to return + an invalid folder. + + * gtk/gtkfilechooserentry.c (RefreshStatus): New enum. + (refresh_current_folder_and_file_part): Return a RefreshStatus. + We filter out incomplete hostnames here (typing + "sftp://incompl[tab]" will error out), as well as completely + unparsable input. + 2009-01-22 Matthew Barnes Bug 568334 – Constructor properties for GtkAction diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 149d74c45b..66f0f24346 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -50,6 +50,15 @@ typedef enum { LOAD_COMPLETE_EXPLICIT_COMPLETION } LoadCompleteAction; +typedef enum +{ + REFRESH_OK, + REFRESH_INVALID_INPUT, + REFRESH_INCOMPLETE_HOSTNAME, + REFRESH_NONEXISTENT, + REFRESH_NOT_LOCAL +} RefreshStatus; + struct _GtkFileChooserEntry { GtkEntry parent_instance; @@ -144,7 +153,7 @@ typedef enum { REFRESH_WHOLE_TEXT } RefreshMode; -static void refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, +static RefreshStatus refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, RefreshMode refresh_mode); static void finished_loading_cb (GtkFolder *folder, gpointer data); @@ -1102,6 +1111,7 @@ explicitly_complete (GtkFileChooserEntry *chooser_entry) static void start_explicit_completion (GtkFileChooserEntry *chooser_entry) { + /* FMQ: get result from the function below */ refresh_current_folder_and_file_part (chooser_entry, REFRESH_UP_TO_CURSOR_POSITION); if (!chooser_entry->current_folder_file) @@ -1203,6 +1213,7 @@ commit_completion_and_refresh (GtkFileChooserEntry *chooser_entry) GTK_ENTRY (chooser_entry)->text_length); } + /* FMQ: get result from the function below */ refresh_current_folder_and_file_part (chooser_entry, REFRESH_WHOLE_TEXT); } @@ -1438,7 +1449,7 @@ reload_current_folder (GtkFileChooserEntry *chooser_entry, start_loading_current_folder (chooser_entry); } -static void +static RefreshStatus refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, RefreshMode refresh_mode) { @@ -1450,6 +1461,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, gsize total_len, file_part_len; gint file_part_pos; GError *error; + RefreshStatus result; editable = GTK_EDITABLE (chooser_entry); @@ -1465,7 +1477,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, default: g_assert_not_reached (); - return; + return REFRESH_INVALID_INPUT; } text = gtk_editable_get_chars (editable, 0, end_pos); @@ -1478,9 +1490,19 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, &folder_file, &file_part, &error)) { if (g_error_matches (error, GTK_FILE_CHOOSER_ERROR, GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME)) - folder_file = NULL; + { + folder_file = NULL; + result = REFRESH_INCOMPLETE_HOSTNAME; + } else - folder_file = (chooser_entry->base_folder) ? g_object_ref (chooser_entry->base_folder) : NULL; + { + folder_file = (chooser_entry->base_folder) ? g_object_ref (chooser_entry->base_folder) : NULL; + + if (g_error_matches (error, GTK_FILE_CHOOSER_ERROR, GTK_FILE_CHOOSER_ERROR_NONEXISTENT)) + result = REFRESH_NONEXISTENT; + else + result = REFRESH_INVALID_INPUT; + } if (error) g_error_free (error); @@ -1496,6 +1518,8 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, file_part_pos = g_utf8_strlen (text, total_len - file_part_len); else file_part_pos = 0; + + result = REFRESH_OK; } g_free (text); @@ -1505,10 +1529,13 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, chooser_entry->file_part = file_part; chooser_entry->file_part_pos = file_part_pos; + /* FMQ: this needs to return an error if the folder is not local */ reload_current_folder (chooser_entry, folder_file, file_part_pos == -1); if (folder_file) g_object_unref (folder_file); + + return result; } static void @@ -1524,6 +1551,7 @@ autocomplete (GtkFileChooserEntry *chooser_entry) static void start_autocompletion (GtkFileChooserEntry *chooser_entry) { + /* FMQ: get result from the function below */ refresh_current_folder_and_file_part (chooser_entry, REFRESH_UP_TO_CURSOR_POSITION); if (!chooser_entry->current_folder)