1 /*
2 * IpatchStateItem.c - Base class for state (undo/redo) items
3 *
4 * libInstPatch
5 * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; version 2.1
10 * of the License only.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA or on the web at http://www.gnu.org.
21 */
22 #include <stdio.h>
23 #include <glib.h>
24 #include <glib-object.h>
25
26 #include "IpatchStateItem.h"
27
28 static void ipatch_state_item_class_init(IpatchStateItemClass *klass);
29 static void ipatch_state_item_finalize(GObject *gobject);
30
31 gpointer item_parent_class = NULL;
32
33 GType
ipatch_state_item_get_type(void)34 ipatch_state_item_get_type(void)
35 {
36 static GType item_type = 0;
37
38 if(!item_type)
39 {
40 static const GTypeInfo item_info =
41 {
42 sizeof(IpatchStateItemClass), NULL, NULL,
43 (GClassInitFunc) ipatch_state_item_class_init, NULL, NULL,
44 sizeof(IpatchStateItem), 0,
45 (GInstanceInitFunc) NULL,
46 };
47
48 item_type = g_type_register_static(G_TYPE_OBJECT, "IpatchStateItem",
49 &item_info, G_TYPE_FLAG_ABSTRACT);
50 }
51
52 return (item_type);
53 }
54
55 static void
ipatch_state_item_class_init(IpatchStateItemClass * klass)56 ipatch_state_item_class_init(IpatchStateItemClass *klass)
57 {
58 GObjectClass *gobj_class = G_OBJECT_CLASS(klass);
59
60 item_parent_class = g_type_class_peek_parent(klass);
61 gobj_class->finalize = ipatch_state_item_finalize;
62 }
63
64 static void
ipatch_state_item_finalize(GObject * gobject)65 ipatch_state_item_finalize(GObject *gobject)
66 {
67 IpatchStateItem *item = IPATCH_STATE_ITEM(gobject);
68
69 if(item->node)
70 {
71 g_node_destroy(item->node); /* destroy item's tree node */
72 }
73
74 if(item->group)
75 {
76 g_object_unref(item->group); /* -- unref item's group */
77 }
78
79 if(G_OBJECT_CLASS(item_parent_class)->finalize)
80 {
81 G_OBJECT_CLASS(item_parent_class)->finalize(gobject);
82 }
83 }
84
85 /**
86 * ipatch_state_item_restore:
87 * @item: State item to restore
88 *
89 * Restore the state saved by @item.
90 */
91 void
ipatch_state_item_restore(const IpatchStateItem * item)92 ipatch_state_item_restore(const IpatchStateItem *item)
93 {
94 IpatchStateItemClass *klass;
95 g_return_if_fail(IPATCH_IS_STATE_ITEM(item));
96
97 klass = IPATCH_STATE_ITEM_GET_CLASS(item);
98 g_return_if_fail(klass->restore != NULL);
99 (*klass->restore)(item);
100 }
101
102 /**
103 * ipatch_state_item_depend:
104 * @item1: First item
105 * @item2: Second item
106 *
107 * Check if @item1 is dependent on @item2.
108 *
109 * Returns: %TRUE if @item1 is dependent on @item2, %FALSE otherwise.
110 */
111 gboolean
ipatch_state_item_depend(const IpatchStateItem * item1,const IpatchStateItem * item2)112 ipatch_state_item_depend(const IpatchStateItem *item1,
113 const IpatchStateItem *item2)
114 {
115 IpatchStateItemClass *klass;
116 g_return_val_if_fail(IPATCH_IS_STATE_ITEM(item1), FALSE);
117 g_return_val_if_fail(IPATCH_IS_STATE_ITEM(item2), FALSE);
118
119 klass = IPATCH_STATE_ITEM_GET_CLASS(item1);
120 return (!klass->depend || (*klass->depend)(item1, item2));
121 }
122
123 /**
124 * ipatch_state_item_conflict:
125 * @item1: First item
126 * @item2: Second item
127 *
128 * Check if @item1 conflicts with @item2.
129 *
130 * Returns: %TRUE if @item1 conflicts with @item2, %FALSE otherwise.
131 */
132 gboolean
ipatch_state_item_conflict(const IpatchStateItem * item1,const IpatchStateItem * item2)133 ipatch_state_item_conflict(const IpatchStateItem *item1,
134 const IpatchStateItem *item2)
135 {
136 IpatchStateItemClass *klass;
137 g_return_val_if_fail(IPATCH_IS_STATE_ITEM(item1), FALSE);
138 g_return_val_if_fail(IPATCH_IS_STATE_ITEM(item2), FALSE);
139
140 klass = IPATCH_STATE_ITEM_GET_CLASS(item1);
141 return (!klass->conflict || (*klass->conflict)(item1, item2));
142 }
143
144 /**
145 * ipatch_state_item_describe:
146 * @item: Item to describe
147 *
148 * Get a detailed description of the action that created the @item state.
149 *
150 * Returns: Newly allocated description of the @item action or %NULL if
151 * no description available. String should be freed when no longer needed.
152 */
153 char *
ipatch_state_item_describe(const IpatchStateItem * item)154 ipatch_state_item_describe(const IpatchStateItem *item)
155 {
156 IpatchStateItemClass *klass;
157 g_return_val_if_fail(IPATCH_IS_STATE_ITEM(item), NULL);
158
159 klass = IPATCH_STATE_ITEM_GET_CLASS(item);
160
161 if(klass->describe)
162 {
163 return ((*klass->describe)(item));
164 }
165 else
166 {
167 return (NULL);
168 }
169 }
170