2006-12-09 21:33:38 +00:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2001-02-13 19:53:07 +00:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2001-04-22 00:38:56 +00:00
|
|
|
* gimpdatafactory.c
|
2018-06-02 21:50:34 +02:00
|
|
|
* Copyright (C) 2001-2018 Michael Natterer <mitch@gimp.org>
|
2001-04-22 00:38:56 +00:00
|
|
|
*
|
2009-01-17 22:28:01 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2001-02-13 19:53:07 +00:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-17 22:28:01 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2001-02-13 19:53:07 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2018-07-11 23:27:07 +02:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2001-02-13 19:53:07 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2013-10-15 01:58:39 +02:00
|
|
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
2012-03-29 19:19:01 +02:00
|
|
|
#include <gegl.h>
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2002-10-23 14:55:07 +00:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2007-03-09 13:00:01 +00:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
2005-01-25 19:11:26 +00:00
|
|
|
#include "libgimpconfig/gimpconfig.h"
|
2002-10-23 14:55:07 +00:00
|
|
|
|
2001-05-09 22:34:59 +00:00
|
|
|
#include "core-types.h"
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2002-11-30 16:31:39 +00:00
|
|
|
#include "gimp.h"
|
2014-08-02 15:07:26 +02:00
|
|
|
#include "gimp-utils.h"
|
2018-06-03 22:28:00 +02:00
|
|
|
#include "gimpasyncset.h"
|
|
|
|
#include "gimpcancelable.h"
|
2001-07-09 19:48:30 +00:00
|
|
|
#include "gimpcontext.h"
|
2001-02-13 19:53:07 +00:00
|
|
|
#include "gimpdata.h"
|
|
|
|
#include "gimpdatafactory.h"
|
2004-05-24 10:49:34 +00:00
|
|
|
#include "gimplist.h"
|
2018-06-03 22:28:00 +02:00
|
|
|
#include "gimpuncancelablewaitable.h"
|
|
|
|
#include "gimpwaitable.h"
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2003-03-25 16:38:19 +00:00
|
|
|
#include "gimp-intl.h"
|
2001-02-14 01:42:12 +00:00
|
|
|
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
PROP_GIMP,
|
|
|
|
PROP_DATA_TYPE,
|
|
|
|
PROP_PATH_PROPERTY_NAME,
|
2018-06-04 12:18:13 +02:00
|
|
|
PROP_WRITABLE_PROPERTY_NAME,
|
2018-07-02 20:33:59 +02:00
|
|
|
PROP_EXT_PROPERTY_NAME,
|
2018-06-04 12:18:13 +02:00
|
|
|
PROP_NEW_FUNC,
|
|
|
|
PROP_GET_STANDARD_FUNC
|
2018-06-02 21:50:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct _GimpDataFactoryPrivate
|
2008-12-19 21:58:17 +00:00
|
|
|
{
|
2018-06-04 13:12:14 +02:00
|
|
|
Gimp *gimp;
|
2009-08-11 20:38:12 +02:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
GType data_type;
|
|
|
|
GimpContainer *container;
|
|
|
|
GimpContainer *container_obsolete;
|
2008-12-19 21:58:17 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
gchar *path_property_name;
|
|
|
|
gchar *writable_property_name;
|
2018-07-02 20:33:59 +02:00
|
|
|
gchar *ext_property_name;
|
2018-06-04 12:18:13 +02:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
GimpDataNewFunc data_new_func;
|
|
|
|
GimpDataGetStandardFunc data_get_standard_func;
|
2018-06-03 22:28:00 +02:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
GimpAsyncSet *async_set;
|
2008-12-19 21:58:17 +00:00
|
|
|
};
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
#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_save (GimpDataFactory *factory);
|
|
|
|
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);
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
static void gimp_data_factory_path_notify (GObject *object,
|
2018-06-02 21:50:34 +02:00
|
|
|
const GParamSpec *pspec,
|
|
|
|
GimpDataFactory *factory);
|
2018-06-04 13:12:14 +02:00
|
|
|
static GFile * gimp_data_factory_get_save_dir (GimpDataFactory *factory,
|
2018-06-02 21:50:34 +02:00
|
|
|
GError **error);
|
|
|
|
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
G_DEFINE_ABSTRACT_TYPE (GimpDataFactory, gimp_data_factory, GIMP_TYPE_OBJECT)
|
2005-12-10 19:24:36 +00:00
|
|
|
|
|
|
|
#define parent_class gimp_data_factory_parent_class
|
2001-02-13 19:53:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_data_factory_class_init (GimpDataFactoryClass *klass)
|
|
|
|
{
|
2004-05-24 10:49:34 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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;
|
2002-01-30 16:14:26 +00:00
|
|
|
object_class->finalize = gimp_data_factory_finalize;
|
|
|
|
|
|
|
|
gimp_object_class->get_memsize = gimp_data_factory_get_memsize;
|
2008-12-19 21:58:17 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
klass->data_init = NULL;
|
|
|
|
klass->data_refresh = NULL;
|
2018-06-02 21:50:34 +02:00
|
|
|
klass->data_save = gimp_data_factory_real_data_save;
|
|
|
|
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));
|
|
|
|
|
2018-07-02 20:33:59 +02:00
|
|
|
g_object_class_install_property (object_class, PROP_EXT_PROPERTY_NAME,
|
|
|
|
g_param_spec_string ("ext-property-name",
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
GIMP_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
2018-06-04 12:18:13 +02:00
|
|
|
g_object_class_install_property (object_class, PROP_NEW_FUNC,
|
|
|
|
g_param_spec_pointer ("new-func",
|
|
|
|
NULL, NULL,
|
|
|
|
GIMP_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
|
|
|
g_object_class_install_property (object_class, PROP_GET_STANDARD_FUNC,
|
|
|
|
g_param_spec_pointer ("get-standard-func",
|
|
|
|
NULL, NULL,
|
|
|
|
GIMP_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
g_type_class_add_private (klass, sizeof (GimpDataFactoryPrivate));
|
2001-02-13 19:53:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_data_factory_init (GimpDataFactory *factory)
|
|
|
|
{
|
2008-12-19 21:58:17 +00:00
|
|
|
factory->priv = G_TYPE_INSTANCE_GET_PRIVATE (factory,
|
|
|
|
GIMP_TYPE_DATA_FACTORY,
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate);
|
2018-06-03 22:28:00 +02:00
|
|
|
|
|
|
|
factory->priv->async_set = gimp_async_set_new ();
|
2001-02-13 19:53:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-06-02 21:50:34 +02:00
|
|
|
gimp_data_factory_constructed (GObject *object)
|
2001-02-13 19:53:07 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
2009-08-11 20:38:12 +02:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
gimp_assert (GIMP_IS_GIMP (priv->gimp));
|
|
|
|
gimp_assert (g_type_is_a (priv->data_type, GIMP_TYPE_DATA));
|
2018-06-04 13:12:14 +02:00
|
|
|
gimp_assert (GIMP_DATA_FACTORY_GET_CLASS (object)->data_init != NULL);
|
|
|
|
gimp_assert (GIMP_DATA_FACTORY_GET_CLASS (object)->data_refresh != NULL);
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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);
|
2001-02-13 19:53:07 +00:00
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static void
|
|
|
|
gimp_data_factory_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2002-01-30 16:14:26 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
|
2002-01-30 16:14:26 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_GIMP:
|
|
|
|
priv->gimp = g_value_get_object (value); /* don't ref */
|
|
|
|
break;
|
2002-01-30 16:14:26 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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;
|
|
|
|
|
2018-07-02 20:33:59 +02:00
|
|
|
case PROP_EXT_PROPERTY_NAME:
|
|
|
|
priv->ext_property_name = g_value_dup_string (value);
|
|
|
|
break;
|
|
|
|
|
2018-06-04 12:18:13 +02:00
|
|
|
case PROP_NEW_FUNC:
|
|
|
|
priv->data_new_func = g_value_get_pointer (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_GET_STANDARD_FUNC:
|
|
|
|
priv->data_get_standard_func = g_value_get_pointer (value);
|
|
|
|
break;
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
2002-01-30 16:14:26 +00:00
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static void
|
|
|
|
gimp_data_factory_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2001-02-13 19:53:07 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case PROP_GIMP:
|
|
|
|
g_value_set_object (value, priv->gimp);
|
|
|
|
break;
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
case PROP_DATA_TYPE:
|
|
|
|
g_value_set_gtype (value, priv->data_type);
|
|
|
|
break;
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
case PROP_PATH_PROPERTY_NAME:
|
|
|
|
g_value_set_string (value, priv->path_property_name);
|
|
|
|
break;
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
case PROP_WRITABLE_PROPERTY_NAME:
|
|
|
|
g_value_set_string (value, priv->writable_property_name);
|
|
|
|
break;
|
2001-02-14 01:42:12 +00:00
|
|
|
|
2018-07-02 20:33:59 +02:00
|
|
|
case PROP_EXT_PROPERTY_NAME:
|
|
|
|
g_value_set_string (value, priv->ext_property_name);
|
|
|
|
break;
|
|
|
|
|
2018-06-04 12:18:13 +02:00
|
|
|
case PROP_NEW_FUNC:
|
|
|
|
g_value_set_pointer (value, priv->data_new_func);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_GET_STANDARD_FUNC:
|
|
|
|
g_value_set_pointer (value, priv->data_get_standard_func);
|
|
|
|
break;
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-02-14 01:42:12 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static void
|
|
|
|
gimp_data_factory_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
|
2001-02-13 19:53:07 +00:00
|
|
|
|
2018-06-03 22:28:00 +02:00
|
|
|
if (priv->async_set)
|
|
|
|
{
|
|
|
|
gimp_cancelable_cancel (GIMP_CANCELABLE (priv->async_set));
|
app: a few async font loading fixes
In gimp_data_factory_finalize(), wait on the factory's async set
after canceling it, and before continuing destruction. It's not
generally safe to just abandon an async op without waiting on it
-- this is a font-specific hack, due to the fact we can't actually
cancel font loading, and GimpFontFactory is prepared to handle
this.
Instead, in gimp_font_factory_finalize(), cancel and clear the
async set, so that GimpDataFactory doesn't actually wait for
loading to finish.
In gimp_font_factory_load_async_callback(), don't try to acess the
factory when the operation is canceled, since cancelation means the
factory is already dead. On the other hand, when the opeation
isn't canceled, make sure to thaw the container even when font
loading failed, so that we always match the freeze at the begining
of the operation.
2018-06-28 15:23:12 -04:00
|
|
|
gimp_waitable_wait (GIMP_WAITABLE (priv->async_set));
|
2018-06-03 22:28:00 +02:00
|
|
|
|
|
|
|
g_clear_object (&priv->async_set);
|
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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);
|
2018-07-02 20:33:59 +02:00
|
|
|
g_clear_pointer (&priv->ext_property_name, g_free);
|
2018-06-02 21:50:34 +02:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
2001-02-13 19:53:07 +00:00
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static gint64
|
|
|
|
gimp_data_factory_get_memsize (GimpObject *object,
|
|
|
|
gint64 *gui_size)
|
2001-02-14 01:42:12 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
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_save (GimpDataFactory *factory)
|
2001-02-13 19:53:07 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
|
|
|
|
GList *dirty = NULL;
|
|
|
|
GList *list;
|
|
|
|
GFile *writable_dir;
|
|
|
|
GError *error = NULL;
|
2001-02-17 21:20:10 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
for (list = GIMP_LIST (priv->container)->queue->head;
|
2015-07-21 19:24:45 +02:00
|
|
|
list;
|
|
|
|
list = g_list_next (list))
|
|
|
|
{
|
|
|
|
GimpData *data = list->data;
|
|
|
|
|
|
|
|
if (gimp_data_is_dirty (data) &&
|
|
|
|
gimp_data_is_writable (data))
|
|
|
|
{
|
|
|
|
dirty = g_list_prepend (dirty, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! dirty)
|
|
|
|
return;
|
|
|
|
|
2009-10-30 21:31:13 +01:00
|
|
|
writable_dir = gimp_data_factory_get_save_dir (factory, &error);
|
2001-02-17 21:20:10 +00:00
|
|
|
|
2004-01-28 21:53:50 +00:00
|
|
|
if (! writable_dir)
|
2009-10-30 21:31:13 +01:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
gimp_message (priv->gimp, NULL, GIMP_MESSAGE_ERROR,
|
2009-10-30 21:31:13 +01:00
|
|
|
_("Failed to save data:\n\n%s"),
|
|
|
|
error->message);
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
2015-07-21 19:24:45 +02:00
|
|
|
g_list_free (dirty);
|
|
|
|
|
2009-10-30 21:31:13 +01:00
|
|
|
return;
|
|
|
|
}
|
2002-12-29 18:58:24 +00:00
|
|
|
|
2015-07-21 19:24:45 +02:00
|
|
|
for (list = dirty; list; list = g_list_next (list))
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
2015-07-21 19:24:45 +02:00
|
|
|
GimpData *data = list->data;
|
|
|
|
GError *error = NULL;
|
2001-02-17 21:20:10 +00:00
|
|
|
|
2014-07-01 01:19:35 +02:00
|
|
|
if (! gimp_data_get_file (data))
|
2004-07-05 18:10:05 +00:00
|
|
|
gimp_data_create_filename (data, writable_dir);
|
2001-02-17 21:20:10 +00:00
|
|
|
|
2018-06-10 15:52:06 +02:00
|
|
|
if (factory->priv->gimp->be_verbose)
|
|
|
|
{
|
|
|
|
GFile *file = gimp_data_get_file (data);
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
g_print ("Writing dirty data '%s'\n",
|
|
|
|
gimp_file_get_utf8_name (file));
|
|
|
|
}
|
|
|
|
|
2015-07-21 19:24:45 +02:00
|
|
|
if (! gimp_data_save (data, &error))
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
2015-07-21 19:24:45 +02:00
|
|
|
/* check if there actually was an error (no error
|
|
|
|
* means the data class does not implement save)
|
|
|
|
*/
|
|
|
|
if (error)
|
2002-12-02 13:39:09 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
gimp_message (priv->gimp, NULL, GIMP_MESSAGE_ERROR,
|
2015-07-21 19:24:45 +02:00
|
|
|
_("Failed to save data:\n\n%s"),
|
|
|
|
error->message);
|
|
|
|
g_clear_error (&error);
|
2002-12-02 13:39:09 +00:00
|
|
|
}
|
|
|
|
}
|
2001-02-17 21:20:10 +00:00
|
|
|
}
|
|
|
|
|
2014-07-26 16:37:30 +02:00
|
|
|
g_object_unref (writable_dir);
|
2015-07-21 19:24:45 +02:00
|
|
|
|
|
|
|
g_list_free (dirty);
|
2001-02-13 19:53:07 +00:00
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static GimpData *
|
|
|
|
gimp_data_factory_real_data_duplicate (GimpDataFactory *factory,
|
|
|
|
GimpData *data)
|
2002-12-02 13:39:09 +00:00
|
|
|
{
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
|
|
|
|
GimpData *new_data;
|
2002-12-02 13:39:09 +00:00
|
|
|
|
2005-06-08 11:27:31 +00:00
|
|
|
new_data = gimp_data_duplicate (data);
|
2002-12-02 13:39:09 +00:00
|
|
|
|
|
|
|
if (new_data)
|
|
|
|
{
|
2009-08-31 22:47:18 +02:00
|
|
|
const gchar *name = gimp_object_get_name (data);
|
2002-12-02 13:39:09 +00:00
|
|
|
gchar *ext;
|
|
|
|
gint copy_len;
|
|
|
|
gint number;
|
|
|
|
gchar *new_name;
|
|
|
|
|
|
|
|
ext = strrchr (name, '#');
|
|
|
|
copy_len = strlen (_("copy"));
|
|
|
|
|
|
|
|
if ((strlen (name) >= copy_len &&
|
|
|
|
strcmp (&name[strlen (name) - copy_len], _("copy")) == 0) ||
|
|
|
|
(ext && (number = atoi (ext + 1)) > 0 &&
|
|
|
|
((gint) (log10 (number) + 1)) == strlen (ext + 1)))
|
|
|
|
{
|
|
|
|
/* don't have redundant "copy"s */
|
|
|
|
new_name = g_strdup (name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_name = g_strdup_printf (_("%s copy"), name);
|
|
|
|
}
|
|
|
|
|
2006-04-07 10:51:22 +00:00
|
|
|
gimp_object_take_name (GIMP_OBJECT (new_data), new_name);
|
2002-12-02 13:39:09 +00:00
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
gimp_container_add (priv->container, GIMP_OBJECT (new_data));
|
2002-12-02 13:39:09 +00:00
|
|
|
g_object_unref (new_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new_data;
|
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
static gboolean
|
|
|
|
gimp_data_factory_real_data_delete (GimpDataFactory *factory,
|
|
|
|
GimpData *data,
|
|
|
|
gboolean delete_from_disk,
|
|
|
|
GError **error)
|
2004-06-01 21:37:36 +00:00
|
|
|
{
|
2018-06-04 13:12:14 +02:00
|
|
|
if (delete_from_disk && gimp_data_get_file (data))
|
|
|
|
return gimp_data_delete_from_disk (data, error);
|
2004-06-01 21:37:36 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
return TRUE;
|
2004-06-01 21:37:36 +00:00
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
2018-06-03 23:16:29 +02:00
|
|
|
/* Always freeze() and thaw() the container around initialization,
|
|
|
|
* even if no_data, the thaw() will implicitly make GimpContext
|
|
|
|
* create the standard data that serves as fallback.
|
|
|
|
*/
|
|
|
|
gimp_container_freeze (priv->container);
|
|
|
|
|
|
|
|
if (! no_data)
|
|
|
|
{
|
|
|
|
if (priv->gimp->be_verbose)
|
|
|
|
{
|
|
|
|
const gchar *name = gimp_object_get_name (factory);
|
|
|
|
|
|
|
|
g_print ("Loading '%s' data\n", name ? name : "???");
|
|
|
|
}
|
|
|
|
|
|
|
|
GIMP_DATA_FACTORY_GET_CLASS (factory)->data_init (factory, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_container_thaw (priv->container);
|
2018-06-02 21:50:34 +02:00
|
|
|
|
|
|
|
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);
|
2018-07-02 20:33:59 +02:00
|
|
|
|
|
|
|
signal_name = g_strdup_printf ("notify::%s", priv->ext_property_name);
|
|
|
|
g_signal_connect_object (priv->gimp->extension_manager, signal_name,
|
|
|
|
G_CALLBACK (gimp_data_factory_path_notify),
|
|
|
|
factory, 0);
|
|
|
|
g_free (signal_name);
|
2018-06-02 21:50:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
static void
|
|
|
|
gimp_data_factory_data_free_foreach (GimpDataFactory *factory,
|
|
|
|
GimpData *data,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gimp_container_remove (factory->priv->container, GIMP_OBJECT (data));
|
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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))
|
2018-06-04 13:12:14 +02:00
|
|
|
{
|
|
|
|
gimp_container_freeze (factory->priv->container);
|
|
|
|
|
|
|
|
gimp_data_factory_data_foreach (factory, TRUE,
|
|
|
|
gimp_data_factory_data_free_foreach,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
gimp_container_thaw (factory->priv->container);
|
|
|
|
}
|
2018-06-02 21:50:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
GimpAsyncSet *
|
|
|
|
gimp_data_factory_get_async_set (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
2018-06-03 22:28:00 +02:00
|
|
|
return factory->priv->async_set;
|
2018-06-02 21:50:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gimp_data_factory_data_wait (GimpDataFactory *factory)
|
|
|
|
{
|
2018-06-03 22:28:00 +02:00
|
|
|
GimpDataFactoryPrivate *priv;
|
|
|
|
GimpWaitable *waitable;
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
|
|
|
|
|
2018-06-03 22:28:00 +02:00
|
|
|
priv = GET_PRIVATE (factory);
|
|
|
|
|
|
|
|
/* don't allow cancellation for now */
|
|
|
|
waitable = gimp_uncancelable_waitable_new (GIMP_WAITABLE (priv->async_set));
|
|
|
|
|
|
|
|
gimp_wait (priv->gimp, waitable,
|
|
|
|
_("Loading fonts (this may take a while...)"));
|
|
|
|
|
|
|
|
g_object_unref (waitable);
|
|
|
|
|
|
|
|
return TRUE;
|
2018-06-02 21:50:34 +02:00
|
|
|
}
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
gboolean
|
|
|
|
gimp_data_factory_has_data_new_func (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
|
|
|
|
|
|
|
|
return factory->priv->data_new_func != NULL;
|
|
|
|
}
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
GimpData *
|
|
|
|
gimp_data_factory_data_new (GimpDataFactory *factory,
|
|
|
|
GimpContext *context,
|
|
|
|
const gchar *name)
|
|
|
|
{
|
2018-06-04 13:12:14 +02:00
|
|
|
GimpDataFactoryPrivate *priv;
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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);
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
priv = GET_PRIVATE (factory);
|
|
|
|
|
|
|
|
if (priv->data_new_func)
|
|
|
|
{
|
|
|
|
GimpData *data = priv->data_new_func (context, name);
|
|
|
|
|
|
|
|
if (data)
|
|
|
|
{
|
|
|
|
gimp_container_add (priv->container, GIMP_OBJECT (data));
|
|
|
|
g_object_unref (data);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_warning ("%s: GimpDataFactory::data_new_func() returned NULL",
|
|
|
|
G_STRFUNC);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
GimpData *
|
|
|
|
gimp_data_factory_data_get_standard (GimpDataFactory *factory,
|
|
|
|
GimpContext *context)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
|
|
|
|
|
|
|
if (factory->priv->data_get_standard_func)
|
|
|
|
return factory->priv->data_get_standard_func (context);
|
|
|
|
|
|
|
|
return NULL;
|
2018-06-02 21:50:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2018-06-04 13:12:14 +02:00
|
|
|
GimpDataFactoryPrivate *priv;
|
|
|
|
gboolean retval = TRUE;
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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);
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
priv = GET_PRIVATE (factory);
|
2018-06-02 21:50:34 +02:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
if (gimp_container_have (priv->container, GIMP_OBJECT (data)))
|
|
|
|
{
|
|
|
|
g_object_ref (data);
|
2001-02-14 01:42:12 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
gimp_container_remove (priv->container, GIMP_OBJECT (data));
|
2001-02-14 01:42:12 +00:00
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
retval = GIMP_DATA_FACTORY_GET_CLASS (factory)->data_delete (factory, data,
|
|
|
|
delete_from_disk,
|
|
|
|
error);
|
|
|
|
|
|
|
|
g_object_unref (data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
2001-02-14 01:42:12 +00:00
|
|
|
}
|
|
|
|
|
2004-01-28 21:53:50 +00:00
|
|
|
gboolean
|
2006-10-09 18:49:15 +00:00
|
|
|
gimp_data_factory_data_save_single (GimpDataFactory *factory,
|
|
|
|
GimpData *data,
|
|
|
|
GError **error)
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), FALSE);
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA (data), FALSE);
|
2006-10-09 18:49:15 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2009-10-31 18:48:38 +01:00
|
|
|
if (! gimp_data_is_dirty (data))
|
2004-01-28 21:53:50 +00:00
|
|
|
return TRUE;
|
|
|
|
|
2014-07-01 01:19:35 +02:00
|
|
|
if (! gimp_data_get_file (data))
|
2004-10-04 09:39:27 +00:00
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
GFile *writable_dir;
|
2009-10-30 21:31:13 +01:00
|
|
|
GError *my_error = NULL;
|
|
|
|
|
|
|
|
writable_dir = gimp_data_factory_get_save_dir (factory, &my_error);
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2004-10-04 09:39:27 +00:00
|
|
|
if (! writable_dir)
|
2006-10-09 18:49:15 +00:00
|
|
|
{
|
|
|
|
g_set_error (error, GIMP_DATA_ERROR, 0,
|
|
|
|
_("Failed to save data:\n\n%s"),
|
2009-10-30 21:31:13 +01:00
|
|
|
my_error->message);
|
|
|
|
g_clear_error (&my_error);
|
|
|
|
|
2006-10-09 18:49:15 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2004-10-04 09:39:27 +00:00
|
|
|
gimp_data_create_filename (data, writable_dir);
|
|
|
|
|
2014-07-26 16:37:30 +02:00
|
|
|
g_object_unref (writable_dir);
|
2004-10-04 09:39:27 +00:00
|
|
|
}
|
|
|
|
|
2009-10-31 18:48:38 +01:00
|
|
|
if (! gimp_data_is_writable (data))
|
2004-10-04 09:39:27 +00:00
|
|
|
return FALSE;
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2018-06-10 15:52:06 +02:00
|
|
|
if (factory->priv->gimp->be_verbose)
|
|
|
|
{
|
|
|
|
GFile *file = gimp_data_get_file (data);
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
g_print ("Writing dirty data '%s'\n",
|
|
|
|
gimp_file_get_utf8_name (file));
|
|
|
|
}
|
|
|
|
|
2006-10-09 18:49:15 +00:00
|
|
|
if (! gimp_data_save (data, error))
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
|
|
|
/* check if there actually was an error (no error
|
|
|
|
* means the data class does not implement save)
|
|
|
|
*/
|
2006-10-09 18:49:15 +00:00
|
|
|
if (! error)
|
|
|
|
g_set_error (error, GIMP_DATA_ERROR, 0,
|
|
|
|
_("Failed to save data:\n\n%s"),
|
|
|
|
"Data class does not implement saving");
|
2004-01-28 21:53:50 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2018-06-04 12:44:50 +02:00
|
|
|
void
|
|
|
|
gimp_data_factory_data_foreach (GimpDataFactory *factory,
|
|
|
|
gboolean skip_internal,
|
|
|
|
GimpDataForeachFunc callback,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
|
|
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-04 13:12:14 +02:00
|
|
|
Gimp *
|
|
|
|
gimp_data_factory_get_gimp (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
return factory->priv->gimp;
|
|
|
|
}
|
|
|
|
|
2012-10-07 00:17:01 +02:00
|
|
|
GType
|
|
|
|
gimp_data_factory_get_data_type (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), G_TYPE_NONE);
|
|
|
|
|
|
|
|
return gimp_container_get_children_type (factory->priv->container);
|
|
|
|
}
|
|
|
|
|
2008-12-19 21:58:17 +00:00
|
|
|
GimpContainer *
|
|
|
|
gimp_data_factory_get_container (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
return factory->priv->container;
|
|
|
|
}
|
|
|
|
|
2009-08-11 20:38:12 +02:00
|
|
|
GimpContainer *
|
|
|
|
gimp_data_factory_get_container_obsolete (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
return factory->priv->container_obsolete;
|
|
|
|
}
|
|
|
|
|
2018-06-03 20:42:21 +02:00
|
|
|
GList *
|
|
|
|
gimp_data_factory_get_data_path (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
|
|
|
|
gchar *path = NULL;
|
|
|
|
GList *list = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
g_object_get (priv->gimp->config,
|
|
|
|
priv->path_property_name, &path,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (path)
|
|
|
|
{
|
|
|
|
list = gimp_config_path_expand_to_files (path, NULL);
|
|
|
|
g_free (path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
GList *
|
|
|
|
gimp_data_factory_get_data_path_writable (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
|
|
|
|
gchar *path = NULL;
|
|
|
|
GList *list = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
g_object_get (priv->gimp->config,
|
|
|
|
priv->writable_property_name, &path,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (path)
|
|
|
|
{
|
|
|
|
list = gimp_config_path_expand_to_files (path, NULL);
|
|
|
|
g_free (path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2018-07-02 20:33:59 +02:00
|
|
|
const GList *
|
|
|
|
gimp_data_factory_get_data_path_ext (GimpDataFactory *factory)
|
|
|
|
{
|
|
|
|
GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
|
|
|
|
GList *list = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
|
|
|
|
|
|
|
|
g_object_get (priv->gimp->extension_manager,
|
|
|
|
priv->ext_property_name, &list,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2004-01-28 21:53:50 +00:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
2018-06-02 21:50:34 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-07-26 16:37:30 +02:00
|
|
|
static GFile *
|
2009-10-30 21:31:13 +01:00
|
|
|
gimp_data_factory_get_save_dir (GimpDataFactory *factory,
|
|
|
|
GError **error)
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
GList *path;
|
|
|
|
GList *writable_path;
|
|
|
|
GFile *writable_dir = NULL;
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2018-06-03 20:42:21 +02:00
|
|
|
path = gimp_data_factory_get_data_path (factory);
|
|
|
|
writable_path = gimp_data_factory_get_data_path_writable (factory);
|
2004-01-28 21:53:50 +00:00
|
|
|
|
2009-10-30 21:31:13 +01:00
|
|
|
if (writable_path)
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
GList *list;
|
|
|
|
gboolean found_any = FALSE;
|
2009-10-30 21:31:13 +01:00
|
|
|
|
2014-07-26 16:37:30 +02:00
|
|
|
for (list = writable_path; list; list = g_list_next (list))
|
2004-01-28 21:53:50 +00:00
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
GList *found = g_list_find_custom (path, list->data,
|
|
|
|
(GCompareFunc) gimp_file_compare);
|
2009-10-30 21:31:13 +01:00
|
|
|
if (found)
|
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
GFile *dir = found->data;
|
2009-10-30 21:31:13 +01:00
|
|
|
|
|
|
|
found_any = TRUE;
|
|
|
|
|
2014-07-26 16:37:30 +02:00
|
|
|
if (g_file_query_file_type (dir, G_FILE_QUERY_INFO_NONE,
|
|
|
|
NULL) != G_FILE_TYPE_DIRECTORY)
|
2009-10-30 21:31:13 +01:00
|
|
|
{
|
|
|
|
/* error out only if this is the last chance */
|
|
|
|
if (! list->next)
|
|
|
|
{
|
|
|
|
g_set_error (error, GIMP_DATA_ERROR, 0,
|
|
|
|
_("You have a writable data folder "
|
|
|
|
"configured (%s), but this folder does "
|
|
|
|
"not exist. Please create the folder or "
|
2013-12-10 14:48:08 +13:00
|
|
|
"fix your configuration in the "
|
2009-12-26 20:46:19 +01:00
|
|
|
"Preferences dialog's 'Folders' section."),
|
2014-07-26 16:37:30 +02:00
|
|
|
gimp_file_get_utf8_name (dir));
|
2009-10-30 21:31:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-26 16:37:30 +02:00
|
|
|
writable_dir = g_object_ref (dir);
|
2009-10-30 21:31:13 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-01-28 21:53:50 +00:00
|
|
|
}
|
2009-10-30 21:31:13 +01:00
|
|
|
|
|
|
|
if (! writable_dir && ! found_any)
|
|
|
|
{
|
|
|
|
g_set_error (error, GIMP_DATA_ERROR, 0,
|
|
|
|
_("You have a writable data folder configured, but this "
|
2009-12-26 20:46:19 +01:00
|
|
|
"folder is not part of your data search path. You "
|
|
|
|
"probably edited the gimprc file manually, "
|
|
|
|
"please fix it in the Preferences dialog's 'Folders' "
|
2009-10-30 21:31:13 +01:00
|
|
|
"section."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_set_error (error, GIMP_DATA_ERROR, 0,
|
|
|
|
_("You don't have any writable data folder configured."));
|
2004-01-28 21:53:50 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 18:38:01 +02:00
|
|
|
g_list_free_full (path, (GDestroyNotify) g_object_unref);
|
2014-07-26 16:37:30 +02:00
|
|
|
g_list_free_full (writable_path, (GDestroyNotify) g_object_unref);
|
2004-01-28 21:53:50 +00:00
|
|
|
|
|
|
|
return writable_dir;
|
|
|
|
}
|