2001-07-06 Joshua Sled <jsled@asynchronous.org>

* src/gnome/gnc-schedxaction-xml-v2.c: Support for new
	SchedXaction options [create/remind-days-in-advance; auto-create,
	notify-on-creation].

	* src/gnome/dialog-scheduledxaction.c (putSchedXactionInClist):
	Fix for next-occurance processing.

	* src/engine/SchedXaction.c (xaccSchedXactionGetNextInstance):
	Better handling of start date/last-occur date/current dates when
	generating the next occurance date.  Gotta remember to clear those
	g_dates, lest the come up 'valid' due to stack trash... :(

	* src/gnome/gnc-sxlastrun.{h,c}: Added; newer/better
	since-last-occur dialog.

	* src/gnome/window-main.c: Added Scheduled Transaction stuff to
	"Tools" menu.

	* src/scm/prefs.scm: Added initial cut at Scheduled Transaction
	preferences.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@4905 57a11ea4-9604-0410-9ed3-97b8803252fd
zzzoldfeatures/g2-gog-integ
Joshua Sled 25 years ago
parent 890be8ccfc
commit d82bd05dfc

@ -1,3 +1,26 @@
2001-07-06 Joshua Sled <jsled@asynchronous.org>
* src/gnome/gnc-schedxaction-xml-v2.c: Support for new
SchedXaction options [create/remind-days-in-advance; auto-create,
notify-on-creation].
* src/gnome/dialog-scheduledxaction.c (putSchedXactionInClist):
Fix for next-occurance processing.
* src/engine/SchedXaction.c (xaccSchedXactionGetNextInstance):
Better handling of start date/last-occur date/current dates when
generating the next occurance date. Gotta remember to clear those
g_dates, lest the come up 'valid' due to stack trash... :(
* src/gnome/gnc-sxlastrun.{h,c}: Added; newer/better
since-last-occur dialog.
* src/gnome/window-main.c: Added Scheduled Transaction stuff to
"Tools" menu.
* src/scm/prefs.scm: Added initial cut at Scheduled Transaction
preferences.
2001-07-06 Robert Graham Merkel <rgmerk@mira.net>
* doc/sgml/C/xacc-balancreport.sgml: minor updates

@ -3,66 +3,160 @@ Author: jsled@asynchronous.org
Main Scheduled Transaction todo list
------------------------------------
. Engine ...Init() functions should be private.
. FreqSpec.c
. xaccFreqSpecGetFreqStr [display] needs to go away [?]
##################################################
### Done
##################################################
X add the ...GetFreqStr() code for the complex composite FreqSpecs
X fix the ...GetNextInstance() code
X XMLv2 I/O
X need policy for start-dates in GNCFrequency
X fix GetNextInstance and GetInstanceAfter, mostly for composite FreqSpecs
X also needs to deal with >28-mday values WRT last-occur date + multipliers
##################################################
### To-Do
##################################################
. Engine ...Init() functions should be private.
. FreqSpec.c
. xaccFreqSpecGetFreqStr [display] needs to go away [?]
X create a template register
X store account and amount data in kvp_frames.
. find a way to list multiple registers for template transaction purposes.
. this is a "normal" general ledger + a "stock" general ledger
. this is going to be: a tabbed notebook in which the tabs contain
the number of transactions the GL they hold contain.
X need policy for start-dates in GNCFrequency
X fix GetNextInstance and GetInstanceAfter, mostly for composite FreqSpecs
X also needs to deal with >28-mday values WRT last-occur date + multipliers
. add a big calendar [gnome-pim? evo?] SXaction List code
. Hook into 'book data changed' save-on-exit decision.
. add a big calendar [gnome-pim? evo?] to SXaction List/overview
. match existing transactions for long-time users
. based off template-transaction data, some big existing-transaction
scanning code.
. need "since-last-run" UI for instanatiation.
X/O create transactions
X numeric
. formula
. need variable fill-in UI...
. re-use gnome-sheet code for a variable-binding table?
. need way to expire/purge scheduled transactions which have no chance of
being created [outside their end date; once-scheduled and past].
. need 'reminders' of upcoming scheduled transactions during since-last-run
. need some configuration for constantly-running GnuCash users of when to pop
up the 'new scheduled transactions' dialog [option, time-of-day]
. need way to expire/purge scheduled transactions which have no chance of
being created [outside their end date; once-scheduled and past].
. need 'reminders' of upcoming scheduled transactions during since-last-run
. Is it sufficient to look at the next instance of ea. transaction only?
I think not... we probably want to look out until the transaction is
outside the reminder range.
. need some configuration for constantly-running GnuCash users of when to
pop up the 'new scheduled transactions' dialog [option, time-of-day]
. Should deal with "nothing-to-do" better [not even show up].
. register mods
. to see upcoming xactions, modifying future balance
. to instantiate xactions.
. to note which are "recurring"
. the mozilla "reload" glyph is kinda neat...
. would like "don't even tell me you instantiated it, just fscking do
. Differently-colored "not-yet-created" entries for a configurable
window.
. Context menus/sensitive toolbar button/menu item for creation of
not-yet-created transactions.
. The ability to turn a non-recurring transaction into a recurring one...
X would like "don't even tell me you instantiated it, just fscking do
it!" option for non-manual-conf SXes
. deal better with formulas in template transactions [real FormulaCell]
. recognize purely numeric template transactions and balance at
template-creation time.
. GNCFrequency
. initial-settings synchronization [start date, optionmenus]
. only a couple left; which ones?
. backend support
. PostgreSQL
. others?
Bugs:
. SX Creation...
. Creation occurs due to a variety of circumstances:
. GnuCash starts and hasn't been run in some length of time; the
transactions which have "come due" since the last run are available for
creation.
. A user opens a register with future transactions in it; they manually
force the creation of the [perhaps not immediately next [though this
seems a bit weird]] one.
. A user is reminded of something which hasn't come due, but will w/in a
configurable amount of time, and thus they pay/create it.
. Configuration options...
. Overall
. Size of template register window
. color of future register entries
. conrad's desires
. policy
. create for N days in advance
. show for N days in advance, create when come-due
. defaults
. create/show for 'N' days in advance
. remind me 'M' days in advance
. just create
. notify when created
. Per-SX
. just create/notify
. create/show
. lead-time
. reminder
. lead-time
. Changes
. Create-into-future vs. create-normal
. into-future -> normal : no change; the last_occur date will be
appropriate, and will catch up eventually [unless the have-been-created
transactions should go away]
. normal -> into-future : should create immed, or wait for user?
. into-future [t_0] -> into_future [t_1]
. frequency
. in presence of create-into-future?
. transaction
. in presence of create-into-future?
##################################################
### Bugs
##################################################
. General
. Date l10n.
. GNCFreqency
. Can't click-out of the register
. transitioning to a new tab doesn't correctly setup the agreement between
the startdate and the page elements.
. Example calendar month change isn't handled correctly/doesn't refresh the
marks.
. "Inappropriate FreqSpec type" on new-SX editing.
. "new; weekly: click on day, click off day: GLib-CRITICAL **: file gdate.c: line 1236 (g_date_to_struct_tm): assertion `g_date_valid (d)' failed."
. Scheduled Transaction Editor
. Can't click-out of the register
. auto-shrink on window create [the register is too wide, leading to too
much whitespace on the two top panels]
. Size/space issues.
. Un-selecting "End Date" leaves calendar widget sensitive
. Scheduled Transaction List
Enhancements:
. Since-last-run
. always goes one date past the instantiation date.
X credit and debit seem reversed at instantiation time...
. this is fixed, but is the fix correct?
##################################################
### Enhancements
##################################################
. SX name should be default value for template transaction description
. loan/repayment SX's
. integrate "Financial Calculator"
@ -70,6 +164,11 @@ Enhancements:
account amount.
. SX since-last-run should be able to sort by Date [conditional on the dialog
staying around].
. There probably wants to be a multi-month "example" View which the
GNCFrequency can work with.
. jalapeno[ben] has some thoughts on this...
. Evolution calendar integ.
. Evolution To-Do list integ. [SX reminders]
========================================
@ -161,14 +260,15 @@ normal people, or a sexp for Schemers.
=================================================
Instantiation
-------------
Instantiation Notes
-------------------
<jsled> Wilddev, conrad: Something that came out of Aaron's mail [see my reply to -devel] that I'd like your comment on:
<jsled> How do you intend to use scheduled transactions?
<jsled> Do you intend to use it to create things have should be in there since you last ran GnuCash?
<jsled> Or, do you intend to use it to create future transactions [perhaps a weeks worth] before they occur?
<jsled> Or, just primarily the former, but use the fact that the future transaction will be in the register to remind you to pay things, &c.?
<conrad> Personally, I'd be looking at future transactions as a reminder thing. But then, I run gnucash every day.
<jsled> conrad: Do you re-invoke it every day, or leave it running?
<conrad> I can see other people wanting case 1 though.
@ -178,7 +278,6 @@ Instantiation
<conrad> I think a further configurable sub-option should be "redisplay on change of day" (possibly with an "at time <blah> option?)")
<conrad> without that option, it will not do what I'm counting on it to do - remind my I'm supposed to pay my bills.
<jsled> Yup yup.
* jsled takes notes this.
Summary...
@ -195,7 +294,6 @@ being created ATM.
<Wilddev> and second
<Wilddev> as an actual transaction that goes into the register on a future date, ie I know that this money leaves my account in 2 days, so I want it to go in automatically on that day. If I leave gnucash running all the time, it'll wait until that day then enter the transaction
<Wilddev> as you can see the purpose of each is quite different
Wilddev WildWEnd
<jsled> Wilddev: Indeed...
<jsled> For the first, you're saying that reminders should start some number of days before the transaction is usually due/paid... and that there are two acknowledgements of that... 'remind me later' or 'here's the amount/create'.
<jsled> For the second, you're looking at ad-hoc once-scheduled transactions... which should go away immediately afterwards.
@ -205,7 +303,6 @@ being created ATM.
<jsled> Okay... so this brings up something that isn't presently in the scheme at all: reminders.
<jsled> I think it's as simple as a "[ ] Remind me __ days in advance" element in the SXEditor, and the appropriate logic in the since-last-run code...
<Wilddev> how often is the last run code 'run'?
Wilddev WildWEnd
<jsled> Wilddev: On startup, or when the timer [a-la conrad's requirement] goes off.
<Wilddev> yes that would work
<jsled> So the "since-last-run" dialog has three panes: 1) auto-created, notification requested. 2) To-create. 3) To-create-soon + reminders.

