GnuCash 2.4.99
qofreference.c
00001 /***************************************************************************
00002  *            qofreference.c
00003  *
00004  *  Mon Feb 13 21:06:44 2006
00005  *  Copyright  2006  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  */
00023 
00024 #include "config.h"
00025 #include <glib.h>
00026 #include "qofreference.h"
00027 
00028 static void
00029 entity_set_reference_cb(QofInstance *ent, gpointer user_data)
00030 {
00031     void (*reference_setter) (QofInstance*, QofInstance*);
00032     void (*choice_setter) (QofInstance*, QofInstance*);
00033     void (*collect_setter)(QofInstance*, QofCollection*);
00034     QofInstanceReference *ref;
00035     GList *book_ref_list;
00036     QofCollection *coll;
00037     QofIdType type;
00038     QofInstance *reference;
00039     QofBook *partial_book;
00040 
00041     partial_book = (QofBook*)user_data;
00042     g_return_if_fail(partial_book && ent);
00043     reference = NULL;
00044     coll = NULL;
00045     book_ref_list = qof_book_get_data(partial_book, ENTITYREFERENCE);
00046     while (book_ref_list)
00047     {
00048         ref = (QofInstanceReference*)book_ref_list->data;
00049         if (0 == guid_compare(ref->ref_guid, qof_instance_get_guid(ent)))
00050         {
00051             /* avoid setting the entity's own guid as a reference. */
00052             book_ref_list = g_list_next(book_ref_list);
00053             continue;
00054         }
00055         if (qof_object_is_choice(ent->e_type))
00056         {
00057             type = ref->choice_type;
00058         }
00059         type = ref->param->param_type;
00060         coll = qof_book_get_collection(partial_book, type);
00061         reference = qof_collection_lookup_entity(coll, ref->ref_guid);
00062         reference_setter = (void(*)(QofInstance*, QofInstance*))ref->param->param_setfcn;
00063         if ((reference) && (reference_setter))
00064         {
00065             qof_begin_edit((QofInstance*)ent);
00066             qof_begin_edit((QofInstance*)reference);
00067             reference_setter(ent, reference);
00068             qof_commit_edit((QofInstance*)ent);
00069             qof_commit_edit((QofInstance*)reference);
00070         }
00071         /* collect and choice handling */
00072         collect_setter = (void(*)(QofInstance*, QofCollection*))ref->param->param_setfcn;
00073         choice_setter = (void(*)(QofInstance*, QofInstance*))ref->param->param_setfcn;
00074         if ((0 == safe_strcmp(ref->param->param_type, QOF_TYPE_COLLECT)) &&
00075                 (0 == guid_compare(qof_instance_get_guid(ent), ref->ent_guid)) &&
00076                 (0 == safe_strcmp(ref->type, ent->e_type)))
00077         {
00078             QofCollection *temp_col;
00079             char cm_sa[GUID_ENCODING_LENGTH + 1];
00080 
00081             temp_col = ref->param->param_getfcn(ent, ref->param);
00082             coll = qof_book_get_collection(partial_book,
00083                                            qof_collection_get_type(temp_col));
00084             guid_to_string_buff(ref->ref_guid, cm_sa);
00085             reference = qof_collection_lookup_entity(coll, ref->ref_guid);
00086             if (reference)
00087             {
00088                 qof_collection_add_entity(temp_col, reference);
00089                 qof_begin_edit((QofInstance*)ent);
00090                 qof_begin_edit((QofInstance*)reference);
00091                 if (collect_setter)
00092                 {
00093                     collect_setter(ent, temp_col);
00094                 }
00095                 qof_commit_edit((QofInstance*)ent);
00096                 qof_commit_edit((QofInstance*)reference);
00097                 qof_collection_destroy(temp_col);
00098             }
00099         }
00100         if (0 == safe_strcmp(ref->param->param_type, QOF_TYPE_CHOICE))
00101         {
00102             coll = qof_book_get_collection(partial_book, ref->type);
00103             reference = qof_collection_lookup_entity(coll, ref->ref_guid);
00104             qof_begin_edit((QofInstance*)ent);
00105             qof_begin_edit((QofInstance*)reference);
00106             if (choice_setter)
00107             {
00108                 choice_setter(ent, reference);
00109             }
00110             qof_commit_edit((QofInstance*)ent);
00111             qof_commit_edit((QofInstance*)reference);
00112         }
00113         book_ref_list = g_list_next(book_ref_list);
00114     }
00115 }
00116 
00117 static void
00118 set_each_type(QofObject *obj, gpointer user_data)
00119 {
00120     QofBook *book;
00121 
00122     book = (QofBook*)user_data;
00123     qof_object_foreach(obj->e_type, book, entity_set_reference_cb, book);
00124 }
00125 
00126 static QofInstanceReference*
00127 create_reference(QofInstance *ent, const QofParam *param)
00128 {
00129     QofInstanceReference *reference;
00130     QofInstance          *ref_ent;
00131     const GncGUID         *cm_guid;
00132     char                cm_sa[GUID_ENCODING_LENGTH + 1];
00133     gchar              *cm_string;
00134 
00135     g_return_val_if_fail(ent, NULL);
00136     ref_ent = QOF_INSTANCE(param->param_getfcn(ent, param));
00137     if (!ref_ent)
00138     {
00139         return NULL;
00140     }
00141     reference = g_new0(QofInstanceReference, 1);
00142     reference->type = ent->e_type;
00143     reference->ref_guid = g_new(GncGUID, 1);
00144     reference->ent_guid = qof_instance_get_guid(ent);
00145     if (qof_object_is_choice(ent->e_type))
00146     {
00147         reference->choice_type = ref_ent->e_type;
00148     }
00149     reference->param = param;
00150     cm_guid = qof_instance_get_guid(ref_ent);
00151     guid_to_string_buff(cm_guid, cm_sa);
00152     cm_string = g_strdup(cm_sa);
00153     if (TRUE == string_to_guid(cm_string, reference->ref_guid))
00154     {
00155         g_free(cm_string);
00156         return reference;
00157     }
00158     g_free(cm_string);
00159     return NULL;
00160 }
00161 
00162 QofInstanceReference*
00163 qof_instance_get_reference_from(QofInstance *ent, const QofParam *param)
00164 {
00165     g_return_val_if_fail(param, NULL);
00166     param = qof_class_get_parameter(ent->e_type, param->param_name);
00167     g_return_val_if_fail(0 != safe_strcmp(param->param_type, QOF_TYPE_COLLECT), NULL);
00168     return create_reference(ent, param);
00169 }
00170 
00171 void qof_book_set_references(QofBook *book)
00172 {
00173     gboolean partial;
00174 
00175     partial =
00176         (gboolean)GPOINTER_TO_INT(qof_book_get_data(book, PARTIAL_QOFBOOK));
00177     g_return_if_fail(partial);
00178     qof_object_foreach_type(set_each_type, book);
00179 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines