[gimp/gimp-2-10] app: make GimpDataFactory properly derivable
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: make GimpDataFactory properly derivable
- Date: Sun, 3 Jun 2018 19:08:54 +0000 (UTC)
commit 0c04d3784b3d2819ce47ef8afb11cdcb53e9ed4f
Author: Michael Natterer <mitch gimp org>
Date: Sat Jun 2 21:50:34 2018 +0200
app: make GimpDataFactory properly derivable
Virtualize a lot of functions and move their code into the default
implementation. Also connect to changes of the "path" property and
reload data automatically when the path changes. Add "wait" method
which is by default empty but is to be implemented by fonts.
(cherry picked from commit 01e41042363ed26a676c9eed1d82132607138502)
app/core/gimpdatafactory.c | 755 ++++++++++++++++++++++++++++++---------------
app/core/gimpdatafactory.h | 34 +-
2 files changed, 540 insertions(+), 249 deletions(-)
---
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index f1becc65ac..0a073de932 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -2,7 +2,7 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpdatafactory.c
- * Copyright (C) 2001 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2001-2018 Michael Natterer <mitch gimp org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,16 +48,27 @@
#define GIMP_OBSOLETE_DATA_DIR_NAME "gimp-obsolete-files"
+enum
+{
+ PROP_0,
+ PROP_GIMP,
+ PROP_DATA_TYPE,
+ PROP_PATH_PROPERTY_NAME,
+ PROP_WRITABLE_PROPERTY_NAME
+};
+
+
typedef void (* GimpDataForeachFunc) (GimpDataFactory *factory,
GimpData *data,
gpointer user_data);
-struct _GimpDataFactoryPriv
+struct _GimpDataFactoryPrivate
{
Gimp *gimp;
- GimpContainer *container;
+ GType data_type;
+ GimpContainer *container;
GimpContainer *container_obsolete;
gchar *path_property_name;
@@ -70,37 +81,71 @@ struct _GimpDataFactoryPriv
GimpDataGetStandardFunc data_get_standard_func;
};
-
-static void gimp_data_factory_finalize (GObject *object);
-
-static gint64 gimp_data_factory_get_memsize (GimpObject *object,
- gint64 *gui_size);
-
-static void gimp_data_factory_data_foreach (GimpDataFactory *factory,
- gboolean skip_internal,
- GimpDataForeachFunc callback,
- gpointer user_data);
-
-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 void gimp_data_factory_load_directory (GimpDataFactory *factory,
- GimpContext *context,
- GHashTable *cache,
- gboolean dir_writable,
- GFile *directory,
- GFile *top_directory);
-static void gimp_data_factory_load_data (GimpDataFactory *factory,
- GimpContext *context,
- GHashTable *cache,
- gboolean dir_writable,
- GFile *file,
- GFileInfo *info,
- GFile *top_directory);
+#define GET_PRIVATE(obj) (((GimpDataFactory *) (obj))->priv)
+
+
+static void gimp_data_factory_constructed (GObject *object);
+static void gimp_data_factory_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_data_factory_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_data_factory_finalize (GObject *object);
+
+static gint64 gimp_data_factory_get_memsize (GimpObject *object,
+ gint64 *gui_size);
+
+static void gimp_data_factory_real_data_init (GimpDataFactory *factory,
+ GimpContext *context,
+ gboolean no_data);
+static void gimp_data_factory_real_data_refresh (GimpDataFactory *factory,
+ GimpContext *context);
+static void gimp_data_factory_real_data_save (GimpDataFactory *factory);
+static void gimp_data_factory_real_data_free (GimpDataFactory *factory);
+static GimpAsyncSet *
+ gimp_data_factory_real_get_async_set (GimpDataFactory *factory);
+static gboolean gimp_data_factory_real_data_wait (GimpDataFactory *factory);
+static GimpData * gimp_data_factory_real_data_new (GimpDataFactory *factory,
+ GimpContext *context,
+ const gchar *name);
+static GimpData * gimp_data_factory_real_data_duplicate (GimpDataFactory *factory,
+ GimpData *data);
+static gboolean gimp_data_factory_real_data_delete (GimpDataFactory *factory,
+ GimpData *data,
+ gboolean delete_from_disk,
+ GError **error);
+
+static void gimp_data_factory_path_notify (GObject *object,
+ const GParamSpec *pspec,
+ GimpDataFactory *factory);
+static void gimp_data_factory_data_foreach (GimpDataFactory *factory,
+ gboolean skip_internal,
+ GimpDataForeachFunc callback,
+ gpointer user_data);
+
+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 void gimp_data_factory_load_directory (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ gboolean dir_writable,
+ GFile *directory,
+ GFile *top_directory);
+static void gimp_data_factory_load_data (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache,
+ gboolean dir_writable,
+ GFile *file,
+ GFileInfo *info,
+ GFile *top_directory);
G_DEFINE_TYPE (GimpDataFactory, gimp_data_factory, GIMP_TYPE_OBJECT)
@@ -114,11 +159,50 @@ gimp_data_factory_class_init (GimpDataFactoryClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
+ object_class->constructed = gimp_data_factory_constructed;
+ object_class->set_property = gimp_data_factory_set_property;
+ object_class->get_property = gimp_data_factory_get_property;
object_class->finalize = gimp_data_factory_finalize;
gimp_object_class->get_memsize = gimp_data_factory_get_memsize;
- g_type_class_add_private (klass, sizeof (GimpDataFactoryPriv));
+ klass->data_init = gimp_data_factory_real_data_init;
+ klass->data_refresh = gimp_data_factory_real_data_refresh;
+ klass->data_save = gimp_data_factory_real_data_save;
+ klass->data_free = gimp_data_factory_real_data_free;
+ klass->get_async_set = gimp_data_factory_real_get_async_set;
+ klass->data_wait = gimp_data_factory_real_data_wait;
+ klass->data_new = gimp_data_factory_real_data_new;
+ klass->data_duplicate = gimp_data_factory_real_data_duplicate;
+ klass->data_delete = gimp_data_factory_real_data_delete;
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp", NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_DATA_TYPE,
+ g_param_spec_gtype ("data-type", NULL, NULL,
+ GIMP_TYPE_DATA,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_PATH_PROPERTY_NAME,
+ g_param_spec_string ("path-property-name",
+ NULL, NULL,
+ NULL,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_WRITABLE_PROPERTY_NAME,
+ g_param_spec_string ("writable-property-name",
+ NULL, NULL,
+ NULL,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (klass, sizeof (GimpDataFactoryPrivate));
}
static void
@@ -126,106 +210,137 @@ gimp_data_factory_init (GimpDataFactory *factory)
{
factory->priv = G_TYPE_INSTANCE_GET_PRIVATE (factory,
GIMP_TYPE_DATA_FACTORY,
- GimpDataFactoryPriv);
-
- factory->priv->gimp = NULL;
- factory->priv->container = NULL;
- factory->priv->container_obsolete = NULL;
- factory->priv->path_property_name = NULL;
- factory->priv->writable_property_name = NULL;
- factory->priv->loader_entries = NULL;
- factory->priv->n_loader_entries = 0;
- factory->priv->data_new_func = NULL;
- factory->priv->data_get_standard_func = NULL;
+ GimpDataFactoryPrivate);
}
static void
-gimp_data_factory_finalize (GObject *object)
+gimp_data_factory_constructed (GObject *object)
{
- GimpDataFactory *factory = GIMP_DATA_FACTORY (object);
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
- g_clear_object (&factory->priv->container);
- g_clear_object (&factory->priv->container_obsolete);
+ G_OBJECT_CLASS (parent_class)->constructed (object);
- g_clear_pointer (&factory->priv->path_property_name, g_free);
- g_clear_pointer (&factory->priv->writable_property_name, g_free);
+ gimp_assert (GIMP_IS_GIMP (priv->gimp));
+ gimp_assert (g_type_is_a (priv->data_type, GIMP_TYPE_DATA));
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ priv->container = gimp_list_new (priv->data_type, TRUE);
+ gimp_list_set_sort_func (GIMP_LIST (priv->container),
+ (GCompareFunc) gimp_data_compare);
+
+ priv->container_obsolete = gimp_list_new (priv->data_type, TRUE);
+ gimp_list_set_sort_func (GIMP_LIST (priv->container_obsolete),
+ (GCompareFunc) gimp_data_compare);
}
-static gint64
-gimp_data_factory_get_memsize (GimpObject *object,
- gint64 *gui_size)
+static void
+gimp_data_factory_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GimpDataFactory *factory = GIMP_DATA_FACTORY (object);
- gint64 memsize = 0;
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
- memsize += gimp_object_get_memsize (GIMP_OBJECT (factory->priv->container),
- gui_size);
- memsize += gimp_object_get_memsize (GIMP_OBJECT (factory->priv->container_obsolete),
- gui_size);
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ priv->gimp = g_value_get_object (value); /* don't ref */
+ break;
- return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
- gui_size);
+ case PROP_DATA_TYPE:
+ priv->data_type = g_value_get_gtype (value);
+ break;
+
+ case PROP_PATH_PROPERTY_NAME:
+ priv->path_property_name = g_value_dup_string (value);
+ break;
+
+ case PROP_WRITABLE_PROPERTY_NAME:
+ priv->writable_property_name = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
-GimpDataFactory *
-gimp_data_factory_new (Gimp *gimp,
- GType data_type,
- const gchar *path_property_name,
- const gchar *writable_property_name,
- const GimpDataFactoryLoaderEntry *loader_entries,
- gint n_loader_entries,
- GimpDataNewFunc new_func,
- GimpDataGetStandardFunc get_standard_func)
+static void
+gimp_data_factory_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GimpDataFactory *factory;
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
- g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
- g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL);
- g_return_val_if_fail (path_property_name != NULL, NULL);
- g_return_val_if_fail (writable_property_name != NULL, NULL);
- g_return_val_if_fail (loader_entries != NULL, NULL);
- g_return_val_if_fail (n_loader_entries > 0, NULL);
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ g_value_set_object (value, priv->gimp);
+ break;
- factory = g_object_new (GIMP_TYPE_DATA_FACTORY, NULL);
+ case PROP_DATA_TYPE:
+ g_value_set_gtype (value, priv->data_type);
+ break;
- factory->priv->gimp = gimp;
- factory->priv->container = gimp_list_new (data_type, TRUE);
- gimp_list_set_sort_func (GIMP_LIST (factory->priv->container),
- (GCompareFunc) gimp_data_compare);
- factory->priv->container_obsolete = gimp_list_new (data_type, TRUE);
- gimp_list_set_sort_func (GIMP_LIST (factory->priv->container_obsolete),
- (GCompareFunc) gimp_data_compare);
+ case PROP_PATH_PROPERTY_NAME:
+ g_value_set_string (value, priv->path_property_name);
+ break;
- factory->priv->path_property_name = g_strdup (path_property_name);
- factory->priv->writable_property_name = g_strdup (writable_property_name);
+ case PROP_WRITABLE_PROPERTY_NAME:
+ g_value_set_string (value, priv->writable_property_name);
+ break;
- factory->priv->loader_entries = loader_entries;
- factory->priv->n_loader_entries = n_loader_entries;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
- factory->priv->data_new_func = new_func;
- factory->priv->data_get_standard_func = get_standard_func;
+static void
+gimp_data_factory_finalize (GObject *object)
+{
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
- return factory;
+ g_clear_object (&priv->container);
+ g_clear_object (&priv->container_obsolete);
+
+ g_clear_pointer (&priv->path_property_name, g_free);
+ g_clear_pointer (&priv->writable_property_name, g_free);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
-void
-gimp_data_factory_data_init (GimpDataFactory *factory,
- GimpContext *context,
- gboolean no_data)
+static gint64
+gimp_data_factory_get_memsize (GimpObject *object,
+ gint64 *gui_size)
{
- g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
- g_return_if_fail (GIMP_IS_CONTEXT (context));
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
+ gint64 memsize = 0;
+
+ memsize += gimp_object_get_memsize (GIMP_OBJECT (priv->container),
+ gui_size);
+ memsize += gimp_object_get_memsize (GIMP_OBJECT (priv->container_obsolete),
+ gui_size);
+
+ return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
+ gui_size);
+}
+
+static void
+gimp_data_factory_real_data_init (GimpDataFactory *factory,
+ GimpContext *context,
+ gboolean no_data)
+{
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
/* Freeze and thaw the container even if no_data,
* this creates the standard data that serves as fallback.
*/
- gimp_container_freeze (factory->priv->container);
+ gimp_container_freeze (priv->container);
if (! no_data)
{
- if (factory->priv->gimp->be_verbose)
+ if (priv->gimp->be_verbose)
{
const gchar *name = gimp_object_get_name (factory);
@@ -235,25 +350,7 @@ gimp_data_factory_data_init (GimpDataFactory *factory,
gimp_data_factory_data_load (factory, context, NULL);
}
- gimp_container_thaw (factory->priv->container);
-}
-
-static void
-gimp_data_factory_clean_cb (GimpDataFactory *factory,
- GimpData *data,
- gpointer user_data)
-{
- if (gimp_data_is_dirty (data))
- gimp_data_clean (data);
-}
-
-void
-gimp_data_factory_data_clean (GimpDataFactory *factory)
-{
- g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
-
- gimp_data_factory_data_foreach (factory, TRUE,
- gimp_data_factory_clean_cb, NULL);
+ gimp_container_thaw (priv->container);
}
static void
@@ -295,79 +392,13 @@ gimp_data_factory_refresh_cache_remove (gpointer key,
}
static void
-gimp_data_factory_data_foreach (GimpDataFactory *factory,
- gboolean skip_internal,
- GimpDataForeachFunc callback,
- gpointer user_data)
-{
- GList *list = GIMP_LIST (factory->priv->container)->queue->head;
-
- if (skip_internal)
- {
- while (list && gimp_data_is_internal (GIMP_DATA (list->data)))
- list = g_list_next (list);
- }
-
- while (list)
- {
- GList *next = g_list_next (list);
-
- callback (factory, list->data, user_data);
-
- list = next;
- }
-}
-
-static void
-gimp_data_factory_data_load (GimpDataFactory *factory,
- GimpContext *context,
- GHashTable *cache)
-{
- gchar *p;
- gchar *wp;
- GList *path;
- GList *writable_path;
- GList *list;
-
- g_object_get (factory->priv->gimp->config,
- factory->priv->path_property_name, &p,
- factory->priv->writable_property_name, &wp,
- NULL);
-
- path = gimp_config_path_expand_to_files (p, NULL);
- writable_path = gimp_config_path_expand_to_files (wp, NULL);
-
- g_free (p);
- g_free (wp);
-
- for (list = path; list; list = g_list_next (list))
- {
- gboolean dir_writable = FALSE;
-
- if (g_list_find_custom (writable_path, list->data,
- (GCompareFunc) gimp_file_compare))
- dir_writable = TRUE;
-
- gimp_data_factory_load_directory (factory, context, cache,
- dir_writable,
- list->data,
- list->data);
- }
-
- g_list_free_full (path, (GDestroyNotify) g_object_unref);
- g_list_free_full (writable_path, (GDestroyNotify) g_object_unref);
-}
-
-void
-gimp_data_factory_data_refresh (GimpDataFactory *factory,
- GimpContext *context)
+gimp_data_factory_real_data_refresh (GimpDataFactory *factory,
+ GimpContext *context)
{
- GHashTable *cache;
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+ GHashTable *cache;
- g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
- g_return_if_fail (GIMP_IS_CONTEXT (context));
-
- gimp_container_freeze (factory->priv->container);
+ gimp_container_freeze (priv->container);
/* First, save all dirty data objects */
gimp_data_factory_data_save (factory);
@@ -393,23 +424,19 @@ gimp_data_factory_data_refresh (GimpDataFactory *factory,
g_hash_table_destroy (cache);
- gimp_container_thaw (factory->priv->container);
+ gimp_container_thaw (priv->container);
}
-void
-gimp_data_factory_data_save (GimpDataFactory *factory)
+static void
+gimp_data_factory_real_data_save (GimpDataFactory *factory)
{
- GList *dirty = NULL;
- GList *list;
- GFile *writable_dir;
- GError *error = NULL;
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+ GList *dirty = NULL;
+ GList *list;
+ GFile *writable_dir;
+ GError *error = NULL;
- g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
-
- if (gimp_container_is_empty (factory->priv->container))
- return;
-
- for (list = GIMP_LIST (factory->priv->container)->queue->head;
+ for (list = GIMP_LIST (priv->container)->queue->head;
list;
list = g_list_next (list))
{
@@ -429,7 +456,7 @@ gimp_data_factory_data_save (GimpDataFactory *factory)
if (! writable_dir)
{
- gimp_message (factory->priv->gimp, NULL, GIMP_MESSAGE_ERROR,
+ gimp_message (priv->gimp, NULL, GIMP_MESSAGE_ERROR,
_("Failed to save data:\n\n%s"),
error->message);
g_clear_error (&error);
@@ -454,7 +481,7 @@ gimp_data_factory_data_save (GimpDataFactory *factory)
*/
if (error)
{
- gimp_message (factory->priv->gimp, NULL, GIMP_MESSAGE_ERROR,
+ gimp_message (priv->gimp, NULL, GIMP_MESSAGE_ERROR,
_("Failed to save data:\n\n%s"),
error->message);
g_clear_error (&error);
@@ -475,11 +502,9 @@ gimp_data_factory_remove_cb (GimpDataFactory *factory,
gimp_container_remove (factory->priv->container, GIMP_OBJECT (data));
}
-void
-gimp_data_factory_data_free (GimpDataFactory *factory)
+static void
+gimp_data_factory_real_data_free (GimpDataFactory *factory)
{
- g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
-
gimp_container_freeze (factory->priv->container);
gimp_data_factory_data_foreach (factory, TRUE,
@@ -488,42 +513,50 @@ gimp_data_factory_data_free (GimpDataFactory *factory)
gimp_container_thaw (factory->priv->container);
}
-GimpData *
-gimp_data_factory_data_new (GimpDataFactory *factory,
- GimpContext *context,
- const gchar *name)
+static GimpAsyncSet *
+gimp_data_factory_real_get_async_set (GimpDataFactory *factory)
{
- g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
- g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (*name != '\0', NULL);
+ return NULL;
+}
- if (factory->priv->data_new_func)
+static gboolean
+gimp_data_factory_real_data_wait (GimpDataFactory *factory)
+{
+ return TRUE;
+}
+
+static GimpData *
+gimp_data_factory_real_data_new (GimpDataFactory *factory,
+ GimpContext *context,
+ const gchar *name)
+{
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+
+ if (priv->data_new_func)
{
- GimpData *data = factory->priv->data_new_func (context, name);
+ GimpData *data = priv->data_new_func (context, name);
if (data)
{
- gimp_container_add (factory->priv->container, GIMP_OBJECT (data));
+ gimp_container_add (priv->container, GIMP_OBJECT (data));
g_object_unref (data);
return data;
}
- g_warning ("%s: factory->priv->data_new_func() returned NULL", G_STRFUNC);
+ g_warning ("%s: GimpDataFactory::data_new_func() returned NULL",
+ G_STRFUNC);
}
return NULL;
}
-GimpData *
-gimp_data_factory_data_duplicate (GimpDataFactory *factory,
- GimpData *data)
+static GimpData *
+gimp_data_factory_real_data_duplicate (GimpDataFactory *factory,
+ GimpData *data)
{
- GimpData *new_data;
-
- g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
- g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+ GimpData *new_data;
new_data = gimp_data_duplicate (data);
@@ -553,30 +586,27 @@ gimp_data_factory_data_duplicate (GimpDataFactory *factory,
gimp_object_take_name (GIMP_OBJECT (new_data), new_name);
- gimp_container_add (factory->priv->container, GIMP_OBJECT (new_data));
+ gimp_container_add (priv->container, GIMP_OBJECT (new_data));
g_object_unref (new_data);
}
return new_data;
}
-gboolean
-gimp_data_factory_data_delete (GimpDataFactory *factory,
- GimpData *data,
- gboolean delete_from_disk,
- GError **error)
+static gboolean
+gimp_data_factory_real_data_delete (GimpDataFactory *factory,
+ GimpData *data,
+ gboolean delete_from_disk,
+ GError **error)
{
- gboolean retval = TRUE;
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+ gboolean retval = TRUE;
- g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
- g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- if (gimp_container_have (factory->priv->container, GIMP_OBJECT (data)))
+ if (gimp_container_have (priv->container, GIMP_OBJECT (data)))
{
g_object_ref (data);
- gimp_container_remove (factory->priv->container, GIMP_OBJECT (data));
+ gimp_container_remove (priv->container, GIMP_OBJECT (data));
if (delete_from_disk && gimp_data_get_file (data))
retval = gimp_data_delete_from_disk (data, error);
@@ -587,6 +617,165 @@ gimp_data_factory_data_delete (GimpDataFactory *factory,
return retval;
}
+
+/* public functions */
+
+GimpDataFactory *
+gimp_data_factory_new (Gimp *gimp,
+ GType data_type,
+ const gchar *path_property_name,
+ const gchar *writable_property_name,
+ const GimpDataFactoryLoaderEntry *loader_entries,
+ gint n_loader_entries,
+ GimpDataNewFunc new_func,
+ GimpDataGetStandardFunc get_standard_func)
+{
+ GimpDataFactory *factory;
+
+ g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+ g_return_val_if_fail (g_type_is_a (data_type, GIMP_TYPE_DATA), NULL);
+ g_return_val_if_fail (path_property_name != NULL, NULL);
+ g_return_val_if_fail (writable_property_name != NULL, NULL);
+ g_return_val_if_fail (loader_entries != NULL, NULL);
+ g_return_val_if_fail (n_loader_entries > 0, NULL);
+
+ factory = g_object_new (GIMP_TYPE_DATA_FACTORY,
+ "gimp", gimp,
+ "data-type", data_type,
+ "path-property-name", path_property_name,
+ "writable-property-name", writable_property_name,
+ NULL);
+
+ factory->priv->loader_entries = loader_entries;
+ factory->priv->n_loader_entries = n_loader_entries;
+
+ factory->priv->data_new_func = new_func;
+ factory->priv->data_get_standard_func = get_standard_func;
+
+ return factory;
+}
+
+void
+gimp_data_factory_data_init (GimpDataFactory *factory,
+ GimpContext *context,
+ gboolean no_data)
+{
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+ gchar *signal_name;
+
+ g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+ g_return_if_fail (GIMP_IS_CONTEXT (context));
+
+ GIMP_DATA_FACTORY_GET_CLASS (factory)->data_init (factory, context, no_data);
+
+ signal_name = g_strdup_printf ("notify::%s", priv->path_property_name);
+ g_signal_connect_object (priv->gimp->config, signal_name,
+ G_CALLBACK (gimp_data_factory_path_notify),
+ factory, 0);
+ g_free (signal_name);
+}
+
+static void
+gimp_data_factory_clean_cb (GimpDataFactory *factory,
+ GimpData *data,
+ gpointer user_data)
+{
+ if (gimp_data_is_dirty (data))
+ gimp_data_clean (data);
+}
+
+void
+gimp_data_factory_data_clean (GimpDataFactory *factory)
+{
+ g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+
+ gimp_data_factory_data_foreach (factory, TRUE,
+ gimp_data_factory_clean_cb, NULL);
+}
+
+void
+gimp_data_factory_data_refresh (GimpDataFactory *factory,
+ GimpContext *context)
+{
+ g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+ g_return_if_fail (GIMP_IS_CONTEXT (context));
+
+ GIMP_DATA_FACTORY_GET_CLASS (factory)->data_refresh (factory, context);
+}
+
+void
+gimp_data_factory_data_save (GimpDataFactory *factory)
+{
+ g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+
+ if (! gimp_container_is_empty (factory->priv->container))
+ GIMP_DATA_FACTORY_GET_CLASS (factory)->data_save (factory);
+}
+
+void
+gimp_data_factory_data_free (GimpDataFactory *factory)
+{
+ g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+
+ if (! gimp_container_is_empty (factory->priv->container))
+ GIMP_DATA_FACTORY_GET_CLASS (factory)->data_free (factory);
+}
+
+GimpAsyncSet *
+gimp_data_factory_get_async_set (GimpDataFactory *factory)
+{
+ g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
+
+ return GIMP_DATA_FACTORY_GET_CLASS (factory)->get_async_set (factory);
+}
+
+gboolean
+gimp_data_factory_data_wait (GimpDataFactory *factory)
+{
+ g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
+
+ return GIMP_DATA_FACTORY_GET_CLASS (factory)->data_wait (factory);
+}
+
+GimpData *
+gimp_data_factory_data_new (GimpDataFactory *factory,
+ GimpContext *context,
+ const gchar *name)
+{
+ g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
+ g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (*name != '\0', NULL);
+
+ return GIMP_DATA_FACTORY_GET_CLASS (factory)->data_new (factory, context,
+ name);
+}
+
+GimpData *
+gimp_data_factory_data_duplicate (GimpDataFactory *factory,
+ GimpData *data)
+{
+ g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
+ g_return_val_if_fail (GIMP_IS_DATA (data), NULL);
+
+ return GIMP_DATA_FACTORY_GET_CLASS (factory)->data_duplicate (factory, data);
+}
+
+gboolean
+gimp_data_factory_data_delete (GimpDataFactory *factory,
+ GimpData *data,
+ gboolean delete_from_disk,
+ GError **error)
+{
+ g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
+ g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ return GIMP_DATA_FACTORY_GET_CLASS (factory)->data_delete (factory, data,
+ delete_from_disk,
+ error);
+}
+
GimpData *
gimp_data_factory_data_get_standard (GimpDataFactory *factory,
GimpContext *context)
@@ -696,6 +885,84 @@ gimp_data_factory_has_data_new_func (GimpDataFactory *factory)
/* private functions */
+static void
+gimp_data_factory_path_notify (GObject *object,
+ const GParamSpec *pspec,
+ GimpDataFactory *factory)
+{
+ GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+
+ gimp_set_busy (priv->gimp);
+
+ gimp_data_factory_data_refresh (factory, gimp_get_user_context (priv->gimp));
+
+ gimp_unset_busy (priv->gimp);
+}
+
+static void
+gimp_data_factory_data_foreach (GimpDataFactory *factory,
+ gboolean skip_internal,
+ GimpDataForeachFunc callback,
+ gpointer user_data)
+{
+ GList *list = GIMP_LIST (factory->priv->container)->queue->head;
+
+ if (skip_internal)
+ {
+ while (list && gimp_data_is_internal (GIMP_DATA (list->data)))
+ list = g_list_next (list);
+ }
+
+ while (list)
+ {
+ GList *next = g_list_next (list);
+
+ callback (factory, list->data, user_data);
+
+ list = next;
+ }
+}
+
+static void
+gimp_data_factory_data_load (GimpDataFactory *factory,
+ GimpContext *context,
+ GHashTable *cache)
+{
+ gchar *p;
+ gchar *wp;
+ GList *path;
+ GList *writable_path;
+ GList *list;
+
+ g_object_get (factory->priv->gimp->config,
+ factory->priv->path_property_name, &p,
+ factory->priv->writable_property_name, &wp,
+ NULL);
+
+ path = gimp_config_path_expand_to_files (p, NULL);
+ writable_path = gimp_config_path_expand_to_files (wp, NULL);
+
+ g_free (p);
+ g_free (wp);
+
+ for (list = path; list; list = g_list_next (list))
+ {
+ gboolean dir_writable = FALSE;
+
+ if (g_list_find_custom (writable_path, list->data,
+ (GCompareFunc) gimp_file_compare))
+ dir_writable = TRUE;
+
+ gimp_data_factory_load_directory (factory, context, cache,
+ dir_writable,
+ list->data,
+ list->data);
+ }
+
+ g_list_free_full (path, (GDestroyNotify) g_object_unref);
+ g_list_free_full (writable_path, (GDestroyNotify) g_object_unref);
+}
+
static GFile *
gimp_data_factory_get_save_dir (GimpDataFactory *factory,
GError **error)
diff --git a/app/core/gimpdatafactory.h b/app/core/gimpdatafactory.h
index 8456464828..8e1abcaf90 100644
--- a/app/core/gimpdatafactory.h
+++ b/app/core/gimpdatafactory.h
@@ -2,7 +2,7 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpdatafactory.h
- * Copyright (C) 2001 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2001-2018 Michael Natterer <mitch gimp org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,19 +52,40 @@ struct _GimpDataFactoryLoaderEntry
#define GIMP_DATA_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DATA_FACTORY,
GimpDataFactoryClass))
-typedef struct _GimpDataFactoryClass GimpDataFactoryClass;
-typedef struct _GimpDataFactoryPriv GimpDataFactoryPriv;
+typedef struct _GimpDataFactoryPrivate GimpDataFactoryPrivate;
+typedef struct _GimpDataFactoryClass GimpDataFactoryClass;
struct _GimpDataFactory
{
- GimpObject parent_instance;
+ GimpObject parent_instance;
- GimpDataFactoryPriv *priv;
+ GimpDataFactoryPrivate *priv;
};
struct _GimpDataFactoryClass
{
GimpObjectClass parent_class;
+
+ void (* data_init) (GimpDataFactory *factory,
+ GimpContext *context,
+ gboolean no_data);
+ void (* data_refresh) (GimpDataFactory *factory,
+ GimpContext *context);
+ void (* data_save) (GimpDataFactory *factory);
+ void (* data_free) (GimpDataFactory *factory);
+
+ GimpAsyncSet * (* get_async_set) (GimpDataFactory *factory);
+ gboolean (* data_wait) (GimpDataFactory *factory);
+
+ GimpData * (* data_new) (GimpDataFactory *factory,
+ GimpContext *context,
+ const gchar *name);
+ GimpData * (* data_duplicate) (GimpDataFactory *factory,
+ GimpData *data);
+ gboolean (* data_delete) (GimpDataFactory *factory,
+ GimpData *data,
+ gboolean delete_from_disk,
+ GError **error);
};
@@ -88,6 +109,9 @@ void gimp_data_factory_data_refresh (GimpDataFactory *factory,
void gimp_data_factory_data_save (GimpDataFactory *factory);
void gimp_data_factory_data_free (GimpDataFactory *factory);
+GimpAsyncSet * gimp_data_factory_get_async_set (GimpDataFactory *factory);
+gboolean gimp_data_factory_data_wait (GimpDataFactory *factory);
+
GimpData * gimp_data_factory_data_new (GimpDataFactory *factory,
GimpContext *context,
const gchar *name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]