@ -44,7 +44,7 @@
static short module = MOD_SX;
/** Local data defs *****/
void transactionListMapDelete( gpointer data, gpointer user_data );
void _transactionListMapDelete( gpointer data, gpointer user_data );
/** Local Prototypes *****/
@ -75,7 +75,10 @@ xaccSchedXactionInit( SchedXaction *sx, GNCBook *book )
sx->num_occurances_total = -1;
sx->kvp_data = kvp_frame_new();
sx->manual = FALSE;
sx->autoCreateOption = FALSE;
sx->autoCreateNotify = FALSE;
sx->advanceCreateDays = 0;
sx->advanceRemindDays = 0;
sx->templateSplits = NULL;
/* create a new template account for our splits */
@ -102,7 +105,7 @@ xaccSchedXactionFree( SchedXaction *sx )
xaccRemoveEntity( &sx->guid );
g_list_foreach( sx->templateSplits,
transactionListMapDelete,
_transactionListMapDelete,
NULL );
g_list_free( sx->templateSplits );
if ( sx->name )
@ -113,7 +116,7 @@ xaccSchedXactionFree( SchedXaction *sx )
}
void
transactionListMapDelete( gpointer data, gpointer user_data )
_transactionListMapDelete( gpointer data, gpointer user_data )
{
Transaction *t = (Transaction*)data;
xaccTransBeginEdit( t );
@ -265,15 +268,45 @@ xaccSchedXactionSetGUID( SchedXaction *sx, GUID g )
}
void
xaccSchedXactionSetManual( SchedXaction *sx, gboolean newManual )
xaccSchedXactionGetAutoCreate( SchedXaction *sx,
gboolean *outAutoCreate,
gboolean *outNotify )
{
sx->manual = newManual;
*outAutoCreate = sx->autoCreateOption;
*outNotify = sx->autoCreateNotify;
}
int
xaccSchedXactionGetManual( SchedXaction *sx )
void
xaccSchedXactionSetAutoCreate( SchedXaction *sx,
gboolean newAutoCreate,
gboolean newNotify )
{
sx->autoCreateOption = newAutoCreate;
sx->autoCreateNotify = newNotify;
}
gint
xaccSchedXactionGetAdvanceCreation( SchedXaction *sx )
{
return sx->advanceCreateDays;
}
void
xaccSchedXactionSetAdvanceCreation( SchedXaction *sx, gint createDays )
{
sx->advanceCreateDays = createDays;
}
gint
xaccSchedXactionGetAdvanceReminder( SchedXaction *sx )
{
return sx->advanceRemindDays;
}
void
xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays )
{
return sx->manual;
sx->advanceRemindDays = reminderDays;
}
GDate
@ -300,6 +333,7 @@ xaccSchedXactionGetNextInstance( SchedXaction *sx )
}
}
#if 0
if ( g_date_valid( &last_occur ) ) {
g_date_set_time( &tmpDate, time(NULL) );
last_occur =
@ -309,6 +343,7 @@ xaccSchedXactionGetNextInstance( SchedXaction *sx )
} else {
g_date_set_time( &last_occur, time(NULL) );
}
#endif // 0
if ( g_date_valid( &sx->start_date )
&& ! g_date_valid( &sx->last_date ) ) {

@ -56,29 +56,29 @@
* of the internal ledger] for this editing.
**/
typedef struct gncp_SchedXaction {
gchar *name;
gchar *name;
FreqSpec *freq;
GDate last_date;
GDate last_date;
GDate start_date;
GDate start_date;
/* if end_date is invalid, then no end. */
GDate end_date;
GDate end_date;
/* if num_occurances_total == 0, then no limit */
gint num_occurances_total;
gint num_occurances_total;
/* reminaing occurances are as-of the 'last_date'. */
gint num_occurances_remain;
gint num_occurances_remain;
/* If true, confirmation is required.
If false, then this can be created when due without
intervention. */
gboolean manual;
gboolean autoCreateOption;
gboolean autoCreateNotify;
gint advanceCreateDays;
gint advanceRemindDays;
GList *templateSplits;
GList *templateSplits;
GUID guid;
GUID guid;
kvp_frame *kvp_data;
} SchedXaction;
@ -136,8 +136,14 @@ void xaccSchedXactionSetRemOccur( SchedXaction *sx, gint numRemain );
GList *xaccSchedXactionGetSplits( SchedXaction *sx );
void xaccSchedXactionSetSplits( SchedXaction *sx, GList *newSplits );
gboolean xaccSchedXactionGetManual( SchedXaction *sx );
void xaccSchedXactionSetManual( SchedXaction *sx, gboolean newManual );
void xaccSchedXactionGetAutoCreate( SchedXaction *sx, gboolean *outAutoCreate, gboolean *outNotify );
void xaccSchedXactionSetAutoCreate( SchedXaction *sx, gboolean newAutoCreate, gboolean newNotify );
gint xaccSchedXactionGetAdvanceCreation( SchedXaction *sx );
void xaccSchedXactionSetAdvanceCreation( SchedXaction *sx, gint createDays );
gint xaccSchedXactionGetAdvanceReminder( SchedXaction *sx );
void xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays );
#if 0
#error vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

@ -52,7 +52,10 @@
* <gnc:schedxaction version="1.0.0">
* <sx:id type="guid">...</sx:id>
* <sx:name>Rent</sx:name>
* <sx:manual-conf>f</sx:manual-conf>
* <sx:autoCreate>y</sx:autoCreate>
* <sx:autoCreateNotify>n</sx:autoCreateNotify>
* <sx:advanceCreateDays>0</sx:advanceCreateDays>
* <sx:advanceRemindDays>5</sx:advanceRemindDays>
* <sx:lastOccur>
* <gdate>2001-02-28</gdate>
* </sx:lastOccur>
@ -118,13 +121,21 @@ gnc_schedXaction_dom_tree_create(SchedXaction *sx)
xmlNewTextChild( ret, NULL, "sx:name", xaccSchedXactionGetName(sx) );
xmlNewTextChild( ret, NULL, "sx:manual-conf",
(xaccSchedXactionGetManual(sx) == 1 ? "t" : "f") );
//xmlNewTextChild( ret, NULL, "sx:manual-conf",
//(xaccSchedXactionGetManual(sx) == 1 ? "t" : "f") );
xmlNewTextChild( ret, NULL, "sx:autoCreate",
( sx->autoCreateOption ? "y" : "n" ) );
xmlNewTextChild( ret, NULL, "sx:autoCreateNotify",
( sx->autoCreateNotify ? "y" : "n" ) );
xml_add_gint32( ret, "sx:advanceCreateDays", sx->advanceCreateDays );
xml_add_gint32( ret, "sx:advanceRemindDays", sx->advanceRemindDays );
xmlAddChild( ret,
gdate_to_dom_tree( "sx:start",
xaccSchedXactionGetStartDate(sx) ) );
date = xaccSchedXactionGetLastOccurDate(sx);
date = xaccSchedXactionGetLastOccurDate(sx);
if ( g_date_valid( date ) ) {
xmlAddChild( ret, gdate_to_dom_tree( "sx:last", date ) );
}
@ -176,13 +187,55 @@ static
gboolean
sx_name_handler( xmlNodePtr node, gpointer sx )
{
gchar *tmp = dom_tree_to_text( node );
gchar *tmp = dom_tree_to_text( node );
g_return_val_if_fail( tmp, FALSE );
xaccSchedXactionSetName( (SchedXaction*)sx, tmp );
g_free( tmp );
return TRUE;
}
static gboolean
sx_autoCreate_handler( xmlNodePtr node, gpointer sx )
{
gchar *tmp = dom_tree_to_text( node );
((SchedXaction*)sx)->autoCreateOption = (safe_strcmp( tmp, "y" ) == 0 ? TRUE : FALSE );
return TRUE;
}
static gboolean
sx_notify_handler( xmlNodePtr node, gpointer sx )
{
gchar *tmp = dom_tree_to_text( node );
((SchedXaction*)sx)->autoCreateNotify = (safe_strcmp( tmp, "y" ) == 0 ? TRUE : FALSE );
return TRUE;
}
static gboolean
sx_advCreate_handler( xmlNodePtr node, gpointer sx )
{
gint64 advCreate;
if ( ! dom_tree_to_integer( node, &advCreate ) ) {
return FALSE;
}
xaccSchedXactionSetAdvanceCreation( (SchedXaction*)sx, advCreate );
return TRUE;
}
static gboolean
sx_advRemind_handler( xmlNodePtr node, gpointer sx )
{
gint64 advRemind;
if ( ! dom_tree_to_integer( node, &advRemind ) ) {
return FALSE;
}
xaccSchedXactionSetAdvanceReminder( (SchedXaction*)sx, advRemind );
return TRUE;
}
static
gboolean
sx_set_date( xmlNodePtr node, SchedXaction *sx,
@ -236,6 +289,7 @@ sx_freqspec_handler( xmlNodePtr node, gpointer sx )
return TRUE;
}
#if 0
static
gboolean
sx_manualConf_handler( xmlNodePtr node, gpointer sx )
@ -251,6 +305,7 @@ sx_manualConf_handler( xmlNodePtr node, gpointer sx )
g_free(tmp);
return TRUE;
}
#endif //0
static
gboolean
@ -291,16 +346,19 @@ sx_slots_handler( xmlNodePtr node, gpointer sx )
}
struct dom_tree_handler sx_dom_handlers[] = {
{ "sx:id", sx_id_handler, 1, 0 },
{ "sx:name", sx_name_handler, 1, 0 },
{ "sx:start", sx_start_handler, 1, 0 },
{ "sx:last", sx_last_handler, 0, 0 },
{ "sx:manual-conf", sx_manualConf_handler, 1, 0 },
{ "sx:num-occur", sx_numOccur_handler, 0, 0 },
{ "sx:rem-occur", sx_remOccur_handler, 0, 0 },
{ "sx:end", sx_end_handler, 0, 0 },
{ "sx:freqspec", sx_freqspec_handler, 1, 0 },
{ "sx:slots", sx_slots_handler, 0, 0 },
{ "sx:id", sx_id_handler, 1, 0 },
{ "sx:name", sx_name_handler, 1, 0 },
{ "sx:autoCreate", sx_autoCreate_handler, 1, 0 },
{ "sx:autoCreateNotify", sx_notify_handler, 1, 0 },
{ "sx:advanceCreateDays", sx_advCreate_handler, 1, 0 },
{ "sx:advanceRemindDays", sx_advRemind_handler, 1, 0 },
{ "sx:start", sx_start_handler, 1, 0 },
{ "sx:last", sx_last_handler, 0, 0 },
{ "sx:num-occur", sx_numOccur_handler, 0, 0 },
{ "sx:rem-occur", sx_remOccur_handler, 0, 0 },
{ "sx:end", sx_end_handler, 0, 0 },
{ "sx:freqspec", sx_freqspec_handler, 1, 0 },
{ "sx:slots", sx_slots_handler, 0, 0 },
};
static gboolean

