QOF: qofgobj.c Source File

QOF 0.7.5

qofgobj.c
1 /********************************************************************\
2 * qofgobj.c -- QOF to GLib GObject mapping *
3 * *
4 * Copyright (c) 2000,2001,2004 Linas Vepstas <linas@linas.org> *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License*
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22 * *
23 \********************************************************************/
24
25 #include "config.h"
26 #include <glib.h>
27 #include "qof.h"
28 #include "qofgobj.h"
29
30 static QofLogModule log_module = QOF_MOD_QUERY;
31
32 static gboolean initialized = FALSE;
33 static GSList *paramList = NULL;
34 static GSList *classList = NULL;
35
36 /* =================================================================== */
37
38 #if 0
39 static gboolean
40 clear_table (gpointer key, gpointer value, gpointer user_data)
41 {
42 g_slist_free (value);
43 return TRUE;
44 }
45 #endif
46
47 void
48 qof_gobject_init (void)
49 {
50 if (initialized)
51 return;
52 initialized = TRUE;
53
54 // gobjectClassTable = g_hash_table_new (g_str_hash, g_str_equal);
55
56 /* Init the other subsystems that we need */
57 qof_object_initialize ();
58 qof_query_init ();
59 }
60
61 void
62 qof_gobject_shutdown (void)
63 {
64 GSList *n;
65
66 if (!initialized)
67 return;
68 initialized = FALSE;
69
70 // GSList *n;
71 for (n = paramList; n; n = n->next)
72 g_free (n->data);
73 g_slist_free (paramList);
74
75 for (n = classList; n; n = n->next)
76 g_free (n->data);
77 g_slist_free (classList);
78
79 #if 0
80 // XXX also need to walk over books, and collection and delete
81 // the collection get_data instance lists !!
82 // without this we have a memory leak !!
83 g_hash_table_foreach_remove (gobjectParamTable, clear_table, NULL);
84 g_hash_table_destroy (gobjectParamTable);
85 #endif
86 }
87
88 /* =================================================================== */
89
90 #define GOBJECT_TABLE "GobjectTable"
91
92 void
93 qof_gobject_register_instance (QofBook * book, QofType type, GObject * gob)
94 {
95 QofCollection *coll;
96 GSList *instance_list;
97
98 if (!book || !type)
99 return;
100
101 coll = qof_book_get_collection (book, type);
102
103 instance_list = qof_collection_get_data (coll);
104 instance_list = g_slist_prepend (instance_list, gob);
105 qof_collection_set_data (coll, instance_list);
106 }
107
108 /* =================================================================== */
109
110 static gpointer
111 qof_gobject_getter (gpointer data, QofParam * getter)
112 {
113 GObject *gob = data;
114 const char *str;
115
116 GParamSpec *gps = getter->param_userdata;
117
118 /* Note that the return type must actually be of type
119 * getter->param_type but we just follow the hard-coded
120 * mapping below ... */
121 if (G_IS_PARAM_SPEC_STRING (gps))
122 {
123 GValue gval;
124 g_value_init (&gval, G_TYPE_STRING);
125 g_object_get_property (gob, getter->param_name, &gval);
126
127 str = g_value_get_string (&gval);
128 return (gpointer) str;
129 }
130 else if (G_IS_PARAM_SPEC_INT (gps))
131 {
132 long ival;
133
134 GValue gval;
135 g_value_init (&gval, G_TYPE_INT);
136 g_object_get_property (gob, getter->param_name, &gval);
137
138 ival = g_value_get_int (&gval);
139 return (gpointer) ival;
140 }
141 else if (G_IS_PARAM_SPEC_UINT (gps))
142 {
143 long ival;
144 GValue gval;
145 g_value_init (&gval, G_TYPE_UINT);
146 g_object_get_property (gob, getter->param_name, &gval);
147
148 ival = g_value_get_uint (&gval);
149 return (gpointer) ival;
150 }
151 else if (G_IS_PARAM_SPEC_BOOLEAN (gps))
152 {
153 gboolean ival;
154
155 GValue gval;
156 g_value_init (&gval, G_TYPE_BOOLEAN);
157 g_object_get_property (gob, getter->param_name, &gval);
158
159 ival = g_value_get_boolean (&gval);
160 return GINT_TO_POINTER (ival);
161 }
162
163 PWARN ("unhandled parameter type %s for paramter %s",
164 G_PARAM_SPEC_TYPE_NAME (gps), getter->param_name);
165 return NULL;
166 }
167
168 static double
169 qof_gobject_double_getter (gpointer data, QofParam * getter)
170 {
171 GObject *gob = data;
172 double fval;
173
174 GParamSpec *gps = getter->param_userdata;
175
176 /* Note that the return type must actually be of type
177 * getter->param_type but we just follow the hard-coded
178 * mapping below ... */
179 if (G_IS_PARAM_SPEC_FLOAT (gps))
180 {
181 GValue gval;
182 g_value_init (&gval, G_TYPE_FLOAT);
183 g_object_get_property (gob, getter->param_name, &gval);
184
185 fval = g_value_get_float (&gval);
186 return fval;
187 }
188 else if (G_IS_PARAM_SPEC_DOUBLE (gps))
189 {
190 GValue gval;
191 g_value_init (&gval, G_TYPE_DOUBLE);
192 g_object_get_property (gob, getter->param_name, &gval);
193
194 fval = g_value_get_double (&gval);
195 return fval;
196 }
197
198 PWARN ("unhandled parameter type %s for paramter %s",
199 G_PARAM_SPEC_TYPE_NAME (gps), getter->param_name);
200 return 0.0;
201 }
202
203 /* =================================================================== */
204 /* Loop over every instance of the given type in the collection
205 * of instances that we have on hand.
206 */
207 static void
208 qof_gobject_foreach (QofCollection * coll, QofEntityForeachCB cb,
209 gpointer ud)
210 {
211 GSList *n;
212 n = qof_collection_get_data (coll);
213 for (; n; n = n->next)
214 {
215 cb (n->data, ud);
216 }
217 }
218
219 /* =================================================================== */
220
221 void
222 qof_gobject_register (QofType e_type, GObjectClass * obclass)
223 {
224 guint i, j;
225 QofParam *qof_param_list, *qpar;
226 QofObject *class_def;
227 GParamSpec **prop_list, *gparam;
228 guint n_props;
229
230 /* Get the GObject properties, convert to QOF properties */
231 prop_list = g_object_class_list_properties (obclass, &n_props);
232
233 qof_param_list = g_new0 (QofParam, n_props);
234 paramList = g_slist_prepend (paramList, qof_param_list);
235
236 PINFO ("object %s has %d props", e_type, n_props);
237 j = 0;
238 for (i = 0; i < n_props; i++)
239 {
240 gparam = prop_list[i];
241 qpar = &qof_param_list[j];
242
243 PINFO ("param %d %s is type %s",
244 i, gparam->name, G_PARAM_SPEC_TYPE_NAME (gparam));
245
246 qpar->param_name = g_param_spec_get_name (gparam);
247 qpar->param_getfcn = (QofAccessFunc) qof_gobject_getter;
248 qpar->param_setfcn = NULL;
249 qpar->param_userdata = gparam;
250 if ((G_IS_PARAM_SPEC_INT (gparam)) ||
251 (G_IS_PARAM_SPEC_UINT (gparam)) ||
252 (G_IS_PARAM_SPEC_ENUM (gparam)) ||
253 (G_IS_PARAM_SPEC_FLAGS (gparam)))
254 {
255 qpar->param_type = QOF_TYPE_INT32;
256 j++;
257 }
258 else if ((G_IS_PARAM_SPEC_INT64 (gparam)) ||
259 (G_IS_PARAM_SPEC_UINT64 (gparam)))
260 {
261 qpar->param_type = QOF_TYPE_INT64;
262 j++;
263 }
264 else if (G_IS_PARAM_SPEC_BOOLEAN (gparam))
265 {
266 qpar->param_type = QOF_TYPE_BOOLEAN;
267 j++;
268 }
269 else if (G_IS_PARAM_SPEC_STRING (gparam))
270 {
271 qpar->param_type = QOF_TYPE_STRING;
272 j++;
273 }
274 else if ((G_IS_PARAM_SPEC_POINTER (gparam)) ||
275 (G_IS_PARAM_SPEC_OBJECT (gparam)))
276 {
277 /* No-op, silently ignore. Someday we should handle this ... */
278 }
279 else if ((G_IS_PARAM_SPEC_FLOAT (gparam)) ||
280 (G_IS_PARAM_SPEC_DOUBLE (gparam)))
281 {
282 qpar->param_getfcn = (QofAccessFunc) qof_gobject_double_getter;
283 qpar->param_type = QOF_TYPE_DOUBLE;
284 j++;
285 }
286 else if (G_IS_PARAM_SPEC_CHAR (gparam))
287 {
288 qpar->param_type = QOF_TYPE_CHAR;
289 j++;
290 }
291 else
292 {
293 PWARN ("Unknown/unhandled parameter type %s on %s:%s\n",
294 G_PARAM_SPEC_TYPE_NAME (gparam), e_type, qpar->param_name);
295 }
296 }
297
298 /* NULL-terminated list! */
299 qof_param_list[j].param_type = NULL;
300
301 qof_class_register (e_type, NULL, qof_param_list);
302
303 /* ------------------------------------------------------ */
304 /* Now do the class itself */
305 class_def = g_new0 (QofObject, 1);
306 classList = g_slist_prepend (classList, class_def);
307
308 class_def->interface_version = QOF_OBJECT_VERSION;
309 class_def->e_type = e_type;
310 /* We could let the user specify a "nick" here, but
311 * the actual class name seems reasonable, e.g. for debugging. */
312 class_def->type_label = G_OBJECT_CLASS_NAME (obclass);
313 class_def->create = NULL;
314 class_def->book_begin = NULL;
315 class_def->book_end = NULL;
316 class_def->is_dirty = NULL;
317 class_def->mark_clean = NULL;
318 class_def->foreach = qof_gobject_foreach;
319 class_def->printable = NULL;
320 class_def->version_cmp = NULL;
321
322 qof_object_register (class_def);
323 }
324
325 /* ======================= END OF FILE ================================ */
PINFO
#define PINFO(format, args...)
Definition: qoflog.h:199
qof_book_get_collection
QofCollection * qof_book_get_collection(QofBook *book, QofIdType entity_type)
Definition: qofbook.c:220
_QofParam
Definition: qofclass.h:195
QOF_OBJECT_VERSION
#define QOF_OBJECT_VERSION
Definition: qofobject.h:57
qof_class_register
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
registers a new object class with the Qof subsystem.
Definition: qofclass.c:93
QofEntityForeachCB
void(* QofEntityForeachCB)(QofEntity *, gpointer user_data)
Definition: qofid.h:187
qof_gobject_register_instance
void qof_gobject_register_instance(QofBook *book, QofType type, GObject *gob)
Definition: qofgobj.c:93
_QofObject::create
gpointer(* create)(QofBook *)
Definition: qofobject.h:80
qofgobj.h
QOF to GLib GObject mapping.
_QofObject::book_end
void(* book_end)(QofBook *)
Definition: qofobject.h:90
QofCollection
struct QofCollection_s QofCollection
Definition: qofid.h:138
_QofObject::book_begin
void(* book_begin)(QofBook *)
Definition: qofobject.h:85
qof_query_init
void qof_query_init(void)
Definition: qofquery.c:1375
qof_gobject_init
void qof_gobject_init(void)
Definition: qofgobj.c:48
_QofObject::mark_clean
void(* mark_clean)(QofCollection *)
Definition: qofobject.h:96
qof_collection_set_data
void qof_collection_set_data(QofCollection *col, gpointer user_data)
Definition: qofid.c:394
_QofObject
Definition: qofobject.h:70
qof_gobject_register
void qof_gobject_register(QofType e_type, GObjectClass *obclass)
Definition: qofgobj.c:222
QofAccessFunc
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:169
_QofObject::is_dirty
gboolean(* is_dirty)(QofCollection *)
Definition: qofobject.h:93
QofType
const gchar * QofType
Definition: qofclass.h:150
qof_object_register
gboolean qof_object_register(const QofObject *object)
Definition: qofobject.c:278
qof_collection_get_data
gpointer qof_collection_get_data(QofCollection *col)
Definition: qofid.c:388
PWARN
#define PWARN(format, args...)
Definition: qoflog.h:191
_QofObject::printable
const gchar *(* printable)(gpointer instance)
Definition: qofobject.h:109
_QofBook
Definition: qofbook-p.h:48
_QofObject::foreach
void(* foreach)(QofCollection *, QofEntityForeachCB, gpointer)
Definition: qofobject.h:105
_QofObject::version_cmp
gint(* version_cmp)(gpointer instance_left, gpointer instance_right)
Definition: qofobject.h:119
QofLogModule
const gchar * QofLogModule
Definition: qofid.h:85