mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-21 16:38:06 -06:00
more double-entry fixes and extensions
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
2dad05d314
commit
2f0e6918aa
4
Makefile
4
Makefile
@ -41,7 +41,9 @@ RANLIB = ranlib
|
||||
# USEDEBUG - causes debugging info to be displayed
|
||||
CFLAGS = $(LFLAGS) -I../include -I../libhtmlw -I/usr/X11/include \
|
||||
-I/usr/local/include -DMOTIF1_2 \
|
||||
-DDEBUGMEMORY -DUSEDEBUG
|
||||
|
||||
|
||||
# -DDEBUGMEMORY -DUSEDEBUG
|
||||
# -DUSEQUICKFILL # -DUSE_NO_COLOR -DDEBUGMEMORY -DUSEDEBUG
|
||||
LFLAGS = -g -L/usr/local/lib -L/usr/X11/lib
|
||||
LIBS = -lXm -lXmu -lXbae -lXt -lXext -lX11 -lSM -lICE -lXpm
|
||||
|
52
README
52
README
@ -39,18 +39,48 @@ 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.
|
||||
As of version 0.9f:
|
||||
---------------
|
||||
Mutual fund and Stock Portfolio handling
|
||||
is implemented, but is in alpha state: many features are
|
||||
missing, and others are broken. Transfers between funds and
|
||||
bank accounts are not properly supported. Also, tabbing between
|
||||
fields for mutual funds does not work correctly. One planned
|
||||
addition is an indication of the type of transaction (Buy,
|
||||
Cap Gain, Dividend Reinvest, etc.) But it is not clear when
|
||||
this will be added.
|
||||
|
||||
An alpha version of import from quicken files is also present,
|
||||
--------
|
||||
An alpha version of import from Quicken files is also present,
|
||||
but it is very broken, and many/most quicken formats are not
|
||||
supported.
|
||||
supported. It is not currently enabled in the code ... adventrous
|
||||
coders are encouraged to hack on this ...
|
||||
|
||||
An alpha-level double-entry system has been created. Its use
|
||||
is not currently forced. It is used only during transfers
|
||||
between accounts. It is not saved to file, or read from file.
|
||||
------------
|
||||
An beta-level double-entry system has been created.
|
||||
"Double-entry" is a form of accounting where all transactions
|
||||
show up in two accounts (for example, a transfer from
|
||||
a credit card(Diners Club) to a cash account(Entertainment Expense)
|
||||
will show up in both accounts. Modifying/deleting a transaction
|
||||
in one account window automatically modifies/deletes it in the
|
||||
other too.
|
||||
|
||||
The system does not force the use of double-entry: in fact,
|
||||
double entries are made ONLY when the "transfer" menu item is
|
||||
used.
|
||||
|
||||
A future extension to force the use of double-entry for an account
|
||||
is planned, as well as the ability to make transfers directly
|
||||
from the register(ledger) window. However, this function will
|
||||
be tricky, since it requires hacks on the Xbae widget used to
|
||||
display the register.
|
||||
|
||||
Double-entries should be correctly saved-to-file & restored
|
||||
from file.
|
||||
|
||||
-------------
|
||||
The "reports" menu item is unimplemented and will result in a core dump.
|
||||
-------------
|
||||
|
||||
That's all folks!
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
typedef struct _accwindow {
|
||||
String notes; /* The text from the "Notes" window */
|
||||
/* The account type buttons: */
|
||||
Widget dialog;
|
||||
Widget bank;
|
||||
Widget cash;
|
||||
Widget asset;
|
||||
@ -116,6 +117,7 @@ accWindow( Widget parent )
|
||||
|
||||
XtAddCallback( dialog, XmNdestroyCallback,
|
||||
closeAccWindow, (XtPointer)accData );
|
||||
accData->dialog = dialog;
|
||||
|
||||
/* The form to put everything in the dialog in */
|
||||
form = XtVaCreateWidget( "form", xmFormWidgetClass, dialog,
|
||||
@ -320,8 +322,10 @@ accWindow( Widget parent )
|
||||
XtAddCallback( widget, XmNactivateCallback,
|
||||
createCB, (XtPointer)accData );
|
||||
/* We need to do something to clean up memory too! */
|
||||
/* this is done at endo fo dialog.
|
||||
XtAddCallback( widget, XmNactivateCallback,
|
||||
destroyShellCB, (XtPointer)dialog );
|
||||
*/
|
||||
|
||||
XtManageChild(buttonform);
|
||||
|
||||
@ -585,13 +589,38 @@ createCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
Transaction *trans;
|
||||
Account *acc;
|
||||
AccWindow *accData = (AccWindow *)cd;
|
||||
|
||||
Boolean set = False;
|
||||
|
||||
String name = XmTextGetString(accData->name);
|
||||
String desc = XmTextGetString(accData->desc);
|
||||
|
||||
{
|
||||
/* since portfolio & mutual not fully implemented, provide warning */
|
||||
int warn = 0;
|
||||
XtVaGetValues( accData->portfolio, XmNset, &set, NULL );
|
||||
if(set) warn = 1;
|
||||
|
||||
XtVaGetValues( accData->mutual, XmNset, &set, NULL );
|
||||
if(set) warn = 1;
|
||||
|
||||
if (warn) {
|
||||
int do_it_anyway;
|
||||
do_it_anyway = verifyBox (toplevel,
|
||||
"Warning: Portfolio and Mutual Fund \n\
|
||||
Account types are not fully implemented. \n\
|
||||
You can play with the interface here, \n\
|
||||
but doing so may damage your data. \n\
|
||||
You have been warned! \n\
|
||||
Do you want to continue anyway?\n");
|
||||
if (!do_it_anyway) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* The account has to have a name! */
|
||||
if( strcmp( name, "" ) == 0 )
|
||||
if( strcmp( name, "" ) == 0 ) {
|
||||
errorBox (toplevel, "The account must be given a name! \n");
|
||||
return;
|
||||
}
|
||||
|
||||
acc = mallocAccount();
|
||||
acc->flags = 0;
|
||||
@ -600,37 +629,34 @@ createCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
acc->notes = accData->notes;
|
||||
|
||||
/* figure out account type */
|
||||
{
|
||||
Boolean set = False;
|
||||
|
||||
XtVaGetValues( accData->bank, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = BANK;
|
||||
|
||||
XtVaGetValues( accData->cash, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = CASH;
|
||||
|
||||
XtVaGetValues( accData->asset, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = ASSET;
|
||||
|
||||
XtVaGetValues( accData->credit, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = CREDIT;
|
||||
|
||||
XtVaGetValues( accData->liability, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = LIABILITY;
|
||||
|
||||
XtVaGetValues( accData->portfolio, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = PORTFOLIO;
|
||||
|
||||
XtVaGetValues( accData->mutual, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = MUTUAL;
|
||||
}
|
||||
XtVaGetValues( accData->bank, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = BANK;
|
||||
|
||||
XtVaGetValues( accData->cash, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = CASH;
|
||||
|
||||
XtVaGetValues( accData->asset, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = ASSET;
|
||||
|
||||
XtVaGetValues( accData->credit, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = CREDIT;
|
||||
|
||||
XtVaGetValues( accData->liability, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = LIABILITY;
|
||||
|
||||
XtVaGetValues( accData->portfolio, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = PORTFOLIO;
|
||||
|
||||
XtVaGetValues( accData->mutual, XmNset, &set, NULL );
|
||||
if(set)
|
||||
acc->type = MUTUAL;
|
||||
|
||||
/* Add an opening balance transaction (as the first transaction) */
|
||||
trans = mallocTransaction();
|
||||
@ -650,6 +676,9 @@ createCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
refreshMainWindow();
|
||||
/* open up the account window for the user */
|
||||
regWindow( toplevel, acc );
|
||||
|
||||
/* if we got to here, tear down the dialog window */
|
||||
XtDestroyWidget (accData->dialog);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
214
src/Account.c
214
src/Account.c
@ -30,6 +30,7 @@
|
||||
#include "date.h"
|
||||
|
||||
extern Data *data;
|
||||
int next_free_unique_account_id = 0;
|
||||
|
||||
/********************************************************************\
|
||||
* Because I can't use C++ for this project, doesn't mean that I *
|
||||
@ -45,6 +46,13 @@ mallocAccount( void )
|
||||
{
|
||||
Account *acc = (Account *)_malloc(sizeof(Account));
|
||||
|
||||
acc->id = next_free_unique_account_id;
|
||||
next_free_unique_account_id ++;
|
||||
|
||||
acc->data = NULL;
|
||||
acc->balance = 0.0;
|
||||
acc->cleared_balance = 0.0;
|
||||
|
||||
acc->flags = 0;
|
||||
acc->type = 0;
|
||||
|
||||
@ -104,13 +112,10 @@ freeAccount( Account *acc )
|
||||
Transaction *
|
||||
getTransaction( Account *acc, int num )
|
||||
{
|
||||
if( acc != NULL )
|
||||
{
|
||||
if( (0 <= num) && (num < acc->numTrans) )
|
||||
return acc->transaction[num];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
if( NULL == acc ) return NULL;
|
||||
|
||||
if( (num >= 0) && (num < acc->numTrans) )
|
||||
return acc->transaction[num];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -194,7 +199,7 @@ insertTransaction( Account *acc, Transaction *trans )
|
||||
/* If this appears to be a new transaction, then default
|
||||
* it to being a credit. If this transaction is already
|
||||
* in another account, assume this is the other half.
|
||||
* This algoriothm is not robust against internal programming
|
||||
* This algorithm is not robust against internal programming
|
||||
* errors ... various bizarre situations can sneak by without
|
||||
* warning ... however, this will do for now.
|
||||
*/
|
||||
@ -272,6 +277,8 @@ insertTransaction( Account *acc, Transaction *trans )
|
||||
double xaccGetAmount (Account *acc, Transaction *trans)
|
||||
{
|
||||
double themount; /* amount */
|
||||
if (NULL == trans) return 0.0;
|
||||
if (NULL == acc) return 0.0;
|
||||
|
||||
/* for a double-entry, determine if this is a credit or a debit */
|
||||
if ( trans->credit == ((struct _account *) acc) ) {
|
||||
@ -305,4 +312,193 @@ void xaccSetAmount (Account *acc, Transaction *trans, double themount)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------- end of file --------------- */
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
double xaccGetBalance (Account *acc, Transaction *trans)
|
||||
{
|
||||
double themount; /* amount */
|
||||
|
||||
/* for a double-entry, determine if this is a credit or a debit */
|
||||
if ( trans->credit == ((struct _account *) acc) ) {
|
||||
themount = trans->credit_balance;
|
||||
} else
|
||||
if ( trans->debit == ((struct _account *) acc) ) {
|
||||
themount = trans->debit_balance;
|
||||
} else {
|
||||
printf ("Internal Error: xaccGetBalance: missing double entry \n");
|
||||
printf ("this error should not occur. Please report the problem. \n");
|
||||
themount = 0.0; /* punt */
|
||||
}
|
||||
return themount;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
double xaccGetClearedBalance (Account *acc, Transaction *trans)
|
||||
{
|
||||
double themount; /* amount */
|
||||
|
||||
/* for a double-entry, determine if this is a credit or a debit */
|
||||
if ( trans->credit == ((struct _account *) acc) ) {
|
||||
themount = trans->credit_cleared_balance;
|
||||
} else
|
||||
if ( trans->debit == ((struct _account *) acc) ) {
|
||||
themount = trans->debit_cleared_balance;
|
||||
} else {
|
||||
printf ("Internal Error: xaccGetClearedBalance: missing double entry \n");
|
||||
printf ("this error should not occur. Please report the problem. \n");
|
||||
themount = 0.0; /* punt */
|
||||
}
|
||||
return themount;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
double xaccGetShareBalance (Account *acc, Transaction *trans)
|
||||
{
|
||||
double themount; /* amount */
|
||||
|
||||
/* for a double-entry, determine if this is a credit or a debit */
|
||||
if ( trans->credit == ((struct _account *) acc) ) {
|
||||
themount = trans->credit_share_balance;
|
||||
} else
|
||||
if ( trans->debit == ((struct _account *) acc) ) {
|
||||
themount = trans->debit_share_balance;
|
||||
} else {
|
||||
printf ("Internal Error: xaccGetShareBalance: missing double entry \n");
|
||||
printf ("this error should not occur. Please report the problem. \n");
|
||||
themount = 0.0; /* punt */
|
||||
}
|
||||
return themount;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* xaccRecomputeBalance *
|
||||
* recomputes the partial balances and the current balance for *
|
||||
* this account. *
|
||||
|
||||
The current balance is always the current share balance times the
|
||||
current share price. The share price for bank accounts is always 1.0,
|
||||
so, for bank acccounts, the current balance is always equal to the current
|
||||
share balance.
|
||||
* *
|
||||
* Args: account -- the account for which to recompute balances *
|
||||
* Return: void *
|
||||
\********************************************************************/
|
||||
void
|
||||
xaccRecomputeBalance( Account * acc )
|
||||
{
|
||||
int i;
|
||||
double dbalance = 0.0;
|
||||
double dcleared_balance = 0.0;
|
||||
Transaction *trans;
|
||||
|
||||
if( NULL == acc ) return;
|
||||
|
||||
for( i=0; (trans=getTransaction(acc,i)) != NULL; i++ ) {
|
||||
dbalance += xaccGetAmount (acc, trans);
|
||||
|
||||
if( trans->reconciled != NREC ) {
|
||||
dcleared_balance += xaccGetAmount (acc, trans);
|
||||
}
|
||||
|
||||
if (acc == (Account *) trans->credit) {
|
||||
trans -> credit_share_balance = dbalance;
|
||||
trans -> credit_share_cleared_balance = dcleared_balance;
|
||||
trans -> credit_balance = trans->share_price * dbalance;
|
||||
trans -> credit_cleared_balance = trans->share_price * dcleared_balance;
|
||||
}
|
||||
if (acc == (Account *) trans->debit) {
|
||||
trans -> debit_share_balance = dbalance;
|
||||
trans -> debit_share_cleared_balance = dcleared_balance;
|
||||
trans -> debit_balance = trans->share_price * dbalance;
|
||||
trans -> debit_cleared_balance = trans->share_price * dcleared_balance;
|
||||
}
|
||||
}
|
||||
|
||||
acc -> balance = dbalance;
|
||||
acc -> cleared_balance = dcleared_balance;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* xaccCheckDateOrder *
|
||||
* check this transaction to see if the date is in correct order *
|
||||
* If it is not, reorder the transactions ... *
|
||||
* *
|
||||
* Args: acc -- the account to check *
|
||||
* trans -- the transaction to check *
|
||||
*
|
||||
* Return: int -- non-zero if out of order *
|
||||
\********************************************************************/
|
||||
int
|
||||
xaccCheckDateOrder (Account * acc, Transaction *trans )
|
||||
{
|
||||
int outOfOrder = 0;
|
||||
Transaction *prevTrans;
|
||||
Transaction *nextTrans;
|
||||
int position;
|
||||
|
||||
if (NULL == acc) return 0;
|
||||
|
||||
position = getNumOfTransaction (acc, trans);
|
||||
|
||||
/* if transaction not present in the account, its because
|
||||
* it hasn't been inserted yet. Insert it now. */
|
||||
if (-1 == position) {
|
||||
insertTransaction( acc, trans );
|
||||
return 1;
|
||||
}
|
||||
|
||||
prevTrans = getTransaction( acc, position-1 );
|
||||
nextTrans = getTransaction( acc, position+1 );
|
||||
|
||||
/* figure out if the transactions are out of order */
|
||||
if (NULL != prevTrans) {
|
||||
if( datecmp(&(prevTrans->date),&(trans->date))>0 ) outOfOrder = True;
|
||||
}
|
||||
if (NULL != nextTrans) {
|
||||
if( datecmp(&(trans->date),&(nextTrans->date))>0 ) outOfOrder = True;
|
||||
}
|
||||
|
||||
/* take care of re-ordering, if necessary */
|
||||
if( outOfOrder ) {
|
||||
removeTransaction( acc, position );
|
||||
insertTransaction( acc, trans );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* xaccCheckDateOrderDE *
|
||||
* check this transaction to see if the date is in correct order *
|
||||
* If it is not, reorder the transactions ... *
|
||||
* This routine perfroms the check for both of the double-entry *
|
||||
* transaction entries ... *
|
||||
* *
|
||||
* Args: trans -- the transaction to check *
|
||||
* Return: int -- non-zero if out of order *
|
||||
\********************************************************************/
|
||||
int
|
||||
xaccCheckDateOrderDE (Transaction *trans )
|
||||
{
|
||||
Account * acc;
|
||||
int outOfOrder = 0;
|
||||
|
||||
if (NULL == trans) return 0;
|
||||
|
||||
acc = (Account *) (trans->credit);
|
||||
outOfOrder += xaccCheckDateOrder (acc, trans);
|
||||
acc = (Account *) (trans->debit);
|
||||
outOfOrder += xaccCheckDateOrder (acc, trans);
|
||||
|
||||
if (outOfOrder) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************** end of file **************************** */
|
||||
|
63
src/Data.c
63
src/Data.c
@ -1,6 +1,7 @@
|
||||
/********************************************************************\
|
||||
* Data.c -- the main data structure of the program *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -83,6 +84,30 @@ getAccount( Data *data, int num )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* Fetch an account, given only it's ID number *
|
||||
\********************************************************************/
|
||||
|
||||
Account *
|
||||
xaccGetPeerAccountFromID ( Account *acc, int acc_id )
|
||||
{
|
||||
Data * data;
|
||||
Account *peer_acc;
|
||||
int i;
|
||||
|
||||
if (NULL == acc) return NULL;
|
||||
if (-1 >= acc_id) return NULL;
|
||||
|
||||
data = (Data *) acc->data;
|
||||
|
||||
for (i=0; i<data->numAcc; i++) {
|
||||
peer_acc = data->account[i];
|
||||
if (acc_id == peer_acc->id) return peer_acc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
Account *
|
||||
@ -124,26 +149,30 @@ int
|
||||
insertAccount( Data *data, Account *acc )
|
||||
{
|
||||
int i=-1;
|
||||
Account **oldAcc;
|
||||
|
||||
if( data != NULL )
|
||||
{
|
||||
Account **oldAcc = data->account;
|
||||
if (NULL == data) return -1;
|
||||
if (NULL == acc) return -1;
|
||||
|
||||
/* set back-pointer to the accounts parent */
|
||||
acc->data = (struct _data *) data;
|
||||
|
||||
oldAcc = data->account;
|
||||
|
||||
data->saved = False;
|
||||
|
||||
data->numAcc++;
|
||||
data->account = (Account **)_malloc((data->numAcc)*sizeof(Account *));
|
||||
|
||||
for( i=0; i<(data->numAcc-1); i++ )
|
||||
data->account[i] = oldAcc[i];
|
||||
|
||||
data->account[i] = acc;
|
||||
|
||||
_free(oldAcc);
|
||||
}
|
||||
data->saved = False;
|
||||
|
||||
data->numAcc++;
|
||||
data->account = (Account **)_malloc((data->numAcc)*sizeof(Account *));
|
||||
|
||||
for( i=0; i<(data->numAcc-1); i++ )
|
||||
data->account[i] = oldAcc[i];
|
||||
|
||||
data->account[i] = acc;
|
||||
|
||||
_free(oldAcc);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************** END OF FILE *************************************/
|
||||
|
317
src/FileIO.c
317
src/FileIO.c
@ -2,6 +2,7 @@
|
||||
* FileIO.c -- read from and writing to a datafile for xacc *
|
||||
* (X-Accountant) *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -27,12 +28,17 @@
|
||||
* position in the file, and so the order which these *
|
||||
* functions are called in important *
|
||||
* *
|
||||
* Version 2 of the file format supports reading and writing of *
|
||||
* double-entry transactions. *
|
||||
* *
|
||||
* *
|
||||
* the format of the data in the file: *
|
||||
* file ::== token numAccounts (Account)^numAccounts *
|
||||
* Account ::== flags type accountName description notes *
|
||||
* Account ::== num flags type accountName description notes *
|
||||
* numTran (Transaction)^numTrans *
|
||||
* Transaction ::== num date description memo catagory reconciled *
|
||||
* amount *
|
||||
* amount share_price *
|
||||
* credit_account debit_account *
|
||||
* token ::== int [the version of file format == VERSION] *
|
||||
* numTrans ::== int *
|
||||
* numAccounts ::== int *
|
||||
@ -41,13 +47,17 @@
|
||||
* accountName ::== String *
|
||||
* description ::== String *
|
||||
* notes ::== String *
|
||||
* *
|
||||
* num ::== String *
|
||||
* date ::== Date *
|
||||
* description ::== String *
|
||||
* memo ::== String *
|
||||
* catagory ::== int *
|
||||
* reconciled ::== char *
|
||||
* amount ::== int *
|
||||
* amount ::== double *
|
||||
* share_price ::== double *
|
||||
* credit_account ::= int *
|
||||
* debit_account ::= int *
|
||||
* String ::== size (char)^size *
|
||||
* size ::== int *
|
||||
* Date ::== year month day *
|
||||
@ -66,14 +76,14 @@
|
||||
#define PERMS 0666
|
||||
#define WFLAGS (O_WRONLY | O_CREAT | O_TRUNC)
|
||||
#define RFLAGS O_RDONLY
|
||||
#define VERSION 1
|
||||
#define VERSION 2
|
||||
|
||||
/** GLOBALS *********************************************************/
|
||||
extern Widget toplevel;
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
Account *readAccount( int fd, int token );
|
||||
Transaction *readTransaction( int fd, int token );
|
||||
int readAccount( int fd, Account *, int token );
|
||||
Transaction *readTransaction( int fd, Account *, int token );
|
||||
char *readString( int fd, int token );
|
||||
Date *readDate( int fd, int token );
|
||||
|
||||
@ -184,19 +194,26 @@ readData( char *datafile )
|
||||
}
|
||||
XACC_FLIP_INT (numAcc);
|
||||
|
||||
/* malloc the accounts, in preparation for reading.
|
||||
* Mmalloc all of them; they will be needed for up front
|
||||
* for inserting the double-entry transactions */
|
||||
for( i=0; i<numAcc; i++ )
|
||||
{
|
||||
Account *acc = mallocAccount();
|
||||
insertAccount( data, acc );
|
||||
}
|
||||
|
||||
/* read in the accounts */
|
||||
for( i=0; i<numAcc; i++ )
|
||||
{
|
||||
Account *acc;
|
||||
acc = readAccount( fd, token );
|
||||
if( acc == NULL )
|
||||
Account *acc = getAccount (data, i);
|
||||
err = readAccount( fd, acc, token );
|
||||
if( -1 == err )
|
||||
{
|
||||
close(fd);
|
||||
printf(" numAcc = %d\n i = %d\n",numAcc,i);
|
||||
printf(" numAcc = %d, i = %d\n",numAcc,i);
|
||||
return data;
|
||||
}
|
||||
else
|
||||
insertAccount( data, acc );
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@ -208,57 +225,78 @@ readData( char *datafile )
|
||||
* reads in the data for an account from the datafile *
|
||||
* *
|
||||
* Args: fd - the filedescriptor of the data file *
|
||||
* acc - the account structure to be filled in *
|
||||
* token - the datafile version *
|
||||
* Return: the account structure *
|
||||
* Return: error value, 0 if OK, else -1 *
|
||||
\********************************************************************/
|
||||
Account *
|
||||
readAccount( int fd, int token )
|
||||
int
|
||||
readAccount( int fd, Account *acc, int token )
|
||||
{
|
||||
int err=0;
|
||||
int i;
|
||||
int numTrans;
|
||||
Account *acc = mallocAccount();
|
||||
int numTrans, nacc;
|
||||
|
||||
ENTER ("readAccount");
|
||||
|
||||
/* version 1 does not store the account number */
|
||||
if (1 < token) {
|
||||
err = read( fd, &nacc, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return -1;
|
||||
}
|
||||
XACC_FLIP_INT (nacc);
|
||||
|
||||
/* normalize the account numbers -- positive-definite.
|
||||
* That is, the unique id must never decrease,
|
||||
* nor must it overalp any existing account id */
|
||||
acc->id = nacc;
|
||||
if (next_free_unique_account_id <= nacc) {
|
||||
next_free_unique_account_id = nacc+1;
|
||||
}
|
||||
}
|
||||
|
||||
err = read( fd, &(acc->flags), sizeof(char) );
|
||||
if( err != sizeof(char) )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = read( fd, &(acc->type), sizeof(char) );
|
||||
if( err != sizeof(char) )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
acc->accountName = readString( fd, token );
|
||||
if( acc->accountName == NULL )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
acc->description = readString( fd, token );
|
||||
if( acc->description == NULL )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
acc->notes = readString( fd, token );
|
||||
if( acc->notes == NULL )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = read( fd, &numTrans, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
freeAccount(acc);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
XACC_FLIP_INT (numTrans);
|
||||
|
||||
@ -266,17 +304,16 @@ readAccount( int fd, int token )
|
||||
for( i=0; i<numTrans; i++ )
|
||||
{
|
||||
Transaction *trans;
|
||||
trans = readTransaction( fd, token );
|
||||
trans = readTransaction( fd, acc, token );
|
||||
if( trans == NULL )
|
||||
{
|
||||
printf(" numTrans = %d\n i = %d\n",numTrans,i);
|
||||
return acc;
|
||||
printf("Error: readAccount: Premature termination: \n");
|
||||
printf (" numTrans = %d i = %d\n",numTrans,i);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
insertTransaction( acc, trans );
|
||||
}
|
||||
|
||||
return acc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -288,16 +325,19 @@ readAccount( int fd, int token )
|
||||
* Return: the transaction structure *
|
||||
\********************************************************************/
|
||||
Transaction *
|
||||
readTransaction( int fd, int token )
|
||||
readTransaction( int fd, Account *acc, int token )
|
||||
{
|
||||
int err=0;
|
||||
int acc_id;
|
||||
Date *date;
|
||||
Transaction *trans = mallocTransaction();
|
||||
int amount;
|
||||
|
||||
ENTER ("readTransaction");
|
||||
|
||||
trans->num = readString( fd, token );
|
||||
if( trans->num == NULL )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at num");
|
||||
_free(trans);
|
||||
return NULL;
|
||||
}
|
||||
@ -305,6 +345,7 @@ readTransaction( int fd, int token )
|
||||
date = readDate( fd, token );
|
||||
if( date == NULL )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at date");
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
@ -315,6 +356,7 @@ readTransaction( int fd, int token )
|
||||
trans->description = readString( fd, token );
|
||||
if( trans->description == NULL )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at description");
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
@ -323,6 +365,7 @@ readTransaction( int fd, int token )
|
||||
trans->memo = readString( fd, token );
|
||||
if( trans->memo == NULL )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at memo");
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
@ -332,6 +375,7 @@ readTransaction( int fd, int token )
|
||||
err = read( fd, &(trans->catagory), sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at category");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
@ -343,6 +387,7 @@ readTransaction( int fd, int token )
|
||||
err = read( fd, &(trans->reconciled), sizeof(char) );
|
||||
if( err != sizeof(char) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at reconciled");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
@ -353,7 +398,8 @@ readTransaction( int fd, int token )
|
||||
/* What used to be reconciled, is now cleared... transactions
|
||||
* aren't reconciled until you get your bank statement, and
|
||||
* use the reconcile window to mark the transaction reconciled */
|
||||
if( token == 0 )
|
||||
/* hack alert -- ?????????? I don't get it ???????????? */
|
||||
if( 0 <= token )
|
||||
if( trans->reconciled == YREC )
|
||||
trans->reconciled = CREC;
|
||||
|
||||
@ -364,17 +410,99 @@ readTransaction( int fd, int token )
|
||||
if( (trans->reconciled != YREC) && (trans->reconciled != CREC) )
|
||||
trans->reconciled = NREC;
|
||||
|
||||
err = read( fd, &amount, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
}
|
||||
XACC_FLIP_INT (amount);
|
||||
trans->damount = 0.01 * ((double) amount); /* file stores pennies */
|
||||
if (1 == token) {
|
||||
int amount;
|
||||
/* version 1 files stored the amount as an integer,
|
||||
* with the amount recorded as pennies */
|
||||
err = read( fd, &amount, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at V1 amount");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
}
|
||||
XACC_FLIP_INT (amount);
|
||||
trans->damount = 0.01 * ((double) amount); /* file stores pennies */
|
||||
} else {
|
||||
double damount;
|
||||
|
||||
/* first, read number of shares ... */
|
||||
err = read( fd, &damount, sizeof(double) );
|
||||
if( err != sizeof(double) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at amount");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
}
|
||||
trans->damount = damount;
|
||||
|
||||
/* ... next read the share price ... */
|
||||
err = read( fd, &damount, sizeof(double) );
|
||||
if( err != sizeof(double) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at share_price");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
_free(trans);
|
||||
return NULL;
|
||||
}
|
||||
trans->share_price = damount;
|
||||
}
|
||||
DEBUGCMD(printf ("Info: readTransaction(): amount %f \n", trans->damount));
|
||||
|
||||
/* read the account numbers for double-entry */
|
||||
/* these are first used in version 2 of the file format */
|
||||
if (1 < token) {
|
||||
Account *peer_acc;
|
||||
/* first, read the credit account number */
|
||||
err = read( fd, &acc_id, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at credit");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
return NULL;
|
||||
}
|
||||
XACC_FLIP_INT (acc_id);
|
||||
DEBUGCMD (printf ("Info: readTransaction(): credit %d\n", acc_id));
|
||||
peer_acc = xaccGetPeerAccountFromID (acc, acc_id);
|
||||
trans -> credit = (struct _account *) peer_acc;
|
||||
|
||||
/* insert the transaction into both the debit and
|
||||
* the credit accounts; first the credit ... */
|
||||
if (peer_acc) insertTransaction( peer_acc, trans );
|
||||
|
||||
/* next read the debit account number */
|
||||
err = read( fd, &acc_id, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
{
|
||||
DEBUG ("Error: Premature end of Transaction at debit");
|
||||
XtFree(trans->memo);
|
||||
XtFree(trans->description);
|
||||
XtFree(trans->num);
|
||||
return NULL;
|
||||
}
|
||||
XACC_FLIP_INT (acc_id);
|
||||
DEBUGCMD (printf ("Info: readTransaction(): debit %d\n", acc_id));
|
||||
peer_acc = xaccGetPeerAccountFromID (acc, acc_id);
|
||||
trans -> debit = (struct _account *) peer_acc;
|
||||
|
||||
/* insert the transaction into both the debit and
|
||||
* the credit accounts; next, the debit ... */
|
||||
if (peer_acc) insertTransaction( peer_acc, trans );
|
||||
} else {
|
||||
|
||||
/* version 1 files did not do double-entry */
|
||||
insertTransaction( acc, trans );
|
||||
}
|
||||
|
||||
return trans;
|
||||
}
|
||||
@ -403,7 +531,7 @@ readString( int fd, int token )
|
||||
err = read( fd, str, size );
|
||||
if( err != size )
|
||||
{
|
||||
printf( " size = %d\n err = %d\n str = %s\n", size, err, str );
|
||||
printf( "Error: readString: size = %d err = %d str = %s\n", size, err, str );
|
||||
_free(str);
|
||||
return NULL;
|
||||
}
|
||||
@ -471,6 +599,26 @@ writeData( char *datafile, Data *data )
|
||||
int token = VERSION; /* The file format version */
|
||||
int fd;
|
||||
|
||||
if (NULL == data) return -1;
|
||||
|
||||
/* first, zero out the write flag on all of the
|
||||
* transactions */
|
||||
numAcc = data ->numAcc;
|
||||
for( i=0; i<numAcc; i++ ) {
|
||||
int n=0;
|
||||
Account *acc;
|
||||
Transaction * trans;
|
||||
acc = getAccount (data,i) ;
|
||||
trans = getTransaction (acc, n);
|
||||
n++;
|
||||
while (trans) {
|
||||
trans->write_flag = 0;
|
||||
trans = getTransaction (acc, n);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
/* now, open the file and start writing */
|
||||
fd = open( datafile, WFLAGS, PERMS );
|
||||
if( fd == -1 )
|
||||
{
|
||||
@ -493,7 +641,7 @@ writeData( char *datafile, Data *data )
|
||||
if( err != sizeof(int) )
|
||||
return -1;
|
||||
|
||||
for( i=0; i<numAcc; i++ )
|
||||
for( i=0; i<data->numAcc; i++ )
|
||||
{
|
||||
err = writeAccount( fd, getAccount(data,i) );
|
||||
if( err == -1 )
|
||||
@ -518,7 +666,15 @@ writeAccount( int fd, Account *acc )
|
||||
Transaction *trans;
|
||||
int err=0;
|
||||
int i,numTrans, ntrans;
|
||||
int acc_id;
|
||||
|
||||
acc_id = acc->id;
|
||||
DEBUGCMD (printf ("Info: writeAccount: writing acct id %d %x \n", acc_id, acc));
|
||||
XACC_FLIP_INT (acc_id);
|
||||
err = write( fd, &acc_id, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
return -1;
|
||||
|
||||
err = write( fd, &(acc->flags), sizeof(char) );
|
||||
if( err != sizeof(char) )
|
||||
return -1;
|
||||
@ -539,25 +695,32 @@ writeAccount( int fd, Account *acc )
|
||||
if( err == -1 )
|
||||
return err;
|
||||
|
||||
/* figure out numTrans */
|
||||
for( numTrans = 0; getTransaction(acc,numTrans) != NULL; numTrans++ )
|
||||
{}
|
||||
|
||||
/* figure out numTrans -- it will be less than the total
|
||||
* number of transactions in this account, because some
|
||||
* of the double entry transactions will already have been
|
||||
* written. */
|
||||
numTrans = 0;
|
||||
i = 0;
|
||||
trans = getTransaction (acc, i);
|
||||
while (trans) {
|
||||
i++;
|
||||
if (0 == trans->write_flag) numTrans ++;
|
||||
trans = getTransaction (acc, i);
|
||||
}
|
||||
|
||||
ntrans = numTrans;
|
||||
XACC_FLIP_INT (ntrans);
|
||||
err = write( fd, &ntrans, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
return -1;
|
||||
|
||||
for( i=0; i<numTrans; i++ )
|
||||
{
|
||||
for( i=0; i<numTrans; i++ ) {
|
||||
err = writeTransaction( fd, acc, getTransaction(acc,i) );
|
||||
if( err == -1 )
|
||||
return err;
|
||||
}
|
||||
if( err == -1 ) return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* writeTransaction *
|
||||
@ -572,7 +735,15 @@ int
|
||||
writeTransaction( int fd, Account * acc, Transaction *trans )
|
||||
{
|
||||
int err=0;
|
||||
int tmp;
|
||||
int tmp, acc_id;
|
||||
double damount;
|
||||
Account *xfer_acc;
|
||||
|
||||
ENTER ("writeTransaction");
|
||||
/* if we've already written this transaction, don't write it again */
|
||||
/* that is, prevent double-entry transactions from being written twice */
|
||||
if (trans->write_flag) return 4;
|
||||
trans->write_flag = 1;
|
||||
|
||||
err = writeString( fd, trans->num );
|
||||
if( err == -1 )
|
||||
@ -600,9 +771,33 @@ writeTransaction( int fd, Account * acc, Transaction *trans )
|
||||
if( err != sizeof(char) )
|
||||
return -1;
|
||||
|
||||
tmp = (int) (100.0 * xaccGetAmount (acc, trans)); /* file stores pennies */
|
||||
XACC_FLIP_INT (tmp);
|
||||
err = write( fd, &tmp, sizeof(int) );
|
||||
damount = trans->damount;
|
||||
DEBUGCMD (printf ("Info: writeTransaction: amount=%f \n", damount));
|
||||
err = write( fd, &damount, sizeof(double) );
|
||||
if( err != sizeof(double) )
|
||||
return -1;
|
||||
|
||||
damount = trans->share_price;
|
||||
err = write( fd, &damount, sizeof(double) );
|
||||
if( err != sizeof(double) )
|
||||
return -1;
|
||||
|
||||
/* write the double-entry values */
|
||||
xfer_acc = (Account *) (trans->credit);
|
||||
acc_id = -1;
|
||||
if (xfer_acc) acc_id = xfer_acc -> id;
|
||||
DEBUGCMD (printf ("Info: writeTransaction: credit %d \n", acc_id));
|
||||
XACC_FLIP_INT (acc_id);
|
||||
err = write( fd, &acc_id, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
return -1;
|
||||
|
||||
xfer_acc = (Account *) (trans->debit);
|
||||
acc_id = -1;
|
||||
if (xfer_acc) acc_id = xfer_acc -> id;
|
||||
DEBUGCMD (printf ("Info: writeTransaction: debit %d \n", acc_id));
|
||||
XACC_FLIP_INT (acc_id);
|
||||
err = write( fd, &acc_id, sizeof(int) );
|
||||
if( err != sizeof(int) )
|
||||
return -1;
|
||||
|
||||
@ -623,6 +818,8 @@ writeString( int fd, char *str )
|
||||
int err=0;
|
||||
int size;
|
||||
int tmp;
|
||||
|
||||
if (NULL == str) str = ""; /* protect against null arguments */
|
||||
|
||||
for( size=0; str[size] != '\0'; size++ )
|
||||
{}
|
||||
@ -676,3 +873,5 @@ writeDate( int fd, Date *date )
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*********************** END OF FILE *********************************/
|
||||
|
@ -206,8 +206,14 @@ helpWindow( Widget parent, char *title, char *htmlfile )
|
||||
XmNdialogStyle, XmDIALOG_APPLICATION_MODAL,
|
||||
XmNtitle, title,
|
||||
XmNdeleteResponse, XmDESTROY,
|
||||
XmNwidth, 500,
|
||||
XmNheight, 400,
|
||||
XmNtransient, FALSE, /* allow window to be repositioned */
|
||||
|
||||
/*
|
||||
XmNminWidth, 500,
|
||||
XmNminHeight, 400,
|
||||
*/
|
||||
NULL );
|
||||
|
||||
XtAddCallback( dialog, XmNdestroyCallback, closeHelpWin, NULL );
|
||||
|
1088
src/Makefile
1088
src/Makefile
File diff suppressed because it is too large
Load Diff
284
src/RegWindow.c
284
src/RegWindow.c
@ -74,7 +74,7 @@ void recordCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void deleteCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void cancelCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void regCB( Widget mw, XtPointer cd, XtPointer cb );
|
||||
void dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs );
|
||||
void dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs, int do_year );
|
||||
|
||||
|
||||
/** GLOBALS *********************************************************/
|
||||
@ -277,6 +277,10 @@ regRefresh( RegWindow *regData )
|
||||
newData[row+1][PRIC_CELL_C] = XtNewString("");
|
||||
newData[row][SHRS_CELL_C] = XtNewString("");
|
||||
newData[row+1][SHRS_CELL_C] = XtNewString("");
|
||||
/*
|
||||
newData[row][ACTN_CELL_C] = XtNewString("");
|
||||
newData[row+1][ACTN_CELL_C] = XtNewString("");
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Ineternal Error: Account type: %d is unknown!\n", regData->acc->type);
|
||||
@ -315,7 +319,7 @@ regRefresh( RegWindow *regData )
|
||||
|
||||
/* set the cell data: */
|
||||
XtVaSetValues( regData->reg, XmNcells, newData, NULL );
|
||||
regRecalculateBalance(regData);
|
||||
regRecalculateBalance (regData);
|
||||
|
||||
/* and free memory!!! */
|
||||
/* ??? */
|
||||
@ -337,31 +341,25 @@ regRecalculateBalance( RegWindow *regData )
|
||||
int i;
|
||||
int position = 1;
|
||||
double dbalance = 0.0;
|
||||
double share_balance = 0.0;
|
||||
double dclearedBalance = 0.0;
|
||||
double share_clearedBalance = 0.0;
|
||||
double share_balance = 0.0;
|
||||
char buf[BUFSIZE];
|
||||
Transaction *trans;
|
||||
Account *acc;
|
||||
Widget reg;
|
||||
|
||||
if( regData != NULL ) {
|
||||
reg = regData->reg;
|
||||
acc = regData->acc;
|
||||
} else {
|
||||
reg = NULL;
|
||||
acc = NULL;
|
||||
}
|
||||
if( NULL == regData ) return 0.0;
|
||||
|
||||
reg = regData->reg;
|
||||
acc = regData->acc;
|
||||
|
||||
xaccRecomputeBalance (acc);
|
||||
|
||||
for( i=0; (trans=getTransaction(regData->acc,i)) != NULL; i++ )
|
||||
for( i=0; (trans=getTransaction(acc,i)) != NULL; i++ )
|
||||
{
|
||||
share_balance += xaccGetAmount (acc, trans);
|
||||
dbalance = trans -> share_price * share_balance;
|
||||
|
||||
if( trans->reconciled != NREC ) {
|
||||
share_clearedBalance += xaccGetAmount (acc, trans);
|
||||
dclearedBalance = trans->share_price * share_clearedBalance;
|
||||
}
|
||||
dbalance = xaccGetBalance (acc, trans);
|
||||
dclearedBalance = xaccGetClearedBalance (acc, trans);
|
||||
share_balance = xaccGetShareBalance (acc, trans);
|
||||
|
||||
if( reg != NULL )
|
||||
{
|
||||
@ -406,15 +404,12 @@ regRecalculateBalance( RegWindow *regData )
|
||||
}
|
||||
}
|
||||
|
||||
if( regData != NULL )
|
||||
if( NULL != regData->balance )
|
||||
{
|
||||
if( regData->balance != NULL )
|
||||
{
|
||||
sprintf( buf, "$ %.2f \n$ %.2f \0",
|
||||
dbalance, dclearedBalance );
|
||||
|
||||
XmTextSetString( regData->balance, buf );
|
||||
}
|
||||
sprintf( buf, "$ %.2f \n$ %.2f \0",
|
||||
dbalance, dclearedBalance );
|
||||
|
||||
XmTextSetString( regData->balance, buf );
|
||||
}
|
||||
|
||||
refreshMainWindow(); /* make sure the balance field in
|
||||
@ -431,6 +426,19 @@ regRecalculateBalance( RegWindow *regData )
|
||||
* Return: none *
|
||||
* Global: data - the data for open datafile *
|
||||
\********************************************************************/
|
||||
|
||||
#define RECALC_BALANCE(sacc) { \
|
||||
Account * xfer_acc; \
|
||||
RegWindow * xfer_reg; \
|
||||
xfer_acc = (Account *) (sacc); \
|
||||
if (xfer_acc) { \
|
||||
xfer_reg = (RegWindow *) (xfer_acc->regData); \
|
||||
if (xfer_reg) { \
|
||||
regRecalculateBalance (xfer_reg); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
regSaveTransaction( RegWindow *regData, int position )
|
||||
{
|
||||
@ -438,7 +446,6 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
* regData->changed is a bitfield that keeps track of things
|
||||
* that might have changed, so we only have to save the stuff
|
||||
* that has changed */
|
||||
Boolean outOfOrder = False;
|
||||
char buf[BUFSIZE];
|
||||
int newPosition;
|
||||
int row = (position * 2) + 1;
|
||||
@ -524,7 +531,8 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,RECN_CELL_C))[0];
|
||||
|
||||
/* Remember, we need to recalculate the reconciled balance now! */
|
||||
regRecalculateBalance(regData);
|
||||
RECALC_BALANCE ((trans->credit));
|
||||
RECALC_BALANCE ((trans->debit));
|
||||
}
|
||||
|
||||
if( regData->changed & MOD_AMNT )
|
||||
@ -561,7 +569,8 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, buf );
|
||||
}
|
||||
|
||||
regRecalculateBalance(regData);
|
||||
RECALC_BALANCE ((trans->credit));
|
||||
RECALC_BALANCE ((trans->debit));
|
||||
}
|
||||
|
||||
/* ignore MOD_PRIC if for non-stock accounts */
|
||||
@ -583,7 +592,8 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
XbaeMatrixSetCell( regData->reg, row, PRIC_CELL_C, buf );
|
||||
|
||||
/* Remember, we need to recalculate the reconciled balance now! */
|
||||
regRecalculateBalance(regData);
|
||||
RECALC_BALANCE ((trans->credit));
|
||||
RECALC_BALANCE ((trans->debit));
|
||||
}
|
||||
|
||||
/* Before we check the date, and possibly insert the new
|
||||
@ -602,18 +612,13 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
_free(trans);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If this is a valid new transaction, add a new
|
||||
* empty transaction to take its place */
|
||||
outOfOrder = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( regData->changed & MOD_DATE )
|
||||
{
|
||||
Transaction *prevTrans;
|
||||
Transaction *nextTrans;
|
||||
Boolean outOfOrder = False;
|
||||
prevTrans = getTransaction( acc, position-1 );
|
||||
nextTrans = getTransaction( acc, position+1 );
|
||||
|
||||
@ -623,32 +628,38 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
&(trans->date.month),
|
||||
&(trans->date.day) );
|
||||
|
||||
trans->date.year = atoi(XbaeMatrixGetCell(regData->reg,row+1,0));
|
||||
trans->date.year = atoi(XbaeMatrixGetCell(regData->reg,row+1,DATE_CELL_C));
|
||||
|
||||
/* figure out if the transactions are out of order */
|
||||
if( prevTrans != NULL )
|
||||
if( datecmp(&(prevTrans->date),&(trans->date))>0 )
|
||||
outOfOrder = True;
|
||||
if( nextTrans != NULL )
|
||||
if( datecmp(&(trans->date),&(nextTrans->date))>0 )
|
||||
outOfOrder = True;
|
||||
outOfOrder = xaccCheckDateOrderDE (trans);
|
||||
|
||||
/* take care of re-ordering, if necessary */
|
||||
/* take care of re-ordering implications on the register, if necessary */
|
||||
if( outOfOrder )
|
||||
{
|
||||
/* We need to change lastTrans, because we remove and re-insert
|
||||
* the transaction... reset lastTrans to zero to prevent it from
|
||||
* indicating a row that doesn't exist. (That shouldn't happen
|
||||
* anyways!) */
|
||||
regData->lastTrans = 0;
|
||||
|
||||
/* We don't need to remove if it isn't in the transaction list */
|
||||
if( !(regData->changed & MOD_NEW) )
|
||||
removeTransaction( acc, position );
|
||||
|
||||
insertTransaction( acc, trans );
|
||||
|
||||
regRefresh(regData);
|
||||
|
||||
/* REFRESH_REGISTER needs to null out lastTrans, because
|
||||
* during date reordering we removed and re-inserted
|
||||
* the transaction... reset lastTrans to zero to prevent it from
|
||||
* indicating a row that doesn't exist. (That shouldn't happen
|
||||
* anyways!) */
|
||||
#define REFRESH_REGISTER(sacc) { \
|
||||
Account * xfer_acc; \
|
||||
RegWindow * xfer_reg; \
|
||||
xfer_acc = (Account *) (sacc); \
|
||||
if (xfer_acc) { \
|
||||
xfer_reg = (RegWindow *) (xfer_acc->regData); \
|
||||
if (xfer_reg) { \
|
||||
xfer_reg->lastTrans = 0; \
|
||||
regRefresh (xfer_reg); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* if the date changed on a double-entry (transfer) transaction,
|
||||
* then make sure that both register windows are updated .. */
|
||||
|
||||
REFRESH_REGISTER ((trans->credit));
|
||||
REFRESH_REGISTER ((trans->debit));
|
||||
}
|
||||
|
||||
/* Scroll to the last row, if it is a new transaction */
|
||||
@ -658,17 +669,27 @@ regSaveTransaction( RegWindow *regData, int position )
|
||||
XbaeMatrixMakeCellVisible( regData->reg, lastRow, DESC_CELL_C );
|
||||
}
|
||||
|
||||
/* recalculate the balances, but only after re-ordering
|
||||
* cells */
|
||||
regRecalculateBalance(regData);
|
||||
/* recalculate the balances, but only after re-ordering cells */
|
||||
RECALC_BALANCE ((trans->credit));
|
||||
RECALC_BALANCE ((trans->debit));
|
||||
}
|
||||
|
||||
/* reset the "changed" bitfield */
|
||||
regData->changed = 0;
|
||||
|
||||
/* If the reconcile window is open, update it!!! */
|
||||
if( acc->recnData != NULL )
|
||||
recnRefresh( acc->recnData );
|
||||
#define REFRESH_RECONCILE_WIN(sacc) { \
|
||||
/* If the reconcile window is open, update it!!! */ \
|
||||
Account * xfer_acc; \
|
||||
xfer_acc = (Account *) (sacc); \
|
||||
if (xfer_acc) { \
|
||||
if (NULL != xfer_acc->recnData) { \
|
||||
recnRefresh( xfer_acc->recnData ); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
REFRESH_RECONCILE_WIN ((trans->credit));
|
||||
REFRESH_RECONCILE_WIN ((trans->debit));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -717,9 +738,9 @@ regWindow( Widget parent, Account *acc )
|
||||
xmDialogShellWidgetClass, parent,
|
||||
XmNdeleteResponse, XmDESTROY,
|
||||
XmNtitle, acc->accountName,
|
||||
XmNwidth, 495,
|
||||
XmNheight, 500,
|
||||
/*
|
||||
XmNwidth, 395,
|
||||
XmNheight, 400,
|
||||
XmNminWidth, 495,
|
||||
XmNmaxWidth, 495,
|
||||
XmNminHeight, 500,
|
||||
@ -839,15 +860,15 @@ regWindow( Widget parent, Account *acc )
|
||||
case MUTUAL:
|
||||
acc->columnLocation [DATE_COL_ID] = 0;
|
||||
acc->columnLocation [NUM_COL_ID] = 1;
|
||||
acc->columnLocation [ACTN_COL_ID] = 2;
|
||||
acc->columnLocation [DESC_COL_ID] = 3;
|
||||
acc->columnLocation [RECN_COL_ID] = 4;
|
||||
acc->columnLocation [PAY_COL_ID] = 5;
|
||||
acc->columnLocation [DEP_COL_ID] = 6;
|
||||
acc->columnLocation [PRIC_COL_ID] = 7;
|
||||
acc->columnLocation [SHRS_COL_ID] = 8;
|
||||
acc->columnLocation [BALN_COL_ID] = 9;
|
||||
acc -> numCols = 10;
|
||||
/* acc->columnLocation [ACTN_COL_ID] = 2; */
|
||||
acc->columnLocation [DESC_COL_ID] = 2;
|
||||
acc->columnLocation [RECN_COL_ID] = 3;
|
||||
acc->columnLocation [PAY_COL_ID] = 4;
|
||||
acc->columnLocation [DEP_COL_ID] = 5;
|
||||
acc->columnLocation [PRIC_COL_ID] = 6;
|
||||
acc->columnLocation [SHRS_COL_ID] = 7;
|
||||
acc->columnLocation [BALN_COL_ID] = 8;
|
||||
acc -> numCols = 9;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Ineternal Error: Account type: %d is unknown!\n", acc->type);
|
||||
@ -856,7 +877,7 @@ regWindow( Widget parent, Account *acc )
|
||||
/* ----------------------------------- */
|
||||
/* set up column widths */
|
||||
|
||||
acc -> colWidths[DATE_CELL_C] = 4; /* the widths of columns */
|
||||
acc -> colWidths[DATE_CELL_C] = 5; /* the widths of columns */
|
||||
acc -> colWidths[NUM_CELL_C] = 4; /* the widths of columns */
|
||||
acc -> colWidths[DESC_CELL_C] = 35; /* the widths of columns */
|
||||
acc -> colWidths[RECN_CELL_C] = 1; /* the widths of columns */
|
||||
@ -876,7 +897,7 @@ regWindow( Widget parent, Account *acc )
|
||||
case MUTUAL:
|
||||
acc -> colWidths[PRIC_CELL_C] = 8; /* price */
|
||||
acc -> colWidths[SHRS_CELL_C] = 8; /* share balance */
|
||||
acc -> colWidths[ACTN_CELL_C] = 6; /* action (category) */
|
||||
/* acc -> colWidths[ACTN_CELL_C] = 6; /* action (category) */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -904,7 +925,7 @@ regWindow( Widget parent, Account *acc )
|
||||
case MUTUAL:
|
||||
acc -> alignments[PRIC_CELL_C] = XmALIGNMENT_END; /* price */
|
||||
acc -> alignments[SHRS_CELL_C] = XmALIGNMENT_END; /* share balance */
|
||||
acc -> alignments[ACTN_CELL_C] = XmALIGNMENT_BEGINNING; /* action */
|
||||
/* acc -> alignments[ACTN_CELL_C] = XmALIGNMENT_BEGINNING; /* action */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -932,7 +953,7 @@ regWindow( Widget parent, Account *acc )
|
||||
case MUTUAL:
|
||||
acc -> rows[0][PRIC_CELL_C] = "Price";
|
||||
acc -> rows[0][SHRS_CELL_C] = "Tot Shrs";
|
||||
acc -> rows[0][ACTN_CELL_C] = "Cat";
|
||||
/* acc -> rows[0][ACTN_CELL_C] = "Cat"; /* action */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -976,7 +997,7 @@ regWindow( Widget parent, Account *acc )
|
||||
XmNfixedRows, 1,
|
||||
XmNfixedColumns, 0,
|
||||
XmNrows, 2,
|
||||
XmNvisibleRows, 20,
|
||||
XmNvisibleRows, 15,
|
||||
XmNfill, True,
|
||||
XmNcolumns, acc -> numCols,
|
||||
XmNcolumnWidths, acc -> colWidths,
|
||||
@ -1206,12 +1227,30 @@ recordCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
* cb - *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
|
||||
#define REMOVE_TRANS(sacc,trans) { \
|
||||
Account *otherAcc = (Account *) (sacc); \
|
||||
if (otherAcc) { \
|
||||
RegWindow *otherRegData = otherAcc -> regData; \
|
||||
int n = getNumOfTransaction (otherAcc, trans); \
|
||||
\
|
||||
/* remove the transaction */ \
|
||||
trans = removeTransaction( otherAcc, n ); \
|
||||
\
|
||||
/* remove the rows from the matrix */ \
|
||||
if (otherRegData) { \
|
||||
int otherrow = 2*n + 1; \
|
||||
XbaeMatrixDeleteRows( otherRegData->reg, otherrow, 2 ); \
|
||||
XbaeMatrixRefresh( otherRegData->reg); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
deleteCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
{
|
||||
RegWindow *regData = (RegWindow *)cd;
|
||||
Account *acc = regData->acc;
|
||||
Account *otherAcc = 0x0;
|
||||
|
||||
if( getTransaction(acc,regData->lastTrans) != NULL )
|
||||
{
|
||||
@ -1220,37 +1259,17 @@ deleteCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
if( verifyBox( toplevel, msg ) )
|
||||
{
|
||||
Transaction *trans;
|
||||
int row = (2*regData->lastTrans) + 1;
|
||||
/* remove the transaction */
|
||||
trans = removeTransaction( acc, regData->lastTrans );
|
||||
trans = getTransaction (acc, regData->lastTrans );
|
||||
|
||||
/* remove the rows from the matrix */
|
||||
XbaeMatrixDeleteRows( regData->reg, row, 2 );
|
||||
XbaeMatrixRefresh(regData->reg);
|
||||
|
||||
/* if this is a double entry transaction,
|
||||
* remove it from the other account too ...... */
|
||||
if (trans->credit) otherAcc = (Account *) trans->credit;
|
||||
if (trans->debit) otherAcc = (Account *) trans->debit;
|
||||
if (otherAcc) {
|
||||
RegWindow *otherRegData = otherAcc -> regData;
|
||||
int otherrow;
|
||||
int n = getNumOfTransaction (otherAcc, trans);
|
||||
trans = removeTransaction( otherAcc, n );
|
||||
/* remove the transaction from both accounts */
|
||||
REMOVE_TRANS ((trans->credit), trans);
|
||||
REMOVE_TRANS ((trans->debit), trans);
|
||||
|
||||
/* remove the rows from the matrix */
|
||||
if (otherRegData) {
|
||||
otherrow = 2*n + 1;
|
||||
XbaeMatrixDeleteRows( otherRegData->reg, otherrow, 2 );
|
||||
XbaeMatrixRefresh( otherRegData->reg);
|
||||
regRecalculateBalance (otherRegData);
|
||||
}
|
||||
}
|
||||
RECALC_BALANCE ((trans->debit));
|
||||
RECALC_BALANCE ((trans->credit));
|
||||
|
||||
/* Delete the transaction */
|
||||
freeTransaction (trans);
|
||||
|
||||
regRecalculateBalance(regData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1327,7 +1346,7 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
!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) && !IN_YEAR_CELL(row,col))
|
||||
{
|
||||
((XbaeMatrixEnterCellCallbackStruct *)cbs)->doit = FALSE;
|
||||
((XbaeMatrixEnterCellCallbackStruct *)cbs)->map = FALSE;
|
||||
@ -1450,7 +1469,11 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
}
|
||||
#endif
|
||||
if( IN_DATE_CELL(row,col) )
|
||||
dateCellFormat( mw, mvcbs ); /* format according to date
|
||||
dateCellFormat( mw, mvcbs, 0); /* format according to date
|
||||
* cell rules */
|
||||
|
||||
if( IN_YEAR_CELL(row,col) )
|
||||
dateCellFormat( mw, mvcbs, 1); /* format according to date
|
||||
* cell rules */
|
||||
|
||||
/* look to see if numeric format is OK. Note that
|
||||
@ -1491,7 +1514,7 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
/* if the cell is modified, mark it as modified, so we know to
|
||||
* save it... (Don't mark reconciled here, because you can't
|
||||
* actually enter the reconciled cell... mark it in XbaerCellReason */
|
||||
if( IN_DATE_CELL(row,col) )
|
||||
if( IN_DATE_CELL(row,col) || IN_YEAR_CELL(row,col) )
|
||||
regData->changed |= MOD_DATE;
|
||||
|
||||
if( IN_NUM_CELL(row,col) )
|
||||
@ -1613,7 +1636,7 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
void
|
||||
dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs )
|
||||
dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs, int do_year )
|
||||
{
|
||||
/* Date format -- valid characters are numerals, '/', and
|
||||
* accelerator keys (accelerator keys have doit = False,
|
||||
@ -1635,15 +1658,24 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs )
|
||||
|
||||
input = (mvcbs->verify->text->ptr)[0];
|
||||
|
||||
row = mvcbs->row;
|
||||
if (do_year) {
|
||||
row = mvcbs->row - 1;
|
||||
} else {
|
||||
row = mvcbs->row;
|
||||
}
|
||||
col = mvcbs->column;
|
||||
|
||||
date.day = 0;
|
||||
date.month = 0;
|
||||
date.year = 0;
|
||||
|
||||
sscanf( mvcbs->prev_text,
|
||||
"%d/%d",&(date.month), &(date.day) );
|
||||
if (do_year) {
|
||||
sscanf( XbaeMatrixGetCell(mw,row,col),
|
||||
"%d/%d",&(date.month), &(date.day) );
|
||||
}else {
|
||||
sscanf( mvcbs->prev_text,
|
||||
"%d/%d",&(date.month), &(date.day) );
|
||||
}
|
||||
sscanf( XbaeMatrixGetCell(mw,row+1,col),
|
||||
"%d", &(date.year) );
|
||||
|
||||
@ -1725,19 +1757,20 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs )
|
||||
* on the first on, we accept, on the second one
|
||||
* we skip to the year cell
|
||||
*/
|
||||
{
|
||||
int i,count=0;
|
||||
DEBUGCMD(printf(" = %s\n",mvcbs->prev_text));
|
||||
for( i=0; (mvcbs->prev_text)[i] != '\0'; i++ )
|
||||
if( (mvcbs->prev_text)[i] == '/' )
|
||||
count++;
|
||||
if( count >= 1 )
|
||||
if (0 == do_year)
|
||||
{
|
||||
XbaeMatrixEditCell( mw, row+1, col );
|
||||
XbaeMatrixSelectCell( mw, row+1, col );
|
||||
int i,count=0;
|
||||
DEBUGCMD(printf(" = %s\n",mvcbs->prev_text));
|
||||
for( i=0; (mvcbs->prev_text)[i] != '\0'; i++ )
|
||||
if( (mvcbs->prev_text)[i] == '/' )
|
||||
count++;
|
||||
if( count >= 1 )
|
||||
{
|
||||
XbaeMatrixEditCell( mw, row+1, col );
|
||||
XbaeMatrixSelectCell( mw, row+1, col );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
/* only accept the input if it is a number */
|
||||
mvcbs->verify->doit = isNum(input);
|
||||
@ -1755,3 +1788,4 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs )
|
||||
}
|
||||
}
|
||||
|
||||
/************************** END OF FILE *************************/
|
||||
|
@ -52,9 +52,16 @@ initTransaction( Transaction * trans )
|
||||
trans->damount = 0.0;
|
||||
trans->share_price = 1.0;
|
||||
|
||||
trans->credit_balance = 0.0;
|
||||
trans->credit_cleared_balance = 0.0;
|
||||
trans->debit_balance = 0.0;
|
||||
trans->debit_cleared_balance = 0.0;
|
||||
|
||||
trans->date.year = 1900;
|
||||
trans->date.month = 1;
|
||||
trans->date.day = 1;
|
||||
|
||||
trans->write_flag = 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
extern Widget toplevel;
|
||||
|
||||
typedef struct _menuData
|
||||
{
|
||||
@ -47,6 +48,7 @@ typedef struct _menuData
|
||||
|
||||
typedef struct _xferwindow
|
||||
{
|
||||
Widget dialog;
|
||||
Widget date;
|
||||
Widget desc;
|
||||
Widget amount;
|
||||
@ -107,12 +109,13 @@ xferWindow( Widget parent )
|
||||
|
||||
XtAddCallback( dialog, XmNdestroyCallback,
|
||||
closeXferWindow, (XtPointer)xferData );
|
||||
xferData->dialog = dialog;
|
||||
|
||||
/* The form to put everything in the dialog in */
|
||||
form = XtVaCreateWidget( "form", xmFormWidgetClass, dialog, NULL );
|
||||
/******************************************************************\
|
||||
* Text fields.... *
|
||||
\******************************************************************/
|
||||
* Text fields.... *
|
||||
\******************************************************************/
|
||||
label =
|
||||
XtVaCreateManagedWidget( "Date",
|
||||
xmLabelGadgetClass, form,
|
||||
@ -346,8 +349,10 @@ xferWindow( Widget parent )
|
||||
|
||||
XtAddCallback( widget, XmNactivateCallback,
|
||||
xferCB, (XtPointer)xferData );
|
||||
/*
|
||||
XtAddCallback( widget, XmNactivateCallback,
|
||||
destroyShellCB, (XtPointer)dialog );
|
||||
*/
|
||||
|
||||
XtManageChild(buttonform);
|
||||
|
||||
@ -422,6 +427,12 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
String str;
|
||||
float val=0.0;
|
||||
|
||||
/* silently reject transfers into-out-of the same account */
|
||||
if (xferData->from == xferData->to) {
|
||||
errorBox (toplevel, "The \"From\" and \"To\" accounts\n must be different!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data->saved = False;
|
||||
|
||||
/* a double-entry transfer -- just one record, two accounts */
|
||||
@ -465,6 +476,9 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
recnRefresh(acc->recnData);
|
||||
|
||||
refreshMainWindow();
|
||||
|
||||
/* now close xfer window */
|
||||
XtDestroyWidget(xferData->dialog);
|
||||
}
|
||||
|
||||
/* ********************** END OF FILE *************************/
|
||||
|
@ -435,7 +435,8 @@ Boolean
|
||||
verifyBox( Widget parent, char *text )
|
||||
{
|
||||
Widget dialog,msgbox;
|
||||
XmString message = XmStringCreateSimple(text);
|
||||
/* XmString message = XmStringCreateSimple(text); */
|
||||
XmString message = XmStringCreateLtoR( text, charset );
|
||||
XmString yes,no;
|
||||
VerifyBox verifyData;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user