@ -59,7 +59,8 @@ libgncgnome_a_SOURCES = \
window-reconcile.c \
window-register.c \
window-report.c \
dialog-nextrun.c
dialog-nextrun.c \
dialog-sxsincelast.c
gnomeappdir = ${datadir}/gnome/apps/Applications
@ -119,7 +120,8 @@ noinst_HEADERS = \
window-reconcile.h \
window-register.h \
window-report.h \
dialog-nextrun.h
dialog-nextrun.h \
dialog-sxsincelast.h
EXTRA_DIST = \
.cvsignore \

@ -44,16 +44,16 @@
static short module = MOD_SX;
typedef struct _toCreateTransaction {
SchedXaction *sx;
GDate *date;
SchedXaction *sx;
GDate *date;
gint clistRow;
gint clistRow;
} toCreateTransaction;
typedef struct _sxSinceLastData {
GtkWidget *nextrunDlg;
GladeXML *gxml;
GList /* <toCreateTransaction*> */ *transList;
GtkWidget *nextrunDlg;
GladeXML *gxml;
GList /* <toCreateTransaction*> */ *transList;
} sxSinceLastData;
static void nextrun_init( sxSinceLastData *sxsld );
@ -69,6 +69,12 @@ static void slr_create_transactions( SchedXaction *sx, GDate *gd );
/* int parse_vars_from_formula( const char *formula, GHashTable *varHash ); */
void
gnc_ui_nextrun_guile_wrapper( char *foo )
{
gnc_ui_nextrun_dialog_create();
}
void
gnc_ui_nextrun_dialog_create(void)
{
@ -200,6 +206,7 @@ nr_next_clicked( GtkButton *b, gpointer ud )
return;
}
/* FIXME: This is actually a non-changeable date. */
endDate = g_date_new();
g_date_set_time( endDate, gdeDate );
@ -207,46 +214,37 @@ nr_next_clicked( GtkButton *b, gpointer ud )
cl = GTK_CLIST(o);
gtk_clist_clear( cl );
gd = *g_date_new();
g_date_clear( &gd, 1 );
row = 0;
do {
sx = (SchedXaction*)sxList->data;
/* this is really "last-run-date", right? */
g_date_set_time( &gd, time(NULL) );
do {
gd = xaccSchedXactionGetNextInstance( sx );
while ( g_date_compare( &gd, endDate ) <= 0
&& g_date_valid( &gd ) ) {
g_date_strftime( buf, 1023, "%a, %b %e, %Y", &gd );
/* add to clist [ahem... register... ahem] */
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(char) * 256 ); /* FIXME */
g_date_strftime( rowText[1], 255, "%a, %b %e, %Y", &gd );
tct = g_new0( toCreateTransaction, 1 );
tct->sx = sx;
tct->date = g_date_new();
*tct->date = gd;
tct->clistRow = row;
sxsld->transList = g_list_append( sxsld->transList, tct );
gtk_clist_insert( cl, row, rowText );
row += 1;
gd = xaccSchedXactionGetInstanceAfter( sx, &gd );
if ( g_date_valid( &gd ) ) {
g_date_strftime( buf, 1023, "%c", &gd );
/* add to clist [ahem... register... ahem] */
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(char) * 256 ); /* FIXME */
g_date_strftime( rowText[1], 255, "%c", &gd );
tct = g_new0( toCreateTransaction, 1 );
tct->sx = sx;
tct->date = g_date_new();
*tct->date = gd;
tct->clistRow = row;
sxsld->transList = g_list_append( sxsld->transList, tct );
gtk_clist_insert( cl, row, rowText );
row += 1;
}
} while ( g_date_compare( &gd, endDate ) <= 0
&& g_date_valid( &gd ) );
}
} while ( (sxList = sxList->next) );
#if 0
sxList = sxsld->transList;
do {
char buf[128];
g_date_strftime( buf, 127, "%c",
((toCreateTransaction*)sxList->data)->date );
DEBUG( "List contains sx \"%s\" on date \"%s\"\n",
xaccSchedXactionGetName( ((toCreateTransaction*)sxList->data)->sx ),
buf );
} while ( (sxList = sxList->next) );
#endif /* 0 */
g_date_free( endDate );
}
static void
@ -304,10 +302,9 @@ create_each_transaction( Transaction *t, void *d )
}
do {
split = (Split*)sList->data;
/* Ick. This assumes that the split lists will be
ordered identically. :( I think it's fair to say
they will, but I'd rather not have to count on
it. --jsled */
/* FIXME: Ick. This assumes that the split lists will be
ordered identically. :( I think it's fair to say they
will, but I'd rather not have to count on it. --jsled */
split_kvpf = xaccSplitGetSlots( (Split*)osList->data );
DEBUG( "\tProcessing Split \"%s\"\n",
@ -374,8 +371,7 @@ create_each_transaction( Transaction *t, void *d )
str, gnc_numeric_to_string( debit_num ) );
}
final = gnc_numeric_sub_fixed( debit_num,
credit_num );
final = gnc_numeric_sub_fixed( credit_num, debit_num );
gncn_error = gnc_numeric_check( final );
if ( gncn_error != GNC_ERROR_OK ) {
@ -383,8 +379,8 @@ create_each_transaction( Transaction *t, void *d )
errFlag = TRUE;
break;
}
printf( "gnc_numeric::final: \"%s\"\n",
gnc_numeric_to_string( final ) );
DEBUG( "gnc_numeric::final: \"%s\"\n",
gnc_numeric_to_string( final ) );
xaccSplitSetValue( split, final );
}
#if 0
@ -394,7 +390,7 @@ create_each_transaction( Transaction *t, void *d )
} while ( (sList = sList->next) && (osList = osList->next) );
if ( errFlag ) {
printf( "Some error in newT creation\n" );
PERR( "Some error in new transaction creation...\n" );
xaccTransRollbackEdit( newT );
} else {
xaccTransCommitEdit( newT );
@ -415,8 +411,8 @@ slr_create_transactions( SchedXaction *sx, GDate *gd )
ag = gnc_book_get_template_group( gncGetCurrentBook() );
id = guid_to_string( xaccSchedXactionGetGUID(sx) );
acct = xaccGetAccountFromName( ag, id );
printf( "Got account \"%s\"\n",
xaccAccountGetName( acct ) );
DEBUG( "Got account \"%s\"\n",
xaccAccountGetName( acct ) );
g_free( id );
xaccAccountForEachTransaction( acct,
@ -447,17 +443,17 @@ parse_vars_from_formula( const char *formula, GHashTable *varHash )
gnc_exp_parser_init();
if ( ! gnc_exp_parser_parse( formula, &num_foo, &foo ) ) {
printf( "Error parsing at \"%s\": %s\n",
PERR( "Error parsing at \"%s\": %s\n",
foo, gnc_exp_parser_error_string() );
}
printf( "Successful parse...\n" );
PINFO( "Successful parse...\n" );
list = gnc_exp_parser_get_variable_names();
if ( list == NULL ) {
printf( "NULL variable list\n" );
PINFO( "NULL variable list\n" );
} else {
do {
printf( "Variable \"%s\"\n",
list->data );
PINFO( "Variable \"%s\"\n",
list->data );
} while ( (list = list->next) );
}

@ -24,5 +24,6 @@
#define DIALOG_NEXTRUN_H
void gnc_ui_nextrun_dialog_create( void );
void gnc_ui_nextrun_guile_wrapper( char* );
#endif

@ -1,6 +1,6 @@
/********************************************************************\
* dialog-scheduledxaction.c : dialog for scheduled transaction *
* editor *
* list and editor *
* Copyright (C) 2001 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *
@ -107,11 +107,12 @@ static void schedXact_editor_populate( SchedXactionEditorDialog * );
static void new_button_clicked( GtkButton *b, gpointer d );
static void edit_button_clicked( GtkButton *b, gpointer d );
static void delete_button_clicked( GtkButton *b, gpointer d );
static void ok_button_clicked( GtkButton *b, gpointer d );
static void cancel_button_clicked( GtkButton *b, gpointer d );
static void close_button_clicked( GtkButton *b, gpointer d );
static void endgroup_rb_toggled( GtkButton *b, gpointer d );
static void set_endgroup_toggle_states( SchedXactionEditorDialog *sxed, EndType t );
static void advance_toggle( GtkButton *b, SchedXactionEditorDialog *sxed );
/* ledger standard-handlers */
static void sxe_ledger_destroy( xaccLedgerDisplay *ld );
@ -156,19 +157,11 @@ sxed_close_handler ( gpointer user_data )
static
void
ok_button_clicked( GtkButton *b, gpointer d )
close_button_clicked( GtkButton *b, gpointer d )
{
sxd_close_handler( d );
}
static
void
cancel_button_clicked( GtkButton *b, gpointer d )
{
/* FIXME. */
gnc_close_gui_component_by_data( DIALOG_SCHEDXACTION_CM_CLASS, d );
}
static
void
editor_close_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
@ -181,13 +174,13 @@ static
void
editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
{
GNCBook *book;
GtkWidget *o, *o2, *o3;
GList *sxList;
FreqSpec *fs;
gint row;
time_t tmpDate;
GDate *gdate;
GNCBook *book;
GtkWidget *o, *o2, *o3;
GList *sxList;
FreqSpec *fs;
gint row;
time_t tmpDate;
GDate *gdate;
gdate = g_date_new();
@ -220,10 +213,43 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
} else {
PERR( "No valid end specified\n" );
}
/* manual conf */
o = glade_xml_get_widget( sxed->gxml, "manual_conf" );
xaccSchedXactionSetManual( sxed->sx,
gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) );
{
gboolean autocreateState, notifyState;
o = glade_xml_get_widget( sxed->gxml, "autocreate_opt" );
autocreateState = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) );
o = glade_xml_get_widget( sxed->gxml, "notify_opt" );
notifyState = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) );
/* "Notify" only makes sense if AutoCreate is actived;
enforce that here. */
xaccSchedXactionSetAutoCreate( sxed->sx,
autocreateState,
(autocreateState & notifyState) );
}
{
int daysInAdvance;
daysInAdvance = 0;
o = glade_xml_get_widget( sxed->gxml, "advance_opt" );
if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) ) {
o = glade_xml_get_widget( sxed->gxml, "advance_days" );
daysInAdvance =
gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) );
}
xaccSchedXactionSetAdvanceCreation( sxed->sx, daysInAdvance );
daysInAdvance = 0;
o = glade_xml_get_widget( sxed->gxml, "remind_opt" );
if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) ) {
o = glade_xml_get_widget( sxed->gxml, "remind_days" );
daysInAdvance =
gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(o) );
}
xaccSchedXactionSetAdvanceReminder( sxed->sx, daysInAdvance );
}
/* get the frequency spec data */
fs = xaccSchedXactionGetFreqSpec( sxed->sx );
@ -249,6 +275,32 @@ editor_ok_button_clicked( GtkButton *b, SchedXactionEditorDialog *sxed )
sxed_close_handler( (gpointer)sxed );
}
static void
autocreate_toggled( GtkObject *o, SchedXactionEditorDialog *sxed )
{
GtkWidget *notifyCheck;
notifyCheck = glade_xml_get_widget( sxed->gxml, "notify_opt" );
gtk_widget_set_sensitive( notifyCheck,
gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) );
}
static void
advance_toggle( GtkButton *o, SchedXactionEditorDialog *sxed )
{
gchar *spinName;
GtkWidget *spin;
spinName = (gchar*)gtk_object_get_data( GTK_OBJECT(o), "whichOneAmI" );
spin = glade_xml_get_widget( sxed->gxml, spinName );
if ( !spin ) {
PERR( "Error getting widget with name \"%s\"", spinName );
return;
}
gtk_widget_set_sensitive( spin,
gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(o) ) );
}
/* Local destruction of dialog */
static void
scheduledxaction_dialog_destroy(GtkObject *object, gpointer data)
@ -326,17 +378,10 @@ gnc_ui_scheduled_xaction_dialog_create(void)
button = glade_xml_get_widget( sxd->gxml, "delete_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(delete_button_clicked), sxd );
button = glade_xml_get_widget( sxd->gxml, "ok_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(ok_button_clicked), sxd );
button = glade_xml_get_widget( sxd->gxml, "cancel_button" );
button = glade_xml_get_widget( sxd->gxml, "close_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(cancel_button_clicked), sxd );
/* turn off the cancel button, for now, as we have no way to cancel. */
gtk_widget_set_sensitive( GTK_WIDGET(button), FALSE );
GTK_SIGNAL_FUNC(close_button_clicked), sxd );
/* Set the clist columns to auto-resize. */
schedXact_populate( sxd );
gtk_widget_show(sxd->dialog);
@ -416,8 +461,30 @@ SchedXactionEditorDialog *
gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
SchedXaction *sx )
{
SchedXactionEditorDialog *sxed;
GtkWidget *button;
SchedXactionEditorDialog *sxed;
GtkWidget *button;
int i;
static struct widgetSignalCallback {
char *name;
char *signal;
void (*fn)();
gpointer objectData;
} widgets[] = {
{ "ok_button", "clicked", editor_ok_button_clicked, NULL },
{ "cancel_button", "clicked", editor_close_button_clicked, NULL },
{ "rb_enddate", "toggled", endgroup_rb_toggled, (gpointer)END_OPTION },
{ "rb_num_occur", "toggled", endgroup_rb_toggled, (gpointer)NUM_OCCUR_OPTION },
{ "autocreate_opt", "toggled", autocreate_toggled, NULL },
{ "advance_opt", "toggled", advance_toggle, (gpointer)"advance_days" },
{ "remind_opt", "toggled", advance_toggle, (gpointer)"remind_days" },
{ "rec_button", "clicked", sxed_reg_recordCB, NULL },
{ NULL, NULL, NULL, NULL }
};
sxed = g_new0( SchedXactionEditorDialog, 1 );
@ -441,30 +508,26 @@ gnc_ui_scheduled_xaction_editor_dialog_create( SchedXactionDialog *sxd,
sxed);
/* FIXME: want delete-event, too. */
button = glade_xml_get_widget( sxed->gxml, "ok_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(editor_ok_button_clicked), sxed);
button = glade_xml_get_widget( sxed->gxml, "cancel_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(editor_close_button_clicked), sxed);
for ( i=0; widgets[i].name != NULL; i++ ) {
button = glade_xml_get_widget( sxed->gxml, widgets[i].name );
if ( widgets[i].objectData != NULL ) {
gtk_object_set_data( GTK_OBJECT(button),
"whichOneAmI",
widgets[i].objectData );
}
gtk_signal_connect( GTK_OBJECT(button),
widgets[i].signal,
GTK_SIGNAL_FUNC( widgets[i].fn ), sxed );
}
button = glade_xml_get_widget( sxed->gxml, "ok_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(editor_close_button_clicked), sxed );
button = glade_xml_get_widget( sxed->gxml, "rb_enddate" );
gtk_object_set_data( GTK_OBJECT(button), "whichOneAmI", (gpointer)END_OPTION );
gtk_signal_connect( GTK_OBJECT(button), "toggled",
GTK_SIGNAL_FUNC(endgroup_rb_toggled), sxed );
button = glade_xml_get_widget( sxed->gxml, "rb_num_occur" );
gtk_object_set_data( GTK_OBJECT(button), "whichOneAmI", (gpointer)NUM_OCCUR_OPTION );
gtk_signal_connect( GTK_OBJECT(button), "toggled",
GTK_SIGNAL_FUNC(endgroup_rb_toggled), sxed );
button = glade_xml_get_widget( sxed->gxml, "rec_button" );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(sxed_reg_recordCB), sxed );
/* FIXME: For some reason the Glade-specified sensitivity settings
are not being honored. */
button = glade_xml_get_widget( sxed->gxml, "notify_opt" );
gtk_widget_set_sensitive( button, FALSE );
button = glade_xml_get_widget( sxed->gxml, "advance_days" );
gtk_widget_set_sensitive( button, FALSE );
button = glade_xml_get_widget( sxed->gxml, "remind_days" );
gtk_widget_set_sensitive( button, FALSE );
/* create the frequency-selection macrowidget */
schedXact_editor_create_freq_sel( sxed );
@ -619,7 +682,7 @@ schedXact_editor_create_ledger( SchedXactionEditorDialog *sxed )
gnc_table_init_gui( regWidget, splitreg );
gtk_container_add( GTK_CONTAINER(glade_xml_get_widget( sxed->gxml,
"vbox124" )),
"register_vbox" )),
regWidget );
sxed->reg = GNUCASH_REGISTER(regWidget);
@ -660,7 +723,7 @@ schedXact_editor_populate( SchedXactionEditorDialog *sxed )
GnomeDateEdit *gde;
SplitRegister *splitReg;
GList *splitList;
GtkWidget *o;
GtkWidget *w;
GString *tmpgStr;
struct tm *tmpTm;
GDate *gd;
@ -672,35 +735,65 @@ schedXact_editor_populate( SchedXactionEditorDialog *sxed )
}
gd = xaccSchedXactionGetEndDate( sxed->sx );
if ( g_date_valid( gd ) ) {
o = glade_xml_get_widget( sxed->gxml, "rb_enddate" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o), TRUE );
w = glade_xml_get_widget( sxed->gxml, "rb_enddate" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), TRUE );
/* fill in date data. */
o = glade_xml_get_widget( sxed->gxml, "sxe_end_date" );
w = glade_xml_get_widget( sxed->gxml, "sxe_end_date" );
tmpTm = g_new0( struct tm, 1 );
g_date_to_struct_tm( gd, tmpTm );
tmpDate = mktime( tmpTm );
g_free( tmpTm );
gnome_date_edit_set_time( GNOME_DATE_EDIT(o), tmpDate );
gnome_date_edit_set_time( GNOME_DATE_EDIT(w), tmpDate );
set_endgroup_toggle_states( sxed, END_DATE );
} else if ( xaccSchedXactionGetNumOccur( sxed->sx ) != -1 ) {
o = glade_xml_get_widget( sxed->gxml, "rb_num_occur" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o), TRUE );
o = glade_xml_get_widget( sxed->gxml, "end_nentry" );
o = gnome_number_entry_gtk_entry( GNOME_NUMBER_ENTRY(o) );
w = glade_xml_get_widget( sxed->gxml, "rb_num_occur" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), TRUE );
w = glade_xml_get_widget( sxed->gxml, "end_nentry" );
w = gnome_number_entry_gtk_entry( GNOME_NUMBER_ENTRY(w) );
tmpgStr = g_string_sized_new(5);
g_string_sprintf( tmpgStr, "%d", xaccSchedXactionGetNumOccur( sxed->sx ) );
gtk_entry_set_text( GTK_ENTRY(o), tmpgStr->str );
gtk_entry_set_text( GTK_ENTRY(w), tmpgStr->str );
g_string_free( tmpgStr, TRUE );
set_endgroup_toggle_states( sxed, END_OCCUR );
} else {
o = glade_xml_get_widget( sxed->gxml, "rb_noend" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o), TRUE );
w = glade_xml_get_widget( sxed->gxml, "rb_noend" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), TRUE );
set_endgroup_toggle_states( sxed, END_NONE );
}
o = glade_xml_get_widget( sxed->gxml, "manual_conf" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(o),
xaccSchedXactionGetManual( sxed->sx ) );
{
gboolean autoCreateState, notifyState;
xaccSchedXactionGetAutoCreate( sxed->sx, &autoCreateState, &notifyState );
w = glade_xml_get_widget( sxed->gxml, "autocreate_opt" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), autoCreateState );
w = glade_xml_get_widget( sxed->gxml, "notify_opt" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), notifyState );
}
{
gint daysInAdvance;
daysInAdvance =
xaccSchedXactionGetAdvanceCreation( sxed->sx );
if ( daysInAdvance != 0 ) {
w = glade_xml_get_widget( sxed->gxml, "advance_opt" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), TRUE );
w = glade_xml_get_widget( sxed->gxml, "advance_days" );
gtk_spin_button_set_value( GTK_SPIN_BUTTON(w),
(gfloat)daysInAdvance );
}
daysInAdvance =
xaccSchedXactionGetAdvanceReminder( sxed->sx );
if ( daysInAdvance != 0 ) {
w = glade_xml_get_widget( sxed->gxml, "remind_opt" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(w), TRUE );
w= glade_xml_get_widget( sxed->gxml, "remind_days" );
gtk_spin_button_set_value( GTK_SPIN_BUTTON(w),
(gfloat)daysInAdvance );
}
}
/* populate the ledger */
{

@ -1,5 +1,5 @@
/********************************************************************\
* dialog-scheduledxaction.h : dialogs for a scheduled transactions *
* dialog-scheduledxaction.h : dialogs for scheduled transactions *
* Copyright (C) 2001 Joshua Sled <jsled@asynchronous.org> *
* *
* This program is free software; you can redistribute it and/or *

@ -0,0 +1,766 @@
/********************************************************************\
* dialog-sxsincelast.c - "since last run" dialog. *
* Copyright (c) 2001 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 *
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
#include "config.h"
#include <gnome.h>
#include <glib.h>
#include "gnc-engine-util.h"
#include "FileDialog.h"
#include "gnc-book.h"
#include "Transaction.h"
#include "Group.h"
#include "gnc-numeric.h"
#include "SchedXaction.h"
#include "gnc-component-manager.h"
#include "SplitLedger.h"
#include "gnc-ui-util.h"
#include "gnc-exp-parser.h"
#include "dialog-utils.h"
#include "dialog-sxsincelast.h"
#define DIALOG_SXSINCELAST_CM_CLASS "dialog-sxsincelast"
static short module = MOD_SX;
typedef struct _toCreateTransaction {
SchedXaction *sx;
GDate *date;
gint clistRow;
} toCreateTransaction;
typedef struct _sxSinceLastData {
GtkWidget *sxsincelastDlg;
GladeXML *gxml;
GList /* <toCreateTransaction*> */ *transList;
} sxSinceLastData;
typedef struct _reminderTuple {
GDate *endDate;
GDate *occurDate;
} reminderTuple;
static void sxsincelast_init( sxSinceLastData *sxsld );
static void sxsincelast_populate( sxSinceLastData *sxsld );
static void sxsincelast_close_handler( gpointer ud );
static void sxsincelast_ok_clicked( GtkButton *b, gpointer ud );
static void sxsincelast_cancel_clicked( GtkButton *b, gpointer ud );
static void sxsincelast_destroy( GtkObject *o, gpointer ud );
static void _create_transactions_on( SchedXaction *sx, GDate *gd );
static void processAutoCreateList( GList *, sxSinceLastData *sxsld, SchedXaction * );
static void processToCreateList( GList *, sxSinceLastData *sxsld, SchedXaction * );
static void processReminderList( GList *, sxSinceLastData *sxsld, SchedXaction * );
/* int parse_vars_from_formula( const char *formula, GHashTable *varHash ); */
void
gnc_ui_sxsincelast_guile_wrapper( char *foo )
{
gnc_ui_sxsincelast_dialog_create();
}
void
gnc_ui_sxsincelast_dialog_create(void)
{
sxSinceLastData *sxsld = g_new0( sxSinceLastData, 1 );
sxsld->gxml = gnc_glade_xml_new( "sched-xact.glade", "Real Since-Last-Run Dialog" );
sxsld->sxsincelastDlg = glade_xml_get_widget( sxsld->gxml, "Real Since-Last-Run Dialog" );
sxsincelast_init( sxsld );
}
static void
sxsincelast_init( sxSinceLastData *sxsld )
{
GtkWidget *o;
int i;
struct widgetSignalHandlerTuple {
char *name;
char *signal;
void (*handlerFn)();
} widgets[] = {
{ "ok_button", "clicked", sxsincelast_ok_clicked },
{ "cancel_button", "clicked", sxsincelast_cancel_clicked },
{ NULL, NULL, NULL }
};
gnc_register_gui_component( DIALOG_SXSINCELAST_CM_CLASS,
NULL,
sxsincelast_close_handler,
sxsld->sxsincelastDlg );
gtk_signal_connect( GTK_OBJECT(sxsld->sxsincelastDlg), "destroy",
GTK_SIGNAL_FUNC( sxsincelast_destroy ), sxsld );
for ( i=0; widgets[i].name != NULL ; i++ ) {
o = glade_xml_get_widget( sxsld->gxml, widgets[i].name );
gtk_signal_connect( GTK_OBJECT(o), widgets[i].signal,
GTK_SIGNAL_FUNC(widgets[i].handlerFn),
sxsld );
}
sxsincelast_populate( sxsld );
gtk_widget_show_all( sxsld->sxsincelastDlg );
}
static void
_generate_instances( SchedXaction *sx,
GDate *end,
GList **instanceList )
{
GDate gd, *gdToReturn;
char tmpBuf[26];
gd = xaccSchedXactionGetNextInstance( sx );
while ( g_date_valid(&gd)
&& g_date_compare( &gd, end ) <= 0 ) {
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", &gd );
DEBUG( "Adding instance %s", tmpBuf );
gdToReturn = g_date_new();
*gdToReturn = gd;
*instanceList = g_list_append( *instanceList, gdToReturn );
gd = xaccSchedXactionGetInstanceAfter( sx, &gd );
}
if ( ! g_date_valid( &gd ) ) {
PERR( "Should be added to dead-list..." );
}
}
static void
_free_gdate_list_elts( gpointer data, gpointer user_data )
{
g_date_free( (GDate*)data );
}
static void
_free_reminderTuple_list_elts( gpointer data, gpointer user_data )
{
g_date_free( ((reminderTuple*)data)->occurDate );
g_free( (reminderTuple*)data );
}
static void
processAutoCreateList( GList *autoCreateList, sxSinceLastData *sxsld, SchedXaction *sx )
{
char tmpBuf[26];
int row;
GtkCList *cl;
gboolean autoCreateState, notifyState;
char *rowText[2];
row = 0;
/*
get the "automagically created and notification requested"
register, and create the entires.
For now, this is a clist...
*/
cl = GTK_CLIST( glade_xml_get_widget( sxsld->gxml, "auto_create_clist" ) );
gtk_clist_freeze( cl );
while ( autoCreateList ) {
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y",
(GDate*)autoCreateList->data );
xaccSchedXactionGetAutoCreate( sx, &autoCreateState, &notifyState );
_create_transactions_on( sx, (GDate*)autoCreateList->data );
if ( notifyState ) {
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(gchar) * 26 ); /* FIXME */
g_date_strftime( rowText[1], 25, "%a, %b %e, %Y",
(GDate*)autoCreateList->data );
gtk_clist_insert( cl, row++, rowText );
}
autoCreateList = autoCreateList->next;
}
gtk_clist_thaw( cl );
}
static void
processToCreateList( GList *toCreateList, sxSinceLastData *sxsld, SchedXaction *sx )
{
GtkCList *clist;
int row;
char *rowText[2];
row = 0;
if ( toCreateList == NULL )
return;
clist = GTK_CLIST( glade_xml_get_widget( sxsld->gxml, "to_create_clist" ) );
do {
/* add to clist [ahem... register... ahem] */
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(char) * 25 ); /* FIXME */
g_date_strftime( rowText[1], 25, "%a, %b %e, %Y", (GDate*)toCreateList->data );
gtk_clist_insert( clist, row++, rowText );
} while ( (toCreateList = toCreateList->next) );
}
static void
processReminderList( GList *reminderList, sxSinceLastData *sxsld, SchedXaction *sx )
{
GtkCList *clist;
int row;
char *rowText[3];
reminderTuple *rt;
/* . need
. orig end date
. this instance date
. sx
*/
row = 0;
if ( reminderList == NULL )
return;
clist = GTK_CLIST( glade_xml_get_widget( sxsld->gxml, "reminders_clist" ) );
do {
rt = (reminderTuple*)reminderList->data;
/* add to clist [ahem... register... ahem] */
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(gchar) * 25 ); /* FIXME */
g_date_strftime( rowText[1], 25, "%a, %b %e, %Y", rt->occurDate );
rowText[2] = malloc( sizeof(gchar) * 5 ); /* FIXME */
sprintf( rowText[2], "%d",
(g_date_julian(rt->occurDate) - g_date_julian(rt->endDate)) );
gtk_clist_insert( clist, row++, rowText );
} while ( (reminderList = reminderList->next) );
}
static void
sxsincelast_populate( sxSinceLastData *sxsld )
{
GList *sxList, *instanceList;
GList *autoCreateList, *toCreateList, *reminderList;
SchedXaction *sx;
GDate end, endPlusReminders;
GDate *instDate;
gint daysInAdvance;
gboolean autocreateState, notifyState;
gchar *rowText[3];
GtkWidget *w;
gint autoCreateRow, toCreateRow, remindersRow;
reminderTuple *rt;
autoCreateList = toCreateList = reminderList = NULL;
autoCreateRow = toCreateRow = remindersRow = 0;
sxList = gnc_book_get_schedxactions( gncGetCurrentBook() );
if ( sxList == NULL ) {
DEBUG( "No scheduled transactions to populate." );
}
do {
sx = (SchedXaction*)sxList->data;
g_date_set_time( &end, time(NULL) );
daysInAdvance = xaccSchedXactionGetAdvanceCreation( sx );
g_date_add_days( &end, daysInAdvance );
endPlusReminders = end;
daysInAdvance = xaccSchedXactionGetAdvanceReminder( sx );
g_date_add_days( &endPlusReminders, daysInAdvance );
if (0) {
char tmpBuf[26];
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", &end );
DEBUG( "We'll generate the appropriate instances, now for "
"SX \"%s\" with end time %s...",
xaccSchedXactionGetName(sx),
tmpBuf );
}
instanceList = NULL;
_generate_instances( sx, &endPlusReminders, &instanceList );
if ( instanceList == NULL )
continue;
xaccSchedXactionGetAutoCreate( sx, &autocreateState, &notifyState );
do {
instDate = (GDate*)instanceList->data;
if ( 0 ) {
char tmpBuf[26];
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", instDate );
DEBUG( "SX \"%s\" instance on %s",
xaccSchedXactionGetName(sx), tmpBuf );
}
if ( (g_date_compare( &end, &endPlusReminders ) != 0)
&& (g_date_compare( &end, instDate ) <= 0) ) {
/* DEBUG( "\tIs a reminder" ); */
rt = g_new0( reminderTuple, 1 );
rt->endDate = &end;
rt->occurDate = instDate;
reminderList = g_list_append( reminderList, rt );
} else {
if ( autocreateState ) {
/* DEBUG( "\tauto-create" ); */
autoCreateList = g_list_append( autoCreateList,
instDate );
} else {
/* DEBUG( "\tAdding to create list" ); */
toCreateList = g_list_append( toCreateList,
instDate );
}
}
} while ( (instanceList = instanceList->next) );
/* process the lists */
processAutoCreateList( autoCreateList, sxsld, sx );
processToCreateList ( toCreateList, sxsld, sx );
processReminderList ( reminderList, sxsld, sx );
g_list_foreach( autoCreateList, _free_gdate_list_elts, NULL );
g_list_free( autoCreateList );
g_list_foreach( reminderList, _free_reminderTuple_list_elts, NULL );
g_list_free( reminderList );
/* FIXME: freeup the toCreate list at a more appropriate
time. */
} while ( (sxList = sxList->next) );
}
static void
sxsincelast_close_handler( gpointer ud )
{
gnome_dialog_close( GNOME_DIALOG( ((sxSinceLastData*)ud)->sxsincelastDlg ) );
}
static void
free_elts( gpointer data, gpointer user_data )
{
g_free( data );
}
static void
sxsincelast_ok_clicked( GtkButton *b, gpointer ud )
{
sxSinceLastData *sxsld;
GtkWidget *dlg;
GtkWidget *o;
GtkCList *cl;
time_t gdeDate;
GList *sxList;
GNCBook *book;
SchedXaction *sx;
GDate gd, *endDate;
gchar buf[1024];
gint row;
char *rowText[2];
toCreateTransaction *tct;
sxsld = (sxSinceLastData*)ud;
sxsincelast_close_handler( sxsld );
/* FIXME: the SX/date list already has been generated; we should use that. */
#if 0
o = glade_xml_get_widget( sxsld->gxml, "next_date" );
gdeDate = gnome_date_edit_get_date( GNOME_DATE_EDIT(o) );
DEBUG( "Okay... I should run with a date of: %s", ctime(&gdeDate) );
/* destroy the previous transactions
destroy all the toCreateTransactions */
if ( sxsld->transList != NULL ) {
g_list_foreach( sxsld->transList, free_elts, NULL );
g_list_free( sxsld->transList );
sxsld->transList = NULL;
}
book = gncGetCurrentBook();
sxList = gnc_book_get_schedxactions( book );
if ( sxList == NULL ) {
PERR( "No scheduled transactions to play with\n" );
return;
}
endDate = g_date_new();
g_date_set_time( endDate, gdeDate );
o = glade_xml_get_widget( sxsld->gxml, "replace_with_register" );
cl = GTK_CLIST(o);
gtk_clist_clear( cl );
g_date_clear( &gd, 1 );
row = 0;
do {
sx = (SchedXaction*)sxList->data;
// this is really "last-run-date", right?
g_date_set_time( &gd, time(NULL) );
gd = xaccSchedXactionGetInstanceAfter( sx, &gd );
while ( g_date_compare( &gd, endDate ) <= 0
&& g_date_valid( &gd ) ) {
g_date_strftime( buf, 1023, "%a, %b %e, %Y", &gd );
/* add to clist [ahem... register... ahem] */
rowText[0] = xaccSchedXactionGetName( sx );
rowText[1] = malloc( sizeof(char) * 256 ); /* FIXME */
g_date_strftime( rowText[1], 255, "%a, %b %e, %Y", &gd );
tct = g_new0( toCreateTransaction, 1 );
tct->sx = sx;
tct->date = g_date_new();
*tct->date = gd;
tct->clistRow = row;
sxsld->transList = g_list_append( sxsld->transList, tct );
gtk_clist_insert( cl, row, rowText );
row += 1;
gd = xaccSchedXactionGetInstanceAfter( sx, &gd );
}
} while ( (sxList = sxList->next) );
g_date_free( endDate );
#endif
}
static void
sxsincelast_cancel_clicked( GtkButton *o, gpointer ud )
{
sxsincelast_close_handler( ud );
}
static void
sxsincelast_destroy( GtkObject *o, gpointer ud )
{
DEBUG( "nuttin' doin...\n" );
}
static gboolean
_create_each_transaction( Transaction *t, void *d )
{
Transaction *newT;
GDate *gd;
GList *sList;
GList *osList;
Split *split;
kvp_frame *split_kvpf;
kvp_value *kvp_val;
gboolean errFlag;
errFlag = FALSE;
DEBUG( "I'm seeing Transaction \"%s\"",
xaccTransGetDescription( t ) );
gd = (GDate*)d;
newT = xaccMallocTransaction();
xaccTransBeginEdit( newT );
/* the action and description/memo are in the template */
gnc_copy_trans_onto_trans( t, newT, FALSE, FALSE );
/* the date is new [gd] */
xaccTransSetDate( newT,
g_date_day( gd ),
g_date_month( gd ),
g_date_year( gd ) );
/* the accounts and amounts are in the kvp_frames of the splits. */
osList = xaccTransGetSplitList( t );
sList = xaccTransGetSplitList( newT );
if ( (osList == NULL) || (sList == NULL) ) {
PERR( "\tseen transaction w/o splits. :(" );
return FALSE;
}
do {
split = (Split*)sList->data;
/* FIXME: Ick. This assumes that the split lists will be
ordered identically. :( I think it's fair to say they
will, but I'd rather not have to count on it. --jsled */
split_kvpf = xaccSplitGetSlots( (Split*)osList->data );
DEBUG( "\tProcessing Split \"%s\"",
xaccSplitGetMemo( split ) );
DEBUG( "\tkvp_frame: %s\n",
kvp_frame_to_string( split_kvpf ) );
/* from-transaction of splits */
{
GUID *acct_guid;
Account *acct;
/* contains the guid of the split's actual account. */
kvp_val = kvp_frame_get_slot( split_kvpf, "sched-xaction/xfrm" );
if ( kvp_val == NULL ) {
PERR( "Null kvp_val for xfrm" );
}
acct_guid = kvp_value_get_guid( kvp_val );
acct = xaccAccountLookup( acct_guid );
DEBUG( "Got account with name \"%s\"",
xaccAccountGetName( acct ) );
/* xaccSplitSetAccount( split, acct ); */
xaccAccountInsertSplit( acct, split );
}
/* credit/debit formulas */
{
char *str;
gnc_numeric credit_num;
gnc_numeric debit_num;
gnc_numeric final;
int gncn_error;
kvp_val = kvp_frame_get_slot( split_kvpf, "sched-xaction/credit_formula" );
str = kvp_value_get_string( kvp_val );
credit_num = gnc_numeric_create( 0, 1 );
if ( str != NULL ) {
/* parse_vars_from_formula( str, NULL ); */
xaccParseAmount( str, TRUE, &credit_num, NULL );
/* string_to_gnc_numeric( str, &credit_num ); */
DEBUG( "gnc_numeric::credit: \"%s\" -> \"%s\"",
str, gnc_numeric_to_string( credit_num ) );
}
kvp_val = kvp_frame_get_slot( split_kvpf, "sched-xaction/debit_formula" );
str = kvp_value_get_string( kvp_val );
debit_num = gnc_numeric_create( 0, 1 );
if ( str != NULL ) {
/* parse_vars_from_formula( str, NULL ); */
xaccParseAmount( str, TRUE, &debit_num, NULL );
/* string_to_gnc_numeric( str, &debit_num ); */
DEBUG( "gnc_numeric::debit: \"%s\" -> \"%s\"",
str, gnc_numeric_to_string( debit_num ) );
}
final = gnc_numeric_sub_fixed( credit_num, debit_num );
gncn_error = gnc_numeric_check( final );
if ( gncn_error != GNC_ERROR_OK ) {
PERR( "Error %d in final gnc_numeric value", gncn_error );
errFlag = TRUE;
break;
}
DEBUG( "gnc_numeric::final: \"%s\"",
gnc_numeric_to_string( final ) );
xaccSplitSetValue( split, final );
}
#if 0
kvp_val = kvp_frame_get_slot( split_kvpf, "sched-xaction/shares" );
kvp_val = kvp_frame_get_slot( split_kvpf, "sched-xaction/amnt" );
#endif /* 0 */
} while ( (sList = sList->next) && (osList = osList->next) );
if ( errFlag ) {
PERR( "Some error in new transaction creation..." );
xaccTransRollbackEdit( newT );
} else {
xaccTransCommitEdit( newT );
}
return TRUE;
}
static void
_create_transactions_on( SchedXaction *sx, GDate *gd )
{
AccountGroup *ag;
Account *acct;
char *id;
char tmpBuf[26];
{
g_date_strftime( tmpBuf, 25, "%a, %b %e, %Y", gd );
DEBUG( "Creating transactions on %s for %s",
tmpBuf, xaccSchedXactionGetName( sx ) );
}
ag = gnc_book_get_template_group( gncGetCurrentBook() );
id = guid_to_string( xaccSchedXactionGetGUID(sx) );
acct = xaccGetAccountFromName( ag, id );
DEBUG( "Got account \"%s\"\n",
xaccAccountGetName( acct ) );
g_free( id );
xaccAccountForEachTransaction( acct,
_create_each_transaction,
gd );
xaccSchedXactionSetLastOccurDate( sx, gd );
}
#if 0
/**
* Parses in-fix mathematical formulas using the standard operators
* [+-/%*], and '(', ')' grouping.
*
* Any strings are placed in the GHashTable as variables. The value of
* each key in the hash-table is a struct of the form:
* { const char *varStr;
* gint idx;
* gint len; };
*
**/
int
parse_vars_from_formula( const char *formula, GHashTable *varHash )
{
gnc_numeric num_foo;
char *foo;
GList *list;
gnc_exp_parser_init();
if ( ! gnc_exp_parser_parse( formula, &num_foo, &foo ) ) {
PERR( "Error parsing at \"%s\": %s\n",
foo, gnc_exp_parser_error_string() );
}
PINFO( "Successful parse...\n" );
list = gnc_exp_parser_get_variable_names();
if ( list == NULL ) {
PINFO( "NULL variable list\n" );
} else {
do {
PINFO( "Variable \"%s\"\n",
list->data );
} while ( (list = list->next) );
}
gnc_exp_parser_shutdown();
}
#endif /* 0 */
#if 0
GScanner *varScanner;
GTokenType tok;
varScanner = g_scanner_new( NULL );
g_scanner_set_scope( varScanner, 0 );
g_scanner_freeze_symbol_table( varScanner );
g_scanner_scope_add_symbol( varScanner, 0, "(", (gpointer)"left-paren" );
g_scanner_scope_add_symbol( varScanner, 0, ")", (gpointer)"right-paren" );
g_scanner_scope_add_symbol( varScanner, 0, "+", (gpointer)"plus" );
g_scanner_scope_add_symbol( varScanner, 0, "-", (gpointer)"minus" );
g_scanner_scope_add_symbol( varScanner, 0, "/", (gpointer)"div" );
g_scanner_scope_add_symbol( varScanner, 0, "*", (gpointer)"mult" );
g_scanner_thaw_symbol_table( varScanner );
g_scanner_input_text( varScanner, formula, strlen( formula ) );
do {
tok = g_scanner_get_next_token( varScanner );
printf( "tok: " );
switch ( varScanner->token ) {
case G_TOKEN_EOF:
printf( "EOF" ); break;
case G_TOKEN_LEFT_PAREN:
printf( "(" ); break;
case G_TOKEN_RIGHT_PAREN:
printf( ")" ); break;
case G_TOKEN_LEFT_CURLY:
printf( "{" ); break;
case G_TOKEN_RIGHT_CURLY:
printf( "}" ); break;
case G_TOKEN_LEFT_BRACE:
printf( "[" ); break;
case G_TOKEN_RIGHT_BRACE:
printf( "]" ); break;
case G_TOKEN_EQUAL_SIGN:
printf( "=" ); break;
case G_TOKEN_COMMA:
printf( "," ); break;
case G_TOKEN_NONE:
printf( "NONE" ); break;
case G_TOKEN_ERROR:
printf( "ERROR(%d)", varScanner->value.v_error ); break;
case G_TOKEN_CHAR:
printf( "CHAR(%c)", varScanner->value.v_char ); break;
case G_TOKEN_BINARY:
printf( "BINARY" ); break;
case G_TOKEN_OCTAL:
printf( "OCTAL(%ul)", varScanner->value.v_octal ); break;
case G_TOKEN_INT:
printf( "INT(%ul)", varScanner->value.v_int ); break;
case G_TOKEN_HEX:
printf( "HEX(%ul)", varScanner->value.v_hex ); break;
case G_TOKEN_FLOAT:
printf( "FLOAT(%f)", varScanner->value.v_float ); break;
case G_TOKEN_STRING:
printf( "STRING(%s)", varScanner->value.v_string ); break;
case G_TOKEN_SYMBOL:
printf( "SYMBOL(%s)", (gchar*)varScanner->value.v_symbol ); break;
case G_TOKEN_IDENTIFIER:
printf( "IDENT(%s)", varScanner->value.v_identifier ); break;
case G_TOKEN_IDENTIFIER_NULL:
printf( "NULL_IDENT" ); break;
case G_TOKEN_COMMENT_SINGLE:
case G_TOKEN_COMMENT_MULTI:
printf( "COMMENT(%s)", varScanner->value.v_comment ); break;
case G_TOKEN_LAST:
printf( "END" ); break;
default:
printf( "UNK" ); break;
};
printf( "\n" );
} while ( (varScanner->token != G_TOKEN_LAST) &&
(varScanner->token != G_TOKEN_EOF) &&
(varScanner->token != G_TOKEN_NONE) );
return 1;
/*
"0.33 * ( base + ld ) + (0.25 * internet)":
tok: FLOAT(0.330000)
tok: UNK
tok: )
tok: IDENT(base)
tok: UNK
tok: IDENT(ld)
tok: (
tok: UNK
tok: )
tok: FLOAT(0.250000)
tok: UNK
tok: IDENT(internet)
tok: (
tok: EOF
*/
#endif /* 0 */

