mutual fund/stock stuff, first attempt

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1997-11-01 02:00:51 +00:00
parent 38d6cc079d
commit 1a6ffbe672
4 changed files with 174 additions and 68 deletions

18
README
View File

@ -36,3 +36,21 @@ To install:
sorry, no "make install" yet. sorry, no "make install" yet.
Status:
-------
As of version 0.9c, Mutual fund and Stock Portfolio handling
is implemented, but is very much in alpha state: many features
are missing, and others are broken. In particular, mutual funds
cannot be saved to disk. Also, transfers to bank accounts are
not properly supported. Also, tabbing between fields for
mutual funds does not work correctly.
An alpha version of import from quicken files is also present,
but it is very broken, and many/most quicken formats are not
supported.
Note: in general, transfers between accounts are not handled
properly as a double-entry system, and so deletion of a
transfer is not handled properly.

View File

@ -91,11 +91,14 @@ refreshMainWindow( void )
String rows[3]; String rows[3];
Transaction *trans=NULL; Transaction *trans=NULL;
Account *acc = getAccount( data, i ); Account *acc = getAccount( data, i );
double dbalance = 0; double dbalance = 0.0;
double share_balance = 0.0;
j=0; j=0;
while( (trans = getTransaction(acc,j++)) != NULL ) while( (trans = getTransaction(acc,j++)) != NULL ) {
dbalance += trans->damount; share_balance += trans->damount;
dbalance = share_balance * trans->share_price;
}
if( 0.0 > dbalance ) if( 0.0 > dbalance )
sprintf( buf,"-$%.2f\0", DABS(dbalance) ); sprintf( buf,"-$%.2f\0", DABS(dbalance) );

View File

