/* * ld-document.c * * This file is a part of logdiag. * Copyright Přemysl Janouch 2010. All rights reserved. * * See the file LICENSE for licensing information. * */ #include #include #include "config.h" #include "ld-document-object.h" #include "ld-document.h" /** * SECTION:ld-document * @short_description: A document object. * @see_also: #LdCanvas * * #LdDocument is a model for storing documents. */ /* * 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; }; G_DEFINE_TYPE (LdDocument, ld_document, G_TYPE_OBJECT); 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. * * Contents of the document have changed. */ klass->changed_signal = g_signal_new ("changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (LdDocumentClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_type_class_add_private (klass, sizeof (LdDocumentPrivate)); } static void ld_document_init (LdDocument *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, LD_TYPE_DOCUMENT, LdDocumentPrivate); } static void 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_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: * * Create an instance. */ LdDocument * ld_document_new (void) { return g_object_new (LD_TYPE_DOCUMENT, NULL); } /** * ld_document_clear: * @self: An #LdDocument object. * * Clear the whole document with it's objects and selection. */ void 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; g_slist_foreach (self->priv->selection, (GFunc) g_object_unref, NULL); g_slist_free (self->priv->selection); self->priv->selection = NULL; g_slist_foreach (self->priv->objects, (GFunc) g_object_unref, NULL); g_slist_free (self->priv->objects); self->priv->objects = NULL; } /** * ld_document_load_from_file: * @self: An #LdDocument object. * @filename: A filename. * @error: Return location for a GError, or NULL. * * Load a file into the document. * * Return value: TRUE if the file could be loaded, FALSE otherwise. */ gboolean ld_document_load_from_file (LdDocument *self, const gchar *filename, GError *error) { g_return_val_if_fail (LD_IS_DOCUMENT (self), FALSE); /* TODO */ return FALSE; } /** * ld_document_save_to_file: * @self: An #LdDocument object. * @filename: A filename. * @error: Return location for a GError, or NULL. * * Save the document into a file. * * Return value: TRUE if the document could be saved, FALSE otherwise. */ gboolean ld_document_save_to_file (LdDocument *self, const gchar *filename, GError *error) { g_return_val_if_fail (LD_IS_DOCUMENT (self), FALSE); /* TODO */ 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. * * Get a list of objects in the document. * You mustn't make any changes to the list. */ GSList * ld_document_get_objects (LdDocument *self) { g_return_val_if_fail (LD_IS_DOCUMENT (self), NULL); return self->priv->objects; } /** * ld_document_insert_object: * @self: An #LdDocument object. * @object: The object to be inserted. * @pos: The position at which the object is to be inserted. * Negative values will append to the end. * * Insert an object into the document. */ void ld_document_insert_object (LdDocument *self, LdDocumentObject *object, gint pos) { g_return_if_fail (LD_IS_DOCUMENT (self)); g_return_if_fail (LD_IS_DOCUMENT_OBJECT (object)); if (!g_slist_find (self->priv->objects, object)) { 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); } } /** * ld_document_remove_object: * @self: An #LdDocument object. * @object: The object to be removed. * * Remove an object from the document. */ void ld_document_remove_object (LdDocument *self, LdDocumentObject *object) { g_return_if_fail (LD_IS_DOCUMENT (self)); g_return_if_fail (LD_IS_DOCUMENT_OBJECT (object)); if (g_slist_find (self->priv->objects, object)) { ld_document_selection_remove (self, 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); } } /** * ld_document_get_selection: * @self: An #LdDocument object. * * Get a list of objects that are currently selected in the document. * You mustn't make any changes to the list. */ GSList * ld_document_get_selection (LdDocument *self) { g_return_val_if_fail (LD_IS_DOCUMENT (self), NULL); return self->priv->selection; } /** * ld_document_selection_add: * @self: An #LdDocument object. * @object: The object to be added to the selection. * @pos: The position at which the object is to be inserted. * Negative values will append to the end. * * Add an object to selection. */ void ld_document_selection_add (LdDocument *self, LdDocumentObject *object, gint pos) { g_return_if_fail (LD_IS_DOCUMENT (self)); g_return_if_fail (LD_IS_DOCUMENT_OBJECT (object)); if (!g_slist_find (self->priv->selection, object) && g_slist_find (self->priv->objects, object)) { 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); } } /** * ld_document_selection_remove: * @self: An #LdDocument object. * @object: The object to be removed from the selection. * * Remove an object from the selection. */ void ld_document_selection_remove (LdDocument *self, LdDocumentObject *object) { g_return_if_fail (LD_IS_DOCUMENT (self)); g_return_if_fail (LD_IS_DOCUMENT_OBJECT (object)); if (g_slist_find (self->priv->selection, 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); } }