@ -0,0 +1,29 @@
/********************************************************************\
* dialog-sxsincelast.h - SchedXaction "Since-Last-Run" dialog *
* Copyright (c) 2001 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 *
* 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 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
\********************************************************************/
#ifndef DIALOG_SXSINCELAST_H
#define DIALOG_SXSINCELAST_H
void gnc_ui_sxsincelast_dialog_create( void );
void gnc_ui_sxsincelast_guile_wrapper( char* );
#endif // !defined(DIALOG_SXSINCELAST_H)

@ -157,9 +157,9 @@
<widget>
<class>GtkFrame</class>
<name>frame66</name>
<name>frame73</name>
<label>Creation Options</label>
<label_xalign>0.05</label_xalign>
<label_xalign>0.1</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
@ -169,41 +169,130 @@
<widget>
<class>GtkVBox</class>
<name>vbox127</name>
<name>vbox133</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkCheckButton</class>
<name>manual_conf</name>
<name>autocreate_opt</name>
<tooltip>Conditional on splits not having variables</tooltip>
<can_focus>True</can_focus>
<label>. Create automatically.</label>
<label>Create Automatically</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>2</padding>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkAlignment</class>
<name>alignment2</name>
<xalign>1</xalign>
<yalign>0.5</yalign>
<xscale>0.66</xscale>
<yscale>1</yscale>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkCheckButton</class>
<name>notify_opt</name>
<sensitive>False</sensitive>
<can_focus>True</can_focus>
<label>Notify me when created</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
</widget>
</widget>
<widget>
<class>GtkCheckButton</class>
<name>auto_create_notify</name>
<name>advance_opt</name>
<can_focus>True</can_focus>
<label>. Notify me when created.</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<child>
<padding>2</padding>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox150</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label847807</name>
<label>Create </label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkSpinButton</class>
<name>advance_days</name>
<sensitive>False</sensitive>
<can_focus>True</can_focus>
<climb_rate>1</climb_rate>
<digits>0</digits>
<numeric>True</numeric>
<update_policy>GTK_UPDATE_ALWAYS</update_policy>
<snap>True</snap>
<wrap>False</wrap>
<value>0</value>
<lower>0</lower>
<upper>100</upper>
<step>1</step>
<page>10</page>
<page_size>10</page_size>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label847808</name>
<label> days in advance</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkCheckButton</class>
<name>checkbutton1</name>
<name>remind_opt</name>
<can_focus>True</can_focus>
<active>False</active>
<draw_indicator>True</draw_indicator>
@ -215,14 +304,14 @@
<widget>
<class>GtkHBox</class>
<name>hbox144</name>
<name>hbox151</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label847789</name>
<label>. Remind me </label>
<name>label847809</name>
<label>Remind me </label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -238,15 +327,16 @@
<widget>
<class>GtkSpinButton</class>
<name>spinbutton1</name>
<name>remind_days</name>
<sensitive>False</sensitive>
<can_focus>True</can_focus>
<climb_rate>1</climb_rate>
<digits>0</digits>
<numeric>True</numeric>
<update_policy>GTK_UPDATE_ALWAYS</update_policy>
<snap>True</snap>
<wrap>True</wrap>
<value>1</value>
<wrap>False</wrap>
<value>0</value>
<lower>0</lower>
<upper>100</upper>
<step>1</step>
@ -255,14 +345,14 @@
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label847790</name>
<label> days in advance.</label>
<name>label847810</name>
<label> days in advance</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -315,52 +405,65 @@
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox98</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<class>GtkRadioButton</class>
<name>rb_enddate</name>
<can_focus>True</can_focus>
<active>False</active>
<draw_indicator>True</draw_indicator>
<group>sx_end_opt</group>
<child>
<padding>2</padding>
<expand>True</expand>
<fill>True</fill>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkRadioButton</class>
<name>rb_enddate</name>
<can_focus>True</can_focus>
<label>End Date:</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<group>sx_end_opt</group>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<class>GtkHBox</class>
<name>hbox152</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GnomeDateEdit</class>
<name>sxe_end_date</name>
<show_time>False</show_time>
<use_24_format>True</use_24_format>
<week_start_monday>False</week_start_monday>
<lower_hour>7</lower_hour>
<upper_hour>19</upper_hour>
<child>
<padding>2</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label847812</name>
<label>End Date: </label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GnomeDateEdit</class>
<name>sxe_end_date</name>
<show_time>False</show_time>
<use_24_format>True</use_24_format>
<week_start_monday>False</week_start_monday>
<lower_hour>7</lower_hour>
<upper_hour>19</upper_hour>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox99</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<class>GtkRadioButton</class>
<name>rb_num_occur</name>
<can_focus>True</can_focus>
<active>False</active>
<draw_indicator>True</draw_indicator>
<group>sx_end_opt</group>
<child>
<padding>2</padding>
<expand>False</expand>
@ -368,39 +471,48 @@
</child>
<widget>
<class>GtkRadioButton</class>
<name>rb_num_occur</name>
<can_focus>True</can_focus>
<label>Number of Occurances:</label>
<active>False</active>
<draw_indicator>True</draw_indicator>
<group>sx_end_opt</group>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<class>GtkVBox</class>
<name>vbox134</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GnomeNumberEntry</class>
<name>end_nentry</name>
<max_saved>10</max_saved>
<child>
<padding>2</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label847811</name>
<label>Number of Occurances:</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>7.45058e-09</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkEntry</class>
<child_name>GnomeEntry:entry</child_name>
<name>combo-entry1</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<class>GnomeNumberEntry</class>
<name>end_nentry</name>
<max_saved>10</max_saved>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkEntry</class>
<child_name>GnomeEntry:entry</child_name>
<name>combo-entry1</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget>
</widget>
</widget>
@ -413,11 +525,11 @@
<name>recur_frame</name>
<border_width>4</border_width>
<label>Recurrance Frequency</label>
<label_xalign>0.05</label_xalign>
<label_xalign>0.1</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>2</padding>
<expand>True</expand>
<expand>False</expand>
<fill>False</fill>
</child>
@ -447,13 +559,13 @@
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox124</name>
<name>register_vbox</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
@ -495,7 +607,7 @@
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<fill>False</fill>
</child>
</widget>
</widget>
@ -661,8 +773,8 @@ Yearly
<popup_enable>False</popup_enable>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
@ -829,7 +941,7 @@ Yearly
<can_focus>True</can_focus>
<show_heading>True</show_heading>
<show_day_names>True</show_day_names>
<no_month_change>True</no_month_change>
<no_month_change>False</no_month_change>
<show_week_numbers>False</show_week_numbers>
<week_start_monday>False</week_start_monday>
</widget>
@ -943,7 +1055,7 @@ Yearly
<can_focus>True</can_focus>
<show_heading>True</show_heading>
<show_day_names>True</show_day_names>
<no_month_change>True</no_month_change>
<no_month_change>False</no_month_change>
<show_week_numbers>False</show_week_numbers>
<week_start_monday>False</week_start_monday>
</widget>
@ -1212,7 +1324,7 @@ Yearly
<can_focus>True</can_focus>
<show_heading>True</show_heading>
<show_day_names>True</show_day_names>
<no_month_change>True</no_month_change>
<no_month_change>False</no_month_change>
<show_week_numbers>False</show_week_numbers>
<week_start_monday>False</week_start_monday>
</widget>
@ -1523,9 +1635,9 @@ Yearly
<name>semimonthly_cal</name>
<sensitive>False</sensitive>
<can_focus>True</can_focus>
<show_heading>False</show_heading>
<show_heading>True</show_heading>
<show_day_names>True</show_day_names>
<no_month_change>True</no_month_change>
<no_month_change>False</no_month_change>
<show_week_numbers>False</show_week_numbers>
<week_start_monday>False</week_start_monday>
</widget>
@ -2443,18 +2555,10 @@ December
<widget>
<class>GtkButton</class>
<name>ok_button</name>
<name>close_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
</widget>
<widget>
<class>GtkButton</class>
<name>cancel_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
<stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
</widget>
</widget>
@ -2866,11 +2970,13 @@ December
<widget>
<class>GnomeDialog</class>
<name>real since-last-run dialog</name>
<name>Real Since-Last-Run Dialog</name>
<title>Since Last Run...</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_CENTER</position>
<modal>False</modal>
<default_width>550</default_width>
<default_height>500</default_height>
<allow_shrink>True</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>True</auto_shrink>
@ -2908,7 +3014,7 @@ December
<widget>
<class>GtkButton</class>
<name>button1</name>
<name>ok_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
@ -2916,15 +3022,7 @@ December
<widget>
<class>GtkButton</class>
<name>button2</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
</widget>
<widget>
<class>GtkButton</class>
<name>button3</name>
<name>cancel_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
@ -2954,9 +3052,97 @@ December
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox135</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label847814</name>
<label>...Replace with GL...</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow7</name>
<hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkCList</class>
<name>auto_create_clist</name>
<can_focus>True</can_focus>
<columns>2</columns>
<column_widths>207,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847815</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847816</name>
<label>Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>frame68</name>
<label>To-create...</label>
<label_xalign>0.1</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow4</name>
<name>scrolledwindow6</name>
<hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
@ -2964,10 +3150,10 @@ December
<widget>
<class>GtkCList</class>
<name>clist1</name>
<name>to_create_clist</name>
<can_focus>True</can_focus>
<columns>3</columns>
<column_widths>80,80,80</column_widths>
<columns>2</columns>
<column_widths>210,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
@ -2975,21 +3161,8 @@ December
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847791</name>
<label>label847791</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847792</name>
<label>label847792</label>
<name>label847802</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -3001,8 +3174,8 @@ December
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847793</name>
<label>label847793</label>
<name>label847803</name>
<label>Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@ -3014,23 +3187,6 @@ December
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>frame68</name>
<label>To-create...</label>
<label_xalign>0.1</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>Placeholder</class>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>frame69</name>
@ -3044,7 +3200,63 @@ December
</child>
<widget>
<class>Placeholder</class>
<class>GtkScrolledWindow</class>
<name>scrolledwindow5</name>
<border_width>3</border_width>
<hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<widget>
<class>GtkCList</class>
<name>reminders_clist</name>
<can_focus>True</can_focus>
<columns>3</columns>
<column_widths>147,198,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847795</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847796</name>
<label>Next Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label847797</name>
<label>Days</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>
</widget>

