2006-12-03 Dimitris Glezos <dimitris@glezos.com>
[dia.git] / lib / prop_attr.c
blob72119c16538933ae4002dbdd7ce03f92b8d48a20
1 /* Dia -- a diagram creation/manipulation program -*- c -*-
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. Chépélov
9 * Property types for "attribute" types (line style, arrow, colour, font)
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include <gtk/gtk.h>
30 #include "dia_xml.h"
31 #include "widgets.h"
32 #include "properties.h"
33 #include "propinternals.h"
34 #include "diaarrowchooser.h"
36 /***************************/
37 /* The LINESTYLE property type. */
38 /***************************/
40 static LinestyleProperty *
41 linestyleprop_new(const PropDescription *pdesc,
42 PropDescToPropPredicate reason)
44 LinestyleProperty *prop = g_new0(LinestyleProperty,1);
45 initialize_property(&prop->common,pdesc,reason);
46 prop->style = LINESTYLE_SOLID;
47 prop->dash = 0.0;
48 return prop;
51 static LinestyleProperty *
52 linestyleprop_copy(LinestyleProperty *src)
54 LinestyleProperty *prop =
55 (LinestyleProperty *)src->common.ops->new_prop(src->common.descr,
56 src->common.reason);
57 copy_init_property(&prop->common,&src->common);
58 prop->style = src->style;
59 prop->dash = src->dash;
60 return prop;
63 static WIDGET *
64 linestyleprop_get_widget(LinestyleProperty *prop, PropDialog *dialog)
66 GtkWidget *ret = dia_line_style_selector_new();
67 prophandler_connect(&prop->common,GTK_OBJECT(ret),"FIXME");
68 return ret;
71 static void
72 linestyleprop_reset_widget(LinestyleProperty *prop, WIDGET *widget)
74 dia_line_style_selector_set_linestyle(DIALINESTYLESELECTOR(widget),
75 prop->style,
76 prop->dash);
79 static void
80 linestyleprop_set_from_widget(LinestyleProperty *prop, WIDGET *widget)
82 dia_line_style_selector_get_linestyle(DIALINESTYLESELECTOR(widget),
83 &prop->style,
84 &prop->dash);
87 static void
88 linestyleprop_load(LinestyleProperty *prop, AttributeNode attr, DataNode data)
90 prop->style = data_enum(data);
91 prop->dash = 1.0;
92 /* don't bother checking dash length if we have a solid line. */
93 if (prop->style != LINESTYLE_SOLID) {
94 data = data_next(data);
95 if (data)
96 prop->dash = data_real(data);
97 else {
98 ObjectNode obj_node = attr->parent;
99 /* backward compatibility */
100 if ((attr = object_find_attribute(obj_node, "dashlength")) &&
101 (data = attribute_first_data(attr)))
102 prop->dash = data_real(data);
107 static void
108 linestyleprop_save(LinestyleProperty *prop, AttributeNode attr)
110 data_add_enum(attr, prop->style);
111 data_add_real(attr, prop->dash);
112 /* for compatibility. It makes more sense to link the two together */
114 data_add_real(new_attribute(attr->parent, "dashlength"),
115 prop->dash);
117 To hell with compatibility with very old dias ! -- CC */
120 static void
121 linestyleprop_get_from_offset(LinestyleProperty *prop,
122 void *base, guint offset, guint offset2)
124 prop->style = struct_member(base, offset, LineStyle);
125 prop->dash = struct_member(base, offset2, real);
128 static void
129 linestyleprop_set_from_offset(LinestyleProperty *prop,
130 void *base, guint offset, guint offset2)
132 struct_member(base, offset, LineStyle) = prop->style;
133 struct_member(base, offset2, real) = prop->dash;
136 static const PropertyOps linestyleprop_ops = {
137 (PropertyType_New) linestyleprop_new,
138 (PropertyType_Free) noopprop_free,
139 (PropertyType_Copy) linestyleprop_copy,
140 (PropertyType_Load) linestyleprop_load,
141 (PropertyType_Save) linestyleprop_save,
142 (PropertyType_GetWidget) linestyleprop_get_widget,
143 (PropertyType_ResetWidget) linestyleprop_reset_widget,
144 (PropertyType_SetFromWidget) linestyleprop_set_from_widget,
146 (PropertyType_CanMerge) noopprop_can_merge,
147 (PropertyType_GetFromOffset) linestyleprop_get_from_offset,
148 (PropertyType_SetFromOffset) linestyleprop_set_from_offset
151 /***************************/
152 /* The ARROW property type. */
153 /***************************/
155 static ArrowProperty *
156 arrowprop_new(const PropDescription *pdesc, PropDescToPropPredicate reason)
158 ArrowProperty *prop = g_new0(ArrowProperty,1);
159 initialize_property(&prop->common,pdesc,reason);
160 prop->arrow_data.type = ARROW_NONE;
161 prop->arrow_data.length = 0.0;
162 prop->arrow_data.width = 0.0;
163 return prop;
166 static ArrowProperty *
167 arrowprop_copy(ArrowProperty *src)
169 ArrowProperty *prop =
170 (ArrowProperty *)src->common.ops->new_prop(src->common.descr,
171 src->common.reason);
172 copy_init_property(&prop->common,&src->common);
173 prop->arrow_data = src->arrow_data;
174 return prop;
177 static WIDGET *
178 arrowprop_get_widget(ArrowProperty *prop, PropDialog *dialog)
180 GtkWidget *ret = dia_arrow_selector_new();
181 prophandler_connect(&prop->common,GTK_OBJECT(ret),"FIXME");
182 return ret;
185 static void
186 arrowprop_reset_widget(ArrowProperty *prop, WIDGET *widget)
188 dia_arrow_selector_set_arrow(DIA_ARROW_SELECTOR(widget),
189 prop->arrow_data);
192 static void
193 arrowprop_set_from_widget(ArrowProperty *prop, WIDGET *widget)
195 prop->arrow_data = dia_arrow_selector_get_arrow(DIA_ARROW_SELECTOR(widget));
198 static void
199 arrowprop_load(ArrowProperty *prop, AttributeNode attr, DataNode data)
201 /* Maybe it would be better to store arrows as a single composite
202 * attribute rather than three seperate attributes. This would break
203 * binary compatibility though.*/
204 prop->arrow_data.type = data_enum(data);
205 prop->arrow_data.length = DEFAULT_ARROW_SIZE;
206 prop->arrow_data.width = DEFAULT_ARROW_SIZE;
207 if (prop->arrow_data.type != ARROW_NONE) {
208 ObjectNode obj_node = attr->parent;
209 gchar *str = g_strconcat(prop->common.name, "_length", NULL);
210 if ((attr = object_find_attribute(obj_node, str)) &&
211 (data = attribute_first_data(attr)))
212 prop->arrow_data.length = data_real(data);
213 g_free(str);
214 str = g_strconcat(prop->common.name, "_width", NULL);
215 if ((attr = object_find_attribute(obj_node, str)) &&
216 (data = attribute_first_data(attr)))
217 prop->arrow_data.width = data_real(data);
218 g_free(str);
222 static void
223 arrowprop_save(ArrowProperty *prop, AttributeNode attr)
225 data_add_enum(attr, prop->arrow_data.type);
226 if (prop->arrow_data.type != ARROW_NONE) {
227 ObjectNode obj_node = attr->parent;
228 gchar *str = g_strconcat(prop->common.name, "_length", NULL);
229 attr = new_attribute(obj_node, str);
230 g_free(str);
231 data_add_real(attr, prop->arrow_data.length);
232 str = g_strconcat(prop->common.name, "_width", NULL);
233 attr = new_attribute(obj_node, str);
234 g_free(str);
235 data_add_real(attr, prop->arrow_data.width);
239 static void
240 arrowprop_get_from_offset(ArrowProperty *prop,
241 void *base, guint offset, guint offset2)
243 prop->arrow_data = struct_member(base,offset,Arrow);
246 static void
247 arrowprop_set_from_offset(ArrowProperty *prop,
248 void *base, guint offset, guint offset2)
250 struct_member(base,offset,Arrow) = prop->arrow_data;
253 static const PropertyOps arrowprop_ops = {
254 (PropertyType_New) arrowprop_new,
255 (PropertyType_Free) noopprop_free,
256 (PropertyType_Copy) arrowprop_copy,
257 (PropertyType_Load) arrowprop_load,
258 (PropertyType_Save) arrowprop_save,
259 (PropertyType_GetWidget) arrowprop_get_widget,
260 (PropertyType_ResetWidget) arrowprop_reset_widget,
261 (PropertyType_SetFromWidget) arrowprop_set_from_widget,
263 (PropertyType_CanMerge) noopprop_can_merge,
264 (PropertyType_GetFromOffset) arrowprop_get_from_offset,
265 (PropertyType_SetFromOffset) arrowprop_set_from_offset
268 /***************************/
269 /* The COLOR property type. */
270 /***************************/
272 static ColorProperty *
273 colorprop_new(const PropDescription *pdesc, PropDescToPropPredicate reason)
275 ColorProperty *prop = g_new0(ColorProperty,1);
276 initialize_property(&prop->common,pdesc,reason);
277 prop->color_data.red = 0.0;
278 prop->color_data.green = 0.0;
279 prop->color_data.blue = 1.0;
280 return prop;
283 static ColorProperty *
284 colorprop_copy(ColorProperty *src)
286 ColorProperty *prop =
287 (ColorProperty *)src->common.ops->new_prop(src->common.descr,
288 src->common.reason);
289 copy_init_property(&prop->common,&src->common);
290 prop->color_data = src->color_data;
291 return prop;
294 static WIDGET *
295 colorprop_get_widget(ColorProperty *prop, PropDialog *dialog)
297 GtkWidget *ret = dia_color_selector_new();
298 prophandler_connect(&prop->common,GTK_OBJECT(ret),"FIXME");
299 return ret;
302 static void
303 colorprop_reset_widget(ColorProperty *prop, WIDGET *widget)
305 dia_color_selector_set_color(widget,
306 &prop->color_data);
309 static void
310 colorprop_set_from_widget(ColorProperty *prop, WIDGET *widget)
312 dia_color_selector_get_color(widget,
313 &prop->color_data);
316 static void
317 colorprop_load(ColorProperty *prop, AttributeNode attr, DataNode data)
319 data_color(data,&prop->color_data);
322 static void
323 colorprop_save(ColorProperty *prop, AttributeNode attr)
325 data_add_color(attr,&prop->color_data);
328 static void
329 colorprop_get_from_offset(ColorProperty *prop,
330 void *base, guint offset, guint offset2)
332 prop->color_data = struct_member(base,offset,Color);
335 static void
336 colorprop_set_from_offset(ColorProperty *prop,
337 void *base, guint offset, guint offset2)
339 struct_member(base,offset,Color) = prop->color_data;
342 static const PropertyOps colorprop_ops = {
343 (PropertyType_New) colorprop_new,
344 (PropertyType_Free) noopprop_free,
345 (PropertyType_Copy) colorprop_copy,
346 (PropertyType_Load) colorprop_load,
347 (PropertyType_Save) colorprop_save,
348 (PropertyType_GetWidget) colorprop_get_widget,
349 (PropertyType_ResetWidget) colorprop_reset_widget,
350 (PropertyType_SetFromWidget) colorprop_set_from_widget,
352 (PropertyType_CanMerge) noopprop_can_merge,
353 (PropertyType_GetFromOffset) colorprop_get_from_offset,
354 (PropertyType_SetFromOffset) colorprop_set_from_offset
358 /***************************/
359 /* The FONT property type. */
360 /***************************/
362 static FontProperty *
363 fontprop_new(const PropDescription *pdesc, PropDescToPropPredicate reason)
365 FontProperty *prop = g_new0(FontProperty,1);
366 initialize_property(&prop->common,pdesc,reason);
367 prop->font_data = NULL;
368 return prop;
371 static void
372 fontprop_free(FontProperty *prop)
374 if (prop->font_data)
375 dia_font_unref(prop->font_data);
376 g_free(prop);
379 static FontProperty *
380 fontprop_copy(FontProperty *src)
382 FontProperty *prop =
383 (FontProperty *)src->common.ops->new_prop(src->common.descr,
384 src->common.reason);
385 copy_init_property(&prop->common,&src->common);
387 if (prop->font_data)
388 dia_font_unref(prop->font_data);
389 prop->font_data = dia_font_ref(src->font_data);
391 return prop;
394 static WIDGET *
395 fontprop_get_widget(FontProperty *prop, PropDialog *dialog)
397 GtkWidget *ret = dia_font_selector_new();
398 prophandler_connect(&prop->common,GTK_OBJECT(ret),"FIXME");
399 return ret;
402 static void
403 fontprop_reset_widget(FontProperty *prop, WIDGET *widget)
405 dia_font_selector_set_font(DIAFONTSELECTOR(widget),
406 prop->font_data);
409 static void
410 fontprop_set_from_widget(FontProperty *prop, WIDGET *widget)
412 prop->font_data = dia_font_selector_get_font(DIAFONTSELECTOR(widget));
415 static void
416 fontprop_load(FontProperty *prop, AttributeNode attr, DataNode data)
418 if (prop->font_data)
419 dia_font_unref(prop->font_data);
420 prop->font_data = data_font(data);
423 static void
424 fontprop_save(FontProperty *prop, AttributeNode attr)
426 data_add_font(attr,prop->font_data);
429 static void
430 fontprop_get_from_offset(FontProperty *prop,
431 void *base, guint offset, guint offset2)
433 if (prop->font_data)
434 dia_font_unref(prop->font_data);
435 prop->font_data = dia_font_ref(struct_member(base,offset,DiaFont *));
438 static void
439 fontprop_set_from_offset(FontProperty *prop,
440 void *base, guint offset, guint offset2)
442 if (prop->font_data) {
443 if (struct_member(base,offset,DiaFont *))
444 dia_font_unref(struct_member(base,offset,DiaFont *));
445 struct_member(base,offset,DiaFont *) = dia_font_ref(prop->font_data);
449 static const PropertyOps fontprop_ops = {
450 (PropertyType_New) fontprop_new,
451 (PropertyType_Free) fontprop_free,
452 (PropertyType_Copy) fontprop_copy,
453 (PropertyType_Load) fontprop_load,
454 (PropertyType_Save) fontprop_save,
455 (PropertyType_GetWidget) fontprop_get_widget,
456 (PropertyType_ResetWidget) fontprop_reset_widget,
457 (PropertyType_SetFromWidget) fontprop_set_from_widget,
459 (PropertyType_CanMerge) noopprop_can_merge,
460 (PropertyType_GetFromOffset) fontprop_get_from_offset,
461 (PropertyType_SetFromOffset) fontprop_set_from_offset
464 /* ************************************************************** */
466 void
467 prop_attr_register(void)
469 prop_type_register(PROP_TYPE_LINESTYLE,&linestyleprop_ops);
470 prop_type_register(PROP_TYPE_ARROW,&arrowprop_ops);
471 prop_type_register(PROP_TYPE_COLOUR,&colorprop_ops);
472 prop_type_register(PROP_TYPE_FONT,&fontprop_ops);