diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index e6d005d9ec..d84078273d 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -19,17 +19,16 @@ */ #include "config.h" + +#include "gtkfilechooserentry.h" + #include #include "gtkalignment.h" #include "gtkcelllayout.h" #include "gtkcellrenderertext.h" #include "gtkentry.h" -<<<<<<< HEAD -#include "gtkfilechooserentry.h" -======= #include "gtkfilesystemmodel.h" ->>>>>>> a1e0c1e... filechooserentry: Use a GtkFileSystemModel #include "gtklabel.h" #include "gtkmain.h" #include "gtkwindow.h" @@ -428,6 +427,144 @@ beep (GtkFileChooserEntry *chooser_entry) gtk_widget_error_bell (GTK_WIDGET (chooser_entry)); } +static gboolean +is_valid_scheme_character (char c) +{ + return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; +} + +static gboolean +has_uri_scheme (const char *str) +{ + const char *p; + + p = str; + + if (!is_valid_scheme_character (*p)) + return FALSE; + + do + p++; + while (is_valid_scheme_character (*p)); + + return (strncmp (p, "://", 3) == 0); +} + +static gboolean +_gtk_file_system_parse (GtkFileSystem *file_system, + GFile *base_file, + const gchar *str, + GFile **folder, + gchar **file_part, + GError **error) +{ + GFile *file; + gboolean result = FALSE; + gboolean is_dir = FALSE; + gchar *last_slash = NULL; + gboolean is_uri; + + if (str && *str) + is_dir = (str [strlen (str) - 1] == G_DIR_SEPARATOR); + + last_slash = strrchr (str, G_DIR_SEPARATOR); + + is_uri = has_uri_scheme (str); + + if (is_uri) + { + const char *colon; + const char *slash_after_hostname; + + colon = strchr (str, ':'); + g_assert (colon != NULL); + g_assert (strncmp (colon, "://", 3) == 0); + + slash_after_hostname = strchr (colon + 3, '/'); + + if (slash_after_hostname == NULL) + { + /* We don't have a full hostname yet. So, don't switch the folder + * until we have seen a full hostname. Otherwise, completion will + * happen for every character the user types for the hostname. + */ + + *folder = NULL; + *file_part = NULL; + g_set_error (error, + GTK_FILE_CHOOSER_ERROR, + GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME, + "Incomplete hostname"); + return FALSE; + } + } + + if (str[0] == '~' || g_path_is_absolute (str) || is_uri) + file = g_file_parse_name (str); + else + { + if (base_file) + file = g_file_resolve_relative_path (base_file, str); + else + { + *folder = NULL; + *file_part = NULL; + g_set_error (error, + GTK_FILE_CHOOSER_ERROR, + GTK_FILE_CHOOSER_ERROR_BAD_FILENAME, + _("Invalid path")); + return FALSE; + } + } + + if (base_file && g_file_equal (base_file, file)) + { + /* this is when user types '.', could be the + * beginning of a hidden file, ./ or ../ + */ + *folder = g_object_ref (file); + *file_part = g_strdup (str); + result = TRUE; + } + else if (is_dir) + { + /* it's a dir, or at least it ends with the dir separator */ + *folder = g_object_ref (file); + *file_part = g_strdup (""); + result = TRUE; + } + else + { + GFile *parent_file; + + parent_file = g_file_get_parent (file); + + if (!parent_file) + { + g_set_error (error, + GTK_FILE_CHOOSER_ERROR, + GTK_FILE_CHOOSER_ERROR_NONEXISTENT, + "Could not get parent file"); + *folder = NULL; + *file_part = NULL; + } + else + { + *folder = parent_file; + result = TRUE; + + if (last_slash) + *file_part = g_strdup (last_slash + 1); + else + *file_part = g_strdup (str); + } + } + + g_object_unref (file); + + return result; +} + /* Determines if the completion model has entries with a common prefix relative * to the current contents of the entry. Also, if there's one and only one such * path, stores it in unique_path_ret. diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c index d0ec4b4fee..5f9e054bfe 100644 --- a/gtk/gtkfilesystem.c +++ b/gtk/gtkfilesystem.c @@ -680,146 +680,6 @@ _gtk_file_system_list_bookmarks (GtkFileSystem *file_system) return g_slist_reverse (files); } -static gboolean -is_valid_scheme_character (char c) -{ - return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; -} - -static gboolean -has_uri_scheme (const char *str) -{ - const char *p; - - p = str; - - if (!is_valid_scheme_character (*p)) - return FALSE; - - do - p++; - while (is_valid_scheme_character (*p)); - - return (strncmp (p, "://", 3) == 0); -} - -gboolean -_gtk_file_system_parse (GtkFileSystem *file_system, - GFile *base_file, - const gchar *str, - GFile **folder, - gchar **file_part, - GError **error) -{ - GFile *file; - gboolean result = FALSE; - gboolean is_dir = FALSE; - gchar *last_slash = NULL; - gboolean is_uri; - - DEBUG ("parse"); - - if (str && *str) - is_dir = (str [strlen (str) - 1] == G_DIR_SEPARATOR); - - last_slash = strrchr (str, G_DIR_SEPARATOR); - - is_uri = has_uri_scheme (str); - - if (is_uri) - { - const char *colon; - const char *slash_after_hostname; - - colon = strchr (str, ':'); - g_assert (colon != NULL); - g_assert (strncmp (colon, "://", 3) == 0); - - slash_after_hostname = strchr (colon + 3, '/'); - - if (slash_after_hostname == NULL) - { - /* We don't have a full hostname yet. So, don't switch the folder - * until we have seen a full hostname. Otherwise, completion will - * happen for every character the user types for the hostname. - */ - - *folder = NULL; - *file_part = NULL; - g_set_error (error, - GTK_FILE_CHOOSER_ERROR, - GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME, - "Incomplete hostname"); - return FALSE; - } - } - - if (str[0] == '~' || g_path_is_absolute (str) || is_uri) - file = g_file_parse_name (str); - else - { - if (base_file) - file = g_file_resolve_relative_path (base_file, str); - else - { - *folder = NULL; - *file_part = NULL; - g_set_error (error, - GTK_FILE_CHOOSER_ERROR, - GTK_FILE_CHOOSER_ERROR_BAD_FILENAME, - _("Invalid path")); - return FALSE; - } - } - - if (base_file && g_file_equal (base_file, file)) - { - /* this is when user types '.', could be the - * beginning of a hidden file, ./ or ../ - */ - *folder = g_object_ref (file); - *file_part = g_strdup (str); - result = TRUE; - } - else if (is_dir) - { - /* it's a dir, or at least it ends with the dir separator */ - *folder = g_object_ref (file); - *file_part = g_strdup (""); - result = TRUE; - } - else - { - GFile *parent_file; - - parent_file = g_file_get_parent (file); - - if (!parent_file) - { - g_set_error (error, - GTK_FILE_CHOOSER_ERROR, - GTK_FILE_CHOOSER_ERROR_NONEXISTENT, - "Could not get parent file"); - *folder = NULL; - *file_part = NULL; - } - else - { - *folder = parent_file; - result = TRUE; - - if (last_slash) - *file_part = g_strdup (last_slash + 1); - else - *file_part = g_strdup (str); - } - } - - g_object_unref (file); - - return result; -} - static void free_async_data (AsyncFuncData *async_data) { @@ -831,79 +691,6 @@ free_async_data (AsyncFuncData *async_data) g_free (async_data); } -static void -enumerate_children_callback (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GFileEnumerator *enumerator; - AsyncFuncData *async_data; - GtkFolder *folder = NULL; - GFile *file; - GError *error = NULL; - - file = G_FILE (source_object); - async_data = (AsyncFuncData *) user_data; - enumerator = g_file_enumerate_children_finish (file, result, &error); - - if (enumerator) - { - folder = g_object_new (GTK_TYPE_FOLDER, - "file", source_object, - "enumerator", enumerator, - "attributes", async_data->attributes, - NULL); - g_object_unref (enumerator); - } - - gdk_threads_enter (); - ((GtkFileSystemGetFolderCallback) async_data->callback) (async_data->cancellable, - folder, error, async_data->data); - gdk_threads_leave (); - - free_async_data (async_data); - - if (folder) - g_object_unref (folder); - - if (error) - g_error_free (error); -} - -GCancellable * -_gtk_file_system_get_folder (GtkFileSystem *file_system, - GFile *file, - const gchar *attributes, - GtkFileSystemGetFolderCallback callback, - gpointer data) -{ - GCancellable *cancellable; - AsyncFuncData *async_data; - - g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - cancellable = g_cancellable_new (); - - async_data = g_new0 (AsyncFuncData, 1); - async_data->file_system = g_object_ref (file_system); - async_data->file = g_object_ref (file); - async_data->cancellable = g_object_ref (cancellable); - async_data->attributes = g_strdup (attributes); - - async_data->callback = callback; - async_data->data = data; - - g_file_enumerate_children_async (file, - attributes, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - cancellable, - enumerate_children_callback, - async_data); - return cancellable; -} - static void query_info_callback (GObject *source_object, GAsyncResult *result, diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h index 6f3be36d4e..7fc539ec18 100644 --- a/gtk/gtkfilesystem.h +++ b/gtk/gtkfilesystem.h @@ -100,18 +100,6 @@ GtkFileSystem * _gtk_file_system_new (void); GSList * _gtk_file_system_list_volumes (GtkFileSystem *file_system); GSList * _gtk_file_system_list_bookmarks (GtkFileSystem *file_system); -gboolean _gtk_file_system_parse (GtkFileSystem *file_system, - GFile *base_file, - const gchar *str, - GFile **folder, - gchar **file_part, - GError **error); - -GCancellable * _gtk_file_system_get_folder (GtkFileSystem *file_system, - GFile *file, - const gchar *attributes, - GtkFileSystemGetFolderCallback callback, - gpointer data); GCancellable * _gtk_file_system_get_info (GtkFileSystem *file_system, GFile *file, const gchar *attributes,