Signal patch
[dia.git] / lib / propobject.c
blob2227a2780b313873f1a0dd76da7179564a2009f3
1 /* Dia -- a diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * Property system for dia objects/shapes.
5 * Copyright (C) 2000 James Henstridge
6 * Copyright (C) 2001 Cyrille Chepelov
7 * Major restructuration done in August 2001 by C. Chepelov
9 * Propobject.c: routines which deal with Dia Objects and affect their
10 * properties.
12 * Most of these routines used to exist in code before the restructuration.
13 * They've lost most of their meat, in favour for more modularity.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
34 #include <string.h>
36 #include <glib.h>
37 #include "properties.h"
38 #include "propinternals.h"
40 const PropDescription *
41 object_get_prop_descriptions(const DiaObject *obj) {
42 const PropDescription *pdesc;
43 if (!obj->ops->describe_props) return NULL;
45 pdesc = obj->ops->describe_props((DiaObject *)obj); /* Yes... */
46 if (pdesc[0].quark != 0) return pdesc;
48 prop_desc_list_calculate_quarks((PropDescription *)pdesc); /* Yes again... */
49 return pdesc;
53 /* ------------------------------------------------------ */
54 /* Change management */
56 /* an ObjectChange structure for setting of properties */
57 typedef struct _ObjectPropChange ObjectPropChange;
58 struct _ObjectPropChange {
59 ObjectChange obj_change;
61 DiaObject *obj;
62 GPtrArray *saved_props;
65 static void
66 object_prop_change_apply_revert(ObjectPropChange *change, DiaObject *obj)
68 GPtrArray *old_props;
70 old_props = prop_list_copy_empty(change->saved_props);
72 if (change->obj->ops->get_props)
73 change->obj->ops->get_props(change->obj, old_props);
75 /* set saved property values */
76 if (change->obj->ops->set_props)
77 change->obj->ops->set_props(change->obj, change->saved_props);
79 /* move old props to saved properties */
80 prop_list_free(change->saved_props);
81 change->saved_props = old_props;
84 static void
85 object_prop_change_free(ObjectPropChange *change)
87 prop_list_free(change->saved_props);
90 ObjectChange *
91 object_apply_props(DiaObject *obj, GPtrArray *props)
93 ObjectPropChange *change;
94 GPtrArray *old_props;
96 change = g_new0(ObjectPropChange, 1);
98 change->obj_change.apply =
99 (ObjectChangeApplyFunc) object_prop_change_apply_revert;
100 change->obj_change.revert =
101 (ObjectChangeRevertFunc) object_prop_change_apply_revert;
102 change->obj_change.free =
103 (ObjectChangeFreeFunc) object_prop_change_free;
105 change->obj = obj;
107 /* create new properties structure with current values */
108 old_props = prop_list_copy_empty(props);
110 if (obj->ops->get_props)
111 obj->ops->get_props(obj, old_props);
113 /* set saved property values */
114 if (obj->ops->set_props)
115 obj->ops->set_props(obj, props);
117 change->saved_props = old_props;
119 return (ObjectChange *)change;
123 /* Get/Set routines */
125 gboolean
126 object_get_props_from_offsets(DiaObject *obj, PropOffset *offsets,
127 GPtrArray *props)
129 prop_offset_list_calculate_quarks(offsets);
130 do_get_props_from_offsets(obj,props,offsets);
132 return TRUE;
135 gboolean
136 object_set_props_from_offsets(DiaObject *obj, PropOffset *offsets,
137 GPtrArray *props)
139 prop_offset_list_calculate_quarks(offsets);
140 do_set_props_from_offsets(obj,props,offsets);
142 return TRUE;
146 WIDGET *
147 object_create_props_dialog(DiaObject *obj, gboolean is_default)
149 return prop_dialog_new(obj, is_default)->widget;
153 ObjectChange *
154 object_apply_props_from_dialog(DiaObject *obj, WIDGET *dialog_widget)
156 PropDialog *dialog = prop_dialog_from_widget(dialog_widget);
158 prop_get_data_from_widgets(dialog);
159 return object_apply_props(obj, dialog->props);
163 gboolean
164 object_complies_with_stdprop(const DiaObject *obj)
166 if (obj->ops->set_props == NULL) {
167 g_warning("No set_props !");
168 return FALSE;
170 if (obj->ops->get_props == NULL) {
171 g_warning("No get_props !");
172 return FALSE;
174 if (obj->ops->describe_props == NULL) {
175 g_warning("No describe_props !");
176 return FALSE;
178 if (object_get_prop_descriptions(obj) == NULL) {
179 g_warning("No properties !");
180 return FALSE;
182 return TRUE;
185 void
186 object_copy_props(DiaObject *dest, const DiaObject *src, gboolean is_default)
188 GPtrArray *props;
190 g_return_if_fail(src != NULL);
191 g_return_if_fail(dest != NULL);
192 g_return_if_fail(strcmp(src->type->name,dest->type->name)==0);
193 g_return_if_fail(src->ops == dest->ops);
194 g_return_if_fail(object_complies_with_stdprop(src));
195 g_return_if_fail(object_complies_with_stdprop(dest));
197 props = prop_list_from_descs(object_get_prop_descriptions(src),
198 (is_default?pdtpp_do_save_no_standard:
199 pdtpp_do_save));
201 src->ops->get_props((DiaObject *)src, props); /* FIXME: really should make
202 get_props' first argument
203 a (const DiaObject *) */
204 dest->ops->set_props(dest, props);
206 prop_list_free(props);
209 void
210 object_load_props(DiaObject *obj, ObjectNode obj_node)
212 GPtrArray *props;
213 GError *err = NULL;
215 g_return_if_fail(obj != NULL);
216 g_return_if_fail(obj_node != NULL);
217 g_return_if_fail(object_complies_with_stdprop(obj));
219 props = prop_list_from_descs(object_get_prop_descriptions(obj),
220 pdtpp_do_load);
222 if (!prop_list_load(props,obj_node, &err)) {
223 g_warning ("%s: %s", obj->type->name, err->message);
224 g_error_free(err);
227 obj->ops->set_props(obj, props);
228 prop_list_free(props);
231 void
232 object_save_props(DiaObject *obj, ObjectNode obj_node)
234 GPtrArray *props;
236 g_return_if_fail(obj != NULL);
237 g_return_if_fail(obj_node != NULL);
238 g_return_if_fail(object_complies_with_stdprop(obj));
240 props = prop_list_from_descs(object_get_prop_descriptions(obj),
241 pdtpp_do_save);
243 obj->ops->get_props(obj, props);
244 prop_list_save(props,obj_node);
245 prop_list_free(props);
248 Property *
249 object_prop_by_name_type(DiaObject *obj, const char *name, const char *type)
251 const PropDescription *pdesc;
252 GQuark name_quark = g_quark_from_string(name);
254 if (!object_complies_with_stdprop(obj)) return NULL;
256 for (pdesc = object_get_prop_descriptions(obj);
257 pdesc->name != NULL;
258 pdesc++) {
259 if ((pdesc->quark == name_quark)) {
260 Property *prop;
261 static GPtrArray *plist = NULL;
263 if (type && (0 != strcmp(pdesc->type,type))) continue;
265 if (!plist) {
266 plist = g_ptr_array_new();
267 g_ptr_array_set_size(plist,1);
269 prop = pdesc->ops->new_prop(pdesc,pdtpp_from_object);
270 g_ptr_array_index(plist,0) = prop;
271 obj->ops->get_props(obj,plist);
272 return prop;
275 return NULL;
278 Property *
279 object_prop_by_name(DiaObject *obj, const char *name)
281 return object_prop_by_name_type(obj,name,NULL);