gnucash/libgnucash/engine/SX-book.c
Geert Janssens 1238b9d8cd Prevent gcc from searching config.h in the current directory
This will avoid a ninja-build from picking up a config.h generated by the autotools build
(in the root build directory). Picking up the wrong config.h may lead to all kinds of
subtle issues if the autotools run was done with different options than the cmake run.
2017-10-26 14:05:17 +02:00

392 lines
10 KiB
C

/********************************************************************\
* SX-book.c -- scheduled transaction dataset access *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
\********************************************************************/
/*
* FILE:
* SX-book.c
*
* FUNCTION:
* Anchor Scheduled Transaction Info into the book.
* See src/doc/books.txt for design overview.
*
* HISTORY:
* Copyright (c) 2003 Linas Vepstas <linas@linas.org>
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "gnc-engine.h"
#include "Account.h"
#include "Split.h"
#include "SchedXaction.h"
#include "SX-book.h"
#include "SX-book-p.h"
#include "gnc-event.h"
#include <qofinstance-p.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "gnc.engine.sx"
/* XXX this whole file is crufty, it doesn't really use entities
* in the most efficient/best way */
/* ====================================================================== */
static Account *
gnc_collection_get_template_root( const QofCollection *col )
{
return qof_collection_get_data (col);
}
Account *
gnc_book_get_template_root( const QofBook *book )
{
QofCollection *col;
if (!book) return NULL;
col = qof_book_get_collection (book, GNC_ID_SXTG);
return gnc_collection_get_template_root (col);
}
static void
gnc_collection_set_template_root (QofCollection *col,
Account *templateRoot)
{
Account *old_root;
if (!col) return;
old_root = gnc_collection_get_template_root (col);
if (old_root == templateRoot) return;
qof_collection_set_data (col, templateRoot);
if (old_root)
{
xaccAccountBeginEdit (old_root);
xaccAccountDestroy (old_root);
}
}
void
gnc_book_set_template_root (QofBook *book, Account *templateRoot)
{
QofCollection *col;
if (!book) return;
if (templateRoot && gnc_account_get_book(templateRoot) != book)
{
g_critical("cannot mix and match books freely!");
return;
}
col = qof_book_get_collection (book, GNC_ID_SXTG);
gnc_collection_set_template_root (col, templateRoot);
}
/* ====================================================================== */
/* gncObject function implementation and registration */
static void
sxtg_book_begin (QofBook *book)
{
Account *root;
root = xaccMallocAccount(book);
xaccAccountBeginEdit(root);
xaccAccountSetType(root, ACCT_TYPE_ROOT);
xaccAccountSetName(root, "Template Root");
qof_instance_set_dirty (QOF_INSTANCE (root));
xaccAccountCommitEdit(root);
gnc_book_set_template_root (book, root);
}
static void
sxtg_book_end (QofBook *book)
{
// gnc_book_set_template_root (book, NULL);
}
static gboolean
sxtg_is_dirty(const QofCollection *col)
{
Account *root;
GList *descendants, *node;
gboolean dirty = FALSE;
root = gnc_collection_get_template_root(col);
descendants = gnc_account_get_descendants(root);
for (node = descendants; node; node = g_list_next(node))
{
if (qof_instance_is_dirty(node->data))
{
dirty = TRUE;
break;
}
}
g_list_free(descendants);
return dirty;
}
/* EFFECTIVE FRIEND FUNCTION declared in qofinstance-p.h */
extern void qof_instance_mark_clean (QofInstance *);
static void
sxtg_mark_clean(QofCollection *col)
{
Account *root;
GList *descendants;
root = gnc_collection_get_template_root(col);
qof_collection_mark_clean(col);
descendants = gnc_account_get_descendants(root);
g_list_foreach(descendants, (GFunc)qof_instance_mark_clean, NULL);
g_list_free(descendants);
}
#ifdef _MSC_VER
/* MSVC compiler doesn't have C99 "designated initializers"
* so we wrap them in a macro that is empty on MSVC. */
# define DI(x) /* */
#else
# define DI(x) x
#endif
static QofObject sxtg_object_def =
{
DI(.interface_version = ) QOF_OBJECT_VERSION,
DI(.e_type = ) GNC_ID_SXTG,
DI(.type_label = ) "Scheduled Transaction Templates",
DI(.create = ) NULL,
DI(.book_begin = ) sxtg_book_begin,
DI(.book_end = ) sxtg_book_end,
DI(.is_dirty = ) sxtg_is_dirty,
DI(.mark_clean = ) sxtg_mark_clean,
DI(.foreach = ) NULL,
DI(.printable = ) NULL,
};
/* ====================================================================== */
SchedXactions*
gnc_collection_get_schedxactions(const QofCollection *col)
{
SchedXactions *rtn = qof_collection_get_data(col);
// @@assert(rtn != null);
return rtn;
}
SchedXactions*
gnc_book_get_schedxactions(QofBook *book)
{
QofCollection *col;
col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
return gnc_collection_get_schedxactions(col);
}
void
gnc_sxes_add_sx(SchedXactions *sxes, SchedXaction *sx)
{
if (g_list_find(sxes->sx_list, sx) != NULL)
return;
sxes->sx_list = g_list_append(sxes->sx_list, sx);
qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_ADDED, (gpointer)sx);
}
void
gnc_sxes_del_sx(SchedXactions *sxes, SchedXaction *sx)
{
GList *to_remove;
to_remove = g_list_find(sxes->sx_list, sx);
if (to_remove == NULL)
return;
sxes->sx_list = g_list_delete_link(sxes->sx_list, to_remove);
qof_event_gen(&sxes->inst, GNC_EVENT_ITEM_REMOVED, (gpointer)sx);
}
/* ====================================================================== */
/* SX-trans stuff */
/* GObject initialization */
QOF_GOBJECT_IMPL(gnc_schedxactions, SchedXactions, QOF_TYPE_INSTANCE);
static void
gnc_schedxactions_init(SchedXactions* sxs)
{
}
static void
gnc_schedxactions_dispose_real (GObject *sxsp)
{
}
static void
gnc_schedxactions_finalize_real(GObject* sxsp)
{
}
static void
mark_sx_clean(gpointer data, gpointer user_data)
{
SchedXaction *sx = (SchedXaction *) data;
qof_instance_mark_clean (QOF_INSTANCE(sx));
}
static void
book_sxes_setup(QofBook *book)
{
QofCollection *col;
SchedXactions *sxes;
col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
sxes = g_object_new (GNC_TYPE_SCHEDXACTIONS, NULL);
g_assert(sxes);
qof_instance_init_data(&sxes->inst, GNC_ID_SXES, book);
sxes->sx_list = NULL;
sxes->sx_notsaved = TRUE;
qof_collection_set_data(col, sxes);
}
static void
book_sxes_end(QofBook* book)
{
QofCollection *col;
SchedXactions *sxes;
col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
sxes = qof_collection_get_data(col);
if (sxes != NULL)
{
g_object_unref(sxes);
qof_collection_set_data(col, NULL);
}
}
static void
book_sxns_mark_saved(QofCollection *col)
{
SchedXactions *sxl;
sxl = gnc_collection_get_schedxactions(col);
if (!sxl)
return;
sxl->sx_notsaved = FALSE;
g_list_foreach(sxl->sx_list,
mark_sx_clean,
NULL);
}
static gboolean
book_sxlist_notsaved(const QofCollection *col)
{
GList *sxlist;
SchedXactions *sxl;
sxl = gnc_collection_get_schedxactions(col);
if (!sxl) return FALSE;
if (sxl->sx_notsaved) return TRUE;
for (sxlist = sxl->sx_list;
sxlist != NULL;
sxlist = g_list_next(sxlist))
{
SchedXaction *sx;
sx = (SchedXaction *) (sxlist->data);
if (xaccSchedXactionIsDirty( sx ))
return TRUE;
}
return FALSE;
}
static QofObject sxes_object_def =
{
DI(.interface_version = ) QOF_OBJECT_VERSION,
DI(.e_type = ) GNC_ID_SXES,
DI(.type_label = ) "Scheduled Transactions List",
DI(.create = ) NULL,
DI(.book_begin = ) book_sxes_setup,
DI(.book_end = ) book_sxes_end,
DI(.is_dirty = ) book_sxlist_notsaved,
DI(.mark_clean = ) book_sxns_mark_saved,
DI(.foreach = ) NULL,
DI(.printable = ) NULL,
DI(.version_cmp = ) NULL
};
static QofObject sxtt_object_def =
{
DI(.interface_version = ) QOF_OBJECT_VERSION,
DI(.e_type = ) GNC_ID_SXTT,
DI(.type_label = ) "Scheduled Transaction Templates",
DI(.create = ) NULL,
DI(.book_begin = ) NULL,
DI(.book_end = ) NULL,
DI(.is_dirty = ) NULL,
DI(.mark_clean = ) NULL,
DI(.foreach = ) NULL,
DI(.printable = ) NULL,
DI(.version_cmp = ) NULL,
};
gboolean
gnc_sxtt_register (void)
{
if (!qof_object_register(&sxes_object_def))
return FALSE;
if (!qof_object_register(&sxtg_object_def))
return FALSE;
return qof_object_register(&sxtt_object_def);
}
GList*
gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
{
GList *rtn = NULL;
const GncGUID *acct_guid = qof_entity_get_guid(QOF_INSTANCE(acct));
GList *sx_list;
SchedXactions *sxactions = gnc_book_get_schedxactions(book);
g_return_val_if_fail( sxactions != NULL, rtn);
for (sx_list = sxactions->sx_list; sx_list != NULL; sx_list = sx_list->next)
{
SchedXaction *sx = (SchedXaction*)sx_list->data;
GList *splits = xaccSchedXactionGetSplits(sx);
for (; splits != NULL; splits = splits->next)
{
Split *s = (Split*)splits->data;
GncGUID *guid = NULL;
qof_instance_get (QOF_INSTANCE (s), "sx-account", &guid, NULL);
if (guid_equal(acct_guid, guid))
{
rtn = g_list_append(rtn, sx);
}
}
}
return rtn;
}
/* ========================== END OF FILE =============================== */