filechooserentry: Move _gtk_file_system_parse()
It's very specific to the file chooser entry, so it's better kept there. It's also not used anywhere else in the code. Also, remove _gtk_file_system_get_folder() as it's no longer used. Conflicts: gtk/gtkfilesystem.h
This commit is contained in:
parent
85563ccd35
commit
c2978cc394
3 changed files with 141 additions and 229 deletions
|
|
@ -19,17 +19,16 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkfilechooserentry.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue