* lib/text.h: Added text_get_line() declaration
[dia.git] / lib / proplist.c
blob955c62d79482a04da3cf4feac1791ab29a51e910
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 * proplist.c: Property list handling routines.
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.
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include "properties.h"
31 #include "propinternals.h"
32 #include "dia_xml.h"
33 #include "diaerror.h"
35 /* ------------------------------------------------------------------------- */
36 /* Construction of a list of properties from a filtered list of descriptors. */
37 /* This is a little halfway between properties and property descriptor */
38 /* lists... */
39 gboolean pdtpp_true(const PropDescription *pdesc)
40 { return TRUE; }
41 gboolean pdtpp_synthetic(const PropDescription *pdesc)
42 { return TRUE; }
43 gboolean pdtpp_from_object(const PropDescription *pdesc)
44 { return TRUE; }
45 gboolean pdtpp_is_visible(const PropDescription *pdesc)
46 { return (pdesc->flags & PROP_FLAG_VISIBLE) != 0; }
47 gboolean pdtpp_is_visible_no_standard(const PropDescription *pdesc)
48 { return (pdesc->flags & PROP_FLAG_VISIBLE) != 0 &&
49 (pdesc->flags & PROP_FLAG_STANDARD) == 0; }
50 gboolean pdtpp_is_not_visible(const PropDescription *pdesc)
51 { return (pdesc->flags & PROP_FLAG_VISIBLE) == 0; }
52 gboolean pdtpp_do_save(const PropDescription *pdesc)
53 { return (pdesc->flags & (PROP_FLAG_DONT_SAVE|PROP_FLAG_LOAD_ONLY)) == 0; }
54 gboolean pdtpp_do_save_no_standard(const PropDescription *pdesc)
55 { return (pdesc->flags & (PROP_FLAG_DONT_SAVE|PROP_FLAG_LOAD_ONLY|PROP_FLAG_STANDARD)) == 0; }
56 gboolean pdtpp_do_load(const PropDescription *pdesc)
57 { return (((pdesc->flags & PROP_FLAG_DONT_SAVE) == 0) ||
58 ((pdesc->flags & PROP_FLAG_LOAD_ONLY) != 0)); }
59 gboolean pdtpp_defaults(const PropDescription *pdesc)
60 { return (pdesc->flags & PROP_FLAG_NO_DEFAULTS) == 0; }
61 gboolean pdtpp_do_not_save(const PropDescription *pdesc)
62 { return (pdesc->flags & PROP_FLAG_DONT_SAVE) != 0; }
64 GPtrArray *
65 prop_list_from_descs(const PropDescription *plist,
66 PropDescToPropPredicate pred)
68 GPtrArray *ret;
69 guint count = 0, i;
71 prop_desc_list_calculate_quarks((PropDescription *)plist);
73 for (i = 0; plist[i].name != NULL; i++)
74 if (pred(&plist[i])) count++;
76 ret = g_ptr_array_new();
77 g_ptr_array_set_size(ret,count);
79 count = 0;
80 for (i = 0; plist[i].name != NULL; i++) {
81 #if 0
82 g_message("about to append property %s/%s to list"
83 "predicate is %s %d %d",plist[i].type,plist[i].name,
84 pred(&plist[i])?"TRUE":"FALSE",
85 plist[i].flags,plist[i].flags & PROP_FLAG_DONT_SAVE);
86 #endif
87 if (pred(&plist[i])) {
88 Property *prop = plist[i].ops->new_prop(&plist[i],pred);
89 g_ptr_array_index(ret,count++) = prop;
93 return ret;
96 void
97 prop_list_free(GPtrArray *plist)
99 int i;
100 if (!plist) return;
102 for (i = 0; i < plist->len; i++) {
103 Property *prop = g_ptr_array_index(plist,i);
104 prop->ops->free(prop);
106 g_ptr_array_free(plist,TRUE);
109 /* copies the whole property structure, including the data. */
110 GPtrArray *
111 prop_list_copy(GPtrArray *src)
113 int i;
114 GPtrArray *dest;
116 dest = g_ptr_array_new();
117 g_ptr_array_set_size(dest, src->len);
119 for (i=0; i < src->len; i++) {
120 Property *psrc = g_ptr_array_index(src,i);
121 Property *pdest = pdest = psrc->ops->copy(psrc);
122 g_ptr_array_index(dest,i) = pdest;
124 return dest;
127 /* copies the whole property structure, excluding the data. */
128 GPtrArray *
129 prop_list_copy_empty(GPtrArray *plist)
131 int i;
132 GPtrArray *dest;
134 dest = g_ptr_array_new();
135 g_ptr_array_set_size(dest, plist->len);
137 for (i=0; i < plist->len; i++) {
138 Property *psrc = g_ptr_array_index(plist,i);
139 Property *pdest = psrc->ops->new_prop(psrc->descr,psrc->reason);
140 g_ptr_array_index(dest,i) = pdest;
142 return dest;
145 gboolean
146 prop_list_load(GPtrArray *props, DataNode data, GError **err)
148 int i;
149 gboolean ret = TRUE;
151 for (i = 0; i < props->len; i++) {
152 Property *prop = g_ptr_array_index(props,i);
153 AttributeNode attr = object_find_attribute(data, prop->name);
154 DataNode data = attr ? attribute_first_data(attr) : NULL;
155 if ((!attr || !data) && prop->descr->flags & PROP_FLAG_OPTIONAL) {
156 prop->experience |= PXP_NOTSET;
157 continue;
159 if ((!attr) || (!data)) {
160 if (err && !*err)
161 *err = g_error_new (DIA_ERROR,
162 DIA_ERROR_FORMAT,
163 _("No attribute '%s' (%p) or no data(%p) in this attribute"),
164 prop->name,attr,data);
165 prop->experience |= PXP_NOTSET;
166 ret = FALSE;
167 continue;
169 prop->ops->load(prop,attr,data);
171 return ret;
174 void
175 prop_list_save(GPtrArray *props, DataNode data)
177 int i;
178 for (i = 0; i < props->len; i++) {
179 Property *prop = g_ptr_array_index(props,i);
180 AttributeNode attr = new_attribute(data,prop->name);
181 prop->ops->save(prop,attr);
185 Property *
186 find_prop_by_name(const GPtrArray *props, const gchar *name)
188 int i;
189 GQuark prop_quark = g_quark_from_string(name);
191 for (i = 0; i < props->len; i++) {
192 Property *prop = g_ptr_array_index(props,i);
193 if (prop->name_quark == prop_quark) return prop;
195 return NULL;
198 Property *
199 find_prop_by_name_and_type(const GPtrArray *props, const gchar *name,
200 PropertyType type)
202 Property *ret = find_prop_by_name(props,name);
203 GQuark type_quark = g_quark_from_string(type);
204 if (!ret) return NULL;
205 if (type_quark != ret->type_quark) return NULL;
206 return ret;
209 void
210 prop_list_add_list (GPtrArray *props, const GPtrArray *ptoadd)
212 guint i;
213 for (i = 0 ; i < ptoadd->len; i++) {
214 Property *prop = g_ptr_array_index(ptoadd,i);
216 g_ptr_array_add(props,prop->ops->copy(prop));
220 GPtrArray *
221 prop_list_from_single(Property *prop) {
222 GPtrArray *plist = g_ptr_array_new();
223 g_ptr_array_add(plist,prop);
224 return plist;