[gimp] app: port GimpDataFactory file loading to GFileEnumerator
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: port GimpDataFactory file loading to GFileEnumerator
- Date: Sat, 2 Aug 2014 13:11:16 +0000 (UTC)
commit 6821eb298c1464f1b682fd94f5890b5b5529f81f
Author: Michael Natterer <mitch gimp org>
Date: Fri Aug 1 20:30:45 2014 +0200
app: port GimpDataFactory file loading to GFileEnumerator
Also slightly change the semantics of gimp_data_set_folder_tags()
to be less complicated.
app/core/gimpdata.c | 63 ++++++------
app/core/gimpdata.h | 2 +-
app/core/gimpdatafactory.c | 240 ++++++++++++++++++++++++--------------------
3 files changed, 161 insertions(+), 144 deletions(-)
---
diff --git a/app/core/gimpdata.c b/app/core/gimpdata.c
index 69171cf..409b1ab 100644
--- a/app/core/gimpdata.c
+++ b/app/core/gimpdata.c
@@ -929,26 +929,28 @@ static const gchar *tag_blacklist[] = { "brushes",
* gimp_data_set_folder_tags:
* @data: a #Gimpdata object.
* @top_directory: the top directory of the currently processed data
- * hierarchy, or %NULL if that top directory is
- * currently processed itself
+ * hierarchy.
*
* Sets tags based on all folder names below top_directory. So if the
- * data's filename is /home/foo/.gimp/brushes/Flowers/Roses/rose.gbr,
- * it will add "Flowers" and "Roses" tags.
+ * data's filename is e.g.
+ * /home/foo/.config/GIMP/X.Y/brushes/Flowers/Roses/rose.gbr, it will
+ * add "Flowers" and "Roses" tags.
*
* if the top directory (as passed, or as derived from the data's
* filename) does not end with one of the default data directory names
* (brushes, patterns etc), its name will be added as tag too.
**/
void
-gimp_data_set_folder_tags (GimpData *data,
- const gchar *top_directory)
+gimp_data_set_folder_tags (GimpData *data,
+ GFile *top_directory)
{
GimpDataPrivate *private;
- gchar *path;
+ gchar *tmp;
gchar *dirname;
+ gchar *top_path;
g_return_if_fail (GIMP_IS_DATA (data));
+ g_return_if_fail (G_IS_FILE (top_directory));
private = GIMP_DATA_GET_PRIVATE (data);
@@ -957,39 +959,34 @@ gimp_data_set_folder_tags (GimpData *data,
g_return_if_fail (private->file != NULL);
- path = g_file_get_path (private->file);
- dirname = g_path_get_dirname (path);
- g_free (path);
+ tmp = g_file_get_path (private->file);
+ dirname = g_path_get_dirname (tmp);
+ g_free (tmp);
- /* if this data is in a subfolder, walk up the hierarchy and
- * set each folder on the way as tag, except the top_directory
- */
- if (top_directory)
- {
- size_t top_directory_len = strlen (top_directory);
+ top_path = g_file_get_path (top_directory);
- g_return_if_fail (g_str_has_prefix (dirname, top_directory) &&
- (dirname[top_directory_len] == '\0' ||
- G_IS_DIR_SEPARATOR (dirname[top_directory_len])));
+ g_return_if_fail (g_str_has_prefix (dirname, top_path));
- do
- {
- gchar *basename = g_path_get_basename (dirname);
- GimpTag *tag = gimp_tag_new (basename);
- gchar *tmp;
+ /* walk up the hierarchy and set each folder on the way as tag,
+ * except the top_directory
+ */
+ while (strcmp (dirname, top_path))
+ {
+ gchar *basename = g_path_get_basename (dirname);
+ GimpTag *tag = gimp_tag_new (basename);
- gimp_tag_set_internal (tag, TRUE);
- gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
- g_object_unref (tag);
- g_free (basename);
+ gimp_tag_set_internal (tag, TRUE);
+ gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
+ g_object_unref (tag);
+ g_free (basename);
- tmp = g_path_get_dirname (dirname);
- g_free (dirname);
- dirname = tmp;
- }
- while (strcmp (dirname, top_directory));
+ tmp = g_path_get_dirname (dirname);
+ g_free (dirname);
+ dirname = tmp;
}
+ g_free (top_path);
+
if (dirname)
{
gchar *basename = g_path_get_basename (dirname);
diff --git a/app/core/gimpdata.h b/app/core/gimpdata.h
index ec7baf8..77454ce 100644
--- a/app/core/gimpdata.h
+++ b/app/core/gimpdata.h
@@ -93,7 +93,7 @@ void gimp_data_create_filename (GimpData *data,
GFile *dest_dir);
void gimp_data_set_folder_tags (GimpData *data,
- const gchar *top_directory);
+ GFile *top_directory);
const gchar * gimp_data_get_mime_type (GimpData *data);
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index c0b000a..a62da4d 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -70,23 +70,32 @@ struct _GimpDataFactoryPriv
};
-static void gimp_data_factory_finalize (GObject *object);
+static void gimp_data_factory_finalize (GObject *object);
-static void gimp_data_factory_data_load (GimpDataFactory *factory,
- GimpContext *context,
- GHashTable *cache);
+static gint64 gimp_data_factory_get_memsize (GimpObject *object,
+ gint64 *gui_size);
-static gint64 gimp_data_factory_get_memsize (GimpObject *object,
- gint64 *gui_size);
+static void gimp_data_factory_data_load (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache);
-static GFile * gimp_data_factory_get_save_dir (GimpDataFactory *factory,
- GError **error);
+static GFile * gimp_data_factory_get_save_dir (GimpDataFactory *factory,
+ GError **error);
-static void gimp_data_factory_load_data (const GimpDatafileData *file_data,
- gpointer data);
+static void gimp_data_factory_load_directory (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ GList *writable_path,
+ GFile *directory,
+ GFile *top_directory);
+static void gimp_data_factory_load_data (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ GList *writable_path,
+ GFile *file,
+ guint64 mtime,
+ GFile *top_directory);
-static void gimp_data_factory_load_data_recursive (const GimpDatafileData *file_data,
- gpointer data);
G_DEFINE_TYPE (GimpDataFactory, gimp_data_factory, GIMP_TYPE_OBJECT)
@@ -303,67 +312,38 @@ gimp_data_factory_data_foreach (GimpDataFactory *factory,
}
}
-typedef struct
-{
- GimpDataFactory *factory;
- GimpContext *context;
- GHashTable *cache;
- const gchar *top_directory;
- GList *writable_path;
-} GimpDataLoadContext;
-
static void
gimp_data_factory_data_load (GimpDataFactory *factory,
GimpContext *context,
GHashTable *cache)
{
- gchar *path;
- gchar *writable_path;
+ gchar *p;
+ gchar *wp;
+ GList *path;
+ GList *writable_path;
+ GList *list;
g_object_get (factory->priv->gimp->config,
- factory->priv->path_property_name, &path,
- factory->priv->writable_property_name, &writable_path,
+ factory->priv->path_property_name, &p,
+ factory->priv->writable_property_name, &wp,
NULL);
- if (path && strlen (path))
- {
- GimpDataLoadContext load_context = { 0, };
- gchar *tmp;
-
- load_context.factory = factory;
- load_context.context = context;
- load_context.cache = cache;
-
- tmp = gimp_config_path_expand (path, TRUE, NULL);
- g_free (path);
- path = tmp;
-
- if (writable_path)
- {
- tmp = gimp_config_path_expand (writable_path, TRUE, NULL);
- g_free (writable_path);
- writable_path = tmp;
-
- load_context.writable_path = gimp_path_parse (writable_path,
- 256, TRUE, NULL);
- }
-
- gimp_datafiles_read_directories (path, G_FILE_TEST_IS_REGULAR,
- gimp_data_factory_load_data,
- &load_context);
+ path = gimp_config_path_expand_to_files (p, NULL);
+ writable_path = gimp_config_path_expand_to_files (wp, NULL);
- gimp_datafiles_read_directories (path, G_FILE_TEST_IS_DIR,
- gimp_data_factory_load_data_recursive,
- &load_context);
+ g_free (p);
+ g_free (wp);
- if (writable_path)
- {
- gimp_path_free (load_context.writable_path);
- }
+ for (list = path; list; list = g_list_next (list))
+ {
+ gimp_data_factory_load_directory (factory, context, cache,
+ writable_path,
+ list->data,
+ list->data);
}
- g_free (path);
- g_free (writable_path);
+ g_list_free_full (path, (GDestroyNotify) g_object_unref);
+ g_list_free_full (writable_path, (GDestroyNotify) g_object_unref);
}
void
@@ -793,67 +773,109 @@ gimp_data_factory_get_save_dir (GimpDataFactory *factory,
}
static gboolean
-gimp_data_factory_is_dir_writable (const gchar *dirname,
+gimp_data_factory_is_dir_writable (const gchar *uri,
GList *writable_path)
{
GList *list;
for (list = writable_path; list; list = g_list_next (list))
{
- if (g_str_has_prefix (dirname, list->data))
- return TRUE;
+ gchar *path_uri = g_file_get_uri (list->data);
+
+ if (g_str_has_prefix (uri, path_uri))
+ {
+ g_free (path_uri);
+ return TRUE;
+ }
+
+ g_free (path_uri);
}
return FALSE;
}
static void
-gimp_data_factory_load_data_recursive (const GimpDatafileData *file_data,
- gpointer data)
+gimp_data_factory_load_directory (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ GList *writable_path,
+ GFile *directory,
+ GFile *top_directory)
{
- GimpDataLoadContext *context = data;
- gboolean top_set = FALSE;
-
- /* When processing subdirectories, set the top_directory if it's
- * unset. This way me make sure gimp_data_set_folder_tags()'
- * calling convention is honored: pass NULL when processing the
- * toplevel directory itself, and pass the toplevel directory when
- * processing any folder inside.
- */
- if (! context->top_directory)
+ GFileEnumerator *enumerator;
+
+ enumerator = g_file_enumerate_children (directory,
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, NULL);
+
+ if (enumerator)
{
- context->top_directory = file_data->dirname;
- top_set = TRUE;
- }
+ GFileInfo *info;
- gimp_datafiles_read_directories (file_data->filename, G_FILE_TEST_IS_REGULAR,
- gimp_data_factory_load_data, context);
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)))
+ {
+ GFileType file_type;
+ GFile *child;
- gimp_datafiles_read_directories (file_data->filename, G_FILE_TEST_IS_DIR,
- gimp_data_factory_load_data_recursive,
- context);
+ if (g_file_info_get_is_hidden (info))
+ {
+ g_object_unref (info);
+ continue;
+ }
- /* Unset, the string is only valid within this function, and will
- * be set again for the next subdirectory.
- */
- if (top_set)
- context->top_directory = NULL;
+ file_type = g_file_info_get_file_type (info);
+ child = g_file_enumerator_get_child (enumerator, info);
+
+ if (file_type == G_FILE_TYPE_DIRECTORY)
+ {
+ gimp_data_factory_load_directory (factory, context, cache,
+ writable_path,
+ child,
+ top_directory);
+ }
+ else if (file_type == G_FILE_TYPE_REGULAR)
+ {
+ guint64 mtime;
+
+ mtime = g_file_info_get_attribute_uint64 (info,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
+ gimp_data_factory_load_data (factory, context, cache,
+ writable_path,
+ child, mtime,
+ top_directory);
+ }
+
+ g_object_unref (child);
+ g_object_unref (info);
+ }
+
+ g_object_unref (enumerator);
+ }
}
static void
-gimp_data_factory_load_data (const GimpDatafileData *file_data,
- gpointer data)
+gimp_data_factory_load_data (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ GList *writable_path,
+ GFile *file,
+ guint64 mtime,
+ GFile *top_directory)
{
- GimpDataLoadContext *context = data;
- GimpDataFactory *factory = context->factory;
- GHashTable *cache = context->cache;
const GimpDataFactoryLoaderEntry *loader = NULL;
GList *data_list = NULL;
- GFile *file;
+ gchar *uri;
GInputStream *input;
gint i;
GError *error = NULL;
+ uri = g_file_get_uri (file);
+
for (i = 0; i < factory->priv->n_loader_entries; i++)
{
loader = &factory->priv->loader_entries[i];
@@ -863,31 +885,30 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
* which must be last in the loader array
*/
if (! loader->extension ||
- gimp_datafiles_check_extension (file_data->filename,
- loader->extension))
- goto insert;
+ gimp_datafiles_check_extension (uri, loader->extension))
+ {
+ goto insert;
+ }
}
+ g_free (uri);
return;
insert:
- file = g_file_new_for_path (file_data->filename);
-
if (cache)
{
GList *cached_data = g_hash_table_lookup (cache, file);
if (cached_data &&
gimp_data_get_mtime (cached_data->data) != 0 &&
- gimp_data_get_mtime (cached_data->data) == file_data->mtime)
+ gimp_data_get_mtime (cached_data->data) == mtime)
{
GList *list;
for (list = cached_data; list; list = g_list_next (list))
gimp_container_add (factory->priv->container, list->data);
- g_object_unref (file);
-
+ g_free (uri);
return;
}
}
@@ -896,7 +917,7 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
if (input)
{
- data_list = loader->load_func (context->context, file, input, &error);
+ data_list = loader->load_func (context, file, input, &error);
if (error)
{
@@ -927,15 +948,14 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
gboolean writable = FALSE;
gboolean deletable = FALSE;
- obsolete = (strstr (file_data->dirname,
- GIMP_OBSOLETE_DATA_DIR_NAME) != 0);
+ obsolete = (strstr (uri, GIMP_OBSOLETE_DATA_DIR_NAME) != 0);
/* obsolete files are immutable, don't check their writability */
if (! obsolete)
{
deletable = (g_list_length (data_list) == 1 &&
- gimp_data_factory_is_dir_writable (file_data->dirname,
- context->writable_path));
+ gimp_data_factory_is_dir_writable (uri,
+ writable_path));
writable = (deletable && loader->writable);
}
@@ -945,7 +965,7 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
GimpData *data = list->data;
gimp_data_set_file (data, file, writable, deletable);
- gimp_data_set_mtime (data, file_data->mtime);
+ gimp_data_set_mtime (data, mtime);
gimp_data_clean (data);
if (obsolete)
@@ -955,7 +975,7 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
}
else
{
- gimp_data_set_folder_tags (data, context->top_directory);
+ gimp_data_set_folder_tags (data, top_directory);
gimp_container_add (factory->priv->container,
GIMP_OBJECT (data));
@@ -967,7 +987,7 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
g_list_free (data_list);
}
- g_object_unref (file);
+ g_free (uri);
/* not else { ... } because loader->load_func() can return a list
* of data objects *and* an error message if loading failed after
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]