@ -7,13 +7,16 @@
gchar *s = N_("Edit Scheduled Transaction");
gchar *s = N_("Name:");
gchar *s = N_("Creation Options");
gchar *s = N_(". Create automatically.");
gchar *s = N_(". Notify me when created.");
gchar *s = N_(". Remind me ");
gchar *s = N_(" days in advance.");
gchar *s = N_("Conditional on splits not having variables");
gchar *s = N_("Create Automatically");
gchar *s = N_("Notify me when created");
gchar *s = N_("Create ");
gchar *s = N_(" days in advance");
gchar *s = N_("Remind me ");
gchar *s = N_(" days in advance");
gchar *s = N_("End");
gchar *s = N_("No End");
gchar *s = N_("End Date:");
gchar *s = N_("End Date: ");
gchar *s = N_("Number of Occurances:");
gchar *s = N_("Recurrance Frequency");
gchar *s = N_("Template Transaction");
@ -351,8 +354,13 @@ gchar *s = N_("Value");
gchar *s = N_("What should this be?");
gchar *s = N_("Since Last Run...");
gchar *s = N_("Auto-created, notification requested...");
gchar *s = N_("label847791");
gchar *s = N_("label847792");
gchar *s = N_("label847793");
gchar *s = N_("...Replace with GL...");
gchar *s = N_("Name");
gchar *s = N_("Date");
gchar *s = N_("To-create...");
gchar *s = N_("Name");
gchar *s = N_("Date");
gchar *s = N_("Reminders");
gchar *s = N_("Name");
gchar *s = N_("Next Date");
gchar *s = N_("Days");

