|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * gnc-budget.c -- Implementation of the top level Budgeting API. * 00003 * Copyright (C) 04 sep 2003 Darin Willits <darin@willits.ca> * 00004 * Copyright (C) 2005-2006 Chris Shoemaker <c.shoemaker@cox.net> * 00005 * * 00006 * This program is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU General Public License as * 00008 * published by the Free Software Foundation; either version 2 of * 00009 * the License, or (at your option) any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License* 00017 * along with this program; if not, contact: * 00018 * * 00019 * Free Software Foundation Voice: +1-617-542-5942 * 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00021 * Boston, MA 02110-1301, USA gnu@gnu.org * 00022 * * 00023 \********************************************************************/ 00024 00025 #include "config.h" 00026 #include <glib.h> 00027 #include <glib/gprintf.h> 00028 #include <glib/gi18n.h> 00029 #include <time.h> 00030 #include "qof.h" 00031 #include "qofbookslots.h" 00032 00033 #include "Account.h" 00034 00035 #include "gnc-budget.h" 00036 #include "gnc-commodity.h" 00037 #include "gnc-gdate-utils.h" 00038 00039 static QofLogModule log_module = GNC_MOD_ENGINE; 00040 00041 enum 00042 { 00043 PROP_0, 00044 PROP_NAME, 00045 PROP_DESCRIPTION, 00046 PROP_NUM_PERIODS, 00047 PROP_RECURRENCE, 00048 }; 00049 00050 struct budget_s 00051 { 00052 QofInstance inst; 00053 }; 00054 00055 typedef struct 00056 { 00057 QofInstanceClass parent_class; 00058 } BudgetClass; 00059 00060 typedef struct BudgetPrivate 00061 { 00062 /* The name is an arbitrary string assigned by the user. */ 00063 gchar* name; 00064 00065 /* The description is an arbitrary string assigned by the user. */ 00066 gchar* description; 00067 00068 /* Recurrence (period info) for the budget */ 00069 Recurrence recurrence; 00070 00071 /* Number of periods */ 00072 guint num_periods; 00073 } BudgetPrivate; 00074 00075 #define GET_PRIVATE(o) \ 00076 (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_BUDGET, BudgetPrivate)) 00077 00078 struct _GncBudgetClass 00079 { 00080 QofInstanceClass parent_class; 00081 }; 00082 00083 /* GObject Initialization */ 00084 G_DEFINE_TYPE(GncBudget, gnc_budget, QOF_TYPE_INSTANCE) 00085 00086 static void 00087 gnc_budget_init(GncBudget* budget) 00088 { 00089 BudgetPrivate* priv; 00090 GDate date; 00091 00092 priv = GET_PRIVATE(budget); 00093 priv->name = CACHE_INSERT(_("Unnamed Budget")); 00094 priv->description = CACHE_INSERT(""); 00095 00096 priv->num_periods = 12; 00097 g_date_set_time_t(&date, time(NULL)); 00098 g_date_subtract_days(&date, g_date_get_day(&date) - 1); 00099 recurrenceSet(&priv->recurrence, 1, PERIOD_MONTH, &date, WEEKEND_ADJ_NONE); 00100 } 00101 00102 static void 00103 gnc_budget_dispose (GObject *budgetp) 00104 { 00105 G_OBJECT_CLASS(gnc_budget_parent_class)->dispose(budgetp); 00106 } 00107 00108 static void 00109 gnc_budget_finalize(GObject* budgetp) 00110 { 00111 G_OBJECT_CLASS(gnc_budget_parent_class)->finalize(budgetp); 00112 } 00113 00114 static void 00115 gnc_budget_get_property( GObject* object, 00116 guint prop_id, 00117 GValue* value, 00118 GParamSpec* pspec) 00119 { 00120 GncBudget* budget; 00121 BudgetPrivate* priv; 00122 00123 g_return_if_fail(GNC_IS_BUDGET(object)); 00124 00125 budget = GNC_BUDGET(object); 00126 priv = GET_PRIVATE(budget); 00127 switch ( prop_id ) 00128 { 00129 case PROP_NAME: 00130 g_value_set_string(value, priv->name); 00131 break; 00132 case PROP_DESCRIPTION: 00133 g_value_set_string(value, priv->description); 00134 break; 00135 case PROP_NUM_PERIODS: 00136 g_value_set_uint(value, priv->num_periods); 00137 break; 00138 case PROP_RECURRENCE: 00139 /* TODO: Make this a BOXED type */ 00140 g_value_set_pointer(value, &priv->recurrence); 00141 break; 00142 default: 00143 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 00144 break; 00145 } 00146 } 00147 00148 static void 00149 gnc_budget_set_property( GObject* object, 00150 guint prop_id, 00151 const GValue* value, 00152 GParamSpec* pspec) 00153 { 00154 GncBudget* budget; 00155 00156 g_return_if_fail(GNC_IS_BUDGET(object)); 00157 00158 budget = GNC_BUDGET(object); 00159 switch ( prop_id ) 00160 { 00161 case PROP_NAME: 00162 gnc_budget_set_name(budget, g_value_get_string(value)); 00163 break; 00164 case PROP_DESCRIPTION: 00165 gnc_budget_set_description(budget, g_value_get_string(value)); 00166 break; 00167 case PROP_NUM_PERIODS: 00168 gnc_budget_set_num_periods(budget, g_value_get_uint(value)); 00169 break; 00170 case PROP_RECURRENCE: 00171 gnc_budget_set_recurrence(budget, g_value_get_pointer(value)); 00172 break; 00173 default: 00174 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 00175 break; 00176 } 00177 } 00178 00179 static void 00180 gnc_budget_class_init(GncBudgetClass* klass) 00181 { 00182 GObjectClass* gobject_class = G_OBJECT_CLASS(klass); 00183 00184 gobject_class->dispose = gnc_budget_dispose; 00185 gobject_class->finalize = gnc_budget_finalize; 00186 gobject_class->get_property = gnc_budget_get_property; 00187 gobject_class->set_property = gnc_budget_set_property; 00188 00189 g_type_class_add_private(klass, sizeof(BudgetPrivate)); 00190 00191 g_object_class_install_property( 00192 gobject_class, 00193 PROP_NAME, 00194 g_param_spec_string( "name", 00195 "Budget Name", 00196 "The name is an arbitrary string " 00197 "assigned by the user. It is intended " 00198 "to be a short, 5 to 30 character long string " 00199 "that is displayed by the GUI as the " 00200 "budget mnemonic", 00201 NULL, 00202 G_PARAM_READWRITE)); 00203 00204 g_object_class_install_property( 00205 gobject_class, 00206 PROP_DESCRIPTION, 00207 g_param_spec_string( "description", 00208 "Budget Description", 00209 "The description is an arbitrary string " 00210 "assigned by the user. It is intended " 00211 "to be a longer, 1-5 sentence description of " 00212 "what the budget is all about.", 00213 NULL, 00214 G_PARAM_READWRITE)); 00215 00216 g_object_class_install_property( 00217 gobject_class, 00218 PROP_NUM_PERIODS, 00219 g_param_spec_uint( "num-periods", 00220 "Number of Periods", 00221 "The number of periods for this budget.", 00222 0, 00223 G_MAXUINT32, 00224 12, 00225 G_PARAM_READWRITE)); 00226 00227 g_object_class_install_property( 00228 gobject_class, 00229 PROP_RECURRENCE, 00230 g_param_spec_pointer( "recurrence", 00231 "Budget Recurrence", 00232 "about.", 00233 G_PARAM_READWRITE)); 00234 } 00235 00236 static void commit_err (QofInstance *inst, QofBackendError errcode) 00237 { 00238 PERR ("Failed to commit: %d", errcode); 00239 gnc_engine_signal_commit_error( errcode ); 00240 } 00241 00242 static void 00243 gnc_budget_free(QofInstance *inst) 00244 { 00245 GncBudget *budget; 00246 BudgetPrivate* priv; 00247 00248 if (inst == NULL) 00249 return; 00250 g_return_if_fail(GNC_IS_BUDGET(inst)); 00251 00252 budget = GNC_BUDGET(inst); 00253 priv = GET_PRIVATE(budget); 00254 00255 /* We first send the message that this object is about to be 00256 * destroyed so that any GUI elements can remove it before it is 00257 * actually gone. */ 00258 qof_event_gen( &budget->inst, QOF_EVENT_DESTROY, NULL); 00259 00260 CACHE_REMOVE(priv->name); 00261 CACHE_REMOVE(priv->description); 00262 00263 /* qof_instance_release (&budget->inst); */ 00264 g_object_unref(budget); 00265 } 00266 00267 static void noop (QofInstance *inst) {} 00268 00269 void 00270 gnc_budget_begin_edit(GncBudget *bgt) 00271 { 00272 qof_begin_edit(QOF_INSTANCE(bgt)); 00273 } 00274 00275 void 00276 gnc_budget_commit_edit(GncBudget *bgt) 00277 { 00278 if (!qof_commit_edit(QOF_INSTANCE(bgt))) return; 00279 qof_commit_edit_part2(QOF_INSTANCE(bgt), commit_err, 00280 noop, gnc_budget_free); 00281 } 00282 00283 GncBudget* 00284 gnc_budget_new(QofBook *book) 00285 { 00286 GncBudget* budget; 00287 00288 g_return_val_if_fail(book, NULL); 00289 00290 ENTER(" "); 00291 budget = g_object_new(GNC_TYPE_BUDGET, NULL); 00292 qof_instance_init_data (&budget->inst, GNC_ID_BUDGET, book); 00293 00294 qof_event_gen( &budget->inst, QOF_EVENT_CREATE , NULL); 00295 00296 LEAVE(" "); 00297 return budget; 00298 } 00299 00300 void 00301 gnc_budget_destroy(GncBudget *budget) 00302 { 00303 g_return_if_fail(GNC_IS_BUDGET(budget)); 00304 gnc_budget_begin_edit(budget); 00305 qof_instance_set_dirty(&budget->inst); 00306 qof_instance_set_destroying(budget, TRUE); 00307 gnc_budget_commit_edit(budget); 00308 } 00309 00311 typedef struct 00312 { 00313 const GncBudget* old_b; 00314 GncBudget* new_b; 00315 guint num_periods; 00316 } CloneBudgetData_t; 00317 00318 static void 00319 clone_budget_values_cb(Account* a, gpointer user_data) 00320 { 00321 CloneBudgetData_t* data = (CloneBudgetData_t*)user_data; 00322 guint i; 00323 00324 for ( i = 0; i < data->num_periods; ++i ) 00325 { 00326 if ( gnc_budget_is_account_period_value_set(data->old_b, a, i) ) 00327 { 00328 gnc_budget_set_account_period_value(data->new_b, a, i, 00329 gnc_budget_get_account_period_value(data->old_b, a, i)); 00330 } 00331 } 00332 } 00333 00334 GncBudget* 00335 gnc_budget_clone(const GncBudget* old_b) 00336 { 00337 GncBudget* new_b; 00338 Account* root; 00339 CloneBudgetData_t clone_data; 00340 00341 g_return_val_if_fail(old_b != NULL, NULL); 00342 00343 ENTER(" "); 00344 00345 new_b = gnc_budget_new(qof_instance_get_book(old_b)); 00346 gnc_budget_begin_edit(new_b); 00347 gnc_budget_set_name(new_b, gnc_budget_get_name(old_b)); 00348 gnc_budget_set_description(new_b, gnc_budget_get_description(old_b)); 00349 gnc_budget_set_recurrence(new_b, gnc_budget_get_recurrence(old_b)); 00350 gnc_budget_set_num_periods(new_b, gnc_budget_get_num_periods(old_b)); 00351 00352 root = gnc_book_get_root_account(qof_instance_get_book(old_b)); 00353 clone_data.old_b = old_b; 00354 clone_data.new_b = new_b; 00355 clone_data.num_periods = gnc_budget_get_num_periods(new_b); 00356 gnc_account_foreach_descendant(root, clone_budget_values_cb, &clone_data); 00357 00358 gnc_budget_commit_edit(new_b); 00359 00360 LEAVE(" "); 00361 00362 return new_b; 00363 } 00364 00365 void 00366 gnc_budget_set_name(GncBudget* budget, const gchar* name) 00367 { 00368 BudgetPrivate* priv; 00369 00370 g_return_if_fail(GNC_IS_BUDGET(budget) && name); 00371 00372 priv = GET_PRIVATE(budget); 00373 if ( name == priv->name ) return; 00374 00375 gnc_budget_begin_edit(budget); 00376 CACHE_REPLACE(priv->name, name); 00377 qof_instance_set_dirty(&budget->inst); 00378 gnc_budget_commit_edit(budget); 00379 00380 qof_event_gen( &budget->inst, QOF_EVENT_MODIFY, NULL); 00381 } 00382 00383 const gchar* 00384 gnc_budget_get_name(const GncBudget* budget) 00385 { 00386 g_return_val_if_fail(GNC_IS_BUDGET(budget), NULL); 00387 return GET_PRIVATE(budget)->name; 00388 } 00389 00390 void 00391 gnc_budget_set_description(GncBudget* budget, const gchar* description) 00392 { 00393 BudgetPrivate* priv; 00394 00395 g_return_if_fail(GNC_IS_BUDGET(budget)); 00396 g_return_if_fail(description); 00397 00398 priv = GET_PRIVATE(budget); 00399 if ( description == priv->description ) return; 00400 gnc_budget_begin_edit(budget); 00401 CACHE_REPLACE(priv->description, description); 00402 qof_instance_set_dirty(&budget->inst); 00403 gnc_budget_commit_edit(budget); 00404 00405 qof_event_gen( &budget->inst, QOF_EVENT_MODIFY, NULL); 00406 } 00407 00408 const gchar* 00409 gnc_budget_get_description(const GncBudget* budget) 00410 { 00411 g_return_val_if_fail(GNC_IS_BUDGET(budget), NULL); 00412 return GET_PRIVATE(budget)->description; 00413 } 00414 00415 void 00416 gnc_budget_set_recurrence(GncBudget *budget, const Recurrence *r) 00417 { 00418 BudgetPrivate* priv; 00419 00420 g_return_if_fail(budget && r); 00421 priv = GET_PRIVATE(budget); 00422 00423 gnc_budget_begin_edit(budget); 00424 priv->recurrence = *r; 00425 qof_instance_set_dirty(&budget->inst); 00426 gnc_budget_commit_edit(budget); 00427 00428 qof_event_gen(&budget->inst, QOF_EVENT_MODIFY, NULL); 00429 } 00430 00431 const Recurrence * 00432 gnc_budget_get_recurrence(const GncBudget *budget) 00433 { 00434 g_return_val_if_fail(budget, NULL); 00435 return (&GET_PRIVATE(budget)->recurrence); 00436 } 00437 00438 const GncGUID* 00439 gnc_budget_get_guid(const GncBudget* budget) 00440 { 00441 g_return_val_if_fail(budget, NULL); 00442 g_return_val_if_fail(GNC_IS_BUDGET(budget), NULL); 00443 return qof_instance_get_guid(QOF_INSTANCE(budget)); 00444 } 00445 00446 void 00447 gnc_budget_set_num_periods(GncBudget* budget, guint num_periods) 00448 { 00449 BudgetPrivate* priv; 00450 00451 g_return_if_fail(GNC_IS_BUDGET(budget)); 00452 00453 priv = GET_PRIVATE(budget); 00454 if ( priv->num_periods == num_periods ) return; 00455 00456 gnc_budget_begin_edit(budget); 00457 priv->num_periods = num_periods; 00458 qof_instance_set_dirty(&budget->inst); 00459 gnc_budget_commit_edit(budget); 00460 00461 qof_event_gen( &budget->inst, QOF_EVENT_MODIFY, NULL); 00462 } 00463 00464 guint 00465 gnc_budget_get_num_periods(const GncBudget* budget) 00466 { 00467 g_return_val_if_fail(GNC_IS_BUDGET(budget), 0); 00468 return GET_PRIVATE(budget)->num_periods; 00469 } 00470 00471 #define BUF_SIZE (10 + GUID_ENCODING_LENGTH + \ 00472 GNC_BUDGET_MAX_NUM_PERIODS_DIGITS) 00473 00474 /* period_num is zero-based */ 00475 /* What happens when account is deleted, after we have an entry for it? */ 00476 void 00477 gnc_budget_unset_account_period_value(GncBudget *budget, const Account *account, 00478 guint period_num) 00479 { 00480 const GncGUID *guid; 00481 KvpFrame *frame; 00482 gchar path[BUF_SIZE]; 00483 gchar *bufend; 00484 00485 gnc_budget_begin_edit(budget); 00486 frame = qof_instance_get_slots(QOF_INSTANCE(budget)); 00487 guid = xaccAccountGetGUID(account); 00488 bufend = guid_to_string_buff(guid, path); 00489 g_sprintf(bufend, "/%d", period_num); 00490 00491 kvp_frame_set_value(frame, path, NULL); 00492 qof_instance_set_dirty(&budget->inst); 00493 gnc_budget_commit_edit(budget); 00494 00495 qof_event_gen( &budget->inst, QOF_EVENT_MODIFY, NULL); 00496 00497 } 00498 00499 /* period_num is zero-based */ 00500 /* What happens when account is deleted, after we have an entry for it? */ 00501 void 00502 gnc_budget_set_account_period_value(GncBudget *budget, const Account *account, 00503 guint period_num, gnc_numeric val) 00504 { 00505 const GncGUID *guid; 00506 KvpFrame *frame; 00507 gchar path[BUF_SIZE]; 00508 gchar *bufend; 00509 00510 gnc_budget_begin_edit(budget); 00511 frame = qof_instance_get_slots(QOF_INSTANCE(budget)); 00512 guid = xaccAccountGetGUID(account); 00513 bufend = guid_to_string_buff(guid, path); 00514 g_sprintf(bufend, "/%d", period_num); 00515 00516 if (gnc_numeric_check(val)) 00517 kvp_frame_set_value(frame, path, NULL); 00518 else 00519 kvp_frame_set_numeric(frame, path, val); 00520 qof_instance_set_dirty(&budget->inst); 00521 gnc_budget_commit_edit(budget); 00522 00523 qof_event_gen( &budget->inst, QOF_EVENT_MODIFY, NULL); 00524 00525 } 00526 00527 /* We don't need these here, but maybe they're useful somewhere else? 00528 Maybe this should move to Account.h */ 00529 00530 gboolean 00531 gnc_budget_is_account_period_value_set(const GncBudget *budget, const Account *account, 00532 guint period_num) 00533 { 00534 gchar path[BUF_SIZE]; 00535 gchar *bufend; 00536 KvpFrame *frame; 00537 00538 g_return_val_if_fail(GNC_IS_BUDGET(budget), FALSE); 00539 g_return_val_if_fail(account, FALSE); 00540 00541 frame = qof_instance_get_slots(QOF_INSTANCE(budget)); 00542 bufend = guid_to_string_buff(xaccAccountGetGUID(account), path); 00543 g_sprintf(bufend, "/%d", period_num); 00544 return (kvp_frame_get_value(frame, path) != NULL); 00545 } 00546 00547 gnc_numeric 00548 gnc_budget_get_account_period_value(const GncBudget *budget, const Account *account, 00549 guint period_num) 00550 { 00551 gnc_numeric numeric; 00552 gchar path[BUF_SIZE]; 00553 gchar *bufend; 00554 KvpFrame *frame; 00555 00556 numeric = gnc_numeric_zero(); 00557 g_return_val_if_fail(GNC_IS_BUDGET(budget), numeric); 00558 g_return_val_if_fail(account, numeric); 00559 00560 frame = qof_instance_get_slots(QOF_INSTANCE(budget)); 00561 bufend = guid_to_string_buff(xaccAccountGetGUID(account), path); 00562 g_sprintf(bufend, "/%d", period_num); 00563 00564 numeric = kvp_frame_get_numeric(frame, path); 00565 /* This still returns zero if unset, but callers can check for that. */ 00566 return numeric; 00567 } 00568 00569 00570 Timespec 00571 gnc_budget_get_period_start_date(const GncBudget *budget, guint period_num) 00572 { 00573 Timespec ts; 00574 timespecFromTime_t( 00575 &ts, recurrenceGetPeriodTime(&GET_PRIVATE(budget)->recurrence, period_num, FALSE)); 00576 return ts; 00577 } 00578 00579 Timespec 00580 gnc_budget_get_period_end_date(const GncBudget *budget, guint period_num) 00581 { 00582 Timespec ts; 00583 timespecFromTime_t( 00584 &ts, recurrenceGetPeriodTime(&GET_PRIVATE(budget)->recurrence, period_num, TRUE)); 00585 return ts; 00586 } 00587 00588 gnc_numeric 00589 gnc_budget_get_account_period_actual_value( 00590 const GncBudget *budget, Account *acc, guint period_num) 00591 { 00592 // FIXME: maybe zero is not best error return val. 00593 g_return_val_if_fail(GNC_IS_BUDGET(budget) && acc, gnc_numeric_zero()); 00594 return recurrenceGetAccountPeriodValue(&GET_PRIVATE(budget)->recurrence, 00595 acc, period_num); 00596 } 00597 00598 GncBudget* 00599 gnc_budget_lookup (const GncGUID *guid, const QofBook *book) 00600 { 00601 QofCollection *col; 00602 00603 g_return_val_if_fail(guid, NULL); 00604 g_return_val_if_fail(book, NULL); 00605 col = qof_book_get_collection (book, GNC_ID_BUDGET); 00606 return GNC_BUDGET(qof_collection_lookup_entity (col, guid)); 00607 } 00608 00609 static void just_get_one(QofInstance *ent, gpointer data) 00610 { 00611 GncBudget **bgt = (GncBudget**)data; 00612 if (bgt && !*bgt) *bgt = GNC_BUDGET(ent); 00613 } 00614 00615 GncBudget* 00616 gnc_budget_get_default (QofBook *book) 00617 { 00618 QofCollection *col; 00619 GncBudget *bgt = NULL; 00620 kvp_value *kvp_default_budget; 00621 const GncGUID *default_budget_guid; 00622 00623 g_return_val_if_fail(book, NULL); 00624 00625 /* See if there is a budget selected in the KVP perferences */ 00626 00627 kvp_default_budget = kvp_frame_get_slot_path(qof_book_get_slots (book), 00628 KVP_OPTION_PATH, 00629 OPTION_SECTION_BUDGETING, 00630 OPTION_NAME_DEFAULT_BUDGET, 00631 NULL); 00632 00633 if (kvp_default_budget != NULL ) 00634 { 00635 default_budget_guid = kvp_value_get_guid(kvp_default_budget); 00636 if (default_budget_guid != NULL) 00637 { 00638 col = qof_book_get_collection(book, GNC_ID_BUDGET); 00639 bgt = (GncBudget *) qof_collection_lookup_entity(col, 00640 default_budget_guid); 00641 } 00642 } 00643 00644 /* Revert to 2.2.x behavior if there is no defined budget in KVP */ 00645 00646 if ( bgt == NULL ) 00647 { 00648 col = qof_book_get_collection(book, GNC_ID_BUDGET); 00649 if (qof_collection_count(col) > 0) 00650 { 00651 qof_collection_foreach(col, just_get_one, &bgt); 00652 } 00653 } 00654 00655 return bgt; 00656 } 00657 00658 static void 00659 destroy_budget_on_book_close(QofInstance *ent, gpointer data) 00660 { 00661 GncBudget* bgt = GNC_BUDGET(ent); 00662 00663 gnc_budget_destroy(bgt); 00664 } 00665 00670 static void 00671 gnc_budget_book_end(QofBook* book) 00672 { 00673 QofCollection *col; 00674 00675 col = qof_book_get_collection(book, GNC_ID_BUDGET); 00676 qof_collection_foreach(col, destroy_budget_on_book_close, NULL); 00677 } 00678 00679 #ifdef _MSC_VER 00680 /* MSVC compiler doesn't have C99 "designated initializers" 00681 * so we wrap them in a macro that is empty on MSVC. */ 00682 # define DI(x) /* */ 00683 #else 00684 # define DI(x) x 00685 #endif 00686 00687 /* Define the QofObject. */ 00688 static QofObject budget_object_def = 00689 { 00690 DI(.interface_version = ) QOF_OBJECT_VERSION, 00691 DI(.e_type = ) GNC_ID_BUDGET, 00692 DI(.type_label = ) "Budget", 00693 DI(.create = ) (gpointer)gnc_budget_new, 00694 DI(.book_begin = ) NULL, 00695 DI(.book_end = ) gnc_budget_book_end, 00696 DI(.is_dirty = ) qof_collection_is_dirty, 00697 DI(.mark_clean = ) qof_collection_mark_clean, 00698 DI(.foreach = ) qof_collection_foreach, 00699 DI(.printable = ) (const char * (*)(gpointer)) gnc_budget_get_name, 00700 DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp, 00701 }; 00702 00703 00704 /* Static wrapper getters for the recurrence params */ 00705 static PeriodType gnc_budget_get_rec_pt(const GncBudget *bgt) 00706 { 00707 return recurrenceGetPeriodType(&(GET_PRIVATE(bgt)->recurrence)); 00708 } 00709 static guint gnc_budget_get_rec_mult(const GncBudget *bgt) 00710 { 00711 return recurrenceGetMultiplier(&(GET_PRIVATE(bgt)->recurrence)); 00712 } 00713 static GDate gnc_budget_get_rec_date(const GncBudget *bgt) 00714 { 00715 return recurrenceGetDate(&(GET_PRIVATE(bgt)->recurrence)); 00716 } 00717 00718 /* Register ourselves with the engine. */ 00719 gboolean gnc_budget_register (void) 00720 { 00721 static QofParam params[] = 00722 { 00723 { 00724 "name", QOF_TYPE_STRING, 00725 (QofAccessFunc) gnc_budget_get_name, 00726 (QofSetterFunc) gnc_budget_set_name 00727 }, 00728 { 00729 "description", QOF_TYPE_STRING, 00730 (QofAccessFunc) gnc_budget_get_description, 00731 (QofSetterFunc) gnc_budget_set_description 00732 }, 00733 { 00734 "recurrence_period_type", QOF_TYPE_INT32, 00735 (QofAccessFunc) gnc_budget_get_rec_pt, NULL 00736 }, 00737 /* Signedness problem: Should be unsigned. */ 00738 { 00739 "recurrence_multiplier", QOF_TYPE_INT32, 00740 (QofAccessFunc) gnc_budget_get_rec_mult, NULL 00741 }, 00742 /* This is the same way that SchedXaction.c uses QOF_TYPE_DATE 00743 but I don't think QOF actually supports a GDate, so I think 00744 this is wrong. */ 00745 { 00746 "recurrence_date", QOF_TYPE_DATE, 00747 (QofAccessFunc) gnc_budget_get_rec_date, NULL 00748 }, 00749 /* Signedness problem: Should be unsigned. */ 00750 { 00751 "num_periods", QOF_TYPE_INT32, 00752 (QofAccessFunc) gnc_budget_get_num_periods, 00753 (QofSetterFunc) gnc_budget_set_num_periods 00754 }, 00755 { 00756 QOF_PARAM_BOOK, QOF_ID_BOOK, 00757 (QofAccessFunc) qof_instance_get_book, NULL 00758 }, 00759 { 00760 QOF_PARAM_GUID, QOF_TYPE_GUID, 00761 (QofAccessFunc) qof_instance_get_guid, NULL 00762 }, 00763 { NULL }, 00764 }; 00765 00766 qof_class_register(GNC_ID_BUDGET, (QofSortFunc) NULL, params); 00767 return qof_object_register(&budget_object_def); 00768 }
1.7.4