qofgobj.c

00001 /********************************************************************\
00002  * qofgobj.c -- QOF to GLib GObject mapping                         *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00020  *                                                                  *
00021 \********************************************************************/
00022 
00023 #include "config.h"
00024 #include <glib.h>
00025 #include "qof.h"
00026 #include "qofgobj.h"
00027 
00028 static QofLogModule log_module = QOF_MOD_QUERY;
00029 
00030 static gboolean initialized = FALSE;
00031 static GSList *paramList = NULL;
00032 static GSList *classList = NULL;
00033 
00034 /* =================================================================== */
00035 
00036 #if 0
00037 static gboolean 
00038 clear_table (gpointer key, gpointer value, gpointer user_data)
00039 {
00040   g_slist_free (value);
00041   return TRUE;
00042 }
00043 #endif
00044 
00045 void 
00046 qof_gobject_init(void)
00047 {
00048   if (initialized) return;
00049   initialized = TRUE;
00050                                                                                 
00051   // gobjectClassTable = g_hash_table_new (g_str_hash, g_str_equal);
00052 
00053   /* Init the other subsystems that we need */
00054   qof_object_initialize();
00055   qof_query_init ();
00056 }
00057 
00058 void 
00059 qof_gobject_shutdown (void)
00060 {
00061   GSList *n;
00062   
00063   if (!initialized) return;
00064   initialized = FALSE;
00065                                                                                 
00066 //  GSList *n;
00067   for (n=paramList; n; n=n->next) g_free(n->data);
00068   g_slist_free (paramList);
00069 
00070   for (n=classList; n; n=n->next) g_free(n->data);
00071   g_slist_free (classList);
00072 
00073 #if 0
00074   // XXX also need to walk over books, and collection and delete
00075   // the collection get_data instance lists !!
00076   // without this we have a memory leak !!
00077   g_hash_table_foreach_remove (gobjectParamTable, clear_table, NULL);
00078   g_hash_table_destroy (gobjectParamTable);
00079 #endif
00080 }
00081 
00082 /* =================================================================== */
00083 
00084 #define GOBJECT_TABLE  "GobjectTable"
00085 
00086 void 
00087 qof_gobject_register_instance (QofBook *book, QofType type, GObject *gob)
00088 {
00089   QofCollection *coll;
00090   GSList *instance_list;
00091   
00092   if (!book || !type) return;
00093 
00094   coll = qof_book_get_collection (book, type);
00095 
00096   instance_list = qof_collection_get_data (coll);
00097   instance_list = g_slist_prepend (instance_list, gob);
00098   qof_collection_set_data (coll, instance_list);
00099 }
00100 
00101 /* =================================================================== */
00102 
00103 static gpointer
00104 qof_gobject_getter (gpointer data, QofParam *getter)
00105 {
00106   GObject *gob = data;
00107   const char *str;
00108 
00109   GParamSpec *gps = getter->param_userdata;
00110 
00111   /* Note that the return type must actually be of type
00112    * getter->param_type but we just follow the hard-coded 
00113    * mapping below ... */
00114   if (G_IS_PARAM_SPEC_STRING(gps))
00115   {
00116     GValue gval = {G_TYPE_INVALID};
00117     g_value_init (&gval, G_TYPE_STRING);
00118     g_object_get_property (gob, getter->param_name, &gval);
00119 
00120     str = g_value_get_string (&gval);
00121     return (gpointer) str;
00122   }
00123   else
00124   if (G_IS_PARAM_SPEC_INT(gps))
00125   {
00126     long ival;
00127     
00128     GValue gval = {G_TYPE_INVALID};
00129     g_value_init (&gval, G_TYPE_INT);
00130     g_object_get_property (gob, getter->param_name, &gval);
00131 
00132     ival = g_value_get_int (&gval);
00133     return (gpointer) ival;
00134   }
00135   else
00136   if (G_IS_PARAM_SPEC_UINT(gps))
00137   {
00138     long ival;
00139     GValue gval = {G_TYPE_INVALID};
00140     g_value_init (&gval, G_TYPE_UINT);
00141     g_object_get_property (gob, getter->param_name, &gval);
00142 
00143     ival = g_value_get_uint (&gval);
00144     return (gpointer) ival;
00145   }
00146   else
00147   if (G_IS_PARAM_SPEC_BOOLEAN(gps))
00148   {
00149     gboolean ival;
00150     
00151     GValue gval = {G_TYPE_INVALID};
00152     g_value_init (&gval, G_TYPE_BOOLEAN);
00153     g_object_get_property (gob, getter->param_name, &gval);
00154 
00155     ival = g_value_get_boolean (&gval);
00156     return GINT_TO_POINTER( ival);
00157   }
00158 
00159   PWARN ("unhandled parameter type %s for paramter %s", 
00160           G_PARAM_SPEC_TYPE_NAME(gps), getter->param_name);
00161   return NULL;
00162 }
00163 
00164 static double
00165 qof_gobject_double_getter (gpointer data, QofParam *getter)
00166 {
00167   GObject *gob = data;
00168    double fval;
00169    
00170   GParamSpec *gps = getter->param_userdata;
00171 
00172   /* Note that the return type must actually be of type
00173    * getter->param_type but we just follow the hard-coded 
00174    * mapping below ... */
00175   if (G_IS_PARAM_SPEC_FLOAT(gps))
00176   {
00177     GValue gval = {G_TYPE_INVALID};
00178     g_value_init (&gval, G_TYPE_FLOAT);
00179     g_object_get_property (gob, getter->param_name, &gval);
00180 
00181     fval = g_value_get_float (&gval);
00182     return fval;
00183   }
00184   else
00185   if (G_IS_PARAM_SPEC_DOUBLE(gps))
00186   {
00187     GValue gval = {G_TYPE_INVALID};
00188     g_value_init (&gval, G_TYPE_DOUBLE);
00189     g_object_get_property (gob, getter->param_name, &gval);
00190 
00191     fval = g_value_get_double (&gval);
00192     return fval;
00193   } 
00194 
00195   PWARN ("unhandled parameter type %s for paramter %s", 
00196           G_PARAM_SPEC_TYPE_NAME(gps), getter->param_name);
00197   return 0.0;
00198 }
00199 
00200 /* =================================================================== */
00201 /* Loop over every instance of the given type in the collection
00202  * of instances that we have on hand.
00203  */
00204 static void
00205 qof_gobject_foreach (QofCollection *coll, QofEntityForeachCB cb, gpointer ud)
00206 {
00207   GSList *n;
00208   n = qof_collection_get_data (coll);
00209   for (; n; n=n->next)
00210   {
00211     cb (n->data, ud);
00212   }
00213 }
00214                                                                                 
00215 /* =================================================================== */
00216 
00217 void
00218 qof_gobject_register (QofType e_type, GObjectClass *obclass)
00219 {
00220   int i;
00221   int j;
00222   QofParam *qof_param_list, *qpar;
00223   QofObject *class_def;
00224   GParamSpec **prop_list, *gparam;
00225   guint n_props;
00226 
00227   /* Get the GObject properties, convert to QOF properties */
00228   prop_list = g_object_class_list_properties (obclass, &n_props);
00229 
00230   qof_param_list = g_new0 (QofParam, n_props);
00231   paramList = g_slist_prepend (paramList, qof_param_list);
00232 
00233   PINFO ("object %s has %d props", e_type, n_props);
00234   j=0;
00235   for (i=0; i<n_props; i++)
00236   {
00237     gparam = prop_list[i];
00238     qpar = &qof_param_list[j];
00239 
00240     PINFO ("param %d %s is type %s", 
00241           i, gparam->name, G_PARAM_SPEC_TYPE_NAME(gparam));
00242 
00243     qpar->param_name = g_param_spec_get_name (gparam);
00244     qpar->param_getfcn = (QofAccessFunc)qof_gobject_getter;
00245     qpar->param_setfcn = NULL;
00246     qpar->param_userdata = gparam;
00247     if ((G_IS_PARAM_SPEC_INT(gparam))  ||
00248         (G_IS_PARAM_SPEC_UINT(gparam)) ||
00249         (G_IS_PARAM_SPEC_ENUM(gparam)) ||
00250         (G_IS_PARAM_SPEC_FLAGS(gparam)))
00251     {
00252       qpar->param_type = QOF_TYPE_INT32;
00253       j++;
00254     } 
00255     else
00256     if ((G_IS_PARAM_SPEC_INT64(gparam)) ||
00257         (G_IS_PARAM_SPEC_UINT64(gparam)))
00258     {
00259       qpar->param_type = QOF_TYPE_INT64;
00260       j++;
00261     } 
00262     else
00263     if (G_IS_PARAM_SPEC_BOOLEAN(gparam))
00264     {
00265       qpar->param_type = QOF_TYPE_BOOLEAN;
00266       j++;
00267     } 
00268     else
00269     if (G_IS_PARAM_SPEC_STRING(gparam))
00270     {
00271       qpar->param_type = QOF_TYPE_STRING;
00272       j++;
00273     } 
00274     else
00275     if ((G_IS_PARAM_SPEC_POINTER(gparam)) ||
00276         (G_IS_PARAM_SPEC_OBJECT(gparam)))
00277     {
00278       /* No-op, silently ignore.  Someday we should handle this ...  */
00279     } 
00280     else
00281     if ((G_IS_PARAM_SPEC_FLOAT(gparam)) ||
00282         (G_IS_PARAM_SPEC_DOUBLE(gparam)))
00283     {
00284       qpar->param_getfcn = (QofAccessFunc) qof_gobject_double_getter;
00285       qpar->param_type = QOF_TYPE_DOUBLE;
00286       j++;
00287     } 
00288     else
00289     if (G_IS_PARAM_SPEC_CHAR(gparam))
00290     {
00291       qpar->param_type = QOF_TYPE_CHAR;
00292       j++;
00293     } 
00294     else
00295     {
00296       PWARN ("Unknown/unhandled parameter type %s on %s:%s\n", 
00297       G_PARAM_SPEC_TYPE_NAME(gparam), e_type, qpar->param_name);
00298     }
00299   }
00300 
00301   /* NULL-terminated list! */
00302   qof_param_list[j].param_type = NULL;
00303 
00304   qof_class_register (e_type, NULL, qof_param_list);
00305 
00306   /* ------------------------------------------------------ */
00307    /* Now do the class itself */
00308   class_def = g_new0 (QofObject, 1);
00309   classList = g_slist_prepend (classList, class_def);
00310 
00311   class_def->interface_version = QOF_OBJECT_VERSION;
00312   class_def->e_type = e_type;
00313   /* We could let the user specify a "nick" here, but
00314    * the actual class name seems reasonable, e.g. for debugging. */
00315   class_def->type_label = G_OBJECT_CLASS_NAME (obclass);
00316   class_def->create = NULL;
00317   class_def->book_begin = NULL;
00318   class_def->book_end = NULL;
00319   class_def->is_dirty = NULL;
00320   class_def->mark_clean = NULL;
00321   class_def->foreach = qof_gobject_foreach;
00322   class_def->printable = NULL;
00323   class_def->version_cmp = NULL;
00324  
00325   qof_object_register (class_def);
00326 }
00327 
00328 /* ======================= END OF FILE ================================ */

Generated on Fri May 12 18:00:33 2006 for QOF by  doxygen 1.4.4