@ -53,6 +53,7 @@
#include "dialog-utils.h"
#include "dialog-scheduledxaction.h"
#include "dialog-nextrun.h"
#include "dialog-sxsincelast.h"
#include "window-help.h"
#include "window-main.h"
@ -917,6 +918,16 @@ gnc_main_window_find_transactions_cb (GtkWidget *widget, gpointer data) {
gnc_ui_find_transactions_dialog_create(NULL);
}
static void
gnc_main_window_sched_xaction_cb (GtkWidget *widget, gpointer data) {
gnc_ui_scheduled_xaction_dialog_create();
}
static void
gnc_main_window_sched_xaction_slr_cb (GtkWidget *widget, gpointer data) {
gnc_ui_sxsincelast_dialog_create();
}
static void
gnc_main_window_about_cb (GtkWidget *widget, gpointer data)
{
@ -1082,6 +1093,20 @@ gnc_main_window_create_menus(GNCMainInfo * maininfo) {
GNOME_APP_PIXMAP_NONE, NULL,
0, 0, NULL
},
{ GNOME_APP_UI_ITEM,
N_("Scheduled Transactions List"),
N_("A list of Scheduled Transactions"),
gnc_main_window_sched_xaction_cb, NULL, NULL,
GNOME_APP_PIXMAP_NONE, NULL,
0, 0, NULL
},
{ GNOME_APP_UI_ITEM,
N_("Scheduled Transactions Since-Last-Run..."),
N_("Create Scheduled Transactions since the last-time-run."),
gnc_main_window_sched_xaction_slr_cb, NULL, NULL,
GNOME_APP_PIXMAP_NONE, NULL,
0, 0, NULL
},
GNOMEUIINFO_END
};