@ -23,10 +23,9 @@
* * * *
* NOTE: This software is *very alpha*, and is likely to core * * NOTE: This software is *very alpha*, and is likely to core *
* dump on unexpected file formats, or otheriwse mangle and * * dump on unexpected file formats, or otheriwse mangle and *
* loose data. It works for the one QIF file its been tested on .. * * loose data. It sort-of works for the one QIF file its been *
* The contents of this file are not well designed, its just a * * tested on ... The contents of this file are not well designed, *
* quick hack ... in particular, pos and neg sums are not * * it is just a quick hack ... a lot more qork is required. *
* marked correctly. *
* * * *
* NOTE: the readxxxx/writexxxx functions changed the current * * NOTE: the readxxxx/writexxxx functions changed the current *
* position in the file, and so the order which these * * position in the file, and so the order which these *
@ -154,7 +153,14 @@ char * xaccReadQIFAccount (int fd, Account * acc)
XACC_PREP_STRING (acc->description); XACC_PREP_STRING (acc->description);
} else } else
if ('T' == qifline [0]) { if ('T' == qifline [0]) {
if (!strcmp (&qifline[1], "Invst\r\n")) {
acc -> type = PORTFOLIO;
} else {
DEBUG ("Unsupported account type\n");
DEBUG (&qifline[1]);
acc -> type = 0x0; // hack alert -- acc -> type = 0x0; // hack alert --
}
} else } else
/* check for end-of-transaction marker */ /* check for end-of-transaction marker */
@ -302,11 +308,11 @@ char * xaccReadQIFTransaction (int fd, Transaction *trans)
xaccParseQIFDate (&(trans->date), &qifline[1]); xaccParseQIFDate (&(trans->date), &qifline[1]);
} else } else
if ('T' == qifline [0]) { /* T == total */ if ('T' == qifline [0]) { /* T == total */
trans -> damount = xaccParseQIFAmount (&qifline[1]); /* amount is int */ trans -> damount = xaccParseQIFAmount (&qifline[1]); /* amount is double */
if (isneg) trans -> damount = - (trans->damount); if (isneg) trans -> damount = - (trans->damount);
} else } else
if ('I' == qifline [0]) { /* I == share price */ if ('I' == qifline [0]) { /* I == share price */
/* hack alert */ trans -> share_price = xaccParseQIFAmount (&qifline[1]); /* amount is double */
} else } else
if ('Q' == qifline [0]) { /* Q == number of shares */ if ('Q' == qifline [0]) { /* Q == number of shares */
/* hack alert */ /* hack alert */

View File

@ -1,4 +1,4 @@
/********************************************************************\ /*******************************************************************\
* RegWindow.c -- the register window for xacc (X-Accountant) * * RegWindow.c -- the register window for xacc (X-Accountant) *
* Copyright (C) 1997 Robin D. Clark * * Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997 Linas Vepstas * * Copyright (C) 1997 Linas Vepstas *
@ -52,7 +52,7 @@ typedef struct _RegWindow {
Widget dialog; Widget dialog;
Widget reg; /* The matrix widget... */ Widget reg; /* The matrix widget... */
Widget balance; /* The balance text field */ Widget balance; /* The balance text field */
unsigned char changed; /* bitmask of fields that have changed in * unsigned short changed; /* bitmask of fields that have changed in *
* transaction lastTrans */ * transaction lastTrans */
unsigned short lastTrans; /* to keep track of last edited transaction*/ unsigned short lastTrans; /* to keep track of last edited transaction*/
XmTextPosition insert; /* used by quickfill for detecting deletes */ XmTextPosition insert; /* used by quickfill for detecting deletes */
@ -98,9 +98,11 @@ extern Pixel negPixel;
#define MOD_DESC 0x04 #define MOD_DESC 0x04
#define MOD_RECN 0x08 #define MOD_RECN 0x08
#define MOD_AMNT 0x10 #define MOD_AMNT 0x10
#define MOD_MEMO 0x20 #define MOD_SHRS 0x20
#define MOD_NEW 0x40 #define MOD_PRIC 0x40
#define MOD_ALL 0xff #define MOD_MEMO 0x80
#define MOD_NEW 0x100
#define MOD_ALL 0x1ff
/* ??? TODO: Use these #defines, instead of hard-coding cell /* ??? TODO: Use these #defines, instead of hard-coding cell
* locations throughout the code */ * locations throughout the code */
@ -116,8 +118,15 @@ extern Pixel negPixel;
#define PAY_CELL_C 4 #define PAY_CELL_C 4
#define DEP_CELL_R 0 #define DEP_CELL_R 0
#define DEP_CELL_C 5 #define DEP_CELL_C 5
#define PRIC_CELL_C 6
#define SHRS_CELL_C 7
#define BALN_CELL_R 0 #define BALN_CELL_R 0
#define BALN_CELL_C 6 /* #define BALN_CELL_C 6 */
#define BALN_CELL_C ((acc->numCols) -1) /* the last column */
#define MEMO_CELL_R 1 #define MEMO_CELL_R 1
#define MEMO_CELL_C 2 #define MEMO_CELL_C 2
@ -128,7 +137,9 @@ extern Pixel negPixel;
#define IN_RECN_CELL(R,C) (((R-1)%2==0) && (C==3)) /* Reconciled cell */ #define IN_RECN_CELL(R,C) (((R-1)%2==0) && (C==3)) /* Reconciled cell */
#define IN_PAY_CELL(R,C) (((R-1)%2==0) && (C==4)) /* Payment cell */ #define IN_PAY_CELL(R,C) (((R-1)%2==0) && (C==4)) /* Payment cell */
#define IN_DEP_CELL(R,C) (((R-1)%2==0) && (C==5)) /* Deposit cell */ #define IN_DEP_CELL(R,C) (((R-1)%2==0) && (C==5)) /* Deposit cell */
#define IN_BALN_CELL(R,C) (((R-1)%2==0) && (C==6)) /* Balance cell */ /* #define IN_BALN_CELL(R,C) (((R-1)%2==0) && (C==6)) /* Balance cell */
#define IN_BALN_CELL(R,C) (((R-1)%2==0) && (C==BALN_CELL_C)) /* Balance cell */
#define IN_PRIC_CELL(R,C) (((R-1)%2==0) && (C==PRIC_CELL_C)) /* Balance cell */
#define IN_YEAR_CELL(R,C) (((R-1)%2==1) && (C==0)) /* Year cell */ #define IN_YEAR_CELL(R,C) (((R-1)%2==1) && (C==0)) /* Year cell */
#define IN_MEMO_CELL(R,C) (((R-1)%2==1) && (C==2)) /* Memo cell */ #define IN_MEMO_CELL(R,C) (((R-1)%2==1) && (C==2)) /* Memo cell */
#define IN_BAD_CELL(R,C) (((R-1)%2==1) && (C==3)) /* cell after memo */ #define IN_BAD_CELL(R,C) (((R-1)%2==1) && (C==3)) /* cell after memo */
@ -155,6 +166,7 @@ regRefresh( RegWindow *regData )
char buf[BUFSIZE]; char buf[BUFSIZE];
String **data = NULL; String **data = NULL;
String **newData; String **newData;
Account *acc;
XtVaGetValues( regData->reg, XmNrows, &nrows, NULL ); XtVaGetValues( regData->reg, XmNrows, &nrows, NULL );
XtVaGetValues( regData->reg, XmNcells, &data, NULL ); XtVaGetValues( regData->reg, XmNcells, &data, NULL );
@ -163,6 +175,7 @@ regRefresh( RegWindow *regData )
nnrows = (regData->acc->numTrans)*2 + 3; nnrows = (regData->acc->numTrans)*2 + 3;
drows = (nnrows-1) - (nrows-1); drows = (nnrows-1) - (nrows-1);
ncols = regData->acc->numCols; ncols = regData->acc->numCols;
acc = regData->acc;
/* allocate a new matrix: */ /* allocate a new matrix: */
newData = (String **)_malloc(nnrows*sizeof(String *)); newData = (String **)_malloc(nnrows*sizeof(String *));
@ -234,7 +247,7 @@ regRefresh( RegWindow *regData )
/* ----------------------------------- */ /* ----------------------------------- */
/* extra columns for mutual funds, etc. */ /* extra columns for mutual funds, etc. */
switch(regData->acc->type) switch(acc->type)
{ {
case BANK: case BANK:
case CASH: case CASH:
@ -244,11 +257,11 @@ regRefresh( RegWindow *regData )
break; break;
case PORTFOLIO: case PORTFOLIO:
case MUTUAL: case MUTUAL:
/* hackk alert -- this is probably incorrect */ sprintf( buf, "%.2f ", trans->share_price );
newData[row][7] = XtNewString(""); newData[row][PRIC_CELL_C] = XtNewString(buf);
newData[row+1][7] = XtNewString(""); newData[row+1][PRIC_CELL_C] = XtNewString("");
newData[row][8] = XtNewString(""); newData[row][SHRS_CELL_C] = XtNewString("");
newData[row+1][8] = XtNewString(""); newData[row+1][SHRS_CELL_C] = XtNewString("");
break; break;
default: default:
fprintf( stderr, "Ineternal Error: Account type: %d is unknown!\n", regData->acc->type); fprintf( stderr, "Ineternal Error: Account type: %d is unknown!\n", regData->acc->type);
@ -309,22 +322,31 @@ regRecalculateBalance( RegWindow *regData )
int i; int i;
int position = 1; int position = 1;
double dbalance = 0.0; double dbalance = 0.0;
double share_balance = 0.0;
double dclearedBalance = 0.0; double dclearedBalance = 0.0;
double share_clearedBalance = 0.0;
char buf[BUFSIZE]; char buf[BUFSIZE];
Transaction *trans; Transaction *trans;
Account *acc;
Widget reg; Widget reg;
if( regData != NULL ) if( regData != NULL ) {
reg = regData->reg; reg = regData->reg;
else acc = regData->acc;
} else {
reg = NULL; reg = NULL;
acc = NULL;
}
for( i=0; (trans=getTransaction(regData->acc,i)) != NULL; i++ ) for( i=0; (trans=getTransaction(regData->acc,i)) != NULL; i++ )
{ {
dbalance += trans->damount; share_balance += trans->damount;
dbalance = trans -> share_price * share_balance;
if( trans->reconciled != NREC ) if( trans->reconciled != NREC ) {
dclearedBalance += trans->damount; share_clearedBalance += trans->damount;
dclearedBalance = trans->share_price * share_clearedBalance;
}
if( reg != NULL ) if( reg != NULL )
{ {
@ -336,13 +358,35 @@ regRecalculateBalance( RegWindow *regData )
/* Set the color of the text, depending on whether the /* Set the color of the text, depending on whether the
* balance is negative or positive */ * balance is negative or positive */
if( 0.0 > dbalance ) if( 0.0 > dbalance )
XbaeMatrixSetCellColor( reg, position, 6, negPixel ); XbaeMatrixSetCellColor( reg, position, BALN_CELL_C, negPixel );
else else
XbaeMatrixSetCellColor( reg, position, 6, posPixel ); XbaeMatrixSetCellColor( reg, position, BALN_CELL_C, posPixel );
#endif #endif
/* Put the value in the cell */ /* Put the value in the cell */
XbaeMatrixSetCell( reg, position, 6, buf ); XbaeMatrixSetCell( reg, position, BALN_CELL_C, buf );
/* update share balances too ... */
if( (MUTUAL == acc->type) ||
(PORTFOLIO == acc->type) )
{
#ifdef USE_NO_COLOR
sprintf( buf, "%.2f ", share_balance );
#else
sprintf( buf, "%.2f ", DABS(share_balance) );
/* Set the color of the text, depending on whether the
* balance is negative or positive */
if( 0.0 > share_balance )
XbaeMatrixSetCellColor( reg, position, SHRS_CELL_C, negPixel );
else
XbaeMatrixSetCellColor( reg, position, SHRS_CELL_C, posPixel );
}
#endif
/* Put the value in the cell */
XbaeMatrixSetCell( reg, position, SHRS_CELL_C, buf );
position+=2; /* each transaction has two rows */ position+=2; /* each transaction has two rows */
} }
} }
@ -410,6 +454,7 @@ regSaveTransaction( RegWindow *regData, int position )
trans->catagory = 0; trans->catagory = 0;
trans->reconciled = NREC; trans->reconciled = NREC;
trans->damount = 0.0; trans->damount = 0.0;
trans->share_price = 1.0;
regData->changed = MOD_ALL; regData->changed = MOD_ALL;
} }
@ -418,7 +463,7 @@ regSaveTransaction( RegWindow *regData, int position )
DEBUG("MOD_NUM"); DEBUG("MOD_NUM");
/* ...the transaction number (String)... */ /* ...the transaction number (String)... */
XtFree( trans->num ); XtFree( trans->num );
trans->num = XtNewString( XbaeMatrixGetCell(regData->reg,row,1) ); trans->num = XtNewString( XbaeMatrixGetCell(regData->reg,row,NUM_CELL_C) );
} }
if( regData->changed & MOD_DESC ) if( regData->changed & MOD_DESC )
@ -427,7 +472,7 @@ regSaveTransaction( RegWindow *regData, int position )
/* ... the description... */ /* ... the description... */
XtFree( trans->description ); XtFree( trans->description );
trans->description = trans->description =
XtNewString( XbaeMatrixGetCell(regData->reg,row,2) ); XtNewString( XbaeMatrixGetCell(regData->reg,row,DESC_CELL_C) );
} }
if( regData->changed & MOD_MEMO ) if( regData->changed & MOD_MEMO )
@ -435,14 +480,14 @@ regSaveTransaction( RegWindow *regData, int position )
DEBUG("MOD_MEMO"); DEBUG("MOD_MEMO");
/* ... the memo ... */ /* ... the memo ... */
XtFree( trans->memo ); XtFree( trans->memo );
trans->memo = XtNewString( XbaeMatrixGetCell(regData->reg,row+1,2) ); trans->memo = XtNewString( XbaeMatrixGetCell(regData->reg,row+1,MEMO_CELL_C) );
} }
if( regData->changed & MOD_RECN ) if( regData->changed & MOD_RECN )
{ {
DEBUG("MOD_RECN"); DEBUG("MOD_RECN");
/* ...the reconciled flag (char)... */ /* ...the reconciled flag (char)... */
trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,3))[0]; trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,RECN_CELL_C))[0];
/* Remember, we need to recalculate the reconciled balance now! */ /* Remember, we need to recalculate the reconciled balance now! */
regRecalculateBalance(regData); regRecalculateBalance(regData);
@ -451,35 +496,57 @@ regSaveTransaction( RegWindow *regData, int position )
if( regData->changed & MOD_AMNT ) if( regData->changed & MOD_AMNT )
{ {
String amount; String amount;
int dollar=0,cent=0; float val=0.0; /* must be float for sscanf to work */
DEBUG("MOD_AMNT"); DEBUG("MOD_AMNT");
/* ...and the amounts */ /* ...and the amounts */
amount = XbaeMatrixGetCell(regData->reg,row,5); amount = XbaeMatrixGetCell(regData->reg,row,DEP_CELL_C);
sscanf( amount, "%d.%2d", &dollar, &cent ); sscanf( amount, "%f", &val );
trans->damount = ((double) dollar) + 0.01 * ((double) cent); trans->damount = val;
dollar = 0; cent = 0; val = 0.0;
amount = XbaeMatrixGetCell(regData->reg,row,4); amount = XbaeMatrixGetCell(regData->reg,row,PAY_CELL_C);
sscanf( amount, "%d.%2d", &dollar, &cent ); sscanf( amount, "%f", &val );
trans->damount -= ((double) dollar) + 0.01 * ((double) cent); trans->damount -= val;
/* Reset so there is only one field filled */ /* Reset so there is only one field filled */
if( 0.0 > trans->damount ) if( 0.0 > trans->damount )
{ {
/* hack alert -- keep 3 digits for share amounts */
sprintf( buf, "%.2f ", (-1.0*(trans->damount)) ); sprintf( buf, "%.2f ", (-1.0*(trans->damount)) );
XbaeMatrixSetCell( regData->reg, row, 4, buf ); XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, buf );
XbaeMatrixSetCell( regData->reg, row, 5, "" ); XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, "" );
} }
else else
{ {
sprintf( buf, "%.2f ", (trans->damount) ); sprintf( buf, "%.2f ", (trans->damount) );
XbaeMatrixSetCell( regData->reg, row, 4, "" ); XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, "" );
XbaeMatrixSetCell( regData->reg, row, 5, buf ); XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, buf );
} }
regRecalculateBalance(regData); regRecalculateBalance(regData);
} }
if( regData->changed & MOD_PRIC )
{
String price;
float val=0.0; /* must be float for sscanf to work */
DEBUG("MOD_PRIC");
/* ...the price flag ... */
trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,PRIC_CELL_C))[0];
price = XbaeMatrixGetCell(regData->reg,row,PRIC_CELL_C);
sscanf( price, "%f", &val );
trans->share_price = val;
printf ("got share price %f \n", val);
sprintf( buf, "%.2f ", trans->share_price );
XbaeMatrixSetCell( regData->reg, row, PRIC_CELL_C, buf );
/* Remember, we need to recalculate the reconciled balance now! */
regRecalculateBalance(regData);
}
/* Before we check the date, and possibly insert the new /* Before we check the date, and possibly insert the new
* transaction, we need to make sure that, if this is a * transaction, we need to make sure that, if this is a
* new transaction, that the user actually entered some * new transaction, that the user actually entered some
@ -490,6 +557,7 @@ regSaveTransaction( RegWindow *regData, int position )
(strcmp("",trans->description) == 0) && (strcmp("",trans->description) == 0) &&
(strcmp("",trans->memo) == 0) && (strcmp("",trans->memo) == 0) &&
(0 == trans->catagory) && (0 == trans->catagory) &&
(1.0 == trans->share_price) &&
(0.0 == trans->damount) ) (0.0 == trans->damount) )
{ {
_free(trans); _free(trans);
@ -512,7 +580,7 @@ regSaveTransaction( RegWindow *regData, int position )
DEBUG("MOD_DATE"); DEBUG("MOD_DATE");
/* read in the date stuff... */ /* read in the date stuff... */
sscanf( XbaeMatrixGetCell(regData->reg,row,0),"%d/%d", sscanf( XbaeMatrixGetCell(regData->reg,row,DATE_CELL_C),"%d/%d",
&(trans->date.month), &(trans->date.month),
&(trans->date.day) ); &(trans->date.day) );
@ -743,9 +811,9 @@ regWindow( Widget parent, Account *acc )
break; break;
case PORTFOLIO: case PORTFOLIO:
case MUTUAL: case MUTUAL:
acc -> colWidths[6] = 8; /* price */ acc -> colWidths[PRIC_CELL_C] = 8; /* price */
acc -> colWidths[7] = 8; /* share balance */ acc -> colWidths[SHRS_CELL_C] = 8; /* share balance */
acc -> colWidths[8] = 8; /* $ balance */ acc -> colWidths[BALN_CELL_C] = 8; /* $ balance */
break; break;
} }
@ -771,9 +839,9 @@ regWindow( Widget parent, Account *acc )
case PORTFOLIO: case PORTFOLIO:
case MUTUAL: case MUTUAL:
acc -> alignments[6] = XmALIGNMENT_END; /* price */ acc -> alignments[PRIC_CELL_C] = XmALIGNMENT_END; /* price */
acc -> alignments[7] = XmALIGNMENT_END; /* share balance */ acc -> alignments[SHRS_CELL_C] = XmALIGNMENT_END; /* share balance */
acc -> alignments[8] = XmALIGNMENT_END; /* $balance */ acc -> alignments[BALN_CELL_C] = XmALIGNMENT_END; /* $balance */
break; break;
} }
@ -799,9 +867,9 @@ regWindow( Widget parent, Account *acc )
break; break;
case PORTFOLIO: case PORTFOLIO:
case MUTUAL: case MUTUAL:
acc -> rows[0][6] = "Price"; acc -> rows[0][PRIC_CELL_C] = "Price";
acc -> rows[0][7] = "Tot Shrs"; acc -> rows[0][SHRS_CELL_C] = "Tot Shrs";
acc -> rows[0][8] = "Balance"; acc -> rows[0][BALN_CELL_C] = "Balance";
break; break;
} }
@ -829,8 +897,8 @@ regWindow( Widget parent, Account *acc )
break; break;
case PORTFOLIO: case PORTFOLIO:
case MUTUAL: case MUTUAL:
acc -> rows[0][PAY_CELL_C] = "Shares Bought"; acc -> rows[0][PAY_CELL_C] = "Sold";
acc -> rows[0][DEP_CELL_C] = "Shares Sold"; acc -> rows[0][DEP_CELL_C] = "Bought";
break; break;
} }
@ -1072,7 +1140,7 @@ deleteCB( Widget mw, XtPointer cd, XtPointer cb )
if( verifyBox( toplevel, msg ) ) if( verifyBox( toplevel, msg ) )
{ {
Transaction *trans; Transaction *trans;
int row = (2*acc->regData->lastTrans) + 1; int row = (2*regData->lastTrans) + 1;
/* remove the transaction */ /* remove the transaction */
trans = removeTransaction( acc, regData->lastTrans ); trans = removeTransaction( acc, regData->lastTrans );
@ -1161,6 +1229,8 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
if( !IN_DATE_CELL(row,col) && !IN_NUM_CELL(row,col) && if( !IN_DATE_CELL(row,col) && !IN_NUM_CELL(row,col) &&
!IN_DESC_CELL(row,col) && !IN_PAY_CELL(row,col) && !IN_DESC_CELL(row,col) && !IN_PAY_CELL(row,col) &&
!IN_RECN_CELL(row,col) && !IN_DEP_CELL(row,col) && !IN_RECN_CELL(row,col) && !IN_DEP_CELL(row,col) &&
!((PORTFOLIO == acc->type) && IN_PRIC_CELL(row,col)) &&
!((MUTUAL == acc->type) && IN_PRIC_CELL(row,col)) &&
!IN_MEMO_CELL(row,col) ) !IN_MEMO_CELL(row,col) )
{ {
((XbaeMatrixEnterCellCallbackStruct *)cbs)->doit = FALSE; ((XbaeMatrixEnterCellCallbackStruct *)cbs)->doit = FALSE;
@ -1173,19 +1243,19 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
((XbaeMatrixEnterCellCallbackStruct *)cbs)->map = FALSE; ((XbaeMatrixEnterCellCallbackStruct *)cbs)->map = FALSE;
XtVaGetValues( mw, XmNcells, &data, NULL ); XtVaGetValues( mw, XmNcells, &data, NULL );
DEBUGCMD(printf("data[%d][3] = %s\n", row, data[row][3])); DEBUGCMD(printf("data[%d][RECN_CELL_C] = %s\n", row, data[row][RECN_CELL_C]));
if( data[row][3][0] == NREC ) if( data[row][RECN_CELL_C][0] == NREC )
data[row][3][0] = CREC; data[row][RECN_CELL_C][0] = CREC;
else else
data[row][3][0] = NREC; data[row][RECN_CELL_C][0] = NREC;
/* this cell has been modified, so we need to save when we /* this cell has been modified, so we need to save when we
* leave!!! */ * leave!!! */
regData->changed |= MOD_RECN; regData->changed |= MOD_RECN;
XtVaSetValues( mw, XmNcells, data, NULL ); XtVaSetValues( mw, XmNcells, data, NULL );
XbaeMatrixRefreshCell( mw, row, 3 ); XbaeMatrixRefreshCell( mw, row, RECN_CELL_C);
} }
break; break;
case XbaeModifyVerifyReason: case XbaeModifyVerifyReason:
@ -1286,7 +1356,12 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
if( IN_DATE_CELL(row,col) ) if( IN_DATE_CELL(row,col) )
dateCellFormat( mw, mvcbs ); /* format according to date dateCellFormat( mw, mvcbs ); /* format according to date
* cell rules */ * cell rules */
if( IN_PAY_CELL(row,col) || IN_DEP_CELL(row,col) )
/* look to see if numeric format is OK. Note that
* the share price cell exists only for certain account types */
if( IN_PAY_CELL(row,col) || IN_DEP_CELL(row,col) ||
((PORTFOLIO == acc->type) && IN_PRIC_CELL(row,col)) ||
((MUTUAL == acc->type) && IN_PRIC_CELL(row,col)) )
{ {
/* text pointer is NULL if non-alpha key hit */ /* text pointer is NULL if non-alpha key hit */
/* for example, the delete key */ /* for example, the delete key */
@ -1332,6 +1407,10 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
if( IN_PAY_CELL(row,col) || IN_DEP_CELL(row,col) ) if( IN_PAY_CELL(row,col) || IN_DEP_CELL(row,col) )
regData->changed |= MOD_AMNT; regData->changed |= MOD_AMNT;
if( ((PORTFOLIO == acc->type) && IN_PRIC_CELL(row,col)) ||
((MUTUAL == acc->type) && IN_PRIC_CELL(row,col)) )
regData->changed |= MOD_PRIC;
if( IN_MEMO_CELL(row,col) ) if( IN_MEMO_CELL(row,col) )
regData->changed |= MOD_MEMO; regData->changed |= MOD_MEMO;
@ -1552,8 +1631,8 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs )
count++; count++;
if( count >= 1 ) if( count >= 1 )
{ {
XbaeMatrixEditCell( mw, row+1, 0 ); XbaeMatrixEditCell( mw, row+1, DATE_CELL_C );
XbaeMatrixSelectCell( mw, row+1, 0 ); XbaeMatrixSelectCell( mw, row+1, DATE_CELL_C );
} }
} }
break; break;