00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00032 #include "config.h"
00033 #ifdef HAVE_QOF
00034
00035 #include <glib.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include <qof/qof.h>
00040
00041 #include "duifield.h"
00042 #include "duifield-qof.h"
00043 #include "duifilter.h"
00044 #include "duiresolver.h"
00045 #include "interface.h"
00046 #include "perr.h"
00047
00049 struct qof_field_s
00050 {
00051 QofBook *book;
00052 QofEntity * entity;
00053 gchar * property;
00054 gchar * value;
00055 };
00056
00057
00058
00059 static void
00060 qof_field_clear (DuiField *f)
00061 {
00062 struct qof_field_s * gf = (struct qof_field_s *)get_gobj_field (f);
00063 g_free (f->fieldname);
00064 g_free (gf->property);
00065 g_free (gf->value);
00066 f->type = DUI_FIELD_NONE;
00067 }
00068
00069
00072 static gboolean
00073 dui_field_find_qof_entity (DuiField *matcher)
00074 {
00075 QofCollection *lection;
00076 GUID guid;
00077 gboolean ok;
00078 QofEntity *ent;
00079 struct qof_field_s *qf = (struct qof_field_s *)get_gobj_field (matcher);
00080
00081 if ((NULL != qf->property) && strcmp (qf->property, "guid"))
00082 {
00083
00084
00085 PERR ("non-null matching properties not handled at this time.");
00086 return FALSE;
00087 }
00088
00089
00090 if (NULL == qf->book)
00091 {
00092 PERR ("Expecting a book to be set for the matcher");
00093 return FALSE;
00094 }
00095
00096 lection = qof_book_get_collection (qf->book, matcher->fieldname);
00097
00098 ok = string_to_guid (qf->value, &guid);
00099 if (!ok)
00100 {
00101 PERR ("Expecting a GUID, got \"%s\"", qf->value);
00102 return FALSE;
00103 }
00104
00105 ent = qof_collection_lookup_entity (lection, &guid);
00106 if (NULL == ent)
00107 {
00108 ent = qof_object_new_instance (matcher->fieldname, qf->book);
00109 qof_entity_set_guid (ent, &guid);
00110 }
00111 qf->entity = ent;
00112
00113 return TRUE;
00114 }
00115
00116 static void
00117 resolve_qof_target (DuiField *target, DuiField *matcher)
00118 {
00119 struct qof_field_s *qt = (struct qof_field_s *)get_gobj_field (target);
00120 struct qof_field_s *qm = (struct qof_field_s *)get_gobj_field (matcher);
00121 if (!target || !matcher) return;
00122 qt->book = qm->book;
00123 qt->entity = qm->entity;
00124 }
00125
00126
00130 static const char *
00131 get_qof_value (DuiField *fs)
00132 {
00133 const QofParam *qp;
00134 gpointer getter;
00135 struct qof_field_s *gf = (struct qof_field_s *)get_gobj_field (fs);
00136
00137 if (!gf->entity)
00138 {
00139 PERR ("Can't find the QOF instance \'%s\'\n", fs->fieldname);
00140 return NULL;
00141 }
00142
00143 qp = qof_class_get_parameter (fs->fieldname, gf->property);
00144 if (NULL == qp)
00145 {
00146 PERR ("Cannot find parameter to get %s:%s\n",
00147 fs->fieldname, gf->property);
00148 return NULL;
00149 }
00150
00151 getter = qof_class_get_parameter_getter (fs->fieldname, gf->property);
00152
00153 if (!strcmp (qp->param_type, QOF_TYPE_STRING))
00154 {
00155 const gchar * (*fn) (QofEntity *) = getter;
00156 const gchar * str = fn (gf->entity);
00157 return str;
00158 }
00159 else
00160 if (!strcmp (qp->param_type, QOF_TYPE_INT32))
00161 {
00162 gint32 (*fn) (QofEntity *) = getter;
00163 gint32 ival = fn (gf->entity);
00164
00165 if (gf->value) g_free (gf->value);
00166 gf->value = g_strdup_printf ("%d", ival);
00167 return gf->value;
00168 }
00169 else
00170 if (!strcmp (qp->param_type, QOF_TYPE_INT64))
00171 {
00172 gint64 (*fn) (QofEntity *) = getter;
00173 gint64 ival = fn (gf->entity);
00174
00175 if (gf->value) g_free (gf->value);
00176 gf->value = g_strdup_printf ("%"G_GINT64_FORMAT"", ival);
00177 return gf->value;
00178 }
00179 else
00180 if (!strcmp (qp->param_type, QOF_TYPE_DOUBLE))
00181 {
00182 gdouble (*fn) (QofEntity *) = getter;
00183 gdouble ival = fn (gf->entity);
00184
00185 if (gf->value) g_free (gf->value);
00186 gf->value = g_strdup_printf ("%24.18g", ival);
00187 return gf->value;
00188 }
00189 else
00190 if (!strcmp (qp->param_type, QOF_TYPE_BOOLEAN))
00191 {
00192 gboolean (*fn) (QofEntity *) = getter;
00193 gboolean ival = fn (gf->entity);
00194
00195 if (gf->value) g_free (gf->value);
00196 if (ival)
00197 {
00198 gf->value = g_strdup ("T");
00199 }
00200 else
00201 {
00202 gf->value = g_strdup ("F");
00203 }
00204 return gf->value;
00205 }
00206 else
00207 if (!strcmp (qp->param_type, QOF_TYPE_GUID))
00208 {
00209 GUID * (*fn) (QofEntity *) = getter;
00210 GUID *guid = fn (gf->entity);
00211
00212 if (gf->value) g_free (gf->value);
00213 gf->value = g_new (char, GUID_ENCODING_LENGTH+1);
00214 guid_to_string_buff (guid, gf->value);
00215 return gf->value;
00216 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 PERR ("unsupported type %s for %s:%s\n",
00235 qp->param_type, fs->fieldname, gf->property);
00236 return NULL;
00237 }
00238
00240 static void
00241 set_qof_value (DuiField *fs, const char *value)
00242 {
00243 QofType pt;
00244 gpointer setter;
00245 struct qof_field_s *gf = (struct qof_field_s *)get_gobj_field (fs);
00246 g_return_if_fail (gf->entity);
00247 ENTER (" %s::%s = %s\n", fs->fieldname, gf->property, value);
00248
00249 setter = qof_class_get_parameter_setter (fs->fieldname, gf->property);
00250 if (!setter) return;
00251
00252 pt = qof_class_get_parameter_type (fs->fieldname, gf->property);
00253 if (!strcmp (pt, QOF_TYPE_STRING))
00254 {
00255 void (*sf) (QofEntity *, const char *) = setter;
00256 (*sf) (gf->entity, value);
00257 }
00258 else
00259 if (!strcmp (pt, QOF_TYPE_INT32))
00260 {
00261 gint32 ival = atoi (value);
00262 void (*sf) (QofEntity *, int) = setter;
00263 (*sf) (gf->entity, ival);
00264 }
00265 else
00266 if (!strcmp (pt, QOF_TYPE_INT64))
00267 {
00268 gint64 ival = atoll (value);
00269 void (*sf) (QofEntity *, gint64) = setter;
00270 (*sf) (gf->entity, ival);
00271 }
00272 else
00273 if (!strcmp (pt, QOF_TYPE_DOUBLE))
00274 {
00275 gdouble ival = strtod (value, NULL);
00276 void (*sf) (QofEntity *, gdouble) = setter;
00277 (*sf) (gf->entity, ival);
00278 }
00279 else
00280 if (!strcmp (pt, QOF_TYPE_BOOLEAN))
00281 {
00282 gboolean ival = dui_util_bool_to_int (value);
00283 void (*sf) (QofEntity *, gboolean) = setter;
00284 (*sf) (gf->entity, ival);
00285 }
00286 else
00287 if (!strcmp (pt, QOF_TYPE_TIME))
00288 {
00289 void (*time_setter) (QofEntity *, QofTime *);
00290 QofDate *qd;
00291 QofTime *qt;
00292
00293 time_setter = (void (*)(QofEntity *, QofTime*)) setter;
00294 qd = qof_date_parse (value, QOF_DATE_FORMAT_UTC);
00295 if(qd)
00296 {
00297 const QofParam * p;
00298 p = qof_class_get_parameter (fs->fieldname, gf->property);
00299 qt = qof_date_to_qtime (qd);
00300 qof_util_param_edit ((QofInstance *) gf->entity, p);
00301 time_setter (gf->entity, qt);
00302 qof_util_param_commit ((QofInstance *) gf->entity, p);
00303 qof_date_free (qd);
00304 }
00305 else
00306 PERR (" failed to parse date string");
00307 }
00309
00310
00311
00312
00313
00314
00315
00316
00317 else
00318 if (!strcmp (pt, QOF_TYPE_GUID))
00319 {
00320 GUID guid;
00321 if (TRUE == string_to_guid (value, &guid))
00322 {
00323 void (*sf) (QofEntity *, GUID *) = setter;
00324 (*sf) (gf->entity, &guid);
00325 }
00326 }
00327 else
00328 if (!strcmp (pt, QOF_TYPE_NUMERIC))
00329 {
00330 QofNumeric num;
00331 void (*sf) (QofEntity *, QofNumeric *) = setter;
00332 value = qof_numeric_to_string (num);
00333 (*sf) (gf->entity, &num);
00334 }
00335 else
00336 {
00337
00338 PERR ("Unsupported type %s", pt);
00339 }
00340 }
00341
00342 static void
00343 set_qof_match_value (DuiField *fs, const char *value)
00344 {
00345 struct qof_field_s *gf;
00346
00347 g_return_if_fail (fs);
00348 gf = (struct qof_field_s *)get_gobj_field (fs);
00349 gf->value = g_strdup (value);
00350 }
00351
00352 void
00353 dui_field_set_qof (DuiField *ft, const gchar * obj_type,
00354 const gchar * prop)
00355 {
00356 struct qof_field_s *gf;
00357
00358 gf = (struct qof_field_s *)get_gobj_field (ft);
00359 ft->type = DUI_FIELD_QOF;
00360 ft->fieldname = g_strdup (obj_type);
00361
00362 ft->get_field_value = get_qof_value;
00363 ft->set_field_value = set_qof_value;
00364 ft->clear_field = qof_field_clear;
00365 ft->iter_column = resolve_qof_target;
00366
00367 gf->entity = NULL;
00368 gf->property = g_strdup (prop);
00369 gf->value = NULL;
00370 }
00371
00372 void
00373 dui_field_set_qof_match (DuiField *ft, const gchar * obj_type,
00374 const gchar * prop)
00375 {
00376 struct qof_field_s *gf;
00377
00378 ft->type = DUI_FIELD_QOF_MATCH;
00379 ft->fieldname = g_strdup (obj_type);
00380
00381 ft->get_field_value = NULL;
00382 ft->set_field_value = set_qof_match_value;
00383 ft->clear_field = qof_field_clear;
00384 ft->iter_next = dui_field_find_qof_entity;
00385
00386 gf = (struct qof_field_s *)get_gobj_field (ft);
00387 gf->entity = NULL;
00388 gf->property = g_strdup (prop);
00389 gf->value = NULL;
00390 }
00391
00392
00393
00394 void
00395 dui_field_resolve_qof (DuiField *fld, gpointer ud)
00396 {
00397 QofBook *book = ud;
00398 struct qof_field_s *gf = (struct qof_field_s *)get_gobj_field (fld);
00399 if ((!DUI_FIELD_IS_TYPE(fld,DUI_FIELD_QOF)) &&
00400 (!DUI_FIELD_IS_TYPE(fld,DUI_FIELD_QOF_MATCH))) return;
00401
00402 gf->book = book;
00403 }
00404
00405 #endif
00406