[dia] change: setup a fundamental type for changes
- From: Zander <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] change: setup a fundamental type for changes
- Date: Thu, 3 Oct 2019 14:25:04 +0000 (UTC)
commit 0c6fd3c425f30f310655cd86360eaa0bf92be540
Author: Zander Brown <zbrown gnome org>
Date: Sat Sep 28 12:06:40 2019 +0100
change: setup a fundamental type for changes
This lets us get the benefits of GType without the unneeded overhead of GObject
app/dia-change.c | 288 ++++++++++++++++++++++++++++++++++++
app/dia-change.h | 76 ++++++++++
app/layer-editor/dia-layer-widget.c | 1 +
app/layer-editor/layer_dialog.c | 44 +++---
app/meson.build | 2 +
docs/dia-app/dia-app-docs.xml | 15 +-
6 files changed, 397 insertions(+), 29 deletions(-)
---
diff --git a/app/dia-change.c b/app/dia-change.c
new file mode 100644
index 00000000..b48689f1
--- /dev/null
+++ b/app/dia-change.c
@@ -0,0 +1,288 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1999 Alexander Larsson
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
+#include "dia-change.h"
+#include "diagram.h"
+
+static void
+dia_change_real_apply (DiaChange *self,
+ Diagram *diagram)
+{
+ g_critical ("%s doesn't implement apply", DIA_CHANGE_TYPE_NAME (self));
+}
+
+
+static void
+dia_change_real_revert (DiaChange *self,
+ Diagram *diagram)
+{
+ g_critical ("%s doesn't implement revert", DIA_CHANGE_TYPE_NAME (self));
+}
+
+
+static void
+dia_change_real_free (DiaChange *self)
+{
+}
+
+
+static void
+dia_change_base_class_init (DiaChangeClass *klass)
+{
+ klass->apply = dia_change_real_apply;
+ klass->revert = dia_change_real_revert;
+ klass->free = dia_change_real_free;
+}
+
+
+static void
+dia_change_class_finalize (DiaChangeClass *klass)
+{
+
+}
+
+
+static void
+dia_change_do_class_init (DiaChangeClass *klass)
+{
+}
+
+
+static void
+dia_change_init (DiaChange *self,
+ DiaChangeClass *klass)
+{
+ g_ref_count_init (&self->refs);
+}
+
+
+static void
+g_value_change_init (GValue *value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+
+static void
+g_value_change_free_value (GValue *value)
+{
+ if (value->data[0].v_pointer) {
+ dia_change_unref (value->data[0].v_pointer);
+ }
+}
+
+
+static void
+g_value_change_copy_value (const GValue *src_value,
+ GValue *dest_value)
+{
+ if (src_value->data[0].v_pointer) {
+ dest_value->data[0].v_pointer = dia_change_ref (src_value->data[0].v_pointer);
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+
+static gpointer
+g_value_change_peek_pointer (const GValue *value)
+{
+ return value->data[0].v_pointer;
+}
+
+
+static gchar*
+g_value_change_collect_value (GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ if (collect_values[0].v_pointer) {
+ DiaChange *change = collect_values[0].v_pointer;
+
+ if (change->g_type_instance.g_class == NULL) {
+ return g_strconcat ("invalid unclassed change pointer for value type '",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+ } else if (!g_value_type_compatible (DIA_CHANGE_TYPE (change), G_VALUE_TYPE (value))) {
+ return g_strconcat ("invalid change type '",
+ DIA_CHANGE_TYPE_NAME (change),
+ "' for value type '",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+ /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
+ value->data[0].v_pointer = dia_change_ref (change);
+ }
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+
+ return NULL;
+}
+
+
+static gchar*
+g_value_change_lcopy_value (const GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ DiaChange **change_p = collect_values[0].v_pointer;
+
+ if (!change_p) {
+ return g_strdup_printf ("value location for '%s' passed as NULL",
+ G_VALUE_TYPE_NAME (value));
+ }
+
+ if (!value->data[0].v_pointer) {
+ *change_p = NULL;
+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
+ *change_p = value->data[0].v_pointer;
+ } else {
+ *change_p = dia_change_ref (value->data[0].v_pointer);
+ }
+
+ return NULL;
+}
+
+
+static void
+g_value_change_transform_value (const GValue *src_value,
+ GValue *dest_value)
+{
+ if (src_value->data[0].v_pointer &&
+ g_type_is_a (DIA_CHANGE_TYPE (src_value->data[0].v_pointer), G_VALUE_TYPE (dest_value))) {
+ dest_value->data[0].v_pointer = dia_change_ref (src_value->data[0].v_pointer);
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+
+GType
+dia_change_get_type (void)
+{
+ static volatile GType type_id = 0;
+
+ if (g_once_init_enter (&type_id)) {
+ static const GTypeFundamentalInfo finfo = {
+ G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE,
+ };
+ GTypeInfo info = {
+ sizeof (DiaChangeClass),
+ (GBaseInitFunc) dia_change_base_class_init,
+ (GBaseFinalizeFunc) dia_change_class_finalize,
+ (GClassInitFunc) dia_change_do_class_init,
+ NULL, /* class_destroy */
+ NULL, /* class_data */
+ sizeof (DiaChange),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) dia_change_init,
+ NULL, /* value_table */
+ };
+ static const GTypeValueTable value_table = {
+ g_value_change_init, /* value_init */
+ g_value_change_free_value, /* value_free */
+ g_value_change_copy_value, /* value_copy */
+ g_value_change_peek_pointer, /* value_peek_pointer */
+ "p", /* collect_format */
+ g_value_change_collect_value, /* collect_value */
+ "p", /* lcopy_format */
+ g_value_change_lcopy_value, /* lcopy_value */
+ };
+ GType type;
+
+ info.value_table = &value_table;
+ type = g_type_register_fundamental (g_type_fundamental_next (),
+ g_intern_static_string ("DiaChange"),
+ &info,
+ &finfo,
+ 0);
+ g_value_register_transform_func (type,
+ type,
+ g_value_change_transform_value);
+
+ g_once_init_leave (&type_id, type);
+ }
+
+ return type_id;
+}
+
+
+gpointer
+dia_change_ref (gpointer self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ g_ref_count_inc (&((DiaChange *) self)->refs);
+
+ return self;
+}
+
+
+void
+dia_change_unref (gpointer self)
+{
+ g_return_if_fail (self != NULL);
+
+ if (g_ref_count_dec (&((DiaChange *) self)->refs)) {
+ DIA_CHANGE_GET_CLASS (self)->free (self);
+
+ g_type_free_instance (self);
+ }
+}
+
+
+gpointer
+dia_change_new (GType type)
+{
+ g_return_val_if_fail (DIA_TYPE_IS_CHANGE (type), NULL);
+
+ return g_type_create_instance (type);
+}
+
+
+void
+dia_change_apply (DiaChange *self,
+ Diagram *diagram)
+{
+ g_return_if_fail (self && DIA_IS_CHANGE (self));
+ g_return_if_fail (diagram && DIA_IS_DIAGRAM (diagram));
+
+ DIA_CHANGE_GET_CLASS (self)->apply (self, diagram);
+}
+
+
+void
+dia_change_revert (DiaChange *self,
+ Diagram *diagram)
+{
+ g_return_if_fail (self && DIA_IS_CHANGE (self));
+ g_return_if_fail (diagram && DIA_IS_DIAGRAM (diagram));
+
+ DIA_CHANGE_GET_CLASS (self)->revert (self, diagram);
+}
diff --git a/app/dia-change.h b/app/dia-change.h
new file mode 100644
index 00000000..f834dc19
--- /dev/null
+++ b/app/dia-change.h
@@ -0,0 +1,76 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1999 Alexander Larsson
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+// TODO: Fix the diagram.h cycle
+typedef struct _Diagram Diagram;
+
+G_BEGIN_DECLS
+
+GType dia_change_get_type (void);
+#define DIA_TYPE_CHANGE dia_change_get_type ()
+
+typedef struct _DiaChange DiaChange;
+typedef struct _DiaChangeClass DiaChangeClass;
+
+#define DIA_TYPE_IS_CHANGE(type) (G_TYPE_FUNDAMENTAL (type) == DIA_TYPE_CHANGE)
+#define DIA_CHANGE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DIA_TYPE_CHANGE, DiaChange))
+#define DIA_CHANGE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), DIA_TYPE_CHANGE, DiaChangeClass))
+#define DIA_IS_CHANGE(object) (G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE ((object), DIA_TYPE_CHANGE))
+#define DIA_IS_CHANGE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), DIA_TYPE_CHANGE))
+#define DIA_CHANGE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), DIA_TYPE_CHANGE, DiaChangeClass))
+#define DIA_CHANGE_TYPE(object) (G_TYPE_FROM_INSTANCE (object))
+#define DIA_CHANGE_TYPE_NAME(object) (g_type_name (DIA_CHANGE_TYPE (object)))
+#define DIA_CHANGE_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
+#define DIA_CHANGE_CLASS_NAME(class) (g_type_name (DIA_CHANGE_CLASS_TYPE (class)))
+#define G_VALUE_HOLDS_CHANGE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), DIA_TYPE_CHANGE))
+
+struct _DiaChange {
+ GTypeInstance g_type_instance;
+
+ grefcount refs;
+};
+
+struct _DiaChangeClass {
+ GTypeClass parent;
+
+ void (*apply) (DiaChange *change,
+ Diagram *dia);
+ void (*revert) (DiaChange *change,
+ Diagram *dia);
+ void (*free) (DiaChange *change);
+};
+
+void dia_change_unref (gpointer self);
+gpointer dia_change_ref (gpointer self);
+gpointer dia_change_new (GType type);
+void dia_change_apply (DiaChange *self,
+ Diagram *diagram);
+void dia_change_revert (DiaChange *self,
+ Diagram *diagram);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (DiaChange, dia_change_unref)
+
+G_END_DECLS
diff --git a/app/layer-editor/dia-layer-widget.c b/app/layer-editor/dia-layer-widget.c
index c0fd6f76..430ee5d8 100644
--- a/app/layer-editor/dia-layer-widget.c
+++ b/app/layer-editor/dia-layer-widget.c
@@ -22,6 +22,7 @@
#include "widgets.h"
#include "dia-layer-widget.h"
+#include "layer_dialog.h"
/* The connectability buttons don't quite behave the way they should.
* The shift-click behavior messes up the active layer.
diff --git a/app/layer-editor/layer_dialog.c b/app/layer-editor/layer_dialog.c
index 1f5ecbb5..d0f80052 100644
--- a/app/layer-editor/layer_dialog.c
+++ b/app/layer-editor/layer_dialog.c
@@ -137,30 +137,6 @@ layer_dialog_set_diagram (Diagram *dia)
}
}
-
-static void
-layer_dialog_edit_layer (Diagram *dia, DiaLayer *layer)
-{
- GtkWidget *dlg;
-
- g_return_if_fail (dia || layer);
-
- if (layer) {
- dlg = g_object_new (DIA_TYPE_LAYER_PROPERTIES,
- "layer", layer,
- "visible", TRUE,
- NULL);
- } else {
- dlg = g_object_new (DIA_TYPE_LAYER_PROPERTIES,
- "diagram", dia,
- "visible", TRUE,
- NULL);
- }
-
- gtk_widget_show (dlg);
-}
-
-
/******** layer changes: */
static void
@@ -345,9 +321,23 @@ undo_layer_visibility(Diagram *dia, DiaLayer *layer, gboolean exclusive)
* \brief edit a layers name, possibly also creating the layer
*/
void
-diagram_edit_layer(Diagram *dia, DiaLayer *layer)
+diagram_edit_layer (Diagram *dia, DiaLayer *layer)
{
- g_return_if_fail(dia != NULL);
+ GtkWidget *dlg;
+
+ g_return_if_fail (dia || layer);
- layer_dialog_edit_layer (layer ? NULL : dia, layer);
+ if (layer) {
+ dlg = g_object_new (DIA_TYPE_LAYER_PROPERTIES,
+ "layer", layer,
+ "visible", TRUE,
+ NULL);
+ } else {
+ dlg = g_object_new (DIA_TYPE_LAYER_PROPERTIES,
+ "diagram", dia,
+ "visible", TRUE,
+ NULL);
+ }
+
+ gtk_widget_show (dlg);
}
diff --git a/app/meson.build b/app/meson.build
index b0a94798..3dd80d71 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -7,6 +7,8 @@ dia_sources = [
'properties-dialog.c',
'defaults.c',
'undo.c',
+ 'dia-change.c',
+ 'dia-change.h',
'object_ops.c',
'layer-editor/dia-layer-widget.c',
diff --git a/docs/dia-app/dia-app-docs.xml b/docs/dia-app/dia-app-docs.xml
index f18db812..795b215e 100644
--- a/docs/dia-app/dia-app-docs.xml
+++ b/docs/dia-app/dia-app-docs.xml
@@ -55,7 +55,14 @@
<xi:include href="xml/handle_ops.xml" />
<xi:include href="xml/highlight.xml" />
<xi:include href="xml/interface.xml" />
- <xi:include href="xml/layer_dialog.xml" />
+ <chapter id="layer-editor">
+ <title>Layer Editor</title>
+ <xi:include href="xml/dia-layer-editor.xml" />
+ <xi:include href="xml/dia-layer-widget.xml" />
+ <xi:include href="xml/dia-layer-editor-dialog.xml" />
+ <xi:include href="xml/dia-layer-properties.xml" />
+ <xi:include href="xml/layer_dialog.xml" />
+ </chapter>
<xi:include href="xml/load_save.xml" />
<xi:include href="xml/magnify.xml" />
<xi:include href="xml/menus.xml" />
@@ -78,7 +85,11 @@
<xi:include href="xml/textedit.xml" />
<xi:include href="xml/toolbox.xml" />
<xi:include href="xml/tool.xml" />
- <xi:include href="xml/undo.xml" />
+ <chapter id="undo-api">
+ <title>Undo</title>
+ <xi:include href="xml/dia-change.xml" />
+ <xi:include href="xml/undo.xml" />
+ </chapter>
</part>
<chapter id="object-tree">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]