@ -73,13 +73,17 @@
(list "Extensions" "")
(lambda () (gnc:sx-editor)))
)
(define schedxact-slr-item
(gnc:make-menu-item (N_ "SchedXact: Since Last Run")
(define schedxact-old-slr-item
(gnc:make-menu-item (N_ "SchedXact: [Old] Since Last Run")
(N_ "since last run dialog")
(list "Extensions" "")
(lambda () (gnc:sx-since-last-run)))
)
(define schedxact-slr-item
(gnc:make-menu-item (N_ "SchedXact: [New] Since Last Run")
(N_ "since last run dialog")
(list "Extensions" "" )
(lambda () (gnc:sx-sincelast-create ))))
(define progress-item
(gnc:make-menu-item (N_ "Test progress dialog")
(N_ "Test progress dialog")
@ -110,6 +114,7 @@
;; appear in the menu [prepending to some list]...
(gnc:add-extension progress-item)
(gnc:add-extension schedxact-old-slr-item)
(gnc:add-extension schedxact-slr-item)
(gnc:add-extension schedxact-editor-item)
)

@ -189,3 +189,12 @@ the account instead of opening a register.") #f))
(gnc:hook-add-dangler gnc:*book-closed-hook*
gnc:main-window-book-close-handler)
(gnc:hook-add-dangler gnc:*book-opened-hook*
(lambda (file)
(if ((gnc:option-getter
(gnc:lookup-global-option
(N_ "Scheduled Transactions")
(N_ "Run on GnuCash Start" ))))
(gnc:sx-since-last-run-wrapper file))) )

@ -77,8 +77,7 @@
;; hook should probably revert back to just save-global-options.
(define (gnc:save-all-options)
(gnc:save-global-options)
; (gnc:save-report-options)
; (gnc:save-acct-tree-options)
; (gnc:save-report-options); (gnc:save-acct-tree-options)
(gnc:save-style-sheet-options))
(define (gnc:save-global-options)
@ -531,6 +530,66 @@ without one.")
"d" (N_ "Host to connect to for user registration and support services")
"www.gnumatic.com"))
;; Scheduled|Recurring Transactions
(gnc:register-configuration-option
(gnc:make-simple-boolean-option
(N_ "Scheduled Transactions")
(N_ "Run on GnuCash Start")
"a" (N_ "Should the Since-Last-Run window appear on GnuCash startup?")
#f ))
(gnc:register-configuration-option
(gnc:make-simple-boolean-option
(N_ "Scheduled Transactions")
(N_ "Default: Auto-Create new Scheduled Transactions?")
"b" (N_ "Should new SchedXactions have the 'AutoCreate' flag set by default?")
#f ))
(gnc:register-configuration-option
(gnc:make-simple-boolean-option
(N_ "Scheduled Transactions")
(N_ "Default: Notify on new, auto-created scheduled transactions")
"c" (N_ "Should new SchedXactions with the 'AutoCreate' flag set also be set to notify?")
#t ))
(gnc:register-configuration-option
(gnc:make-number-range-option
(N_ "Scheduled Transactions")
(N_ "Default create-in-advance days")
"d" (N_ "Default number of days-in-advance to create new SXes")
0 ; default
0 ; min
99999999 ; max
0 ; num decimals
1 ; step size
))
(gnc:register-configuration-option
(gnc:make-number-range-option
(N_ "Scheduled Transactions")
(N_ "Default remind-in-advance days")
"e" (N_ "Default number of days-in-advance to remind on new SXes")
0 ; default
0 ; min
99999 ; max
0 ; num-decimals
1 ; step size
))
(gnc:register-configuration-option
(gnc:make-number-range-option
(N_ "Scheduled Transactions")
(N_ "Template Register Lines")
"f" (N_ "How many lines in the template register?")
4 ; default
1 ; min
50 ; max
0 ; num-decimals
1 ; step size
))
;;; Configuation variables
(define gnc:*arg-show-version*

Loading…
Cancel
Save