Start the FreqSpec->Recurrence migration:

- remove the "private" SX header.
- add GList<Recurrence*> to the SX model
- Parse a GList<Recurrence> from FreqSpec xml.
- GncFrequency changes
  - modify GncFrequency to load/save Recurrences.
  - simplify GncFrequency: remove "daily [m-f]", "bi-weekly" and super-monthly pages.
  - add (Recurrence-only) support for "last weekday of month" to {,semi-}monthly 
- update SX cleanup todo-list.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15601 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Joshua Sled 2007-02-18 17:39:54 +00:00
parent d02ccef535
commit 1d2e90dce7
15 changed files with 1836 additions and 3043 deletions

View File

@ -125,6 +125,9 @@ typedef struct
FreqSpec *fs; /* FreqSpec we're parsing into. */
QofBook *book; /* Book we're loading into. */
Recurrence *recurrence;
GList *recurrence_list;
/* fields used in the union of unions... :) */
GDate once_day; /* once */
gint64 interval; /* all [except once] */
@ -140,6 +143,8 @@ fspd_init( fsParseData *fspd )
fspd->fs = NULL;
fspd->list = NULL;
fspd->book = NULL;
fspd->recurrence = g_new0(Recurrence, 1);
fspd->recurrence_list = NULL;
fspd->interval
= fspd->offset
= fspd->day
@ -399,10 +404,24 @@ fs_subelement_handler( xmlNodePtr node, gpointer data )
{
fsParseData *fspd = data;
FreqSpec *fs;
GList *recurrences;
fs = dom_tree_to_freqSpec( node, fspd->book );
if ( fs == NULL )
return FALSE;
fspd->list = g_list_append( fspd->list, fs );
recurrences = dom_tree_freqSpec_to_recurrences(node, fspd->book);
if (recurrences == NULL)
return FALSE;
{
GList *r_iter;
for (r_iter = recurrences; r_iter != NULL; r_iter = r_iter->next)
{
fspd->recurrence_list = g_list_append(fspd->recurrence_list, r_iter->data);
}
}
return TRUE;
}
@ -417,8 +436,15 @@ struct dom_tree_handler fs_union_dom_handlers[] = {
{ NULL, NULL, 0, 0 },
};
static
gboolean
static void
compute_date(fsParseData *parsed, GDate *date)
{
g_date_clear(date, 1);
g_date_set_dmy(date, 1, 1, 1970);
g_date_add_days(date, parsed->offset);
}
static gboolean
fs_none_handler( xmlNodePtr node, gpointer data )
{
fsParseData *fspd = data;
@ -444,22 +470,27 @@ fs_once_handler( xmlNodePtr node, gpointer data )
fspd );
if ( !successful )
return FALSE;
recurrenceSet(fspd->recurrence, 0, PERIOD_ONCE, &fspd->once_day);
fspd->fs->type = ONCE;
fspd->fs->s.once.date = fspd->once_day;
return TRUE;
}
static
gboolean
fs_daily_handler( xmlNodePtr node, gpointer data)
static gboolean
fs_daily_handler(xmlNodePtr node, gpointer data)
{
fsParseData *fspd = data;
GDate offset_date;
gboolean successful;
successful = dom_tree_generic_parse( node,
fs_union_dom_handlers,
fspd );
if ( !successful )
return FALSE;
successful = dom_tree_generic_parse(node, fs_union_dom_handlers, fspd );
if (!successful)
return FALSE;
compute_date(fspd, &offset_date);
recurrenceSet(fspd->recurrence, fspd->interval, PERIOD_DAY, &offset_date);
fspd->fs->type = DAILY;
fspd->fs->s.daily.interval_days = fspd->interval;
fspd->fs->s.daily.offset_from_epoch = fspd->offset;
@ -471,15 +502,21 @@ gboolean
fs_weekly_handler( xmlNodePtr node, gpointer data )
{
fsParseData *fspd = data;
GDate offset_date;
gboolean successful;
successful = dom_tree_generic_parse( node,
fs_union_dom_handlers,
fspd );
if ( !successful )
return FALSE;
compute_date(fspd, &offset_date);
recurrenceSet(fspd->recurrence, fspd->interval, PERIOD_DAY, &offset_date);
fspd->fs->type = WEEKLY;
fspd->fs->s.weekly.interval_weeks = fspd->interval;
fspd->fs->s.weekly.offset_from_epoch = fspd->offset;
return TRUE;
}
@ -488,16 +525,23 @@ gboolean
fs_monthly_handler( xmlNodePtr node, gpointer data)
{
fsParseData *fspd = data;
GDate offset_date;
gboolean successful;
successful = dom_tree_generic_parse( node,
fs_union_dom_handlers,
fspd );
if ( !successful )
return FALSE;
compute_date(fspd, &offset_date);
g_date_set_day(&offset_date, fspd->day);
recurrenceSet(fspd->recurrence, fspd->interval, PERIOD_MONTH, &offset_date);
fspd->fs->type = MONTHLY;
fspd->fs->s.monthly.interval_months = fspd->interval;
fspd->fs->s.monthly.offset_from_epoch = fspd->offset;
fspd->fs->s.monthly.day_of_month = fspd->day;
return successful;
}
@ -505,19 +549,8 @@ static
gboolean
fs_month_relative_handler( xmlNodePtr node, gpointer data)
{
fsParseData *fspd = data;
gboolean successful;
successful = dom_tree_generic_parse( node,
fs_union_dom_handlers,
fspd );
if ( !successful )
return FALSE;
fspd->fs->type = MONTH_RELATIVE;
fspd->fs->s.month_relative.interval_months = fspd->interval;
fspd->fs->s.month_relative.offset_from_epoch = fspd->offset;
fspd->fs->s.month_relative.weekday = fspd->day;
fspd->fs->s.month_relative.occurrence = fspd->occurrence;
return TRUE;
g_critical("this was never supported, how is it in the datafile?");
return FALSE;
}
static
@ -544,6 +577,7 @@ fs_composite_handler( xmlNodePtr node, gpointer data)
return FALSE;
fspd->fs->type = COMPOSITE;
fspd->fs->s.composites.subSpecs = fspd->list;
return TRUE;
}
@ -604,21 +638,40 @@ gnc_freqSpec_sixtp_parser_create(void)
return sixtp_dom_parser_new( gnc_freqSpec_end_handler, NULL, NULL );
}
static void
common_parse(fsParseData *fspd, xmlNodePtr node, QofBook *book)
{
gboolean successful;
fspd->book = book;
fspd->fs = xaccFreqSpecMalloc(book);
successful = dom_tree_generic_parse( node, fs_dom_handlers, fspd );
if (!successful)
{
xmlElemDump(stdout, NULL, node);
xaccFreqSpecFree( fspd->fs );
fspd->fs = NULL;
}
}
GList*
dom_tree_freqSpec_to_recurrences(xmlNodePtr node, QofBook *book)
{
fsParseData fspd;
fspd_init( &fspd );
common_parse(&fspd, node, book);
if (fspd.recurrence_list == NULL)
{
fspd.recurrence_list = g_list_append(fspd.recurrence_list, fspd.recurrence);
}
return fspd.recurrence_list;
}
FreqSpec*
dom_tree_to_freqSpec(xmlNodePtr node, QofBook *book)
{
gboolean successful;
fsParseData fspd;
fspd_init( &fspd );
fspd.book = book;
fspd.fs = xaccFreqSpecMalloc(book);
successful = dom_tree_generic_parse( node, fs_dom_handlers, &fspd );
if ( !successful ) {
xmlElemDump(stdout, NULL, node);
xaccFreqSpecFree( fspd.fs );
fspd.fs = NULL;
}
common_parse(&fspd, node, book);
return fspd.fs;
}

