|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * SX-book.c -- scheduled transaction dataset access * 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 * FILE: 00024 * SX-book.c 00025 * 00026 * FUNCTION: 00027 * Anchor Scheduled Transaction Info into the book. 00028 * See src/doc/books.txt for design overview. 00029 * 00030 * HISTORY: 00031 * Copyright (c) 2003 Linas Vepstas <linas@linas.org> 00032 */ 00033 00034 #include "config.h" 00035 00036 #include <stdlib.h> 00037 #include <string.h> 00038 00039 #include <glib.h> 00040 00041 #include "gnc-engine.h" 00042 #include "Account.h" 00043 #include "Split.h" 00044 #include "SchedXaction.h" 00045 #include "SX-book.h" 00046 #include "SX-book-p.h" 00047 #include "gnc-event.h" 00048 00049 #undef G_LOG_DOMAIN 00050 #define G_LOG_DOMAIN "gnc.engine.sx" 00051 00052 /* XXX this whole file is crufty, it doesn't really use entities 00053 * in the most efficient/best way */ 00054 00055 /* ====================================================================== */ 00056 00057 static Account * 00058 gnc_collection_get_template_root( const QofCollection *col ) 00059 { 00060 return qof_collection_get_data (col); 00061 } 00062 00063 Account * 00064 gnc_book_get_template_root( const QofBook *book ) 00065 { 00066 QofCollection *col; 00067 if (!book) return NULL; 00068 col = qof_book_get_collection (book, GNC_ID_SXTG); 00069 return gnc_collection_get_template_root (col); 00070 } 00071 00072 static void 00073 gnc_collection_set_template_root (QofCollection *col, 00074 Account *templateRoot) 00075 { 00076 Account *old_root; 00077 if (!col) return; 00078 00079 old_root = gnc_collection_get_template_root (col); 00080 if (old_root == templateRoot) return; 00081 00082 qof_collection_set_data (col, templateRoot); 00083 00084 if (old_root) 00085 { 00086 xaccAccountBeginEdit (old_root); 00087 xaccAccountDestroy (old_root); 00088 } 00089 } 00090 00091 00092 void 00093 gnc_book_set_template_root (QofBook *book, Account *templateRoot) 00094 { 00095 QofCollection *col; 00096 if (!book) return; 00097 00098 if (templateRoot && gnc_account_get_book(templateRoot) != book) 00099 { 00100 g_critical("cannot mix and match books freely!"); 00101 return; 00102 } 00103 00104 col = qof_book_get_collection (book, GNC_ID_SXTG); 00105 gnc_collection_set_template_root (col, templateRoot); 00106 } 00107 00108 00109 /* ====================================================================== */ 00110 /* gncObject function implementation and registration */ 00111 00112 static void 00113 sxtg_book_begin (QofBook *book) 00114 { 00115 Account *root; 00116 00117 root = xaccMallocAccount(book); 00118 xaccAccountBeginEdit(root); 00119 xaccAccountSetType(root, ACCT_TYPE_ROOT); 00120 xaccAccountSetName(root, "Template Root"); 00121 xaccAccountCommitEdit(root); 00122 gnc_book_set_template_root (book, root); 00123 } 00124 00125 static void 00126 sxtg_book_end (QofBook *book) 00127 { 00128 // gnc_book_set_template_root (book, NULL); 00129 } 00130 00131 static gboolean 00132 sxtg_is_dirty(const QofCollection *col) 00133 { 00134 Account *root; 00135 GList *descendants, *node; 00136 gboolean dirty = FALSE; 00137 00138 root = gnc_collection_get_template_root(col); 00139 descendants = gnc_account_get_descendants(root); 00140 for (node = descendants; node; node = g_list_next(node)) 00141 { 00142 if (qof_instance_is_dirty(node->data)) 00143 { 00144 dirty = TRUE; 00145 break; 00146 } 00147 } 00148 g_list_free(descendants); 00149 00150 return dirty; 00151 } 00152 00153 static void 00154 sxtg_mark_clean(QofCollection *col) 00155 { 00156 Account *root; 00157 GList *descendants; 00158 00159 root = gnc_collection_get_template_root(col); 00160 qof_collection_mark_clean(col); 00161 00162 descendants = gnc_account_get_descendants(root); 00163 g_list_foreach(descendants, (GFunc)qof_instance_mark_clean, NULL); 00164 g_list_free(descendants); 00165 } 00166 00167 #ifdef _MSC_VER 00168 /* MSVC compiler doesn't have C99 "designated initializers" 00169 * so we wrap them in a macro that is empty on MSVC. */ 00170 # define DI(x) /* */ 00171 #else 00172 # define DI(x) x 00173 #endif 00174 static QofObject sxtg_object_def = 00175 { 00176 DI(.interface_version = ) QOF_OBJECT_VERSION, 00177 DI(.e_type = ) GNC_ID_SXTG, 00178 DI(.type_label = ) "Scheduled Transaction Templates", 00179 DI(.create = ) NULL, 00180 DI(.book_begin = ) sxtg_book_begin, 00181 DI(.book_end = ) sxtg_book_end, 00182 DI(.is_dirty = ) sxtg_is_dirty, 00183 DI(.mark_clean = ) sxtg_mark_clean, 00184 DI(.foreach = ) NULL, 00185 DI(.printable = ) NULL, 00186 }; 00187 00188 /* ====================================================================== */ 00189 00190 SchedXactions* 00191 gnc_collection_get_schedxactions(const QofCollection *col) 00192 { 00193 SchedXactions *rtn = qof_collection_get_data(col); 00194 // @@assert(rtn != null); 00195 return rtn; 00196 } 00197 00198 SchedXactions* 00199 gnc_book_get_schedxactions(QofBook *book) 00200 { 00201 QofCollection *col; 00202 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION); 00203 return gnc_collection_get_schedxactions(col); 00204 } 00205 00206 void 00207 gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx) 00208 { 00209 if (g_list_find(sxes->sx_list, sx) != NULL) 00210 return; 00211 sxes->sx_list = g_list_append(sxes->sx_list, sx); 00212 qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_ADDED, (gpointer)sx); 00213 } 00214 00215 void 00216 gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx) 00217 { 00218 GList *to_remove; 00219 to_remove = g_list_find(sxes->sx_list, sx); 00220 if (to_remove == NULL) 00221 return; 00222 sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove); 00223 qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_REMOVED, (gpointer)sx); 00224 } 00225 00226 /* ====================================================================== */ 00227 /* SX-trans stuff */ 00228 00229 /* GObject initialization */ 00230 QOF_GOBJECT_IMPL(gnc_schedxactions, SchedXactions, QOF_TYPE_INSTANCE); 00231 00232 static void 00233 gnc_schedxactions_init(SchedXactions* sxs) 00234 { 00235 } 00236 00237 static void 00238 gnc_schedxactions_dispose_real (GObject *sxsp) 00239 { 00240 } 00241 00242 static void 00243 gnc_schedxactions_finalize_real(GObject* sxsp) 00244 { 00245 } 00246 00247 static void 00248 mark_sx_clean(gpointer data, gpointer user_data) 00249 { 00250 SchedXaction *sx = (SchedXaction *) data; 00251 qof_instance_mark_clean (QOF_INSTANCE(sx)); 00252 } 00253 00254 static void 00255 book_sxes_setup(QofBook *book) 00256 { 00257 QofCollection *col; 00258 SchedXactions *sxes; 00259 00260 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION); 00261 sxes = g_object_new (GNC_TYPE_SCHEDXACTIONS, NULL); 00262 g_assert(sxes); 00263 qof_instance_init_data(&sxes->inst, GNC_ID_SXES, book); 00264 sxes->sx_list = NULL; 00265 sxes->sx_notsaved = TRUE; 00266 qof_collection_set_data(col, sxes); 00267 } 00268 00269 static void 00270 book_sxes_end(QofBook* book) 00271 { 00272 QofCollection *col; 00273 SchedXactions *sxes; 00274 00275 col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION); 00276 sxes = qof_collection_get_data(col); 00277 if (sxes != NULL) 00278 { 00279 g_object_unref(sxes); 00280 qof_collection_set_data(col, NULL); 00281 } 00282 } 00283 00284 static void 00285 book_sxns_mark_saved(QofCollection *col) 00286 { 00287 SchedXactions *sxl; 00288 sxl = gnc_collection_get_schedxactions(col); 00289 if (!sxl) 00290 return; 00291 sxl->sx_notsaved = FALSE; 00292 g_list_foreach(sxl->sx_list, 00293 mark_sx_clean, 00294 NULL); 00295 } 00296 00297 static gboolean 00298 book_sxlist_notsaved(const QofCollection *col) 00299 { 00300 GList *sxlist; 00301 SchedXactions *sxl; 00302 00303 sxl = gnc_collection_get_schedxactions(col); 00304 if (!sxl) return FALSE; 00305 if (sxl->sx_notsaved) return TRUE; 00306 00307 for (sxlist = sxl->sx_list; 00308 sxlist != NULL; 00309 sxlist = g_list_next(sxlist)) 00310 { 00311 SchedXaction *sx; 00312 sx = (SchedXaction *) (sxlist->data); 00313 if (xaccSchedXactionIsDirty( sx )) 00314 return TRUE; 00315 } 00316 00317 return FALSE; 00318 } 00319 00320 static QofObject sxes_object_def = 00321 { 00322 DI(.interface_version = ) QOF_OBJECT_VERSION, 00323 DI(.e_type = ) GNC_ID_SXES, 00324 DI(.type_label = ) "Scheduled Transactions List", 00325 DI(.create = ) NULL, 00326 DI(.book_begin = ) book_sxes_setup, 00327 DI(.book_end = ) book_sxes_end, 00328 DI(.is_dirty = ) book_sxlist_notsaved, 00329 DI(.mark_clean = ) book_sxns_mark_saved, 00330 DI(.foreach = ) NULL, 00331 DI(.printable = ) NULL, 00332 DI(.version_cmp = ) NULL 00333 }; 00334 00335 static QofObject sxtt_object_def = 00336 { 00337 DI(.interface_version = ) QOF_OBJECT_VERSION, 00338 DI(.e_type = ) GNC_ID_SXTT, 00339 DI(.type_label = ) "Scheduled Transaction Templates", 00340 DI(.create = ) NULL, 00341 DI(.book_begin = ) NULL, 00342 DI(.book_end = ) NULL, 00343 DI(.is_dirty = ) NULL, 00344 DI(.mark_clean = ) NULL, 00345 DI(.foreach = ) NULL, 00346 DI(.printable = ) NULL, 00347 DI(.version_cmp = ) NULL, 00348 }; 00349 00350 gboolean 00351 gnc_sxtt_register (void) 00352 { 00353 if (!qof_object_register(&sxes_object_def)) 00354 return FALSE; 00355 if (!qof_object_register(&sxtg_object_def)) 00356 return FALSE; 00357 return qof_object_register(&sxtt_object_def); 00358 } 00359 00360 GList* 00361 gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct) 00362 { 00363 GList *rtn = NULL; 00364 const GncGUID *acct_guid = qof_entity_get_guid(QOF_INSTANCE(acct)); 00365 GList *sx_list; 00366 SchedXactions *sxactions = gnc_book_get_schedxactions(book); 00367 g_return_val_if_fail( sxactions != NULL, rtn); 00368 for (sx_list = sxactions->sx_list; sx_list != NULL; sx_list = sx_list->next) 00369 { 00370 SchedXaction *sx = (SchedXaction*)sx_list->data; 00371 GList *splits = xaccSchedXactionGetSplits(sx); 00372 for (; splits != NULL; splits = splits->next) 00373 { 00374 Split *s = (Split*)splits->data; 00375 KvpFrame *frame = kvp_frame_get_frame(xaccSplitGetSlots(s), GNC_SX_ID); 00376 GncGUID *sx_split_acct_guid = kvp_frame_get_guid(frame, GNC_SX_ACCOUNT); 00377 if (guid_equal(acct_guid, sx_split_acct_guid)) 00378 { 00379 rtn = g_list_append(rtn, sx); 00380 } 00381 } 00382 } 00383 return rtn; 00384 } 00385 00386 /* ========================== END OF FILE =============================== */
1.7.4