[gimp] app: make sure name references to GimpData objects are serialized correctly
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: make sure name references to GimpData objects are serialized correctly
- Date: Thu, 26 Feb 2015 21:32:30 +0000 (UTC)
commit 9be16e00bccc3f5c8ee47b998ab10df04d3f86e1
Author: Michael Natterer <mitch gimp org>
Date: Thu Feb 26 22:17:45 2015 +0100
app: make sure name references to GimpData objects are serialized correctly
They were also serialized correctly before, but only because many
GimpData objects were (bogusly) always dirty after loading, which
caused them to always be written do disk on exit. This commit fixes
this problem and updates by-name references explicitly as things are
renamed, instead of relying on bugs.
Add gimp_data_factory_data_clean() which clears the dirty flags from
all a factory's objects. Call the new function on all factories at the
end of gimp_restore(), when all data has been loaded. This might be
total overkill, but ensures that everything is clean in the beginning.
Add new signal GimpContext::prop_name_changed() which is emitted when
any of the context's object properties (brush, gradient etc) is
renamed.
In GimpToolPreset, connect to the new signal and dirty the preset if a
relevant object propery was renamed, making sure the preset is saved
to disk later. Also optmize updates quite a bit by ignoring
notifications on tool option properties that are irrelevant to the
preset.
This might or might not address the issues discussed in bug #739487.
app/core/gimp.c | 11 ++++++
app/core/gimpcontext.c | 48 +++++++++++++++++++++++++++++
app/core/gimpcontext.h | 3 ++
app/core/gimpdatafactory.c | 73 +++++++++++++++++++++++++++++---------------
app/core/gimpdatafactory.h | 1 +
app/core/gimptoolpreset.c | 44 ++++++++++++++++++++++++++-
6 files changed, 154 insertions(+), 26 deletions(-)
---
diff --git a/app/core/gimp.c b/app/core/gimp.c
index d1e00a6..7571f69 100644
--- a/app/core/gimp.c
+++ b/app/core/gimp.c
@@ -1101,6 +1101,17 @@ gimp_restore (Gimp *gimp,
gimp_data_factory_get_container (gimp->tool_preset_factory));
g_signal_emit (gimp, gimp_signals[RESTORE], 0, status_callback);
+
+ /* when done, make sure everything is clean, to clean out dirty
+ * states from data object which reference each other and got
+ * dirtied by loading the referenced object
+ */
+ gimp_data_factory_data_clean (gimp->brush_factory);
+ gimp_data_factory_data_clean (gimp->dynamics_factory);
+ gimp_data_factory_data_clean (gimp->pattern_factory);
+ gimp_data_factory_data_clean (gimp->palette_factory);
+ gimp_data_factory_data_clean (gimp->gradient_factory);
+ gimp_data_factory_data_clean (gimp->tool_preset_factory);
}
/**
diff --git a/app/core/gimpcontext.c b/app/core/gimpcontext.c
index f962f9c..02e6f1f 100644
--- a/app/core/gimpcontext.c
+++ b/app/core/gimpcontext.c
@@ -301,6 +301,7 @@ enum
BUFFER_CHANGED,
IMAGEFILE_CHANGED,
TEMPLATE_CHANGED,
+ PROP_NAME_CHANGED,
LAST_SIGNAL
};
@@ -553,6 +554,16 @@ gimp_context_class_init (GimpContextClass *klass)
G_TYPE_NONE, 1,
GIMP_TYPE_TEMPLATE);
+ gimp_context_signals[PROP_NAME_CHANGED] =
+ g_signal_new ("prop-name-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpContextClass, prop_name_changed),
+ NULL, NULL,
+ gimp_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
object_class->constructed = gimp_context_constructed;
object_class->set_property = gimp_context_set_property;
object_class->get_property = gimp_context_get_property;
@@ -579,6 +590,7 @@ gimp_context_class_init (GimpContextClass *klass)
klass->buffer_changed = NULL;
klass->imagefile_changed = NULL;
klass->template_changed = NULL;
+ klass->prop_name_changed = NULL;
gimp_context_prop_types[GIMP_CONTEXT_PROP_IMAGE] = GIMP_TYPE_IMAGE;
gimp_context_prop_types[GIMP_CONTEXT_PROP_TOOL] = GIMP_TYPE_TOOL_INFO;
@@ -2013,6 +2025,9 @@ gimp_context_tool_dirty (GimpToolInfo *tool_info,
{
g_free (context->tool_name);
context->tool_name = g_strdup (gimp_object_get_name (tool_info));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_TOOL);
}
/* the global tool list is there again after refresh */
@@ -2137,6 +2152,9 @@ gimp_context_paint_info_dirty (GimpPaintInfo *paint_info,
{
g_free (context->paint_name);
context->paint_name = g_strdup (gimp_object_get_name (paint_info));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_PAINT_INFO);
}
/* the global paint info list is there again after refresh */
@@ -2548,6 +2566,9 @@ gimp_context_brush_dirty (GimpBrush *brush,
{
g_free (context->brush_name);
context->brush_name = g_strdup (gimp_object_get_name (brush));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_BRUSH);
}
/* the global brush list is there again after refresh */
@@ -2668,6 +2689,9 @@ gimp_context_dynamics_dirty (GimpDynamics *dynamics,
{
g_free (context->dynamics_name);
context->dynamics_name = g_strdup (gimp_object_get_name (dynamics));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_DYNAMICS);
}
static void
@@ -2786,6 +2810,9 @@ gimp_context_pattern_dirty (GimpPattern *pattern,
{
g_free (context->pattern_name);
context->pattern_name = g_strdup (gimp_object_get_name (pattern));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_PATTERN);
}
/* the global pattern list is there again after refresh */
@@ -2906,6 +2933,9 @@ gimp_context_gradient_dirty (GimpGradient *gradient,
{
g_free (context->gradient_name);
context->gradient_name = g_strdup (gimp_object_get_name (gradient));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_GRADIENT);
}
/* the global gradient list is there again after refresh */
@@ -3026,6 +3056,9 @@ gimp_context_palette_dirty (GimpPalette *palette,
{
g_free (context->palette_name);
context->palette_name = g_strdup (gimp_object_get_name (palette));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_PALETTE);
}
/* the global palette list is there again after refresh */
@@ -3146,6 +3179,9 @@ gimp_context_tool_preset_dirty (GimpToolPreset *tool_preset,
{
g_free (context->tool_preset_name);
context->tool_preset_name = g_strdup (gimp_object_get_name (tool_preset));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_TOOL_PRESET);
}
static void
@@ -3292,6 +3328,9 @@ gimp_context_font_dirty (GimpFont *font,
{
g_free (context->font_name);
context->font_name = g_strdup (gimp_object_get_name (font));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_FONT);
}
/* the global font list is there again after refresh */
@@ -3412,6 +3451,9 @@ gimp_context_buffer_dirty (GimpBuffer *buffer,
{
g_free (context->buffer_name);
context->buffer_name = g_strdup (gimp_object_get_name (buffer));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_BUFFER);
}
/* the global buffer list is there again after refresh */
@@ -3535,6 +3577,9 @@ gimp_context_imagefile_dirty (GimpImagefile *imagefile,
{
g_free (context->imagefile_name);
context->imagefile_name = g_strdup (gimp_object_get_name (imagefile));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_IMAGEFILE);
}
/* the global imagefile list is there again after refresh */
@@ -3658,6 +3703,9 @@ gimp_context_template_dirty (GimpTemplate *template,
{
g_free (context->template_name);
context->template_name = g_strdup (gimp_object_get_name (template));
+
+ g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
+ GIMP_CONTEXT_PROP_TEMPLATE);
}
/* the global template list is there again after refresh */
diff --git a/app/core/gimpcontext.h b/app/core/gimpcontext.h
index 48623ee..0406a95 100644
--- a/app/core/gimpcontext.h
+++ b/app/core/gimpcontext.h
@@ -143,6 +143,9 @@ struct _GimpContextClass
GimpImagefile *imagefile);
void (* template_changed) (GimpContext *context,
GimpTemplate *template);
+
+ void (* prop_name_changed) (GimpContext *context,
+ GimpContextPropType prop);
};
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index 2351cae..81d1486 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -71,31 +71,36 @@ struct _GimpDataFactoryPriv
};
-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_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,
- guint64 mtime,
- GFile *top_directory);
+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,
+ guint64 mtime,
+ GFile *top_directory);
G_DEFINE_TYPE (GimpDataFactory, gimp_data_factory, GIMP_TYPE_OBJECT)
@@ -252,6 +257,24 @@ gimp_data_factory_data_init (GimpDataFactory *factory,
}
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);
+}
+
+static void
gimp_data_factory_refresh_cache_add (GimpDataFactory *factory,
GimpData *data,
gpointer user_data)
diff --git a/app/core/gimpdatafactory.h b/app/core/gimpdatafactory.h
index edc3f16..8456464 100644
--- a/app/core/gimpdatafactory.h
+++ b/app/core/gimpdatafactory.h
@@ -82,6 +82,7 @@ GimpDataFactory * gimp_data_factory_new (Gimp *
void gimp_data_factory_data_init (GimpDataFactory *factory,
GimpContext *context,
gboolean no_data);
+void gimp_data_factory_data_clean (GimpDataFactory *factory);
void gimp_data_factory_data_refresh (GimpDataFactory *factory,
GimpContext *context);
void gimp_data_factory_data_save (GimpDataFactory *factory);
diff --git a/app/core/gimptoolpreset.c b/app/core/gimptoolpreset.c
index b4c6003..f47a89a 100644
--- a/app/core/gimptoolpreset.c
+++ b/app/core/gimptoolpreset.c
@@ -90,6 +90,9 @@ static void gimp_tool_preset_set_options (GimpToolPreset *pr
static void gimp_tool_preset_options_notify (GObject *tool_options,
const GParamSpec *pspec,
GimpToolPreset *preset);
+static void gimp_tool_preset_options_prop_name_changed (GimpContext *tool_options,
+ GimpContextPropType prop,
+ GimpToolPreset *preset);
G_DEFINE_TYPE_WITH_CODE (GimpToolPreset, gimp_tool_preset, GIMP_TYPE_DATA,
@@ -449,6 +452,10 @@ gimp_tool_preset_set_options (GimpToolPreset *preset,
gimp_tool_preset_options_notify,
preset);
+ g_signal_handlers_disconnect_by_func (preset->tool_options,
+ gimp_tool_preset_options_prop_name_changed,
+ preset);
+
g_object_unref (preset->tool_options);
preset->tool_options = NULL;
}
@@ -491,6 +498,10 @@ gimp_tool_preset_set_options (GimpToolPreset *preset,
g_signal_connect (preset->tool_options, "notify",
G_CALLBACK (gimp_tool_preset_options_notify),
preset);
+
+ g_signal_connect (preset->tool_options, "prop-name-changed",
+ G_CALLBACK (gimp_tool_preset_options_prop_name_changed),
+ preset);
}
g_object_notify (G_OBJECT (preset), "tool-options");
@@ -501,7 +512,38 @@ gimp_tool_preset_options_notify (GObject *tool_options,
const GParamSpec *pspec,
GimpToolPreset *preset)
{
- g_object_notify (G_OBJECT (preset), "tool-options");
+ if (pspec->owner_type == GIMP_TYPE_CONTEXT)
+ {
+ GimpContextPropMask serialize_props;
+
+ serialize_props =
+ gimp_context_get_serialize_properties (GIMP_CONTEXT (tool_options));
+
+ if ((1 << pspec->param_id) & serialize_props)
+ {
+ g_object_notify (G_OBJECT (preset), "tool-options");
+ }
+ }
+ else if (pspec->flags & GIMP_CONFIG_PARAM_SERIALIZE)
+ {
+ g_object_notify (G_OBJECT (preset), "tool-options");
+ }
+}
+
+static void
+gimp_tool_preset_options_prop_name_changed (GimpContext *tool_options,
+ GimpContextPropType prop,
+ GimpToolPreset *preset)
+{
+ GimpContextPropMask serialize_props;
+
+ serialize_props =
+ gimp_context_get_serialize_properties (GIMP_CONTEXT (preset->tool_options));
+
+ if ((1 << prop) & serialize_props)
+ {
+ g_object_notify (G_OBJECT (preset), "tool-options");
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]