View File

@ -90,7 +90,7 @@ static struct dom_tree_handler recurrence_dom_handlers[] = {
{ NULL, NULL, 0, 0 }
};
Recurrence *
Recurrence*
dom_tree_to_recurrence(xmlNodePtr node)
{
gboolean successful;

View File

@ -1,6 +1,6 @@
/********************************************************************
* gnc-schedxactions-xml-v2.c -- xml routines for transactions *
* Copyright (C) 2001 Joshua Sled <jsled@asynchronous.org> *
* Copyright (C) 2001,2007 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -27,7 +27,6 @@
#include <string.h>
#include "Group.h"
#include "SchedXactionP.h"
#include "SX-book.h"
#include "gnc-xml-helper.h"
@ -46,7 +45,10 @@
#include "sixtp-dom-parsers.h"
static QofLogModule log_module = GNC_MOD_SX;
#define LOG_MOD "gnc.backend.file.sx"
static QofLogModule log_module = LOG_MOD;
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN LOG_MOD
/**
* The XML output should look something like:
@ -131,6 +133,7 @@ static QofLogModule log_module = GNC_MOD_SX;
#define SX_END "sx:end"
#define SX_TEMPL_ACCT "sx:templ-acct"
#define SX_FREQSPEC "sx:freqspec"
#define SX_SCHEDULE "sx:schedule"
#define SX_SLOTS "sx:slots"
#define SX_DEFER_INSTANCE "sx:deferredInstance"
@ -143,6 +146,7 @@ static QofLogModule log_module = GNC_MOD_SX;
#define GNC_SCHEDXACTION_TAG "gnc:schedxaction"
const gchar *schedxaction_version_string = "1.0.0";
const gchar *schedxaction_version2_string = "2.0.0";
xmlNodePtr
gnc_schedXaction_dom_tree_create(SchedXaction *sx)
@ -257,6 +261,8 @@ struct sx_pdata
{
SchedXaction *sx;
QofBook *book;
gboolean saw_freqspec;
gboolean saw_recurrence;
};
static
@ -415,22 +421,45 @@ sx_end_handler( xmlNodePtr node, gpointer sx_pdata )
return sx_set_date( node, sx, xaccSchedXactionSetEndDate );
}
static
gboolean
static gboolean
sx_freqspec_handler( xmlNodePtr node, gpointer sx_pdata )
{
struct sx_pdata *pdata = sx_pdata;
SchedXaction *sx = pdata->sx;
FreqSpec *fs;
GList *schedule;
g_return_val_if_fail( node, FALSE );
fs = dom_tree_to_freqSpec( node, pdata->book );
xaccSchedXactionSetFreqSpec( sx, fs );
xaccSchedXactionSetFreqSpec(sx, dom_tree_to_freqSpec(node, pdata->book));
schedule = dom_tree_freqSpec_to_recurrences(node, pdata->book);
gnc_sx_set_schedule(sx, schedule);
for (; schedule != NULL; schedule = schedule->next)
{
g_debug("parsed from freqspec [%s]", recurrenceToString((Recurrence*)schedule->data));
}
pdata->saw_freqspec = TRUE;
return TRUE;
}
static gboolean
sx_recurrence_handler(xmlNodePtr node, gpointer _pdata)
{
struct sx_pdata *parsing_data = _pdata;
GList *schedule;
g_return_val_if_fail(node, FALSE);
//schedule = dom_tree_to_recurrence(node);
//g_return_val_if_fail(schedule, FALSE);
//gnc_sx_set_schedule(parsing_data->sx, schedule);
parsing_data->saw_recurrence = TRUE;
return TRUE;
}
static
gboolean
sx_defer_last_handler( xmlNodePtr node, gpointer gpTSD )
@ -590,7 +619,8 @@ struct dom_tree_handler sx_dom_handlers[] = {
{ SX_REM_OCCUR, sx_remOccur_handler, 0, 0 },
{ SX_END, sx_end_handler, 0, 0 },
{ SX_TEMPL_ACCT, sx_templ_acct_handler, 0, 0 },
{ SX_FREQSPEC, sx_freqspec_handler, 1, 0 },
{ SX_FREQSPEC, sx_freqspec_handler, 0, 0 },
{ SX_SCHEDULE, sx_recurrence_handler, 0, 0 },
{ SX_DEFER_INSTANCE, sx_defer_inst_handler, 0, 0 },
{ SX_SLOTS, sx_slots_handler, 0, 0 },
{ NULL, NULL, 0, 0 }
@ -620,34 +650,58 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
sx = xaccSchedXactionMalloc( gdata->bookdata );
/* FIXME: this should be removed somewhere near 1.8 release time. */
{
/* This is the just-created template acct. It can safely be
removed, as we either will find or don't have a relevent
template_acct. */
xaccAccountBeginEdit (sx->template_acct);
xaccAccountDestroy( sx->template_acct );
sx->template_acct = NULL;
}
memset(&sx_pdata, 0, sizeof(sx_pdata));
sx_pdata.sx = sx;
sx_pdata.book = gdata->bookdata;
g_assert( sx_dom_handlers != NULL );
successful = dom_tree_generic_parse( tree, sx_dom_handlers, &sx_pdata );
if ( successful )
if (!successful)
{
gdata->cb( tag, gdata->parsedata, sx );
}
else
{
PERR ("failed to parse scheduled xaction");
g_critical("failed to parse scheduled xaction");
xmlElemDump( stdout, NULL, tree );
xaccSchedXactionFree( sx );
goto done;
}
if (tree->properties)
{
gchar *sx_name = xaccSchedXactionGetName(sx);
xmlAttr *attr;
for (attr = tree->properties; attr != NULL; attr = attr->next)
{
xmlChar *attr_value = attr->children->content;
g_debug("sx attribute name[%s] value[%s]", attr->name, attr_value);
if (strcmp(attr->name, "version") != 0)
{
g_warning("unknown sx attribute [%s]", attr->name);
continue;
}
// if version == 1.0.0: ensure freqspec, no recurrence
// if version == 2.0.0: ensure recurrence, no freqspec.
if (strcmp(attr_value, schedxaction_version_string) == 0)
{
if (!sx_pdata.saw_freqspec)
g_critical("did not see freqspec in version 1 sx [%s]", sx_name);
if (sx_pdata.saw_recurrence)
g_warning("saw recurrence in supposedly version 1 sx [%s]", sx_name);
}
if (strcmp(attr_value, schedxaction_version2_string) == 0)
{
if (sx_pdata.saw_freqspec)
g_warning("saw freqspec in version 2 sx [%s]", sx_name);
if (!sx_pdata.saw_recurrence)
g_critical("did not find recurrence in version 2 sx [%s]", sx_name);
}
}
}
// generic_callback -> book_callback: insert the SX in the book
gdata->cb( tag, gdata->parsedata, sx );
/* FIXME: this should be removed somewhere near 1.8 release time. */
if ( sx->template_acct == NULL )
{
@ -668,21 +722,18 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
ag = gnc_book_get_template_group(book);
if ( ag == NULL )
{
PERR( "Error getting template account group "
"from being-parsed Book." );
g_warning( "Error getting template account group from being-parsed Book." );
xmlFreeNode( tree );
return FALSE;
}
acct = xaccGetAccountFromName( ag, id );
if ( acct == NULL )
acct = xaccGetAccountFromName(ag, id);
if (acct == NULL)
{
PERR( "Error getting template account "
"with name \"%s\"", id );
g_warning("no template account with name [%s]", id);
xmlFreeNode( tree );
return FALSE;
}
DEBUG( "Got template account with name \"%s\" for "
"SX with GUID \"%s\"",
g_debug("template account name [%s] for SX with GUID [%s]",
xaccAccountGetName( acct ), id );
/* FIXME: free existing template account.
@ -693,6 +744,8 @@ gnc_schedXaction_end_handler(gpointer data_for_children,
sx->template_acct = acct;
}
done:
xmlFreeNode( tree );
return successful;
@ -731,7 +784,7 @@ tt_act_handler( xmlNodePtr node, gpointer data )
applies for
SchedXaction.c:xaccSchedXactionInit... */
com = gnc_commodity_new( txd->book,
"template", "template",
"template", "template",
"template", "template",
1 );
xaccAccountSetCommodity( acc, com );
@ -813,7 +866,7 @@ gnc_template_transaction_end_handler(gpointer data_for_children,
}
else
{
PERR ("failed to parse template transaction");
g_warning("failed to parse template transaction");
xmlElemDump( stdout, NULL, tree );
}

View File

@ -39,6 +39,7 @@ gnc_commodity* dom_tree_to_commodity_ref(xmlNodePtr node, QofBook *book);
gnc_commodity *dom_tree_to_commodity_ref_no_engine(xmlNodePtr node, QofBook *);
FreqSpec* dom_tree_to_freqSpec( xmlNodePtr node, QofBook *book);
GList* dom_tree_freqSpec_to_recurrences(xmlNodePtr node, QofBook *book);
Recurrence* dom_tree_to_recurrence(xmlNodePtr node);
Timespec dom_tree_to_timespec(xmlNodePtr node);

View File

@ -74,6 +74,7 @@ test_xml_account_SOURCES = \
${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-commodity-xml-v2.c \
@ -92,6 +93,7 @@ test_xml_commodity_SOURCES = \
${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-commodity-xml-v2.c \
@ -110,6 +112,7 @@ test_xml_pricedb_SOURCES = \
${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-commodity-xml-v2.c \

View File

@ -112,17 +112,38 @@ TODO
- use Recurrence instead of FreqSpec
! - [ ] XML migration, handling
- xml:freqSpec -> obj:Recurrence
- [ ] none (Recurrence doesn't support)
- [x] once
- [x] daily
- [ ] daily [m-f] (composite)
- [x] weekly, single
- [ ] weekly, multiple (composite)
- [x] monthly (+quarterly, tri-anually, semi-annually, yearly)
- [ ] semi-monthly (composite)
- gnc-frequency
! - [x] Support Recurrence
- [x] in
- [x] out
! - [x] Support 'last-day-of-month'
- [x] simplify
- [x] remove daily [m-f] (-> weekly)
- [x] remove biweekly page (-> weekly)
- [x] remove > monthly pages (-> monthly)
- [ ] clean up, reformat source
- dialog-sx-editor
- [ ] gnc_sxed_check_changed
- [ ] gnc_sxed_check_consistent
- [ ] gnc_sxed_update_cal
- [x] gnc_sxed_save_sx
- [ ] remove FreqSpec code
- [ ] SX code
- [ ] src/gnome/druid-acct-period.c
- gnc-frequency
! - [ ] Use Recurrence
! - [ ] Support 'last-day-of-month'
- [ ] clean up, reformat
- since-last-run
! - [ ] save/restore dialog window size
- [ ] "reminder" instances show number of days until due
- [ ] "Find unfinished" button; count; sensitize Ok as function of unfinished.
! - [x] rewrite adapter (re-)population logic
- [x] move "effect_change" up to app-utils/, test.
- [x] move state-change up to app-utils

View File

@ -97,7 +97,6 @@ noinst_HEADERS = \
FreqSpecP.h \
GroupP.h \
QueryP.h \
SchedXactionP.h \
ScrubP.h \
SplitP.h \
SX-book.h \

View File

@ -1,6 +1,6 @@
/********************************************************************\
* SchedXaction.c -- Scheduled Transaction implementation. *
* Copyright (C) 2001 Joshua Sled <jsled@asynchronous.org> *
* Copyright (C) 2001,2007 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@ -37,7 +37,6 @@
#include "SX-book.h"
#include "SX-ttinfo.h"
#include "SchedXaction.h"
#include "SchedXactionP.h"
#include "Transaction.h"
#include "gnc-engine.h"
@ -57,6 +56,7 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
qof_instance_init (&sx->inst, GNC_ID_SCHEDXACTION, book);
sx->schedule = NULL;
sx->freq = xaccFreqSpecMalloc(book);
g_date_clear( &sx->last_date, 1 );
@ -74,13 +74,12 @@ xaccSchedXactionInit(SchedXaction *sx, QofBook *book)
/* create a new template account for our splits */
sx->template_acct = xaccMallocAccount(book);
/* THREAD-UNSAFE */
xaccAccountSetName( sx->template_acct,
guid_to_string( &sx->inst.entity.guid ));
xaccAccountSetCommodity
(sx->template_acct,
gnc_commodity_new( book,
"template", "template",
"template", "template",
"template", "template", 1 ) );
xaccAccountSetType( sx->template_acct, ACCT_TYPE_BANK );
ag = gnc_book_get_template_group( book );
@ -111,7 +110,6 @@ sxprivTransMapDelete( gpointer data, gpointer user_data )
return;
}
static void
delete_template_trans(SchedXaction *sx)
{
@ -230,6 +228,22 @@ xaccSchedXactionSetFreqSpec( SchedXaction *sx, FreqSpec *fs )
gnc_sx_commit_edit(sx);
}
GList*
gnc_sx_get_schedule(SchedXaction *sx)
{
return sx->schedule;
}
void
gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
{
g_return_if_fail(sx && schedule);
gnc_sx_begin_edit(sx);
sx->schedule = schedule;
qof_instance_set_dirty(&sx->inst);
gnc_sx_commit_edit(sx);
}
gchar *
xaccSchedXactionGetName( SchedXaction *sx )
{
@ -287,7 +301,7 @@ xaccSchedXactionSetEndDate( SchedXaction *sx, GDate *newEnd )
* This warning is only human readable - the caller
* doesn't know the call failed. This is bad
*/
PWARN( "New end date before start date" );
g_critical("New end date before start date");
return;
}
@ -346,7 +360,7 @@ xaccSchedXactionSetRemOccur( SchedXaction *sx,
/* FIXME This condition can be tightened up */
if ( numRemain > sx->num_occurances_total )
{
PWARN("The number remaining is greater than the total occurrences");
g_warning("The number remaining is greater than the total occurrences");
}
else
{

View File

@ -40,15 +40,78 @@
#include <glib.h>
#include "qof.h"
#include "FreqSpec.h"
#include "Recurrence.h"
#include "gnc-engine.h"
#define GNC_IS_SX(obj) (QOF_CHECK_TYPE((obj), GNC_ID_SCHEDXACTION))
#define GNC_SX(obj) (QOF_CHECK_CAST((obj), GNC_ID_SCHEDXACTION, SchedXaction))
typedef struct _SchedXaction SchedXaction;
/**
* The SchedXaction data.
*/
typedef struct gncp_SchedXaction SchedXaction;
* A single scheduled transaction.
*
* Scheduled transactions have a list of transactions, and a frequency
* [and associated date anchors] with which they are scheduled.
*
* Things that make sense to have in a template transaction:
* [not] Date [though eventually some/multiple template transactions
* might have relative dates].
* Memo
* Account
* Funds In/Out... or an expr involving 'amt' [A, x, y, a?] for
* variable expenses.
*
* Template transactions are instantiated by:
* . copying the fields of the template
* . setting the date to the calculated "due" date.
*
* We should be able to use the GeneralLedger [or, yet-another-subtype
* of the internal ledger] for this editing.
**/
struct _SchedXaction
{
QofInstance inst;
gchar *name;
GList *schedule;
FreqSpec *freq;
GDate last_date;
GDate start_date;
/* if end_date is invalid, then no end. */
GDate end_date;
/* if num_occurances_total == 0, then no limit */
gint num_occurances_total;
/* reminaing occurances are as-of the 'last_date'. */
gint num_occurances_remain;
/* the current instance-count of the SX. */
gint instance_num;
gboolean enabled;
gboolean autoCreateOption;
gboolean autoCreateNotify;
gint advanceCreateDays;
gint advanceRemindDays;
Account *template_acct;
/** The list of deferred SX instances. This list is of temporalStateData
* instances. */
GList /* <temporalStateData*> */ *deferredList;
};
/** Just the variable temporal bits from the SX structure. */
typedef struct _temporalStateData {
GDate last_date;
gint num_occur_rem;
gint num_inst;
} temporalStateData;
#define xaccSchedXactionSetGUID(X,G) qof_entity_set_guid(QOF_ENTITY(X),(G))
/**
* Creates and initializes a scheduled transaction.
@ -63,6 +126,11 @@ void xaccSchedXactionFree( SchedXaction *sx );
void gnc_sx_begin_edit (SchedXaction *sx);
void gnc_sx_commit_edit (SchedXaction *sx);
/** @return GList<Recurrence*> **/
GList* gnc_sx_get_schedule(SchedXaction *sx);
/** @param[in] schedule A GList<Recurrence*> **/
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule);
FreqSpec *xaccSchedXactionGetFreqSpec( SchedXaction *sx );
/**
* The FreqSpec is given to the SchedXaction for mem mgmt; it should
@ -162,7 +230,7 @@ void *gnc_sx_clone_temporal_state( void *stateData );
/** @} */
/** \brief Returns the next occurance of a scheduled transaction.
*
* If the transaction hasn't occured, then it's based off the start date.
* Otherwise, it's based off the last-occurance date.
*

View File

@ -1,93 +0,0 @@
/********************************************************************\
* SchedXactionP.h -- Scheduled Transaction private header *
* Copyright (C) 2001 Linux Developers Group *
* *
* 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 *
* *
\********************************************************************/
#ifndef XACC_SCHEDXACTION_P_H
#define XACC_SCHEDXACTION_P_H
#include "SchedXaction.h"
/**
* A single scheduled transaction.
*
* Scheduled transactions have a list of transactions, and a frequency
* [and associated date anchors] with which they are scheduled.
*
* Things that make sense to have in a template transaction:
* [not] Date [though eventually some/multiple template transactions
* might have relative dates].
* Memo
* Account
* Funds In/Out... or an expr involving 'amt' [A, x, y, a?] for
* variable expenses.
*
* Template transactions are instantiated by:
* . copying the fields of the template
* . setting the date to the calculated "due" date.
*
* We should be able to use the GeneralLedger [or, yet-another-subtype
* of the internal ledger] for this editing.
**/
struct gncp_SchedXaction
{
QofInstance inst;
gchar *name;
FreqSpec *freq;
GDate last_date;
GDate start_date;
/* if end_date is invalid, then no end. */
GDate end_date;
/* if num_occurances_total == 0, then no limit */
gint num_occurances_total;
/* reminaing occurances are as-of the 'last_date'. */
gint num_occurances_remain;
/* the current instance-count of the SX. */
gint instance_num;
gboolean enabled;
gboolean autoCreateOption;
gboolean autoCreateNotify;
gint advanceCreateDays;
gint advanceRemindDays;
Account *template_acct;
/** The list of deferred SX instances. This list is of temporalStateData
* instances. */
GList /* <temporalStateData*> */ *deferredList;
};
/** Just the variable temporal bits from the SX structure. */
typedef struct _temporalStateData {
GDate last_date;
gint num_occur_rem;
gint num_inst;
} temporalStateData;
#define xaccSchedXactionSetGUID(X,G) qof_entity_set_guid(QOF_ENTITY(X),(G))
#endif /* XACC_SCHEDXACTION_P_H */

View File

@ -34,7 +34,6 @@
#include "TransactionP.h"
#include "gnc-commodity.h"
#include "gnc-lot-p.h"
#include "SchedXactionP.h"
#include "FreqSpecP.h"
#include "gnc-pricedb-p.h"

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
#define GNC_FREQUENCY_H
#include "gnc-date-edit.h"
#include "Recurrence.h"
#include "FreqSpec.h"
#define GNC_TYPE_FREQUENCY (gnc_frequency_get_type())
@ -41,54 +42,55 @@
**/
typedef struct _GncFrequency
{
GtkVBox widget;
GtkVBox *vb;
GtkNotebook *nb;
GtkComboBox *freqComboBox;
GNCDateEdit *startDate;
GladeXML *gxml;
GtkVBox widget;
GtkVBox *vb;
GtkNotebook *nb;
GtkComboBox *freqComboBox;
GNCDateEdit *startDate;
GladeXML *gxml;
} GncFrequency;
typedef struct _GncFrequencyClass
{
GtkVBoxClass parent_class;
GtkVBoxClass parent_class;
void (*changed) (GncFrequency *gf);
void (*changed) (GncFrequency *gf);
} GncFrequencyClass;
struct pageDataTuple
{
int idx;
UIFreqType uiFTVal;
char *name;
int idx;
UIFreqType uiFTVal;
char *name;
};
GType gnc_frequency_get_type( void );
GType gnc_frequency_get_type(void);
/**
* Create a new GncFrequencey widget.
* The menus and panels will be initialized to correspond to the
* settings in the FreqSpec, and the date window will show the
* indicated date. Either or both may be NULL.
* For the default freq spec widget, use 'NULL'.
* Create a new GncFrequencey widget, reflecting the given FreqSpec \a fs and
* starting on \a start_date. Either or both may be NULL for reasonable
* defaults.
**/
GtkWidget* gnc_frequency_new(FreqSpec *fs, GDate *start_date);
void gnc_frequency_init( GncFrequency *gf );
GtkWidget* gnc_frequency_new_from_recurrence(GList *recurrences, GDate *start_date);
void gnc_frequency_init(GncFrequency *gf);
/**
* Change the given GncFrequency with the given FreqSpec and GDate.
* Change the given GncFrequency with the given FreqSpec and GDate.
* If the FreqSpec is NULL, then no change is made to the widget menus.
* If the date is NULL, then no change is made to the widget date field.
**/
void gnc_frequency_setup( GncFrequency *gf, FreqSpec *fs, GDate *date );
void gnc_frequency_setup(GncFrequency *gf, FreqSpec *fs, GDate *date);
void gnc_frequency_setup_recurrence(GncFrequency *gf, GList *recurrences, GDate *start_date);
/**
* Saves the state of the GNCFrequenecy widget.
* Saves the state of the GncFrequency widget.
* Updates the given FreqSpec if it's not NULL.
* Places the date in outDate, if it's not NULL.
**/
void gnc_frequency_save_state( GncFrequency *gf, FreqSpec *fs, GDate *outDate);
void gnc_frequency_save_state(GncFrequency *gf, FreqSpec *fs, GDate *outDate);
void gnc_frequency_save_to_recurrence(GncFrequency *gf, GList **recurrences, GDate *out_start_date);
/**
* Set the label text for the frequency option menu. In the current
@ -102,6 +104,4 @@ void gnc_frequency_set_frequency_label_text (GncFrequency *gf, const gchar *txt)
*/
void gnc_frequency_set_date_label_text (GncFrequency *gf, const gchar *txt);
void gnc_frequency_setup_default( GncFrequency *gf, FreqSpec *fs, GDate *date );
#endif /* !defined( GNC_FREQUENCY_H ) */

View File

@ -972,6 +972,7 @@ gnc_sxed_save_sx( GncSxEditorDialog *sxed )
FreqSpec *fs;
GDate gdate;
GString *str;
GList *schedule = NULL;
fs = xaccSchedXactionGetFreqSpec( sxed->sx );
gnc_frequency_save_state( sxed->gncfreq, fs, &gdate );
@ -980,10 +981,13 @@ gnc_sxed_save_sx( GncSxEditorDialog *sxed )
xaccFreqSpecGetFreqStr( fs, str );
g_debug("fs: %s", str->str);
gnc_frequency_save_to_recurrence(sxed->gncfreq, &schedule, &gdate);
gnc_sx_set_schedule(sxed->sx, schedule);
g_debug("recurrences parsed [%s]", recurrenceListToString(schedule));
/* now that we have it, set the start date */
xaccSchedXactionSetStartDate( sxed->sx, &gdate );
}
}
static void
@ -1259,10 +1263,13 @@ schedXact_editor_create_freq_sel( GncSxEditorDialog *sxed )
GtkBox *b;
b = GTK_BOX(glade_xml_get_widget( sxed->gxml, "gncfreq_hbox" ));
sxed->gncfreq =
/*sxed->gncfreq =
GNC_FREQUENCY( gnc_frequency_new( xaccSchedXactionGetFreqSpec(sxed->sx),
xaccSchedXactionGetStartDate(sxed->sx) ) );
g_assert( sxed->gncfreq );
xaccSchedXactionGetStartDate(sxed->sx) ) );*/
sxed->gncfreq =
GNC_FREQUENCY(gnc_frequency_new_from_recurrence(gnc_sx_get_schedule(sxed->sx),
xaccSchedXactionGetStartDate(sxed->sx)));
g_assert(sxed->gncfreq);
g_signal_connect( sxed->gncfreq, "changed",
G_CALLBACK(gnc_sxed_freq_changed),
sxed );

File diff suppressed because it is too large Load Diff