From e364267010db1242757f67ad9c7aef5abc2c3103 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sat, 11 Dec 2010 15:00:48 +0100
Subject: Add a "modified" property to LdDocument.
The property is set to TRUE whenever the document changes.
The user may set it back to FALSE with ld_document_set_modified().
Also don't emit the "changed" signal when nothing has happened.
---
src/ld-document.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++------
src/ld-document.h | 6 +++
2 files changed, 148 insertions(+), 16 deletions(-)
diff --git a/src/ld-document.c b/src/ld-document.c
index dbd367e..54c0ff9 100644
--- a/src/ld-document.c
+++ b/src/ld-document.c
@@ -27,12 +27,15 @@
/*
* LdDocumentPrivate:
+ * @modified: Whether the document has been modified.
* @objects: All the objects in the document.
* @selection: All currently selected objects.
* @connections: Connections between objects.
*/
struct _LdDocumentPrivate
{
+ gboolean modified;
+
GSList *objects;
GSList *selection;
GSList *connections;
@@ -40,18 +43,47 @@ struct _LdDocumentPrivate
G_DEFINE_TYPE (LdDocument, ld_document, G_TYPE_OBJECT);
-static void
-ld_document_finalize (GObject *gobject);
+enum
+{
+ PROP_0,
+ PROP_MODIFIED
+};
+
+static void ld_document_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec);
+static void ld_document_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec);
+static void ld_document_dispose (GObject *gobject);
+static void ld_document_finalize (GObject *gobject);
+
+static void ld_document_real_changed (LdDocument *self);
+static void ld_document_clear_internal (LdDocument *self);
static void
ld_document_class_init (LdDocumentClass *klass)
{
GObjectClass *object_class;
+ GParamSpec *pspec;
object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = ld_document_get_property;
+ object_class->set_property = ld_document_set_property;
+ object_class->dispose = ld_document_dispose;
object_class->finalize = ld_document_finalize;
+ klass->changed = ld_document_real_changed;
+
+/**
+ * LdDocument:modified:
+ *
+ * Whether the document has been modified.
+ */
+ pspec = g_param_spec_boolean ("modified", "Modified",
+ "Whether the document has been modified.",
+ FALSE, G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_MODIFIED, pspec);
+
/**
* LdDocument::changed:
* @document: The document object.
@@ -61,7 +93,8 @@ ld_document_class_init (LdDocumentClass *klass)
klass->changed_signal = g_signal_new
("changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
- 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ G_STRUCT_OFFSET (LdDocumentClass, changed), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_type_class_add_private (klass, sizeof (LdDocumentPrivate));
}
@@ -74,17 +107,67 @@ ld_document_init (LdDocument *self)
}
static void
-ld_document_finalize (GObject *gobject)
+ld_document_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ LdDocument *self;
+
+ self = LD_DOCUMENT (object);
+ switch (property_id)
+ {
+ case PROP_MODIFIED:
+ g_value_set_boolean (value, ld_document_get_modified (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ld_document_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ LdDocument *self;
+
+ self = LD_DOCUMENT (object);
+ switch (property_id)
+ {
+ case PROP_MODIFIED:
+ ld_document_set_modified (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+ld_document_dispose (GObject *gobject)
{
LdDocument *self;
self = LD_DOCUMENT (gobject);
- ld_document_clear (self);
+ ld_document_clear_internal (self);
+ /* Chain up to the parent class. */
+ G_OBJECT_CLASS (ld_document_parent_class)->dispose (gobject);
+}
+
+static void
+ld_document_finalize (GObject *gobject)
+{
/* Chain up to the parent class. */
G_OBJECT_CLASS (ld_document_parent_class)->finalize (gobject);
}
+static void
+ld_document_real_changed (LdDocument *self)
+{
+ g_return_if_fail (LD_IS_DOCUMENT (self));
+
+ ld_document_set_modified (self, TRUE);
+}
+
+
/**
* ld_document_new:
*
@@ -107,6 +190,21 @@ ld_document_clear (LdDocument *self)
{
g_return_if_fail (LD_IS_DOCUMENT (self));
+ ld_document_clear_internal (self);
+
+ g_signal_emit (self,
+ LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
+}
+
+/*
+ * ld_document_clear_internal:
+ * @self: An #LdDocument object.
+ *
+ * Do the same what ld_document_clear() does but don't emit signals.
+ */
+static void
+ld_document_clear_internal (LdDocument *self)
+{
g_slist_free (self->priv->connections);
self->priv->connections = NULL;
@@ -117,9 +215,6 @@ ld_document_clear (LdDocument *self)
g_slist_foreach (self->priv->objects, (GFunc) g_object_unref, NULL);
g_slist_free (self->priv->objects);
self->priv->objects = NULL;
-
- g_signal_emit (self,
- LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
/**
@@ -162,6 +257,33 @@ ld_document_save_to_file (LdDocument *self,
return FALSE;
}
+/**
+ * ld_document_get_modified:
+ * @self: An #LdDocument object.
+ *
+ * Return value: The modification status of document.
+ */
+gboolean
+ld_document_get_modified (LdDocument *self)
+{
+ g_return_val_if_fail (LD_IS_DOCUMENT (self), FALSE);
+ return self->priv->modified;
+}
+
+/**
+ * ld_document_set_modified:
+ * @self: An #LdDocument object.
+ * @value: Whether the document has been modified.
+ *
+ * Set the modification status of document.
+ */
+void
+ld_document_set_modified (LdDocument *self, gboolean value)
+{
+ g_return_if_fail (LD_IS_DOCUMENT (self));
+ self->priv->modified = value;
+}
+
/**
* ld_document_get_objects:
* @self: An #LdDocument object.
@@ -196,9 +318,10 @@ ld_document_insert_object (LdDocument *self, LdDocumentObject *object, gint pos)
self->priv->objects =
g_slist_insert (self->priv->objects, object, pos);
g_object_ref (object);
+
+ g_signal_emit (self,
+ LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
- g_signal_emit (self,
- LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
/**
@@ -220,9 +343,10 @@ ld_document_remove_object (LdDocument *self, LdDocumentObject *object)
self->priv->objects = g_slist_remove (self->priv->objects, object);
g_object_unref (object);
+
+ g_signal_emit (self,
+ LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
- g_signal_emit (self,
- LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
/**
@@ -260,9 +384,10 @@ ld_document_selection_add (LdDocument *self, LdDocumentObject *object, gint pos)
self->priv->selection =
g_slist_insert (self->priv->selection, object, pos);
g_object_ref (object);
+
+ g_signal_emit (self,
+ LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
- g_signal_emit (self,
- LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
/**
@@ -282,7 +407,8 @@ ld_document_selection_remove (LdDocument *self, LdDocumentObject *object)
{
self->priv->selection = g_slist_remove (self->priv->selection, object);
g_object_unref (object);
+
+ g_signal_emit (self,
+ LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
- g_signal_emit (self,
- LD_DOCUMENT_GET_CLASS (self)->changed_signal, 0);
}
diff --git a/src/ld-document.h b/src/ld-document.h
index 12d59cb..a27fe23 100644
--- a/src/ld-document.h
+++ b/src/ld-document.h
@@ -48,7 +48,10 @@ struct _LdDocumentClass
/*< private >*/
GObjectClass parent_class;
+ /* FIXME: Add a selection_changed signal? */
guint changed_signal;
+
+ void (*changed) (LdDocument *self);
};
@@ -61,6 +64,9 @@ gboolean ld_document_load_from_file (LdDocument *self,
gboolean ld_document_save_to_file (LdDocument *self,
const gchar *filename, GError *error);
+gboolean ld_document_get_modified (LdDocument *self);
+void ld_document_set_modified (LdDocument *self, gboolean value);
+
GSList *ld_document_get_objects (LdDocument *self);
void ld_document_insert_object (LdDocument *self,
LdDocumentObject *object, gint pos);
--
cgit v1.2.3-70-g09d2