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. Chepelov
9 * Property types for static and dynamic arrays.
10 * These arrays are simply arrays of records whose structures are themselves
11 * described by property descriptors.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #define WIDGET GtkWidget
34 #include "properties.h"
35 #include "propinternals.h"
37 /******************************************/
38 /* The SARRAY and DARRAY property types. */
39 /******************************************/
41 static ArrayProperty
*
42 arrayprop_new(const PropDescription
*pdesc
, PropDescToPropPredicate reason
)
44 ArrayProperty
*prop
= g_new0(ArrayProperty
,1);
45 const PropDescCommonArrayExtra
*extra
= pdesc
->extra_data
;
47 initialize_property(&prop
->common
, pdesc
, reason
);
48 prop
->ex_props
= prop_list_from_descs(extra
->record
,reason
);
49 prop
->records
= g_ptr_array_new();
54 arrayprop_freerecords(ArrayProperty
*prop
) /* but not the array itself. */
58 for (i
=0; i
< prop
->records
->len
; i
++)
59 prop_list_free(g_ptr_array_index(prop
->records
,i
));
63 arrayprop_free(ArrayProperty
*prop
)
65 arrayprop_freerecords(prop
);
66 g_ptr_array_free(prop
->records
,TRUE
);
70 static ArrayProperty
*
71 arrayprop_copy(ArrayProperty
*src
)
74 (ArrayProperty
*)src
->common
.ops
->new_prop(src
->common
.descr
,
77 copy_init_property(&prop
->common
,&src
->common
);
78 prop
->ex_props
= prop_list_copy(src
->ex_props
);
79 prop
->records
= g_ptr_array_new();
80 for (i
= 0; i
< src
->records
->len
; i
++) {
81 g_ptr_array_add(prop
->records
,
82 prop_list_copy(g_ptr_array_index(src
->records
,i
)));
88 arrayprop_load(ArrayProperty
*prop
, AttributeNode attr
, DataNode data
)
90 const PropDescCommonArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
94 arrayprop_freerecords(prop
);
95 g_ptr_array_set_size(prop
->records
,0);
97 for (composite
= data
;
99 composite
= data_next(composite
)) {
100 GPtrArray
*record
= prop_list_from_descs(extra
->record
,
101 prop
->common
.reason
);
102 if (!prop_list_load(record
,composite
, &err
)) {
103 g_warning ("%s:%s", prop
->common
.name
, err
->message
);
107 g_ptr_array_add(prop
->records
,record
);
112 arrayprop_save(ArrayProperty
*prop
, AttributeNode attr
)
115 const PropDescCommonArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
117 for (i
= 0; i
< prop
->records
->len
; i
++) {
118 prop_list_save(g_ptr_array_index(prop
->records
,i
),
119 data_add_composite(attr
,extra
->composite_type
));
124 sarrayprop_get_from_offset(ArrayProperty
*prop
,
125 void *base
, guint offset
, guint offset2
)
127 const PropDescSArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
128 PropOffset
*suboffsets
= extra
->common
.offsets
;
131 prop_offset_list_calculate_quarks(suboffsets
);
133 arrayprop_freerecords(prop
);
134 g_ptr_array_set_size(prop
->records
,extra
->array_len
);
136 for (i
=0; i
< prop
->records
->len
; i
++) {
137 void *rec_in_obj
= &struct_member(base
,
138 offset
+ (i
* extra
->element_size
),
140 GPtrArray
*subprops
= prop_list_copy(prop
->ex_props
);
142 do_get_props_from_offsets(rec_in_obj
,subprops
,suboffsets
);
144 g_ptr_array_index(prop
->records
,i
) = subprops
;
149 sarrayprop_set_from_offset(ArrayProperty
*prop
,
150 void *base
, guint offset
, guint offset2
)
152 const PropDescSArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
153 PropOffset
*suboffsets
= extra
->common
.offsets
;
156 g_assert(prop
->records
->len
== extra
->array_len
);
158 prop_offset_list_calculate_quarks(suboffsets
);
160 for (i
=0; i
< prop
->records
->len
; i
++) {
161 void *rec_in_obj
= &struct_member(base
,
162 offset
+ (i
* extra
->element_size
),
164 GPtrArray
*subprops
= g_ptr_array_index(prop
->records
,i
);
166 do_set_props_from_offsets(rec_in_obj
,subprops
,suboffsets
);
171 darrayprop_get_from_offset(ArrayProperty
*prop
,
172 void *base
, guint offset
, guint offset2
)
174 /* This sucks. We do almost exactly like in sarrayprop_get_from_offset(). */
175 const PropDescSArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
176 PropOffset
*suboffsets
= extra
->common
.offsets
;
178 GList
*obj_rec
= struct_member(base
,offset
,GList
*);
180 prop_offset_list_calculate_quarks(suboffsets
);
182 arrayprop_freerecords(prop
);
183 g_ptr_array_set_size(prop
->records
,0);
185 for (obj_rec
= g_list_first(obj_rec
), i
= 0;
187 obj_rec
= g_list_next(obj_rec
), i
++) {
188 void *rec_in_obj
= obj_rec
->data
;
189 GPtrArray
*subprops
= prop_list_copy(prop
->ex_props
);
191 do_get_props_from_offsets(rec_in_obj
,subprops
,suboffsets
);
193 g_ptr_array_add(prop
->records
,subprops
);
198 darrayprop_adjust_object_records(ArrayProperty
*prop
,
199 const PropDescDArrayExtra
*extra
,
201 guint list_len
= g_list_length(obj_rec
);
203 while (list_len
> prop
->records
->len
) {
204 gpointer rec
= obj_rec
->data
;
205 obj_rec
= g_list_remove(obj_rec
,rec
);
209 while (list_len
< prop
->records
->len
) {
210 obj_rec
= g_list_append(obj_rec
,extra
->newrec());
217 darrayprop_set_from_offset(ArrayProperty
*prop
,
218 void *base
, guint offset
, guint offset2
)
220 /* This sucks. We do almost exactly like in darrayprop_set_from_offset(). */
221 const PropDescDArrayExtra
*extra
= prop
->common
.descr
->extra_data
;
222 PropOffset
*suboffsets
= extra
->common
.offsets
;
224 GList
*obj_rec
= struct_member(base
,offset
,GList
*);
226 prop_offset_list_calculate_quarks(suboffsets
);
228 obj_rec
= darrayprop_adjust_object_records(prop
,extra
,obj_rec
);
229 struct_member(base
,offset
,GList
*) = obj_rec
;
231 for (obj_rec
= g_list_first(obj_rec
), i
= 0;
233 obj_rec
= g_list_next(obj_rec
), i
++) {
234 void *rec_in_obj
= obj_rec
->data
;
235 GPtrArray
*subprops
= g_ptr_array_index(prop
->records
,i
);
237 do_set_props_from_offsets(rec_in_obj
,subprops
,suboffsets
);
242 arrayprop_can_merge(const PropDescription
*pd1
, const PropDescription
*pd2
)
244 if (pd1
->extra_data
!= pd2
->extra_data
) return FALSE
;
248 static const PropertyOps sarrayprop_ops
= {
249 (PropertyType_New
) arrayprop_new
,
250 (PropertyType_Free
) arrayprop_free
,
251 (PropertyType_Copy
) arrayprop_copy
,
252 (PropertyType_Load
) arrayprop_load
,
253 (PropertyType_Save
) arrayprop_save
,
255 (PropertyType_GetWidget
) unimplementedprop_get_widget
,
256 (PropertyType_ResetWidget
) unimplementedprop_reset_widget
,
257 (PropertyType_SetFromWidget
) unimplementedprop_set_from_widget
,
259 (PropertyType_CanMerge
) arrayprop_can_merge
,
260 (PropertyType_GetFromOffset
) sarrayprop_get_from_offset
,
261 (PropertyType_SetFromOffset
) sarrayprop_set_from_offset
264 static const PropertyOps darrayprop_ops
= {
265 (PropertyType_New
) arrayprop_new
,
266 (PropertyType_Free
) arrayprop_free
,
267 (PropertyType_Copy
) arrayprop_copy
,
268 (PropertyType_Load
) arrayprop_load
,
269 (PropertyType_Save
) arrayprop_save
,
271 (PropertyType_GetWidget
) unimplementedprop_get_widget
,
272 (PropertyType_ResetWidget
) unimplementedprop_reset_widget
,
273 (PropertyType_SetFromWidget
) unimplementedprop_set_from_widget
,
275 (PropertyType_CanMerge
) noopprop_can_merge
,
276 (PropertyType_GetFromOffset
) darrayprop_get_from_offset
,
277 (PropertyType_SetFromOffset
) darrayprop_set_from_offset
280 /* ************************************************************** */
283 prop_sdarray_register(void)
285 prop_type_register(PROP_TYPE_SARRAY
,&sarrayprop_ops
);
286 prop_type_register(PROP_TYPE_DARRAY
,&darrayprop_ops
);