mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
2002-07-24 Joshua Sled <jsled@asynchronous.org>
* src/scm/fin.scm: Made the exposed calcualtion functions output positive values. * src/gnome/window-main.c (gnc_main_window_create_menus): Added accelerators to SX-related menu items. * src/gnome/druid-loan.c: Primary change: actually create the Scheduled Transactions which are setup by the user. Miscellaneous other cleanups, text, layout and consistency changes. * src/gnome/dialog-sxsincelast.c: Support handling of the instance-count in forward-looking transaction creation. Simplfied some of the internal data-representation regarding lists of items to be created [removed autoCreateTuple, now uses toCreateTuple]. Removed some DEBUGging output. Handles setting up the implicit 'i' variable. * src/gnome/dialog-sx-from-trans.c (sxftd_compute_sx): Create SXes with an appropriate initial instance-count value. * src/gnome/dialog-scheduledxaction.c (schedXact_editor_populate): Create SXes with an appropriate initial instance-count value. * src/engine/SchedXaction.[ch]: Added support for an instance-count, in order to support an implicit 'i' [of N] variable to SX formula/function processing. * src/engine/SX-ttinfo.c (gnc_ttsplitinfo_free): Made the ttsplitinfo_free'ing a bit safer. * src/calculation/expression_parser.c: Added support for parsing/handling quoted strings. Intended to be parameters to functions. Fixed bug regarding nested handling of strings in the parser. * src/backend/file/gnc-schedxaction-xml-v2.c: Added support for saving/restoring instance-count field of SXes. * src/app-utils/test/test-exp-parser.c (run_parser_test): Fixed pass/fail indication check. (test_parser): Added tests for string params to functions. * ChangeLog: Added entry I forgot from last time. * src/app-utils/gnc-exp-parser.c (func_op): Added support for typed parameters to functions; params are either numerics or strings. Result of function is now parsed correctly. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7125 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
2a990a6cfd
commit
135289725c
61
ChangeLog
61
ChangeLog
@ -1,3 +1,54 @@
|
||||
2002-07-24 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/scm/fin.scm: Made the exposed calcualtion functions output
|
||||
positive values.
|
||||
|
||||
* src/gnome/window-main.c (gnc_main_window_create_menus): Added
|
||||
accelerators to SX-related menu items.
|
||||
|
||||
* src/gnome/druid-loan.c: Primary change: actually create the
|
||||
Scheduled Transactions which are setup by the user. Miscellaneous
|
||||
other cleanups, text, layout and consistency changes.
|
||||
|
||||
* src/gnome/dialog-sxsincelast.c: Support handling of the
|
||||
instance-count in forward-looking transaction creation. Simplfied
|
||||
some of the internal data-representation regarding lists of items
|
||||
to be created [removed autoCreateTuple, now uses toCreateTuple].
|
||||
Removed some DEBUGging output. Handles setting up the implicit
|
||||
'i' variable.
|
||||
|
||||
* src/gnome/dialog-sx-from-trans.c (sxftd_compute_sx): Create SXes
|
||||
with an appropriate initial instance-count value.
|
||||
|
||||
* src/gnome/dialog-scheduledxaction.c
|
||||
(schedXact_editor_populate): Create SXes with an appropriate
|
||||
initial instance-count value.
|
||||
|
||||
* src/engine/SchedXaction.[ch]: Added support for an
|
||||
instance-count, in order to support an implicit 'i' [of N]
|
||||
variable to SX formula/function processing.
|
||||
|
||||
* src/engine/SX-ttinfo.c (gnc_ttsplitinfo_free): Made the
|
||||
ttsplitinfo_free'ing a bit safer.
|
||||
|
||||
* src/calculation/expression_parser.c: Added support for
|
||||
parsing/handling quoted strings. Intended to be parameters to
|
||||
functions. Fixed bug regarding nested handling of strings in the
|
||||
parser.
|
||||
|
||||
* src/backend/file/gnc-schedxaction-xml-v2.c: Added support for
|
||||
saving/restoring instance-count field of SXes.
|
||||
|
||||
* src/app-utils/test/test-exp-parser.c
|
||||
(run_parser_test): Fixed pass/fail indication check.
|
||||
(test_parser): Added tests for string params to functions.
|
||||
|
||||
* ChangeLog: Added entry I forgot from last time.
|
||||
|
||||
* src/app-utils/gnc-exp-parser.c (func_op): Added support for
|
||||
typed parameters to functions; params are either numerics or
|
||||
strings. Result of function is now parsed correctly.
|
||||
|
||||
2002-07-24 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/import-export/hbci/glade/hbci.glade: Some HBCI GUI work --
|
||||
@ -13,6 +64,16 @@
|
||||
* src/backend/file/gnc-backend-file.c: File permission fix by Matt
|
||||
Brubeck <mbrubeck@cs.hmc.edu>
|
||||
|
||||
2002-07-12 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/gnome/glade/sched-xact.glade: Glade-side UI cleanup.
|
||||
|
||||
* src/gnome/druid-loan.c: Many updates; now uses GNCAccountSel,
|
||||
more inter-page consistency checks. UI cleanup
|
||||
|
||||
* src/gnome-utils/gnc-account-sel.[ch]: Added; GTK combobox for
|
||||
selecting an Account.
|
||||
|
||||
2002-07-11 Derek Atkins <derek@ihtfp.com>
|
||||
|
||||
* change gncEntry->account into gncEntry->invAccount and
|
||||
|
@ -350,6 +350,8 @@ func_op( const char *fname,
|
||||
{
|
||||
SCM scmFn, scmArgs, scmTmp;
|
||||
int i;
|
||||
var_store *vs;
|
||||
gchar *str;
|
||||
gnc_numeric n, *result;
|
||||
GString *realFnName;
|
||||
|
||||
@ -365,15 +367,37 @@ func_op( const char *fname,
|
||||
scmArgs = gh_list( SCM_UNDEFINED );
|
||||
for ( i=0; i<argc; i++ ) {
|
||||
/* cons together back-to-front. */
|
||||
n = *(gnc_numeric*)argv[argc - i - 1];
|
||||
scmTmp = gh_double2scm( gnc_numeric_to_double( n ) );
|
||||
vs = (var_store*)argv[argc - i - 1];
|
||||
switch ( vs->type ) {
|
||||
case VST_NUMERIC:
|
||||
n = *(gnc_numeric*)(vs->value);
|
||||
scmTmp = gh_double2scm( gnc_numeric_to_double( n ) );
|
||||
break;
|
||||
case VST_STRING:
|
||||
str = (char*)(vs->value);
|
||||
scmTmp = gh_str2scm( str, strlen(str) );
|
||||
break;
|
||||
default:
|
||||
/* FIXME: error */
|
||||
printf( "argument %d not a numeric or string [type = %d]\n",
|
||||
i, vs->type );
|
||||
return NULL;
|
||||
break; /* notreached */
|
||||
}
|
||||
scmArgs = gh_cons( scmTmp, scmArgs );
|
||||
}
|
||||
scmTmp = gh_apply( scmFn, scmArgs );
|
||||
|
||||
result = g_new0( gnc_numeric, 1 );
|
||||
*result = double_to_gnc_numeric( gh_scm2double(scmTmp), 1,
|
||||
GNC_DENOM_SIGFIG | (6<<8) );
|
||||
*result = double_to_gnc_numeric( gh_scm2double(scmTmp),
|
||||
GNC_DENOM_AUTO,
|
||||
GNC_DENOM_SIGFIGS(6) | GNC_RND_ROUND );
|
||||
/* I'm not sure why this explicit negation step is necessary, but it
|
||||
* doesn't seem like it should be. */
|
||||
if ( gh_scm2double( scmTmp ) < 0 ) {
|
||||
*result = gnc_numeric_neg( *result );
|
||||
}
|
||||
/* FIXME: cleanup scmArgs = gh_list, cons'ed cells? */
|
||||
return (void*)result;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "gnc-numeric.h"
|
||||
#include "test-stuff.h"
|
||||
|
||||
void real_main (int argc, char **argv);
|
||||
|
||||
static GList *tests = NULL;
|
||||
|
||||
typedef struct
|
||||
@ -62,12 +64,12 @@ run_parser_test (TestNode *node)
|
||||
succeeded = gnc_exp_parser_parse (node->exp, &result, &error_loc);
|
||||
{
|
||||
int pass;
|
||||
pass = succeeded;
|
||||
pass ^= node->should_succeed;
|
||||
pass = !pass;
|
||||
printf( "%0.2f [%s]\n",
|
||||
( ( pass && node->should_succeed ) ?
|
||||
gnc_numeric_to_double( result ) : 0.0 ),
|
||||
pass = (succeeded == node->should_succeed);
|
||||
if ( pass && node->should_succeed ) {
|
||||
pass &= gnc_numeric_equal( result, node->expected_result );
|
||||
}
|
||||
printf( "%0.4f [%s]\n",
|
||||
gnc_numeric_to_double( result ),
|
||||
(pass ? "PASS" : "FAIL" ) );
|
||||
}
|
||||
|
||||
@ -139,7 +141,7 @@ test_parser (void)
|
||||
"- 42.72 + 13.32 + 15.48 + 23.4 + 115.4",
|
||||
gnc_numeric_create(35897, 100) );
|
||||
|
||||
gh_eval_str( "(define (plus a b) (+ a b))" );
|
||||
gh_eval_str( "(define (gnc:plus a b) (+ a b))" );
|
||||
add_pass_test( "plus( 1 : 2 ) + 3", NULL, gnc_numeric_create( 6, 1 ) );
|
||||
add_pass_test( "plus( 1 : 2 ) * 3", NULL, gnc_numeric_create( 9, 1 ) );
|
||||
add_pass_test( "plus( 1 + 2 : 3 ) * 5", NULL, gnc_numeric_create( 30, 1 ) );
|
||||
@ -148,14 +150,31 @@ test_parser (void)
|
||||
add_pass_test( "plus( plus( 1 : 2 ) : 3 )", NULL, gnc_numeric_create( 6, 1 ) );
|
||||
add_pass_test( "plus( 4 : plus( plus( 1 : 2 ) : 3))", NULL, gnc_numeric_create( 10, 1 ) );
|
||||
|
||||
gh_eval_str( "(define (foo a b) (+ a b))" );
|
||||
add_pass_test( "foo( 1 : 2 ) + 4", NULL, gnc_numeric_create( 7, 1 ) );
|
||||
gh_eval_str( "(define (gnc:foo a b) (- a b))" );
|
||||
add_pass_test( "foo( 1 : 2 ) + 4", NULL, gnc_numeric_create( 3, 1 ) );
|
||||
|
||||
add_pass_test( "foo( (1 + 2 * 3) : 4 ) + 5",
|
||||
NULL, gnc_numeric_create( 16, 1 ) );
|
||||
NULL, gnc_numeric_create( 8, 1 ) );
|
||||
add_pass_test( "foo( 1 : 2 ) + foo( 3 : 4 ) + 5",
|
||||
NULL, gnc_numeric_create( 15, 1 ) );
|
||||
add_pass_test( "foo( a = 42 : foo( foo( 1 : 2 ) : 6 * 7 )) + a",
|
||||
NULL, gnc_numeric_create( 129, 1 ) );
|
||||
NULL, gnc_numeric_create( 3, 1 ) );
|
||||
add_pass_test( "foo( a = 42 : foo( plus( 1 : 2 ) : 6 * 7 )) + a",
|
||||
NULL, gnc_numeric_create( 123, 1 ) );
|
||||
|
||||
gh_eval_str( "(define (gnc:test_str str b)"
|
||||
" (+ b (cond ((equal? str \"one\") 1)"
|
||||
" ((equal? str \"two\") 2)"
|
||||
" ((equal? str \"three\") 3)"
|
||||
" (0))))" );
|
||||
add_pass_test( "test_str( \"one\" : 1 )", NULL, gnc_numeric_create( 2, 1 ) );
|
||||
add_pass_test( "test_str( \"two\" : 2 )", NULL, gnc_numeric_create( 4, 1 ) );
|
||||
add_fail_test( "test_str( 3 : \"three\" )", NULL, 0 );
|
||||
add_pass_test( "test_str( \"asdf\" : 1 )", NULL, gnc_numeric_create( 1, 1 ) );
|
||||
add_fail_test( "\"asdf\" + 0", NULL, 0 );
|
||||
|
||||
gh_eval_str( "(define (gnc:blindreturn val) val)" );
|
||||
add_pass_test( "blindreturn( 123.1 )", NULL, gnc_numeric_create( 1231, 10 ) );
|
||||
add_pass_test( "blindreturn( 123.01 )", NULL, gnc_numeric_create( 12301, 100 ) );
|
||||
add_pass_test( "blindreturn( 123.001 )", NULL, gnc_numeric_create( 123001, 1000 ) );
|
||||
|
||||
run_parser_tests ();
|
||||
|
||||
@ -163,7 +182,7 @@ test_parser (void)
|
||||
success ("shutdown expression parser");
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
real_main (int argc, char **argv)
|
||||
{
|
||||
/* set_should_print_success (TRUE); */
|
||||
@ -176,5 +195,5 @@ int main( int argc, char **argv )
|
||||
{
|
||||
/* do things this way so we can test scheme function calls from expressions */
|
||||
gh_enter( argc, argv, real_main );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ static short module = MOD_SX;
|
||||
* <sx:autoCreateNotify>n</sx:autoCreateNotify>
|
||||
* <sx:advanceCreateDays>0</sx:advanceCreateDays>
|
||||
* <sx:advanceRemindDays>5</sx:advanceRemindDays>
|
||||
* <sx:instanceCount>100</sx:instanceCount>
|
||||
* <sx:lastOccur>
|
||||
* <gdate>2001-02-28</gdate>
|
||||
* </sx:lastOccur>
|
||||
@ -80,6 +81,7 @@ static short module = MOD_SX;
|
||||
* <sx:end type="date">
|
||||
* <gdate>2004-03-20</gdate>
|
||||
* </sx:end>
|
||||
* <sx:instanceCount>100</sx:instanceCount>
|
||||
* <sx:freq>
|
||||
* <!-- freqspec tree -->
|
||||
* </sx:freq>
|
||||
@ -88,6 +90,7 @@ static short module = MOD_SX;
|
||||
* <sx:id type="guid">...</sx:id>
|
||||
* <sx:name>Loan 2</sx:name>
|
||||
* <sx:manual-conf>f</sx:manual-conf>
|
||||
* <sx:instanceCount>100</sx:instanceCount>
|
||||
* <sx:start>
|
||||
* <gdate>2000-12-31</gdate>
|
||||
* </sx:start>
|
||||
@ -113,6 +116,7 @@ static short module = MOD_SX;
|
||||
#define SX_AUTOCREATE_NOTIFY "sx:autoCreateNotify"
|
||||
#define SX_ADVANCE_CREATE_DAYS "sx:advanceCreateDays"
|
||||
#define SX_ADVANCE_REMIND_DAYS "sx:advanceRemindDays"
|
||||
#define SX_INSTANCE_COUNT "sx:instanceCount"
|
||||
#define SX_START "sx:start"
|
||||
#define SX_LAST "sx:last"
|
||||
#define SX_NUM_OCCUR "sx:num-occur"
|
||||
@ -139,6 +143,7 @@ gnc_schedXaction_dom_tree_create(SchedXaction *sx)
|
||||
xmlNodePtr ret;
|
||||
xmlNodePtr fsNode;
|
||||
GDate *date;
|
||||
gint instCount;
|
||||
const GUID *templ_acc_guid;
|
||||
|
||||
templ_acc_guid = xaccAccountGetGUID(sx->template_acct);
|
||||
@ -163,6 +168,10 @@ gnc_schedXaction_dom_tree_create(SchedXaction *sx)
|
||||
xmlAddChild(ret, int_to_dom_tree(SX_ADVANCE_REMIND_DAYS,
|
||||
sx->advanceRemindDays));
|
||||
|
||||
instCount = gnc_sx_get_instance_count( sx, NULL );
|
||||
xmlAddChild( ret, int_to_dom_tree( SX_INSTANCE_COUNT,
|
||||
instCount ) );
|
||||
|
||||
xmlAddChild( ret,
|
||||
gdate_to_dom_tree( SX_START,
|
||||
xaccSchedXactionGetStartDate(sx) ) );
|
||||
@ -318,6 +327,22 @@ sx_set_date( xmlNodePtr node, SchedXaction *sx,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
sx_instcount_handler( xmlNodePtr node, gpointer sx_pdata )
|
||||
{
|
||||
struct sx_pdata *pdata = sx_pdata;
|
||||
SchedXaction *sx = pdata->sx;
|
||||
gint64 instanceNum;
|
||||
|
||||
if ( ! dom_tree_to_integer( node, &instanceNum ) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gnc_sx_set_instance_count( sx, instanceNum );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
sx_start_handler( xmlNodePtr node, gpointer sx_pdata )
|
||||
@ -436,6 +461,7 @@ struct dom_tree_handler sx_dom_handlers[] = {
|
||||
{ SX_AUTOCREATE_NOTIFY, sx_notify_handler, 1, 0 },
|
||||
{ SX_ADVANCE_CREATE_DAYS, sx_advCreate_handler, 1, 0 },
|
||||
{ SX_ADVANCE_REMIND_DAYS, sx_advRemind_handler, 1, 0 },
|
||||
{ SX_INSTANCE_COUNT, sx_instcount_handler, 0, 0 },
|
||||
{ SX_START, sx_start_handler, 1, 0 },
|
||||
{ SX_LAST, sx_last_handler, 0, 0 },
|
||||
{ SX_NUM_OCCUR, sx_numOccur_handler, 0, 0 },
|
||||
|
@ -388,7 +388,7 @@ typedef struct parser_env
|
||||
const char *parse_str;
|
||||
char radix_point;
|
||||
char group_char;
|
||||
char name[50];
|
||||
char name[128];
|
||||
|
||||
char Token;
|
||||
char asn_op;
|
||||
@ -417,6 +417,7 @@ parser_env;
|
||||
#define ARG_TOKEN ':'
|
||||
#define VAR_TOKEN 'V'
|
||||
#define NUM_TOKEN 'I'
|
||||
#define STR_TOKEN '"'
|
||||
|
||||
#define STACK_INIT 50
|
||||
|
||||
@ -671,6 +672,7 @@ get_named_var (parser_env_ptr pe)
|
||||
else
|
||||
bv->next_var = retp;
|
||||
retp->variable_name = g_strdup (pe->name);
|
||||
retp->type = VST_NUMERIC;
|
||||
retp->value =
|
||||
pe->trans_numeric ("0", pe->radix_point, pe->group_char, NULL);
|
||||
}
|
||||
@ -691,6 +693,7 @@ get_unnamed_var (parser_env_ptr pe)
|
||||
retp = &(pe->unnamed_vars[cntr]);
|
||||
retp->variable_name = NULL;
|
||||
retp->use_flag = USED_VAR;
|
||||
retp->type = VST_NUMERIC;
|
||||
if (retp->value)
|
||||
{
|
||||
pe->free_numeric (retp->value);
|
||||
@ -756,8 +759,8 @@ next_token (parser_env_ptr pe)
|
||||
add_token (pe, *str_parse++);
|
||||
if (*str_parse == ASN_OP)
|
||||
{
|
||||
/* BUG/FIXME: this allows '(=' and ')=' [?], neither of which make
|
||||
* sense. */
|
||||
/* BUG/FIXME: this seems to allow '(=' and ')=' [?], neither of which
|
||||
* make sense. */
|
||||
if (pe->Token != ASN_OP)
|
||||
{
|
||||
str_parse++;
|
||||
@ -768,6 +771,18 @@ next_token (parser_env_ptr pe)
|
||||
pe->error_code = UNDEFINED_CHARACTER;
|
||||
} /* endif */
|
||||
}
|
||||
/* test for string */
|
||||
else if ( *str_parse == '"' ) {
|
||||
nstr = pe->name;
|
||||
/* skip over the '"'. */
|
||||
str_parse++;
|
||||
do {
|
||||
*nstr++ = *str_parse++;
|
||||
} while ( *str_parse != '"' );
|
||||
*nstr = EOS;
|
||||
str_parse++;
|
||||
add_token( pe, STR_TOKEN );
|
||||
}
|
||||
/* test for name */
|
||||
else if (isalpha (*str_parse)
|
||||
|| (*str_parse == '_'))
|
||||
@ -818,15 +833,6 @@ next_token (parser_env_ptr pe)
|
||||
pe->parse_str = str_parse;
|
||||
} /* next_token */
|
||||
|
||||
/* evaluate function operators
|
||||
* <name>( arg0, arg1, ... )
|
||||
*/
|
||||
static void
|
||||
function_op( parser_env_ptr pe )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* evaluate assignment operators,
|
||||
* =
|
||||
* +=
|
||||
@ -834,6 +840,7 @@ function_op( parser_env_ptr pe )
|
||||
* \=
|
||||
* *=
|
||||
*/
|
||||
/* FIXME: add non-numeric checking. */
|
||||
static void
|
||||
assignment_op (parser_env_ptr pe)
|
||||
{
|
||||
@ -913,6 +920,7 @@ assignment_op (parser_env_ptr pe)
|
||||
} /* assignment_op */
|
||||
|
||||
/* evaluate addition, subtraction operators */
|
||||
/* FIXME: add non-numeric checking. */
|
||||
static void
|
||||
add_sub_op (parser_env_ptr pe)
|
||||
{
|
||||
@ -972,6 +980,7 @@ add_sub_op (parser_env_ptr pe)
|
||||
} /* add_sub_op */
|
||||
|
||||
/* evaluate multiplication, division operators */
|
||||
/* FIXME: add non-numeric checking. */
|
||||
static void
|
||||
multiply_divide_op (parser_env_ptr pe)
|
||||
{
|
||||
@ -1036,15 +1045,25 @@ multiply_divide_op (parser_env_ptr pe)
|
||||
* numerics
|
||||
* grouped expressions, "()"
|
||||
* functions [ <name>( [exp, exp, ..., exp] ) ]
|
||||
* strings
|
||||
*/
|
||||
static void
|
||||
primary_exp (parser_env_ptr pe)
|
||||
{
|
||||
var_store_ptr rslt = NULL;
|
||||
char *fnIdent;
|
||||
char *ident = NULL;
|
||||
int funcArgCount;
|
||||
char LToken = pe->Token;
|
||||
|
||||
/* If we are in a state where the non-stacked 'pe->name' is valuable, then
|
||||
* save it before we process the next token. */
|
||||
switch ( LToken ) {
|
||||
case FN_TOKEN:
|
||||
case STR_TOKEN:
|
||||
ident = g_strdup( pe->name );
|
||||
break;
|
||||
}
|
||||
|
||||
next_token (pe);
|
||||
if (pe->error_code)
|
||||
return;
|
||||
@ -1099,7 +1118,6 @@ primary_exp (parser_env_ptr pe)
|
||||
break;
|
||||
|
||||
case FN_TOKEN:
|
||||
fnIdent = pe->name;
|
||||
funcArgCount = 0;
|
||||
|
||||
do {
|
||||
@ -1126,18 +1144,28 @@ primary_exp (parser_env_ptr pe)
|
||||
|
||||
argv = g_new0( void*, funcArgCount );
|
||||
for ( i=0; i<funcArgCount; i++ ) {
|
||||
/* fill back-to-front */
|
||||
/* fill, in back-to-front order, the funcArgCount tokens we just
|
||||
* parsed out of the expression into a argument list to hand back
|
||||
* to the caller's func_op callback. */
|
||||
val = pop(pe);
|
||||
argv[funcArgCount - i - 1] = val->value;
|
||||
argv[funcArgCount - i - 1] = val;
|
||||
}
|
||||
|
||||
rslt = get_unnamed_var(pe);
|
||||
rslt->value = (*pe->func_op)( fnIdent, funcArgCount, argv );
|
||||
rslt->value = (*pe->func_op)( ident, funcArgCount, argv );
|
||||
|
||||
for ( i=0; i<funcArgCount; i++ ) {
|
||||
free_var( argv[i], pe );
|
||||
}
|
||||
g_free( argv );
|
||||
g_free( ident );
|
||||
|
||||
if ( rslt->value == NULL ) {
|
||||
pe->error_code = NOT_A_FUNC;
|
||||
add_token( pe, EOS );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
next_token(pe);
|
||||
@ -1146,6 +1174,11 @@ primary_exp (parser_env_ptr pe)
|
||||
case VAR_TOKEN:
|
||||
rslt = get_named_var (pe);
|
||||
break;
|
||||
case STR_TOKEN:
|
||||
rslt = get_unnamed_var( pe );
|
||||
rslt->type = VST_STRING;
|
||||
rslt->value = ident;
|
||||
break;
|
||||
} /* endswitch */
|
||||
|
||||
if (rslt != NULL)
|
||||
|
@ -69,11 +69,18 @@ ParseError;
|
||||
*/
|
||||
typedef struct var_store *var_store_ptr;
|
||||
|
||||
/* the type of entity contained in the var_store */
|
||||
typedef enum {
|
||||
VST_NUMERIC = 0,
|
||||
VST_STRING
|
||||
} VarStoreType;
|
||||
|
||||
typedef struct var_store
|
||||
{
|
||||
char *variable_name; /* variable name if variable, NULL otherwise */
|
||||
char use_flag; /* flag if variable has been assigned to */
|
||||
char assign_flag; /* flag if variable is used */
|
||||
VarStoreType type;
|
||||
void *value; /* pointer to implementation defined numeric value */
|
||||
var_store_ptr next_var; /* pointer to next variable in linked list */
|
||||
}
|
||||
|
@ -476,7 +476,6 @@ http://www.interest.com/hugh/calc/mort_links.html
|
||||
|
||||
Druid Feedback:
|
||||
|
||||
|
||||
<Wilddev> jsled: <auspex> Wilddev: The labels need colons, mnemonics, and right-alignment.
|
||||
<Wilddev> <auspex> Wilddev: It may be worthwhile for gnucash to create GtkSpinButton subclasses which show the percent symbol and others within the field.
|
||||
<Wilddev> <auspex> Wilddev: I don't know how complicated that will be.
|
||||
@ -495,3 +494,29 @@ Druid Feedback:
|
||||
<jsled> Hmm. Okay. The between-transaction period is a frequency editor on the Repayment page.
|
||||
<Wilddev> <auspex> I'm wondering if "Original Principal" should be a vulgate
|
||||
such as "Loan Amount"
|
||||
|
||||
----------
|
||||
|
||||
Expression changes, round 2
|
||||
|
||||
We need the following abilities in order to get mortgage/loan repayment
|
||||
working:
|
||||
. Ability to get the original value of an account
|
||||
. [perhaps, ability to reference an external value?]
|
||||
. Ability to get the present value of an account
|
||||
. Ability to get the current i in an "i-of-N" sequence
|
||||
|
||||
As well, it'd be nice to have:
|
||||
. some sort of signature checking on functions in expressions
|
||||
. safe[r] error handling?
|
||||
|
||||
We decide that the original/present value of the account should be handled in
|
||||
scheme, and thus we actually need a way to reference accounts down to the
|
||||
scheme expressions. We decide to use the Quote symbols to refer to a string
|
||||
literal. The expression parser should be modified to parse this.
|
||||
|
||||
----------
|
||||
|
||||
The current 'i' and 'N' are going to be handled by having a list of
|
||||
predefined variables which the user cannot have access to. For the time
|
||||
being, this is 'i' and 'N'.
|
||||
|
@ -191,10 +191,14 @@ gnc_ttsplitinfo_malloc(void)
|
||||
void
|
||||
gnc_ttsplitinfo_free(TTSplitInfo *ttsi)
|
||||
{
|
||||
g_free(ttsi->action);
|
||||
g_free(ttsi->memo);
|
||||
g_free(ttsi->credit_formula);
|
||||
g_free(ttsi->debit_formula);
|
||||
if ( ttsi->action )
|
||||
g_free(ttsi->action);
|
||||
if ( ttsi->memo )
|
||||
g_free(ttsi->memo);
|
||||
if ( ttsi->credit_formula )
|
||||
g_free(ttsi->credit_formula);
|
||||
if ( ttsi->debit_formula )
|
||||
g_free(ttsi->debit_formula);
|
||||
g_free(ttsi);
|
||||
return;
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ void gnc_ttinfo_set_num(TTInfo *tti, const char *num);
|
||||
|
||||
|
||||
/* this one points to a persistent pointer so ownership isn't relevant */
|
||||
|
||||
void gnc_ttinfo_set_currency(TTInfo *tti, gnc_commodity *common_currency);
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@ typedef struct _temporalStateData {
|
||||
GDate end_date;
|
||||
gint num_occur_total;
|
||||
gint num_occur_rem;
|
||||
gint num_inst;
|
||||
} temporalStateData;
|
||||
|
||||
/** Local Prototypes *****/
|
||||
@ -80,6 +81,7 @@ xaccSchedXactionInit( SchedXaction *sx, GNCBook *book)
|
||||
sx->autoCreateNotify = FALSE;
|
||||
sx->advanceCreateDays = 0;
|
||||
sx->advanceRemindDays = 0;
|
||||
sx->instance_num = 0;
|
||||
sx->dirty = TRUE;
|
||||
|
||||
/* create a new template account for our splits */
|
||||
@ -507,6 +509,29 @@ xaccSchedXactionGetInstanceAfter( SchedXaction *sx,
|
||||
return next_occur;
|
||||
}
|
||||
|
||||
gint
|
||||
gnc_sx_get_instance_count( SchedXaction *sx, void *stateData )
|
||||
{
|
||||
gint toRet = -1;
|
||||
temporalStateData *tsd;
|
||||
|
||||
if ( stateData ) {
|
||||
tsd = (temporalStateData*)stateData;
|
||||
toRet = tsd->num_inst;
|
||||
} else {
|
||||
toRet = sx->instance_num;
|
||||
}
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_sx_set_instance_count( SchedXaction *sx, gint instanceNum )
|
||||
{
|
||||
g_return_if_fail( sx );
|
||||
sx->instance_num = instanceNum;
|
||||
}
|
||||
|
||||
GList *
|
||||
xaccSchedXactionGetSplits( SchedXaction *sx )
|
||||
{
|
||||
@ -642,10 +667,11 @@ void
|
||||
xaccSchedXactionIncrSequenceState( SchedXaction *sx,
|
||||
void *stateData )
|
||||
{
|
||||
temporalStateData *tsd = (temporalStateData*)stateData;
|
||||
if ( xaccSchedXactionHasOccurDef( sx ) ) {
|
||||
temporalStateData *tsd = (temporalStateData*)stateData;
|
||||
tsd->num_occur_rem -= 1;
|
||||
}
|
||||
tsd->num_inst += 1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -663,6 +689,7 @@ gnc_sx_create_temporal_state_snapshot( SchedXaction *sx )
|
||||
toRet->end_date = sx->end_date;
|
||||
toRet->num_occur_total = sx->num_occurances_total;
|
||||
toRet->num_occur_rem = sx->num_occurances_remain;
|
||||
toRet->num_inst = sx->instance_num;
|
||||
return (void*)toRet;
|
||||
}
|
||||
|
||||
@ -675,6 +702,7 @@ gnc_sx_revert_to_temporal_state_snapshot( SchedXaction *sx, void *stateData )
|
||||
sx->end_date = tsd->end_date;
|
||||
sx->num_occurances_total = tsd->num_occur_total;
|
||||
sx->num_occurances_remain = tsd->num_occur_rem;
|
||||
sx->instance_num = tsd->num_inst;
|
||||
|
||||
sx->dirty = TRUE;
|
||||
}
|
||||
|
@ -118,11 +118,27 @@ void xaccSchedXactionSetNumOccur( SchedXaction *sx, gint numNum );
|
||||
gint xaccSchedXactionGetRemOccur( SchedXaction *sx );
|
||||
void xaccSchedXactionSetRemOccur( SchedXaction *sx, gint numRemain );
|
||||
|
||||
/**
|
||||
* Set the instance count. This is incremented by one for every created
|
||||
* instance of the SX.
|
||||
* @param stateData may be NULL.
|
||||
**/
|
||||
gint gnc_sx_get_instance_count( SchedXaction *sx, void *stateData );
|
||||
/**
|
||||
* Sets the instance count to something other than the default. As the
|
||||
* default is the incorrect value '0', callers should DTRT here.
|
||||
**/
|
||||
void gnc_sx_set_instance_count( SchedXaction *sx, gint instanceNum );
|
||||
|
||||
GList *xaccSchedXactionGetSplits( SchedXaction *sx );
|
||||
void xaccSchedXactionSetSplits( SchedXaction *sx, GList *newSplits );
|
||||
|
||||
void xaccSchedXactionGetAutoCreate( SchedXaction *sx, gboolean *outAutoCreate, gboolean *outNotify );
|
||||
void xaccSchedXactionSetAutoCreate( SchedXaction *sx, gboolean newAutoCreate, gboolean newNotify );
|
||||
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 );
|
||||
@ -177,6 +193,9 @@ void xaccSchedXactionSetGUID( SchedXaction *sx, GUID g );
|
||||
* looking at reminders... and generally thinking about not wanting the
|
||||
* caller to know every possible thing that needs to be kept track of in a
|
||||
* forward-looking sequence of SXes.
|
||||
*
|
||||
* THESE (3) FUNCTIONS ARE DEPRECATED. See/Use the
|
||||
* 'temporal_state_snapshot' functions below.
|
||||
**/
|
||||
void *xaccSchedXactionCreateSequenceState( SchedXaction *sx );
|
||||
void xaccSchedXactionIncrSequenceState( SchedXaction *sx, void *stateData );
|
||||
@ -194,7 +213,8 @@ void xaccSchedXactionDestroySequenceState( void *stateData );
|
||||
* SX without having to rollback all the individual state changes.
|
||||
*
|
||||
* NOTE that this is similar to the above SequenceState interface, and
|
||||
* perhaps can be seen as entailing the above interface.
|
||||
* perhaps can be seen as entailing the above interface. In fact, the above
|
||||
* interface is deprecated in favor of this one.
|
||||
**/
|
||||
void *gnc_sx_create_temporal_state_snapshot( SchedXaction *sx );
|
||||
void gnc_sx_revert_to_temporal_state_snapshot( SchedXaction *sx, void *stateData );
|
||||
|
@ -64,6 +64,9 @@ struct gncp_SchedXaction
|
||||
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 autoCreateOption;
|
||||
gboolean autoCreateNotify;
|
||||
|
@ -465,6 +465,7 @@ gnc_sxed_check_consistent( SchedXactionEditorDialog *sxed )
|
||||
* Do checks on validity and such, interrupting the user if
|
||||
* things aren't right.
|
||||
*
|
||||
* . support formulas [?!]
|
||||
* . balancing the SX if contain numeric-only formula data.
|
||||
* . agreement with create-automagically/notification controls
|
||||
* X the 'will ever be valid' check should take num-occur vals into
|
||||
@ -1429,6 +1430,10 @@ schedXact_editor_populate( SchedXactionEditorDialog *sxed )
|
||||
(gfloat)daysInAdvance );
|
||||
}
|
||||
|
||||
if ( sxed->newsxP ) {
|
||||
gnc_sx_set_instance_count( sxed->sx, 1 );
|
||||
}
|
||||
|
||||
/* populate the ledger */
|
||||
{
|
||||
/* create the split list */
|
||||
|
@ -387,6 +387,8 @@ sxftd_compute_sx(SXFromTransInfo *sxfti)
|
||||
break;
|
||||
}
|
||||
|
||||
gnc_sx_set_instance_count( sx, 1 );
|
||||
|
||||
sxftd_add_template_trans( sxfti );
|
||||
|
||||
return sxftd_errno;
|
||||
|
@ -140,10 +140,10 @@ typedef struct _sxSinceLastData {
|
||||
GtkProgressBar *prog;
|
||||
|
||||
/* Multi-stage processing-related stuff... */
|
||||
GList /* <autoCreateTuple*> */ *autoCreateList;
|
||||
GList /* <toCreateTuple*> */ *toCreateList;
|
||||
GList /* <reminderTuple*> */ *reminderList;
|
||||
GList /* <toDeleteTuple*> */ *toRemoveList;
|
||||
GList /* <toCreateTuple*> */ *autoCreateList;
|
||||
GList /* <toCreateTuple*> */ *toCreateList;
|
||||
GList /* <reminderTuple*> */ *reminderList;
|
||||
GList /* <toDeleteTuple*> */ *toRemoveList;
|
||||
|
||||
/********** "Cancel"-related stuff... **********/
|
||||
|
||||
@ -165,12 +165,6 @@ typedef struct _sxSinceLastData {
|
||||
|
||||
} sxSinceLastData;
|
||||
|
||||
|
||||
typedef struct autoCreateTuple_ {
|
||||
SchedXaction *sx;
|
||||
GList /* <GDate*> */ *instanceList;
|
||||
} autoCreateTuple;
|
||||
|
||||
typedef struct toCreateTuple_ {
|
||||
SchedXaction *sx;
|
||||
GList /* <toCreateInstance*> */ *instanceList;
|
||||
@ -179,6 +173,7 @@ typedef struct toCreateTuple_ {
|
||||
typedef struct toCreateInstance_ {
|
||||
GDate *date;
|
||||
GHashTable *varBindings;
|
||||
gint instanceNum;
|
||||
GtkCTreeNode *node;
|
||||
toCreateTuple *parentTCT;
|
||||
} toCreateInstance;
|
||||
@ -197,6 +192,7 @@ typedef struct reminderTuple_ {
|
||||
typedef struct reminderInstanceTuple_ {
|
||||
GDate *endDate;
|
||||
GDate *occurDate;
|
||||
gint instanceNum;
|
||||
gboolean isSelected;
|
||||
reminderTuple *parentRT;
|
||||
} reminderInstanceTuple;
|
||||
@ -453,7 +449,6 @@ reminders_page_prep( sxSinceLastData *sxsld )
|
||||
if ( g_list_length( sxsld->reminderList ) == 0 ) {
|
||||
w = glade_xml_get_widget( sxsld->gxml,
|
||||
AUTO_CREATE_NOTIFY_PG );
|
||||
DEBUG( "Going to auto_create_notify page" );
|
||||
gnome_druid_set_page( sxsld->sincelast_druid,
|
||||
GNOME_DRUID_PAGE(w) );
|
||||
return;
|
||||
@ -510,7 +505,6 @@ auto_create_prep( GnomeDruidPage *druid_page,
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
|
||||
if ( ! sxsld->autoCreatedSomething ) {
|
||||
DEBUG( "Going to to_create page" );
|
||||
w = glade_xml_get_widget( sxsld->gxml, TO_CREATE_PG );
|
||||
gnome_druid_set_page( sxsld->sincelast_druid,
|
||||
GNOME_DRUID_PAGE(w) );
|
||||
@ -526,7 +520,6 @@ created_prep( GnomeDruidPage *druid_page,
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
|
||||
if ( !sxsld->createdSomething ) {
|
||||
DEBUG( "Going to obsolete page" );
|
||||
w = glade_xml_get_widget( sxsld->gxml, OBSOLETE_PG );
|
||||
gnome_druid_set_page( sxsld->sincelast_druid,
|
||||
GNOME_DRUID_PAGE(w) );
|
||||
@ -541,7 +534,6 @@ obsolete_prep( GnomeDruidPage *druid_page,
|
||||
GtkWidget *w;
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
if ( g_list_length( sxsld->toRemoveList ) == 0 ) {
|
||||
DEBUG( "Going to finish page" );
|
||||
w = glade_xml_get_widget( sxsld->gxml, FINISH_PG );
|
||||
gnome_druid_set_page( sxsld->sincelast_druid,
|
||||
GNOME_DRUID_PAGE(w) );
|
||||
@ -560,7 +552,6 @@ obsolete_next( GnomeDruidPage *druid_page,
|
||||
toDeleteTuple *tdt;
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
|
||||
DEBUG( "obsolete_next" );
|
||||
sxList = gnc_book_get_schedxactions( gnc_get_current_book() );
|
||||
cl = GTK_CLIST( glade_xml_get_widget( sxsld->gxml,
|
||||
SX_OBSOLETE_CLIST ) );
|
||||
@ -569,11 +560,7 @@ obsolete_next( GnomeDruidPage *druid_page,
|
||||
toDelPtr;
|
||||
toDelPtr = toDelPtr->next ) {
|
||||
row = (gint)toDelPtr->data;
|
||||
DEBUG( "getting row data for SX_OBSOLETE_CLIST row %d",
|
||||
row );
|
||||
tdt = (toDeleteTuple*)gtk_clist_get_row_data( cl, row );
|
||||
DEBUG( "got tdt with sx with name \"%s\"",
|
||||
xaccSchedXactionGetName( tdt->sx ) );
|
||||
{
|
||||
elt = g_list_find( sxList, tdt->sx );
|
||||
sxList = g_list_remove_link( sxList, elt );
|
||||
@ -699,8 +686,6 @@ to_create_next( GnomeDruidPage *druid_page,
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG( "Done with creation; updating created ledger." );
|
||||
|
||||
oldQuery = gnc_ledger_display_get_query( sxsld->created_ledger );
|
||||
newQuery = xaccQueryMerge( oldQuery, q, QUERY_AND );
|
||||
gnc_ledger_display_set_query( sxsld->created_ledger, newQuery );
|
||||
@ -925,7 +910,7 @@ sxsincelast_init( sxSinceLastData *sxsld )
|
||||
}
|
||||
}
|
||||
|
||||
//reminders_page_prep( sxsld );
|
||||
/*reminders_page_prep( sxsld );*/
|
||||
gtk_widget_show_all( sxsld->sincelast_window );
|
||||
|
||||
process_auto_create_list( sxsld->autoCreateList, sxsld );
|
||||
@ -952,7 +937,8 @@ generate_instances( SchedXaction *sx,
|
||||
GList **reminderList,
|
||||
GList **deadList )
|
||||
{
|
||||
GDate gd, *gdToReturn;
|
||||
GDate gd;
|
||||
toCreateInstance *tci;
|
||||
reminderTuple *rt;
|
||||
reminderInstanceTuple *rit;
|
||||
void *seqStateData;
|
||||
@ -966,9 +952,13 @@ generate_instances( SchedXaction *sx,
|
||||
|
||||
g_date_strftime( tmpBuf, GNC_D_WIDTH, GNC_D_FMT, &gd );
|
||||
|
||||
gdToReturn = g_date_new();
|
||||
*gdToReturn = gd;
|
||||
*instanceList = g_list_append( *instanceList, gdToReturn );
|
||||
tci = g_new0( toCreateInstance, 1 );
|
||||
|
||||
tci->date = g_date_new();
|
||||
*tci->date = gd;
|
||||
tci->instanceNum = gnc_sx_get_instance_count( sx, seqStateData );
|
||||
|
||||
*instanceList = g_list_append( *instanceList, tci );
|
||||
|
||||
xaccSchedXactionIncrSequenceState( sx, seqStateData );
|
||||
gd = xaccSchedXactionGetInstanceAfter( sx, &gd, seqStateData );
|
||||
@ -990,14 +980,17 @@ generate_instances( SchedXaction *sx,
|
||||
rt->instanceList = NULL;
|
||||
while ( g_date_valid(&gd)
|
||||
&& g_date_compare( &gd, reminderEnd ) <= 0 ) {
|
||||
|
||||
g_date_strftime( tmpBuf, GNC_D_WIDTH, GNC_D_FMT, &gd );
|
||||
|
||||
rit = g_new0( reminderInstanceTuple, 1 );
|
||||
rit->endDate = g_date_new();
|
||||
*rit->endDate = *end;
|
||||
rit->occurDate = g_date_new();
|
||||
*rit->occurDate = gd;
|
||||
rit->isSelected = FALSE;
|
||||
rit->parentRT = rt;
|
||||
rit->endDate = g_date_new();
|
||||
*rit->endDate = *end;
|
||||
rit->occurDate = g_date_new();
|
||||
*rit->occurDate = gd;
|
||||
rit->isSelected = FALSE;
|
||||
rit->parentRT = rt;
|
||||
rit->instanceNum = gnc_sx_get_instance_count( sx, seqStateData );
|
||||
|
||||
rt->instanceList = g_list_append( rt->instanceList, rit );
|
||||
|
||||
@ -1072,7 +1065,8 @@ process_auto_create_list( GList *autoCreateList, sxSinceLastData *sxsld )
|
||||
{
|
||||
GList *createdGUIDs = NULL;
|
||||
GList *thisGUID;
|
||||
autoCreateTuple *act;
|
||||
toCreateTuple *tct;
|
||||
toCreateInstance *tci;
|
||||
gboolean autoCreateState, notifyState;
|
||||
Query *q, *dlQuery, *newQuery;
|
||||
GList *instances;
|
||||
@ -1084,18 +1078,19 @@ process_auto_create_list( GList *autoCreateList, sxSinceLastData *sxsld )
|
||||
gtk_progress_configure( GTK_PROGRESS(sxsld->prog), 0, 0,
|
||||
g_list_length( autoCreateList ) );
|
||||
for ( ; autoCreateList ; autoCreateList = autoCreateList->next ) {
|
||||
act = (autoCreateTuple*)autoCreateList->data;
|
||||
tct = (toCreateTuple*)autoCreateList->data;
|
||||
|
||||
xaccSchedXactionGetAutoCreate( act->sx,
|
||||
xaccSchedXactionGetAutoCreate( tct->sx,
|
||||
&autoCreateState,
|
||||
¬ifyState );
|
||||
|
||||
for ( instances = act->instanceList;
|
||||
for ( instances = tct->instanceList;
|
||||
instances;
|
||||
instances = instances->next ) {
|
||||
tci = (toCreateInstance*)instances->data;
|
||||
thisGUID = createdGUIDs = NULL;
|
||||
create_transactions_on( act->sx,
|
||||
(GDate*)instances->data,
|
||||
create_transactions_on( tct->sx,
|
||||
(GDate*)tci->date,
|
||||
NULL, &createdGUIDs );
|
||||
|
||||
count += g_list_length( createdGUIDs );
|
||||
@ -1121,7 +1116,7 @@ process_auto_create_list( GList *autoCreateList, sxSinceLastData *sxsld )
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG( "Finished creating transactions; updating ledger" );
|
||||
/*DEBUG( "Finished creating transactions; updating ledger" );*/
|
||||
|
||||
dlQuery = gnc_ledger_display_get_query( sxsld->ac_ledger );
|
||||
newQuery = xaccQueryMerge( dlQuery, q, QUERY_AND );
|
||||
@ -1141,6 +1136,8 @@ add_to_create_list_to_gui( GList *toCreateList, sxSinceLastData *sxsld )
|
||||
GtkCTreeNode *sxNode;
|
||||
char *rowText[ TO_CREATE_LIST_WIDTH ];
|
||||
GList *insts;
|
||||
int htSize;
|
||||
gpointer unusedkey, unusedvalue;
|
||||
|
||||
ct = GTK_CTREE( glade_xml_get_widget( sxsld->gxml, TO_CREATE_LIST ) );
|
||||
|
||||
@ -1170,7 +1167,13 @@ add_to_create_list_to_gui( GList *toCreateList, sxSinceLastData *sxsld )
|
||||
g_date_strftime( rowText[0], GNC_D_WIDTH, GNC_D_FMT, tci->date );
|
||||
sxsl_get_sx_vars( tci->parentTCT->sx, tci->varBindings );
|
||||
|
||||
if ( g_hash_table_size( tci->varBindings ) == 0 ) {
|
||||
htSize = g_hash_table_size( tci->varBindings );
|
||||
if ( g_hash_table_lookup_extended( tci->varBindings, "i",
|
||||
&unusedkey,
|
||||
&unusedvalue ) ) {
|
||||
htSize -= 1;
|
||||
}
|
||||
if ( htSize == 0 ) {
|
||||
rowText[1] = "y";
|
||||
} else {
|
||||
rowText[1] = "n";
|
||||
@ -1299,41 +1302,45 @@ processSelectedReminderList( GList *goodList, sxSinceLastData *sxsld )
|
||||
{
|
||||
GList *list = NULL;
|
||||
reminderInstanceTuple *rit;
|
||||
autoCreateTuple *act;
|
||||
toCreateTuple *tct;
|
||||
toCreateInstance *tci;
|
||||
gboolean autoCreateOpt, notifyOpt;
|
||||
|
||||
tct = NULL;
|
||||
act = NULL;
|
||||
for ( ; goodList ; goodList = goodList->next ) {
|
||||
rit = (reminderInstanceTuple*)goodList->data;
|
||||
|
||||
DEBUG( "Processing selected reminder \"%s\"",
|
||||
xaccSchedXactionGetName( rit->parentRT->sx ) );
|
||||
|
||||
xaccSchedXactionGetAutoCreate( rit->parentRT->sx,
|
||||
&autoCreateOpt, ¬ifyOpt );
|
||||
if ( autoCreateOpt ) {
|
||||
for ( list = sxsld->autoCreateList;
|
||||
list;
|
||||
list = list->next ) {
|
||||
act = (autoCreateTuple*)list->data;
|
||||
// Find any already-existing toCreateTuples to add to...
|
||||
if ( act->sx == rit->parentRT->sx ) {
|
||||
tct = (toCreateTuple*)list->data;
|
||||
/* Find any already-existing toCreateTuples to add to...*/
|
||||
if ( tct->sx == rit->parentRT->sx ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !list ) {
|
||||
act = g_new0( autoCreateTuple, 1 );
|
||||
act->sx = rit->parentRT->sx;
|
||||
tct = g_new0( toCreateTuple, 1 );
|
||||
tct->sx = rit->parentRT->sx;
|
||||
sxsld->autoCreateList =
|
||||
g_list_append( sxsld->autoCreateList, act );
|
||||
g_list_append( sxsld->autoCreateList, tct );
|
||||
}
|
||||
act->instanceList = g_list_append( act->instanceList,
|
||||
rit->occurDate );
|
||||
|
||||
tci = g_new0( toCreateInstance, 1 );
|
||||
tci->parentTCT = tct;
|
||||
tci->date = rit->occurDate;
|
||||
tci->varBindings = NULL;
|
||||
tci->instanceNum = rit->instanceNum;
|
||||
tci->node = NULL;
|
||||
|
||||
tct->instanceList =
|
||||
g_list_append( tct->instanceList, tci );
|
||||
|
||||
list = NULL;
|
||||
list = g_list_append( list, act );
|
||||
list = g_list_append( list, tct );
|
||||
process_auto_create_list( list, sxsld );
|
||||
list = NULL;
|
||||
} else {
|
||||
@ -1341,7 +1348,7 @@ processSelectedReminderList( GList *goodList, sxSinceLastData *sxsld )
|
||||
list;
|
||||
list = list->next ) {
|
||||
tct = (toCreateTuple*)list->data;
|
||||
// Find any already-existing toCreateTuples to add to...
|
||||
/* Find any already-existing toCreateTuples to add to...*/
|
||||
if ( tct->sx == rit->parentRT->sx ) {
|
||||
break;
|
||||
}
|
||||
@ -1353,10 +1360,11 @@ processSelectedReminderList( GList *goodList, sxSinceLastData *sxsld )
|
||||
g_list_append( sxsld->toCreateList, tct );
|
||||
}
|
||||
tci = g_new0( toCreateInstance, 1 );
|
||||
tci->parentTCT = tct;
|
||||
tci->date = rit->occurDate;
|
||||
tci->node = NULL;
|
||||
tci->parentTCT = tct;
|
||||
tci->date = rit->occurDate;
|
||||
tci->node = NULL;
|
||||
tci->varBindings = NULL;
|
||||
tci->instanceNum = rit->instanceNum;
|
||||
|
||||
tct->instanceList =
|
||||
g_list_append( tct->instanceList, tci );
|
||||
@ -1377,11 +1385,9 @@ sxsincelast_populate( sxSinceLastData *sxsld )
|
||||
SchedXaction *sx;
|
||||
void *sx_state;
|
||||
GDate end, endPlusReminders;
|
||||
GDate *instDate;
|
||||
gint daysInAdvance;
|
||||
gboolean autocreateState, notifyState;
|
||||
gboolean showIt;
|
||||
autoCreateTuple *act;
|
||||
toCreateTuple *tct;
|
||||
toCreateInstance *tci;
|
||||
|
||||
@ -1432,27 +1438,24 @@ sxsincelast_populate( sxSinceLastData *sxsld )
|
||||
xaccSchedXactionGetAutoCreate( sx, &autocreateState,
|
||||
¬ifyState );
|
||||
if ( autocreateState ) {
|
||||
act = g_new0( autoCreateTuple, 1 );
|
||||
act->sx = sx;
|
||||
tct = g_new0( toCreateTuple, 1 );
|
||||
tct->sx = sx;
|
||||
for ( ; instanceList; instanceList = instanceList->next ) {
|
||||
instDate = (GDate*)instanceList->data;
|
||||
act->instanceList =
|
||||
g_list_append( act->instanceList,
|
||||
instDate );
|
||||
tci = (toCreateInstance*)instanceList->data;
|
||||
tci->parentTCT = tct;
|
||||
tct->instanceList =
|
||||
g_list_append( tct->instanceList,
|
||||
tci );
|
||||
}
|
||||
sxsld->autoCreateList =
|
||||
g_list_append( sxsld->autoCreateList,
|
||||
act );
|
||||
tct );
|
||||
} else {
|
||||
tct = g_new0( toCreateTuple, 1 );
|
||||
tct->sx = sx;
|
||||
for ( ; instanceList; instanceList = instanceList->next ) {
|
||||
instDate = (GDate*)instanceList->data;
|
||||
tci = g_new0( toCreateInstance, 1 );
|
||||
tci = (toCreateInstance*)instanceList->data;
|
||||
tci->parentTCT = tct;
|
||||
tci->date = instDate;
|
||||
tci->node = NULL;
|
||||
tci->varBindings = NULL;
|
||||
tct->instanceList =
|
||||
g_list_append( tct->instanceList, tci );
|
||||
}
|
||||
@ -1508,8 +1511,7 @@ static void
|
||||
sxsincelast_close_handler( gpointer ud )
|
||||
{
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
|
||||
DEBUG( "sxsincelast_close_handler" );
|
||||
|
||||
gtk_widget_hide( sxsld->sincelast_window );
|
||||
sxsincelast_save_size( sxsld );
|
||||
clean_sincelast_dlg( sxsld );
|
||||
@ -1521,7 +1523,9 @@ static void
|
||||
andequal_numerics_set( gpointer key, gpointer value, gpointer data )
|
||||
{
|
||||
gboolean *allVarsBound = data;
|
||||
*allVarsBound &= (value != NULL);
|
||||
if ( strcmp( (gchar*)key, "i" ) != 0 ) {
|
||||
*allVarsBound &= (value != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1598,7 +1602,6 @@ sxsincelast_destroy( GtkObject *o, gpointer ud )
|
||||
{
|
||||
sxSinceLastData *sxsld = (sxSinceLastData*)ud;
|
||||
|
||||
DEBUG( "sxsincelast_destroy called\n" );
|
||||
gnc_unregister_gui_component_by_data( DIALOG_SXSINCELAST_CM_CLASS,
|
||||
sxsld->sincelast_window );
|
||||
|
||||
@ -1614,6 +1617,40 @@ sxsincelast_destroy( GtkObject *o, gpointer ud )
|
||||
g_free( sxsld );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to copy the varBinding GHashTable.
|
||||
**/
|
||||
static
|
||||
void
|
||||
gnc_sxsl_copy_ea_hash( gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data )
|
||||
{
|
||||
gchar *name = (gchar*)key;
|
||||
gnc_numeric *val = (gnc_numeric*)value;
|
||||
gnc_numeric *newVal;
|
||||
GHashTable *table = (GHashTable*)user_data;
|
||||
|
||||
newVal = g_new0( gnc_numeric, 1 );
|
||||
*newVal = gnc_numeric_error( -2 );
|
||||
if ( val )
|
||||
*newVal = *val;
|
||||
|
||||
g_hash_table_insert( table,
|
||||
(gpointer)g_strdup( name ),
|
||||
(gpointer)newVal );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_sxsl_del_vars_table_ea( gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data )
|
||||
{
|
||||
g_free( (gchar*)key );
|
||||
g_free( (gnc_numeric*)value );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_each_transaction_helper( Transaction *t, void *d )
|
||||
{
|
||||
@ -1627,6 +1664,8 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
createData *createUD;
|
||||
toCreateInstance *tci;
|
||||
gnc_commodity *commonCommodity = NULL;
|
||||
GHashTable *actualVars;
|
||||
gnc_numeric *varIValue;
|
||||
|
||||
errFlag = FALSE;
|
||||
|
||||
@ -1637,15 +1676,25 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
/* FIXME: when we copy the trans_onto_trans, we don't want to copy
|
||||
the Split's kvp_frames... */
|
||||
|
||||
/* FIXME: This should setup the predefined variables 'i' and 'N' */
|
||||
|
||||
createUD = (createData*)d;
|
||||
tci = createUD->tci;
|
||||
|
||||
actualVars = g_hash_table_new( g_str_hash, g_str_equal );
|
||||
if ( tci->varBindings != NULL ) {
|
||||
g_hash_table_foreach( tci->varBindings,
|
||||
gnc_sxsl_copy_ea_hash, actualVars );
|
||||
}
|
||||
varIValue = g_new0( gnc_numeric, 1 );
|
||||
*varIValue = gnc_numeric_create( tci->instanceNum, 1 );
|
||||
g_hash_table_insert( actualVars, "i", varIValue );
|
||||
|
||||
newT = xaccMallocTransaction(gnc_get_current_book ());
|
||||
xaccTransBeginEdit( newT );
|
||||
/* the action and description/memo are in the template */
|
||||
gnc_copy_trans_onto_trans( t, newT, FALSE, FALSE );
|
||||
|
||||
/* the date is new [by definition :)] */
|
||||
xaccTransSetDate( newT,
|
||||
g_date_day( tci->date ),
|
||||
g_date_month( tci->date ),
|
||||
@ -1658,7 +1707,8 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
PERR( "\tseen transaction w/o splits. :(" );
|
||||
return FALSE;
|
||||
}
|
||||
do {
|
||||
for ( ; sList && osList ;
|
||||
sList = sList->next, osList = osList->next ) {
|
||||
split = (Split*)sList->data;
|
||||
/* FIXME: Ick. This assumes that the split lists will be
|
||||
ordered identically. :( I think it's fair to say they
|
||||
@ -1683,10 +1733,10 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
acct_guid = kvp_value_get_guid( kvp_val );
|
||||
acct = xaccAccountLookup( acct_guid,
|
||||
gnc_get_current_book ());
|
||||
#if 0
|
||||
#if 0 /* debug */
|
||||
DEBUG( "Got account with name \"%s\"",
|
||||
xaccAccountGetName( acct ) );
|
||||
#endif /* 0 */
|
||||
#endif /* 0 -- debug */
|
||||
if ( commonCommodity != NULL ) {
|
||||
if ( commonCommodity != xaccAccountGetCommodity( acct ) ) {
|
||||
PERR( "Common-commodity difference: old=%s, new=%s\n",
|
||||
@ -1701,7 +1751,7 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
}
|
||||
|
||||
|
||||
/*commonCommodity = xaccTransGetCurrency( t );*/
|
||||
/* commonCommodity = xaccTransGetCurrency( t ); */
|
||||
/* credit/debit formulas */
|
||||
{
|
||||
char *str, *parseErrorLoc;
|
||||
@ -1717,17 +1767,18 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
if ( str != NULL
|
||||
&& strlen(str) != 0 ) {
|
||||
if ( ! gnc_exp_parser_parse_separate_vars( str, &credit_num,
|
||||
&parseErrorLoc, tci->varBindings ) ) {
|
||||
&parseErrorLoc,
|
||||
actualVars ) ) {
|
||||
PERR( "Error parsing credit formula \"%s\" at \"%s\": %s",
|
||||
str, parseErrorLoc, gnc_exp_parser_error_string() );
|
||||
errFlag = TRUE;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
#if 0 /* debug */
|
||||
DEBUG( "gnc_numeric::credit: \"%s\" -> %s [%s]",
|
||||
str, gnc_numeric_to_string( credit_num ),
|
||||
gnc_numeric_to_string( gnc_numeric_reduce( credit_num ) ) );
|
||||
#endif /* 0 */
|
||||
#endif /* 0 -- debug */
|
||||
}
|
||||
|
||||
kvp_val = kvp_frame_get_slot_path( split_kvpf,
|
||||
@ -1740,18 +1791,19 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
if ( str != NULL
|
||||
&& strlen(str) != 0 ) {
|
||||
if ( ! gnc_exp_parser_parse_separate_vars( str, &debit_num,
|
||||
&parseErrorLoc, tci->varBindings ) ) {
|
||||
&parseErrorLoc,
|
||||
actualVars ) ) {
|
||||
PERR( "Error parsing debit_formula \"%s\" at \"%s\": %s",
|
||||
str, parseErrorLoc, gnc_exp_parser_error_string() );
|
||||
errFlag = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 0 /* debug */
|
||||
DEBUG( "gnc_numeric::debit: \"%s\" -> %s [%s]",
|
||||
str, gnc_numeric_to_string( debit_num ),
|
||||
gnc_numeric_to_string( gnc_numeric_reduce( debit_num ) ) );
|
||||
#endif /* 0 */
|
||||
#endif /* 0 -- debug */
|
||||
}
|
||||
|
||||
final = gnc_numeric_sub_fixed( debit_num, credit_num );
|
||||
@ -1762,12 +1814,15 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
errFlag = TRUE;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
#if 0 /* debug */
|
||||
DEBUG( "gnc_numeric::final: \"%s\"",
|
||||
gnc_numeric_to_string( final ) );
|
||||
#endif /* 0 */
|
||||
xaccSplitSetBaseValue( split, final, commonCommodity );
|
||||
#endif /* 0 -- debug */
|
||||
|
||||
xaccSplitSetValue( split, final );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* NOT [YET] USED */
|
||||
kvp_val = kvp_frame_get_slot_path( split_kvpf,
|
||||
@ -1780,12 +1835,17 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
GNC_SX_AMNT,
|
||||
NULL);
|
||||
#endif /* 0 */
|
||||
/* FIXME:
|
||||
* . We'd like to store the variable bindings, but this might be
|
||||
* problematic [if the formulas change in the SX] [?]
|
||||
*/
|
||||
|
||||
} while ( (sList = sList->next) && (osList = osList->next) );
|
||||
}
|
||||
|
||||
/* Cleanup actualVars table. */
|
||||
{
|
||||
g_hash_table_foreach( actualVars,
|
||||
gnc_sxsl_del_vars_table_ea,
|
||||
NULL );
|
||||
g_hash_table_destroy( actualVars );
|
||||
actualVars = NULL;
|
||||
}
|
||||
|
||||
/* set the balancing currency. */
|
||||
if ( commonCommodity == NULL ) {
|
||||
@ -1797,7 +1857,7 @@ create_each_transaction_helper( Transaction *t, void *d )
|
||||
{
|
||||
kvp_frame *txn_frame;
|
||||
/* set a kvp-frame element in the transaction indicating and
|
||||
pointing-to the SX this was created from. */
|
||||
* pointing-to the SX this was created from. */
|
||||
txn_frame = xaccTransGetSlots( newT );
|
||||
if ( txn_frame == NULL ) {
|
||||
txn_frame = kvp_frame_new();
|
||||
@ -1875,7 +1935,6 @@ create_transactions_on( SchedXaction *sx,
|
||||
createdTCT = TRUE;
|
||||
}
|
||||
|
||||
gnc_suspend_gui_refresh();
|
||||
ag = gnc_book_get_template_group( gnc_get_current_book () );
|
||||
id = guid_to_string( xaccSchedXactionGetGUID(sx) );
|
||||
if(ag && id)
|
||||
@ -1895,9 +1954,19 @@ create_transactions_on( SchedXaction *sx,
|
||||
{
|
||||
g_free( id );
|
||||
}
|
||||
gnc_resume_gui_refresh();
|
||||
|
||||
xaccSchedXactionSetLastOccurDate( sx, tci->date );
|
||||
/* Increment the SX state */
|
||||
{
|
||||
gint tmp;
|
||||
|
||||
xaccSchedXactionSetLastOccurDate( sx, tci->date );
|
||||
tmp = gnc_sx_get_instance_count( sx, NULL );
|
||||
gnc_sx_set_instance_count( sx, tmp+1 );
|
||||
if ( xaccSchedXactionHasOccurDef( sx ) ) {
|
||||
tmp = xaccSchedXactionGetRemOccur(sx);
|
||||
xaccSchedXactionSetRemOccur( sx, tmp-1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( createdTCT ) {
|
||||
g_free( tci );
|
||||
@ -1992,7 +2061,6 @@ static gboolean
|
||||
tct_table_entry_key_handle( GtkWidget *widget, GdkEventKey *event, gpointer ud )
|
||||
{
|
||||
gnc_numeric *num;
|
||||
//gchar *entryText;
|
||||
GtkEntry *ent = NULL;
|
||||
GString *str;
|
||||
|
||||
@ -2059,8 +2127,19 @@ sxsincelast_tc_row_sel( GtkCTree *ct,
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (varHashSize = g_hash_table_size( tci->varBindings )) == 0 ) {
|
||||
PINFO( "No variables to deal with" );
|
||||
/* Get the count of variables; potentially remove the system-defined
|
||||
* variables if they're present in the expression. */
|
||||
varHashSize = g_hash_table_size( tci->varBindings );
|
||||
{
|
||||
gpointer *foo, *bar;
|
||||
if ( g_hash_table_lookup_extended( tci->varBindings, "i",
|
||||
(gpointer)&foo,
|
||||
(gpointer)&bar ) ) {
|
||||
varHashSize -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( varHashSize == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2072,19 +2151,25 @@ sxsincelast_tc_row_sel( GtkCTree *ct,
|
||||
|
||||
tableIdx = 1;
|
||||
for ( ; varList ; varList = varList->next ) {
|
||||
gchar *varName;
|
||||
GString *gstr;
|
||||
const gchar *numValueStr;
|
||||
gnc_numeric *numValue, *tmpNumValue;
|
||||
|
||||
varName = (gchar*)varList->data;
|
||||
if ( strcmp( varName, "i" ) == 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gstr = g_string_sized_new(16);
|
||||
g_string_sprintf( gstr, "%s: ", (gchar*)varList->data );
|
||||
g_string_sprintf( gstr, "%s: ", varName );
|
||||
label = gtk_label_new( gstr->str );
|
||||
gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_RIGHT );
|
||||
g_string_free( gstr, TRUE );
|
||||
|
||||
entry = gtk_entry_new();
|
||||
gtk_object_set_data( GTK_OBJECT(entry), "varName",
|
||||
varList->data );
|
||||
varName );
|
||||
gtk_object_set_data( GTK_OBJECT(entry), "tci", tci );
|
||||
tmpNumValue = g_new0( gnc_numeric, 1 );
|
||||
*tmpNumValue = gnc_numeric_create( 0, 1 );
|
||||
@ -2099,7 +2184,7 @@ sxsincelast_tc_row_sel( GtkCTree *ct,
|
||||
|
||||
gtk_widget_set_usize( entry, 64, 0 );
|
||||
numValue = (gnc_numeric*)g_hash_table_lookup( tci->varBindings,
|
||||
varList->data );
|
||||
varName );
|
||||
if ( numValue != NULL ) {
|
||||
numValueStr =
|
||||
xaccPrintAmount( *numValue,
|
||||
@ -2144,14 +2229,14 @@ clean_variable_table( sxSinceLastData *sxsld )
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
for( ; children ; children = children->next ) {
|
||||
/* Destroy all children after the first [label-continaing]
|
||||
row... ie, leave the labels in place. */
|
||||
child = (GtkTableChild*)children->data;
|
||||
if ( child->top_attach > 0 ) {
|
||||
toFree = g_list_append( toFree, child->widget );
|
||||
}
|
||||
} while ( (children = children->next) );
|
||||
}
|
||||
|
||||
gtk_table_resize( table, 1, 2 );
|
||||
|
||||
@ -2503,7 +2588,6 @@ sxsld_ledger_get_parent( GNCLedgerDisplay *ld )
|
||||
sxSinceLastData *sxsld;
|
||||
|
||||
sxsld = (sxSinceLastData*)gnc_ledger_display_get_user_data( ld );
|
||||
//return (gncUIWidget)sxsld->reg->sheet->window;
|
||||
return (gncUIWidget)sxsld->sincelast_window;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -916,14 +916,14 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo)
|
||||
static GnomeUIInfo gnc_sched_xaction_tools_submenu_template[] =
|
||||
{
|
||||
{ GNOME_APP_UI_ITEM,
|
||||
N_("List and Editor"),
|
||||
N_("_List and Editor"),
|
||||
N_("The 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_("Since Last Run..."),
|
||||
N_("_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,
|
||||
@ -931,7 +931,7 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo)
|
||||
},
|
||||
GNOMEUIINFO_SEPARATOR,
|
||||
{ GNOME_APP_UI_ITEM,
|
||||
N_( "Mortgage/Loan Repayment Setup" ),
|
||||
N_( "_Mortgage/Loan Repayment Setup" ),
|
||||
N_( "Setup scheduled transactions for repayment of a loan" ),
|
||||
gnc_main_window_sx_loan_druid_cb, NULL, NULL,
|
||||
GNOME_APP_PIXMAP_NONE, NULL,
|
||||
@ -942,7 +942,7 @@ gnc_main_window_create_menus(GNCMDIInfo * maininfo)
|
||||
|
||||
static GnomeUIInfo gnc_actions_menu_template[] =
|
||||
{
|
||||
GNOMEUIINFO_SUBTREE( N_("Scheduled Transactions"),
|
||||
GNOMEUIINFO_SUBTREE( N_("_Scheduled Transactions"),
|
||||
gnc_sched_xaction_tools_submenu_template ),
|
||||
GNOMEUIINFO_END
|
||||
};
|
||||
|
@ -16,26 +16,37 @@
|
||||
;; Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
;; Copyright 2002 Joshua Sled <jsled@asynchronous.org>
|
||||
;; pretty literal copies of similar code from gnumeric-1.0.8
|
||||
;;
|
||||
;; pretty literal copies of similar code from gnumeric-1.0.8, except we want
|
||||
;; positive values to be returned [as gnucash will handle the credit/debit
|
||||
;; appropriately]
|
||||
|
||||
(define (gnc:ipmt rate nper per pv fv type)
|
||||
(* rate
|
||||
(- 0 (calc-principal pv
|
||||
(calc-pmt rate nper pv fv type)
|
||||
rate (- per 1))
|
||||
)
|
||||
)
|
||||
(define (gnc:ipmt rate per nper pv fv type)
|
||||
(* -1 (* rate
|
||||
(- 0 (calc-principal pv
|
||||
(calc-pmt rate nper pv fv type)
|
||||
rate (- per 1)))
|
||||
))
|
||||
)
|
||||
|
||||
(define (gnc:ppmt rate nper per pv fv type)
|
||||
(let ((pmt (calc-pmt rate nper pv fv type)))
|
||||
(let ((ipmt (* rate
|
||||
(- 0 (calc-principal pv pmt rate (- per 1))))))
|
||||
(- pmt ipmt)))
|
||||
(define (gnc:ppmt rate per nper pv fv type)
|
||||
(let* ((pmt (calc-pmt rate nper pv fv type))
|
||||
(ipmt (* rate
|
||||
(calc-principal pv pmt rate (- per 1)))))
|
||||
(* -1 (-
|
||||
pmt
|
||||
(* -1 ipmt))))
|
||||
)
|
||||
|
||||
(define (gnc:pmt rate nper pv fv type)
|
||||
(calc-pmt rate nper pv fv type))
|
||||
(* -1 (calc-pmt rate nper pv fv type)))
|
||||
|
||||
(define (gnc:foobar val) val)
|
||||
|
||||
;;;;;
|
||||
;; below: not-exposed/"private" functions, used by the "public" functions
|
||||
;; above.
|
||||
;;;;;
|
||||
|
||||
(define (calc-pmt rate nper pv fv type)
|
||||
(let ((pvif (calc-pvif rate nper))
|
||||
|
Loading…
Reference in New Issue
Block a user