mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge in changes for in-line transfer between accounts
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@53 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
f4b8273650
commit
a9d8972674
1
Makefile
1
Makefile
@ -47,6 +47,7 @@ CFLAGS = $(LFLAGS) -I../include -I../libhtmlw -I../Xbae-4.6.2-linas \
|
|||||||
# -DUSEQUICKFILL # -DUSE_NO_COLOR -DDEBUGMEMORY -DUSEDEBUG
|
# -DUSEQUICKFILL # -DUSE_NO_COLOR -DDEBUGMEMORY -DUSEDEBUG
|
||||||
LFLAGS = -g -L/usr/local/lib -L/usr/X11/lib -L../lib
|
LFLAGS = -g -L/usr/local/lib -L/usr/X11/lib -L../lib
|
||||||
LIBS = -lXm -lXmu -lXt -lXpm -lXext -lSM -lICE -lX11
|
LIBS = -lXm -lXmu -lXt -lXpm -lXext -lSM -lICE -lX11
|
||||||
|
# LIBS = -lXm -lXmu -lXt -lXpm -lXext -lSM -lICE -lX11 -lefence
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
6
README
6
README
@ -39,11 +39,15 @@ sorry, no "make install" yet.
|
|||||||
|
|
||||||
Status:
|
Status:
|
||||||
-------
|
-------
|
||||||
As of version 0.9j:
|
As of version 0.9k:
|
||||||
Bugs:
|
Bugs:
|
||||||
|
-- Cash distributions & cash dividends on stock not handled properly
|
||||||
-- tabbing between fields for mutual funds does not work correctly.
|
-- tabbing between fields for mutual funds does not work correctly.
|
||||||
-- should add "number of shares" to transfer popup when transferring
|
-- should add "number of shares" to transfer popup when transferring
|
||||||
from bank account to portfolio.
|
from bank account to portfolio.
|
||||||
|
-- Nasty core dump in motif when two register windows are opened,
|
||||||
|
and then closed. Beats the heck out of me.
|
||||||
|
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
Bare-bones Mutual Fund and Stock Portfolio handling
|
Bare-bones Mutual Fund and Stock Portfolio handling
|
||||||
|
@ -662,12 +662,12 @@ Do you want to continue anyway?\n");
|
|||||||
|
|
||||||
/* Add an opening balance transaction (as the first transaction) */
|
/* Add an opening balance transaction (as the first transaction) */
|
||||||
trans = mallocTransaction();
|
trans = mallocTransaction();
|
||||||
|
initTransaction(trans);
|
||||||
|
|
||||||
todaysDate( &(trans->date) );
|
todaysDate( &(trans->date) );
|
||||||
trans->num = XtNewString("");
|
XtFree (trans->description);
|
||||||
trans->description = XtNewString("Opening Balance\0");
|
trans->description = XtNewString("Opening Balance");
|
||||||
trans->memo = XtNewString("");
|
|
||||||
|
|
||||||
/* add the new transaction to the account */
|
/* add the new transaction to the account */
|
||||||
insertTransaction( acc, trans );
|
insertTransaction( acc, trans );
|
||||||
|
|
||||||
|
190
src/Account.c
190
src/Account.c
@ -23,11 +23,11 @@
|
|||||||
* Huntington Beach, CA 92648-4632 *
|
* Huntington Beach, CA 92648-4632 *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "Data.h"
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
|
#include "Data.h"
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
extern Data *data;
|
extern Data *data;
|
||||||
int next_free_unique_account_id = 0;
|
int next_free_unique_account_id = 0;
|
||||||
@ -94,13 +94,14 @@ freeAccount( Account *acc )
|
|||||||
|
|
||||||
/* free the transaction only if its not
|
/* free the transaction only if its not
|
||||||
* a part of a double entry */
|
* a part of a double entry */
|
||||||
if (trans->credit == _acc) trans->credit = NULL;
|
if (_acc == trans->credit) trans->credit = NULL;
|
||||||
if (trans->debit == _acc) trans->debit = NULL;
|
if (_acc == trans->debit) trans->debit = NULL;
|
||||||
if ( (NULL == trans->debit) && (NULL == trans->credit) ) {
|
if ( (NULL == trans->debit) && (NULL == trans->credit) ) {
|
||||||
freeTransaction( trans );
|
freeTransaction( trans );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free the array of pointers */
|
||||||
_free( acc->transaction );
|
_free( acc->transaction );
|
||||||
|
|
||||||
_free(acc);
|
_free(acc);
|
||||||
@ -142,7 +143,6 @@ removeTransaction( Account *acc, int num )
|
|||||||
if( acc != NULL )
|
if( acc != NULL )
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
struct _account * _acc = (struct _account *) acc;
|
|
||||||
Transaction **oldTrans = acc->transaction;
|
Transaction **oldTrans = acc->transaction;
|
||||||
|
|
||||||
/* check for valid number */
|
/* check for valid number */
|
||||||
@ -173,104 +173,138 @@ removeTransaction( Account *acc, int num )
|
|||||||
|
|
||||||
/* if this is a double-entry transaction, be sure to
|
/* if this is a double-entry transaction, be sure to
|
||||||
* unmark it. */
|
* unmark it. */
|
||||||
if (trans->credit == _acc) trans->credit = NULL;
|
if (((Account *)trans->credit) == acc) trans->credit = NULL;
|
||||||
if (trans->debit == _acc) trans->debit = NULL;
|
if (((Account *)trans->debit) == acc) trans->debit = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
return trans;
|
return trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
xaccRemoveTransaction( Account *acc, Transaction *trans)
|
||||||
|
{
|
||||||
|
int i = getNumOfTransaction (acc, trans);
|
||||||
|
if (0 <= i) {
|
||||||
|
removeTransaction (acc, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
int
|
int
|
||||||
insertTransaction( Account *acc, Transaction *trans )
|
insertTransaction( Account *acc, Transaction *trans )
|
||||||
{
|
{
|
||||||
int position=-1;
|
int position=-1;
|
||||||
|
int i,j;
|
||||||
|
Date *dj,*dt;
|
||||||
|
int inserted = False;
|
||||||
|
Transaction **oldTrans;
|
||||||
|
|
||||||
if( acc != NULL )
|
if (NULL == acc) {
|
||||||
|
printf ("Internal Error: insertTransaction(): \n");
|
||||||
|
printf (" no account specified ! \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the transaction hasn't already been marked as a debit
|
||||||
|
* or a credit to this account, then provide a default
|
||||||
|
* behavior for double-entry insertion.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( (acc != (Account *) trans->credit) &&
|
||||||
|
(acc != (Account *) trans->debit) ) {
|
||||||
|
|
||||||
|
if (NULL == trans->credit) {
|
||||||
|
trans->credit = (struct _account *) acc;
|
||||||
|
} else
|
||||||
|
if (NULL == trans->debit) {
|
||||||
|
trans->debit = (struct _account *) acc;
|
||||||
|
} else
|
||||||
{
|
{
|
||||||
int i,j;
|
printf ("Internal Error: insertTransaction(): \n");
|
||||||
Date *dj,*dt;
|
printf ("can't insert a transaction more than twice! \n");
|
||||||
int inserted = False;
|
printf ("This error should not occur, please report it \n");
|
||||||
struct _account * _acc = (struct _account *) acc;
|
|
||||||
Transaction **oldTrans = acc->transaction;
|
|
||||||
|
|
||||||
/* provide a default behavior for double-entry insertion */
|
|
||||||
/* 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 algorithm is not robust against internal programming
|
|
||||||
* errors ... various bizarre situations can sneak by without
|
|
||||||
* warning ... however, this will do for now.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( !((_acc == trans->debit) || (_acc == trans->credit)) ) {
|
|
||||||
if ( (NULL == trans->debit) && (NULL == trans->credit) ) {
|
|
||||||
trans->credit = _acc;
|
|
||||||
} else {
|
|
||||||
if (NULL == trans->debit) {
|
|
||||||
trans->debit = _acc;
|
|
||||||
} else
|
|
||||||
if (NULL == trans->credit) {
|
|
||||||
trans->credit = _acc;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
printf ("Internal Error: insertTransaction: inserting transaction \n");
|
|
||||||
printf ("that already exists! \n");
|
|
||||||
printf ("This error should not occur, please report it \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* mark the data file as needing to be saved: */
|
/* mark the data file as needing to be saved: */
|
||||||
if( data != NULL )
|
if( data != NULL )
|
||||||
data->saved = False;
|
data->saved = False;
|
||||||
|
|
||||||
acc->numTrans++;
|
acc->numTrans++;
|
||||||
acc->transaction = (Transaction **)_malloc((acc->numTrans)*
|
oldTrans = acc->transaction;
|
||||||
sizeof(Transaction *));
|
acc->transaction = (Transaction **)_malloc((acc->numTrans)*
|
||||||
|
sizeof(Transaction *));
|
||||||
/* dt is the date of the transaction we are inserting, and dj
|
|
||||||
* is the date of the "cursor" transaction... we want to insert
|
/* dt is the date of the transaction we are inserting, and dj
|
||||||
* the new transaction before the first transaction of the same
|
* is the date of the "cursor" transaction... we want to insert
|
||||||
* or later date. The !inserted bit is a bit of a kludge to
|
* the new transaction before the first transaction of the same
|
||||||
* make sure we only insert the new transaction once! */
|
* or later date. The !inserted bit is a bit of a kludge to
|
||||||
dt = &(trans->date);
|
* make sure we only insert the new transaction once! */
|
||||||
for( i=0,j=0; i<acc->numTrans; i++,j++ )
|
dt = &(trans->date);
|
||||||
|
for( i=0,j=0; i<acc->numTrans; i++,j++ )
|
||||||
|
{
|
||||||
|
/* if we didn't do this, and we needed to insert into the
|
||||||
|
* last spot in the array, we would walk off the end of the
|
||||||
|
* old array, which is no good! */
|
||||||
|
if( j>=(acc->numTrans-1) )
|
||||||
{
|
{
|
||||||
/* if we didn't do this, and we needed to insert into the
|
position = i;
|
||||||
* last spot in the array, we would walk off the end of the
|
acc->transaction[i] = trans;
|
||||||
* old array, which is no good! */
|
break;
|
||||||
if( j>=(acc->numTrans-1) )
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dj = &(oldTrans[j]->date);
|
||||||
|
if( (datecmp(dj,dt) > 0) & !inserted )
|
||||||
{
|
{
|
||||||
position = i;
|
position = i;
|
||||||
acc->transaction[i] = trans;
|
acc->transaction[i] = trans;
|
||||||
break;
|
j--;
|
||||||
|
inserted = True;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
acc->transaction[i] = oldTrans[j];
|
||||||
dj = &(oldTrans[j]->date);
|
|
||||||
if( (datecmp(dj,dt) > 0) & !inserted )
|
|
||||||
{
|
|
||||||
position = i;
|
|
||||||
acc->transaction[i] = trans;
|
|
||||||
j--;
|
|
||||||
inserted = True;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
acc->transaction[i] = oldTrans[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_free(oldTrans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_free(oldTrans);
|
||||||
|
|
||||||
if( position != -1 )
|
if( position != -1 )
|
||||||
qfInsertTransaction( acc->qfRoot, trans );
|
qfInsertTransaction( acc->qfRoot, trans );
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
\********************************************************************/
|
||||||
|
Account *
|
||||||
|
xaccGetOtherAccount( Account *acc, Transaction *trans )
|
||||||
|
{
|
||||||
|
struct _account * _acc = (struct _account *) acc;
|
||||||
|
|
||||||
|
if (NULL == acc) return NULL;
|
||||||
|
|
||||||
|
if (acc == ((Account *) trans->debit)) {
|
||||||
|
return ((Account *) trans->credit);
|
||||||
|
} else
|
||||||
|
if (acc == ((Account *) trans->credit)) {
|
||||||
|
return ((Account *) trans->debit);
|
||||||
|
} else {
|
||||||
|
printf ("Internal Error: xaccGetOtherAccount(): inconsistent entry \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
@ -517,12 +551,10 @@ xaccCheckDateOrder (Account * acc, Transaction *trans )
|
|||||||
if (NULL == acc) return 0;
|
if (NULL == acc) return 0;
|
||||||
|
|
||||||
position = getNumOfTransaction (acc, trans);
|
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) {
|
if (-1 == position) {
|
||||||
insertTransaction( acc, trans );
|
printf ("Internal Error: xaccCheckDateOrder(): \n");
|
||||||
return 1;
|
printf ("transaction not present in the account !\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevTrans = getTransaction( acc, position-1 );
|
prevTrans = getTransaction( acc, position-1 );
|
||||||
|
156
src/Action.c
156
src/Action.c
@ -1,5 +1,5 @@
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* action.c -- account actions for xacc (X-Accountant) *
|
* Action.c -- account actions for xacc (X-Accountant) *
|
||||||
* Copyright (C) 1997 Linas Vepstas *
|
* Copyright (C) 1997 Linas Vepstas *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or *
|
* This program is free software; you can redistribute it and/or *
|
||||||
@ -19,161 +19,37 @@
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#include <Xm/Xm.h>
|
#include <Xm/Xm.h>
|
||||||
#include <ComboBox.h>
|
|
||||||
#include <Xbae/Matrix.h>
|
|
||||||
#include "Action.h"
|
#include "Action.h"
|
||||||
|
#include "PopBox.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/** STRUCTS *********************************************************/
|
|
||||||
typedef struct _ActionBox {
|
|
||||||
Widget combobox;
|
|
||||||
Widget reg; /* the parent register widget */
|
|
||||||
int currow;
|
|
||||||
int curcol;
|
|
||||||
} ActionBox;
|
|
||||||
|
|
||||||
/** PROTOTYPES ******************************************************/
|
|
||||||
|
|
||||||
void selectCB (Widget w, XtPointer cd, XtPointer cb );
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* actionBox *
|
* actionBox *
|
||||||
* creates the action widget *
|
* creates the action widget *
|
||||||
* *
|
* *
|
||||||
* Args: parent - the parent of this window *
|
* Args: parent - the parent of this window *
|
||||||
* Return: actionData - the action GUI structure *
|
* Return: PopBox - the action GUI structure *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#define ADD_MENU_ITEM(menustr) { \
|
PopBox *
|
||||||
str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET); \
|
|
||||||
XmComboBoxAddItem(combobox, str, 0); XmStringFree(str); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ActionBox *
|
|
||||||
actionBox (Widget parent)
|
actionBox (Widget parent)
|
||||||
{
|
{
|
||||||
Widget combobox;
|
PopBox *popGUI;
|
||||||
XmString str;
|
|
||||||
ActionBox *actionData;
|
|
||||||
|
|
||||||
/* malloc the action GUI structure */
|
popGUI = popBox (parent);
|
||||||
actionData = (ActionBox *) _malloc (sizeof (ActionBox));
|
|
||||||
actionData->currow = -1;
|
|
||||||
actionData->curcol = -1;
|
|
||||||
actionData->reg = parent;
|
|
||||||
|
|
||||||
/* create the action GUI */
|
|
||||||
combobox = XtVaCreateManagedWidget("actionbox", xmComboBoxWidgetClass, parent,
|
|
||||||
XmNshadowThickness, 0, /* don't draw a shadow, use bae shadows */
|
|
||||||
XmNeditable, False, /* user can only pick from list */
|
|
||||||
XmNsorted, False,
|
|
||||||
XmNshowLabel, False,
|
|
||||||
XmNmarginHeight, 0,
|
|
||||||
XmNmarginWidth, 0,
|
|
||||||
XmNselectionPolicy, XmSINGLE_SELECT,
|
|
||||||
XmNvalue, "",
|
|
||||||
|
|
||||||
/* hack alert -- the width of the combobox should be relative to the font, should
|
|
||||||
be relative to the size of the cell in which it will fit. */
|
|
||||||
XmNwidth, 43,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
actionData -> combobox = combobox;
|
|
||||||
|
|
||||||
/* build the action menu */
|
/* build the action menu */
|
||||||
ADD_MENU_ITEM("Buy");
|
AddPopBoxMenuItem (popGUI, "Buy");
|
||||||
ADD_MENU_ITEM("Sell");
|
AddPopBoxMenuItem (popGUI, "Sell");
|
||||||
ADD_MENU_ITEM("Price");
|
AddPopBoxMenuItem (popGUI, "Price");
|
||||||
ADD_MENU_ITEM("Div");
|
AddPopBoxMenuItem (popGUI, "Div");
|
||||||
ADD_MENU_ITEM("LTCG");
|
AddPopBoxMenuItem (popGUI, "LTCG");
|
||||||
ADD_MENU_ITEM("STCG");
|
AddPopBoxMenuItem (popGUI, "STCG");
|
||||||
ADD_MENU_ITEM("Dist");
|
AddPopBoxMenuItem (popGUI, "Dist");
|
||||||
ADD_MENU_ITEM("Split");
|
AddPopBoxMenuItem (popGUI, "Split");
|
||||||
|
|
||||||
/* add callbacks to detect a selection */
|
return popGUI;
|
||||||
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)actionData);
|
|
||||||
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)actionData);
|
|
||||||
|
|
||||||
|
|
||||||
return actionData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void SetActionBox (ActionBox *ab, int row, int col)
|
|
||||||
{
|
|
||||||
String choice;
|
|
||||||
XmString choosen;
|
|
||||||
|
|
||||||
/* if the drop-down menu is showing, hide it now */
|
|
||||||
XmComboBoxHideList (ab->combobox);
|
|
||||||
|
|
||||||
/* if there is an old widget, remove it */
|
|
||||||
if ((0 <= ab->currow) && (0 <= ab->curcol)) {
|
|
||||||
XbaeMatrixSetCellWidget (ab->reg, ab->currow, ab->curcol, NULL);
|
|
||||||
}
|
|
||||||
ab->currow = row;
|
|
||||||
ab->curcol = col;
|
|
||||||
|
|
||||||
/* if the new position is valid, go to it,
|
|
||||||
* otherwise, unmanage the widget */
|
|
||||||
if ((0 <= ab->currow) && (0 <= ab->curcol)) {
|
|
||||||
|
|
||||||
/* Get the current cell contents, and set the
|
|
||||||
* combobox menu selction to match the contents */
|
|
||||||
choice = XbaeMatrixGetCell (ab->reg, ab->currow, ab->curcol);
|
|
||||||
|
|
||||||
/* do a menu selection only if the cell ain't empty. */
|
|
||||||
if (0x0 != choice[0]) {
|
|
||||||
/* convert String to XmString ... arghhh */
|
|
||||||
choosen = XmCvtCTToXmString (choice);
|
|
||||||
XmComboBoxSelectItem (ab->combobox, choosen, False);
|
|
||||||
XmStringFree (choosen);
|
|
||||||
} else {
|
|
||||||
XmComboBoxClearItemSelection (ab->combobox);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the cell widget */
|
|
||||||
XbaeMatrixSetCellWidget (ab->reg, row, col, ab->combobox);
|
|
||||||
|
|
||||||
if (!XtIsManaged (ab->combobox)) {
|
|
||||||
XtManageChild (ab->combobox);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* drop down the menu so that its ready to go. */
|
|
||||||
XmComboBoxShowList (ab->combobox);
|
|
||||||
} else {
|
|
||||||
XtUnmanageChild (ab->combobox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
* selectCB -- get the user's selection, put the string into the *
|
|
||||||
* cell. *
|
|
||||||
* *
|
|
||||||
* Args: w - the widget that called us *
|
|
||||||
* cd - actionData - the data struct for this combobox *
|
|
||||||
* cb - *
|
|
||||||
* Return: none *
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void selectCB (Widget w, XtPointer cd, XtPointer cb )
|
|
||||||
|
|
||||||
{
|
|
||||||
ActionBox *ab = (ActionBox *) cd;
|
|
||||||
XmComboBoxSelectionCallbackStruct *selection =
|
|
||||||
(XmComboBoxSelectionCallbackStruct *) cb;
|
|
||||||
char * choice;
|
|
||||||
|
|
||||||
choice = XmCvtXmStringToCT (selection->value);
|
|
||||||
if (0x0 == choice) choice = "";
|
|
||||||
|
|
||||||
XbaeMatrixSetCell (ab->reg, ab->currow, ab->curcol, choice);
|
|
||||||
|
|
||||||
/* a diffeent way of getting the user's selection ... */
|
|
||||||
/* text = XmComboBoxGetString (ab->combobox); */
|
|
||||||
}
|
|
||||||
/************************* END OF FILE ******************************/
|
/************************* END OF FILE ******************************/
|
||||||
|
24
src/Data.c
24
src/Data.c
@ -108,6 +108,30 @@ xaccGetPeerAccountFromID ( Account *acc, int acc_id )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* Fetch an account, given it's name *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
Account *
|
||||||
|
xaccGetPeerAccountFromName ( Account *acc, char * name )
|
||||||
|
{
|
||||||
|
Data * data;
|
||||||
|
Account *peer_acc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (NULL == acc) return NULL;
|
||||||
|
if (NULL == name) return NULL;
|
||||||
|
|
||||||
|
data = (Data *) acc->data;
|
||||||
|
|
||||||
|
for (i=0; i<data->numAcc; i++) {
|
||||||
|
peer_acc = data->account[i];
|
||||||
|
if (!strcmp(peer_acc->accountName, name)) return peer_acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
Account *
|
Account *
|
||||||
|
@ -415,7 +415,7 @@ mainWindow( Widget parent )
|
|||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* closeMainWindow *
|
* closeMainWindow *
|
||||||
* frees memory allocated for an regWindow, and other cleanup *
|
* frees memory allocated for an mainWindow, and other cleanup *
|
||||||
* stuff *
|
* stuff *
|
||||||
* *
|
* *
|
||||||
* Args: mw - the widget that called us *
|
* Args: mw - the widget that called us *
|
||||||
|
@ -27,9 +27,9 @@
|
|||||||
# DO NOT EDIT THE STUFF BELOW THIS LINE! #
|
# DO NOT EDIT THE STUFF BELOW THIS LINE! #
|
||||||
|
|
||||||
OBJS = Account.o AccWindow.o Action.o AdjBWindow.o BuildMenu.o Data.o date.o \
|
OBJS = Account.o AccWindow.o Action.o AdjBWindow.o BuildMenu.o Data.o date.o \
|
||||||
FileBox.o FileIO.o HelpWindow.o main.o MainWindow.o \
|
FileBox.o FileIO.o HelpWindow.o main.o MainWindow.o PopBox.o \
|
||||||
QIFIO.o QuickFill.o RecnWindow.o RegWindow.o Reports.o \
|
QIFIO.o QuickFill.o RecnWindow.o RegWindow.o Reports.o \
|
||||||
Transaction.o util.o XferWindow.o
|
Transaction.o util.o XferBox.o XferWindow.o
|
||||||
|
|
||||||
SRCS = ${OBJS:.o=.c}
|
SRCS = ${OBJS:.o=.c}
|
||||||
|
|
||||||
|
185
src/PopBox.c
Normal file
185
src/PopBox.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/********************************************************************\
|
||||||
|
* Pop.c -- generic ComboBox for xacc (X-Accountant) *
|
||||||
|
* 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 *
|
||||||
|
* published by the Free Software Foundation; either version 2 of *
|
||||||
|
* the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License*
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||||
|
* *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <ComboBox.h>
|
||||||
|
#include <Xbae/Matrix.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/** STRUCTS *********************************************************/
|
||||||
|
typedef struct _PopBox {
|
||||||
|
Widget combobox;
|
||||||
|
Widget reg; /* the parent register widget */
|
||||||
|
int currow;
|
||||||
|
int curcol;
|
||||||
|
} PopBox;
|
||||||
|
|
||||||
|
/** PROTOTYPES ******************************************************/
|
||||||
|
|
||||||
|
void selectCB (Widget w, XtPointer cd, XtPointer cb );
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* popBox *
|
||||||
|
* creates the pop widget *
|
||||||
|
* *
|
||||||
|
* Args: parent - the parent of this window *
|
||||||
|
* Return: popData - the pop GUI structure *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
PopBox *
|
||||||
|
popBox (Widget parent)
|
||||||
|
{
|
||||||
|
Widget combobox;
|
||||||
|
XmString str;
|
||||||
|
PopBox *popData;
|
||||||
|
|
||||||
|
/* malloc the pop GUI structure */
|
||||||
|
popData = (PopBox *) _malloc (sizeof (PopBox));
|
||||||
|
popData->currow = -1;
|
||||||
|
popData->curcol = -1;
|
||||||
|
popData->reg = parent;
|
||||||
|
|
||||||
|
/* create the pop GUI */
|
||||||
|
combobox = XtVaCreateManagedWidget("popbox", xmComboBoxWidgetClass, parent,
|
||||||
|
XmNshadowThickness, 0, /* don't draw a shadow, use bae shadows */
|
||||||
|
XmNeditable, False, /* user can only pick from list */
|
||||||
|
XmNsorted, False,
|
||||||
|
XmNshowLabel, False,
|
||||||
|
XmNmarginHeight, 0,
|
||||||
|
XmNmarginWidth, 0,
|
||||||
|
XmNselectionPolicy, XmSINGLE_SELECT,
|
||||||
|
XmNvalue, "",
|
||||||
|
|
||||||
|
/* hack alert -- the width of the combobox should be relative to the font, should
|
||||||
|
be relative to the size of the cell in which it will fit. */
|
||||||
|
XmNwidth, 53,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
popData -> combobox = combobox;
|
||||||
|
|
||||||
|
/* add callbacks to detect a selection */
|
||||||
|
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)popData);
|
||||||
|
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)popData);
|
||||||
|
|
||||||
|
return popData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* AddPopBoxMenuItem *
|
||||||
|
* add a menu item to the pop box *
|
||||||
|
* *
|
||||||
|
* Args: PopBox - the pop GUI structure *
|
||||||
|
* menustr -- the menu entry to be added *
|
||||||
|
* Return: void *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void AddPopBoxMenuItem (PopBox *ab, char * menustr)
|
||||||
|
{
|
||||||
|
XmString str;
|
||||||
|
str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET);
|
||||||
|
XmComboBoxAddItem (ab->combobox, str, 0);
|
||||||
|
XmStringFree (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* SetPopBox *
|
||||||
|
* moves the ComboBox to the indicated column, row *
|
||||||
|
* *
|
||||||
|
* Args: PopBox - the pop GUI structure *
|
||||||
|
* row -- the row of the Xbae Matrix *
|
||||||
|
* col -- the col of the Xbae Matrix *
|
||||||
|
* Return: void *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void SetPopBox (PopBox *ab, int row, int col)
|
||||||
|
{
|
||||||
|
String choice;
|
||||||
|
XmString choosen;
|
||||||
|
|
||||||
|
/* if the drop-down menu is showing, hide it now */
|
||||||
|
XmComboBoxHideList (ab->combobox);
|
||||||
|
|
||||||
|
/* if there is an old widget, remove it */
|
||||||
|
if ((0 <= ab->currow) && (0 <= ab->curcol)) {
|
||||||
|
XbaeMatrixSetCellWidget (ab->reg, ab->currow, ab->curcol, NULL);
|
||||||
|
}
|
||||||
|
ab->currow = row;
|
||||||
|
ab->curcol = col;
|
||||||
|
|
||||||
|
/* if the new position is valid, go to it,
|
||||||
|
* otherwise, unmanage the widget */
|
||||||
|
if ((0 <= ab->currow) && (0 <= ab->curcol)) {
|
||||||
|
|
||||||
|
/* Get the current cell contents, and set the
|
||||||
|
* combobox menu selction to match the contents */
|
||||||
|
choice = XbaeMatrixGetCell (ab->reg, ab->currow, ab->curcol);
|
||||||
|
|
||||||
|
/* do a menu selection only if the cell ain't empty. */
|
||||||
|
if (0x0 != choice[0]) {
|
||||||
|
/* convert String to XmString ... arghhh */
|
||||||
|
choosen = XmCvtCTToXmString (choice);
|
||||||
|
XmComboBoxSelectItem (ab->combobox, choosen, False);
|
||||||
|
XmStringFree (choosen);
|
||||||
|
} else {
|
||||||
|
XmComboBoxClearItemSelection (ab->combobox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the cell widget */
|
||||||
|
XbaeMatrixSetCellWidget (ab->reg, row, col, ab->combobox);
|
||||||
|
|
||||||
|
if (!XtIsManaged (ab->combobox)) {
|
||||||
|
XtManageChild (ab->combobox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* drop down the menu so that its ready to go. */
|
||||||
|
XmComboBoxShowList (ab->combobox);
|
||||||
|
} else {
|
||||||
|
XtUnmanageChild (ab->combobox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* selectCB -- get the user's selection, put the string into the *
|
||||||
|
* cell. *
|
||||||
|
* *
|
||||||
|
* Args: w - the widget that called us *
|
||||||
|
* cd - popData - the data struct for this combobox *
|
||||||
|
* cb - *
|
||||||
|
* Return: none *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void selectCB (Widget w, XtPointer cd, XtPointer cb )
|
||||||
|
|
||||||
|
{
|
||||||
|
PopBox *ab = (PopBox *) cd;
|
||||||
|
XmComboBoxSelectionCallbackStruct *selection =
|
||||||
|
(XmComboBoxSelectionCallbackStruct *) cb;
|
||||||
|
char * choice;
|
||||||
|
|
||||||
|
choice = XmCvtXmStringToCT (selection->value);
|
||||||
|
if (0x0 == choice) choice = "";
|
||||||
|
|
||||||
|
XbaeMatrixSetCell (ab->reg, ab->currow, ab->curcol, choice);
|
||||||
|
|
||||||
|
/* a diffeent way of getting the user's selection ... */
|
||||||
|
/* text = XmComboBoxGetString (ab->combobox); */
|
||||||
|
}
|
||||||
|
/************************* END OF FILE ******************************/
|
@ -113,17 +113,21 @@ qfInsertTransactionRec( QuickFill *qf, Transaction *trans, int depth )
|
|||||||
{
|
{
|
||||||
if( qf != NULL )
|
if( qf != NULL )
|
||||||
{
|
{
|
||||||
if( trans->description[depth] != '\0' )
|
if( trans->description )
|
||||||
{
|
{
|
||||||
int index = CHAR_TO_INDEX( trans->description[depth] );
|
if( trans->description[depth] != '\0' )
|
||||||
|
{
|
||||||
if( qf->qf[index] == NULL )
|
int index = CHAR_TO_INDEX( trans->description[depth] );
|
||||||
qf->qf[index] = mallocQuickFill();
|
|
||||||
|
if( qf->qf[index] == NULL )
|
||||||
qf->qf[index]->trans = trans;
|
qf->qf[index] = mallocQuickFill();
|
||||||
|
|
||||||
qfInsertTransactionRec( qf->qf[index], trans, ++depth );
|
qf->qf[index]->trans = trans;
|
||||||
|
|
||||||
|
qfInsertTransactionRec( qf->qf[index], trans, ++depth );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/********************** END OF FILE *********************************\
|
||||||
|
\********************************************************************/
|
||||||
|
415
src/RegWindow.c
415
src/RegWindow.c
@ -35,13 +35,14 @@
|
|||||||
#include <Xbae/Matrix.h>
|
#include <Xbae/Matrix.h>
|
||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "ActionBox.h"
|
#include "Action.h"
|
||||||
#include "AdjBWindow.h"
|
#include "AdjBWindow.h"
|
||||||
#include "BuildMenu.h"
|
#include "BuildMenu.h"
|
||||||
#include "Data.h"
|
#include "Data.h"
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
#include "PopBox.h"
|
||||||
#include "QuickFill.h"
|
#include "QuickFill.h"
|
||||||
#include "RecnWindow.h"
|
#include "RecnWindow.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
@ -62,7 +63,8 @@ typedef struct _RegWindow {
|
|||||||
QuickFill *qf; /* keeps track of current quickfill node. *
|
QuickFill *qf; /* keeps track of current quickfill node. *
|
||||||
* Reset to Account->qfRoot when entering *
|
* Reset to Account->qfRoot when entering *
|
||||||
* a new transaction */
|
* a new transaction */
|
||||||
ActionBox *ab;
|
PopBox *actbox; /* ComboBox for actions */
|
||||||
|
PopBox *xferbox; /* ComboBox for transfers */
|
||||||
} RegWindow;
|
} RegWindow;
|
||||||
|
|
||||||
|
|
||||||
@ -106,8 +108,9 @@ extern Pixel negPixel;
|
|||||||
#define MOD_PRIC 0x40
|
#define MOD_PRIC 0x40
|
||||||
#define MOD_MEMO 0x80
|
#define MOD_MEMO 0x80
|
||||||
#define MOD_ACTN 0x100
|
#define MOD_ACTN 0x100
|
||||||
#define MOD_NEW 0x200
|
#define MOD_XFER 0x200
|
||||||
#define MOD_ALL 0x3ff
|
#define MOD_NEW 0x400
|
||||||
|
#define MOD_ALL 0x7ff
|
||||||
|
|
||||||
/* These defines are indexes into the column location array */
|
/* These defines are indexes into the column location array */
|
||||||
#define DATE_COL_ID 0
|
#define DATE_COL_ID 0
|
||||||
@ -141,10 +144,14 @@ extern Pixel negPixel;
|
|||||||
#define SHRS_CELL_C (acc->columnLocation[SHRS_COL_ID])
|
#define SHRS_CELL_C (acc->columnLocation[SHRS_COL_ID])
|
||||||
#define ACTN_CELL_C (acc->columnLocation[ACTN_COL_ID])
|
#define ACTN_CELL_C (acc->columnLocation[ACTN_COL_ID])
|
||||||
|
|
||||||
|
#define YEAR_CELL_R 1
|
||||||
|
#define YEAR_CELL_C DATE_CELL_C /* same column as the date */
|
||||||
|
#define XFER_CELL_R 1
|
||||||
|
#define XFER_CELL_C NUM_CELL_C /* same column as the transaction number */
|
||||||
#define MEMO_CELL_R 1
|
#define MEMO_CELL_R 1
|
||||||
#define MEMO_CELL_C DESC_CELL_C /* same cilumn as the description */
|
#define MEMO_CELL_C DESC_CELL_C /* same column as the description */
|
||||||
|
|
||||||
/** COOL MACROS *****************************************************/
|
/** CELL MACROS *****************************************************/
|
||||||
#define IN_DATE_CELL(R,C) (((R-1)%2==0) && (C==DATE_CELL_C)) /* Date cell */
|
#define IN_DATE_CELL(R,C) (((R-1)%2==0) && (C==DATE_CELL_C)) /* Date cell */
|
||||||
#define IN_NUM_CELL(R,C) (((R-1)%2==0) && (C==NUM_CELL_C)) /* Number cell */
|
#define IN_NUM_CELL(R,C) (((R-1)%2==0) && (C==NUM_CELL_C)) /* Number cell */
|
||||||
#define IN_DESC_CELL(R,C) (((R-1)%2==0) && (C==DESC_CELL_C)) /* Description cell */
|
#define IN_DESC_CELL(R,C) (((R-1)%2==0) && (C==DESC_CELL_C)) /* Description cell */
|
||||||
@ -156,6 +163,7 @@ extern Pixel negPixel;
|
|||||||
#define IN_ACTN_CELL(R,C) (((R-1)%2==0) && (C==ACTN_CELL_C)) /* Action cell */
|
#define IN_ACTN_CELL(R,C) (((R-1)%2==0) && (C==ACTN_CELL_C)) /* Action cell */
|
||||||
|
|
||||||
#define IN_YEAR_CELL(R,C) (((R-1)%2==1) && (C==DATE_CELL_C)) /* Year cell */
|
#define IN_YEAR_CELL(R,C) (((R-1)%2==1) && (C==DATE_CELL_C)) /* Year cell */
|
||||||
|
#define IN_XFER_CELL(R,C) (((R-1)%2==1) && (C==XFER_CELL_C)) /* Transfer cell */
|
||||||
#define IN_MEMO_CELL(R,C) (((R-1)%2==1) && (C==MEMO_CELL_C)) /* Memo cell */
|
#define IN_MEMO_CELL(R,C) (((R-1)%2==1) && (C==MEMO_CELL_C)) /* Memo cell */
|
||||||
#define IN_BAD_CELL(R,C) (((R-1)%2==1) && (C!=MEMO_CELL_C)) /* Not the memo cell*/
|
#define IN_BAD_CELL(R,C) (((R-1)%2==1) && (C!=MEMO_CELL_C)) /* Not the memo cell*/
|
||||||
|
|
||||||
@ -181,7 +189,7 @@ regRefresh( RegWindow *regData )
|
|||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
String **data = NULL;
|
String **data = NULL;
|
||||||
String **newData;
|
String **newData;
|
||||||
Account *acc;
|
Account *acc, *xfer_acc;
|
||||||
double themount; /* amount */
|
double themount; /* amount */
|
||||||
|
|
||||||
XtVaGetValues( regData->reg, XmNrows, &nrows, NULL );
|
XtVaGetValues( regData->reg, XmNrows, &nrows, NULL );
|
||||||
@ -214,7 +222,7 @@ regRefresh( RegWindow *regData )
|
|||||||
|
|
||||||
/* and fill in the data for the matrix: */
|
/* and fill in the data for the matrix: */
|
||||||
i=-1;
|
i=-1;
|
||||||
while( (trans=getTransaction(regData->acc,++i)) != NULL )
|
while( (trans = getTransaction (acc,++i)) != NULL )
|
||||||
{
|
{
|
||||||
int row = i*2+1;
|
int row = i*2+1;
|
||||||
|
|
||||||
@ -222,25 +230,29 @@ regRefresh( RegWindow *regData )
|
|||||||
trans->date.month,
|
trans->date.month,
|
||||||
trans->date.day );
|
trans->date.day );
|
||||||
newData[row][DATE_CELL_C] = XtNewString(buf);
|
newData[row][DATE_CELL_C] = XtNewString(buf);
|
||||||
|
|
||||||
sprintf( buf, "%4d", trans->date.year );
|
sprintf( buf, "%4d", trans->date.year );
|
||||||
newData[row+1][DATE_CELL_C] = XtNewString(buf);
|
newData[row+1][DATE_CELL_C] = XtNewString(buf); /* YEAR_CELL_C */
|
||||||
|
|
||||||
sprintf( buf, "%s", trans->num );
|
sprintf( buf, "%s", trans->num );
|
||||||
newData[row][NUM_CELL_C] = XtNewString(buf);
|
newData[row][NUM_CELL_C] = XtNewString(buf);
|
||||||
|
|
||||||
newData[row+1][NUM_CELL_C] = XtNewString("");
|
/* XFER_CELL_C is same as NUM_CELL_C */
|
||||||
|
xfer_acc = xaccGetOtherAccount (acc, trans);
|
||||||
|
if (xfer_acc) {
|
||||||
|
sprintf( buf, "%s", xfer_acc->accountName );
|
||||||
|
newData[row+1][NUM_CELL_C] = XtNewString(buf);
|
||||||
|
} else {
|
||||||
|
newData[row+1][NUM_CELL_C] = XtNewString("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sprintf( buf, "%s", trans->description );
|
sprintf( buf, "%s", trans->description );
|
||||||
newData[row][DESC_CELL_C] = XtNewString(buf);
|
newData[row][DESC_CELL_C] = XtNewString(buf);
|
||||||
|
|
||||||
sprintf( buf, "%s", trans->memo );
|
sprintf( buf, "%s", trans->memo );
|
||||||
newData[row+1][DESC_CELL_C] = XtNewString(buf);
|
newData[row+1][DESC_CELL_C] = XtNewString(buf);
|
||||||
|
|
||||||
sprintf( buf, "%c", trans->reconciled );
|
sprintf( buf, "%c", trans->reconciled );
|
||||||
newData[row][RECN_CELL_C] = XtNewString(buf);
|
newData[row][RECN_CELL_C] = XtNewString(buf);
|
||||||
|
|
||||||
newData[row+1][RECN_CELL_C] = XtNewString("");
|
newData[row+1][RECN_CELL_C] = XtNewString("");
|
||||||
|
|
||||||
/* ----------------------------------- */
|
/* ----------------------------------- */
|
||||||
@ -463,50 +475,112 @@ regRecalculateBalance( RegWindow *regData )
|
|||||||
* Global: data - the data for open datafile *
|
* Global: data - the data for open datafile *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#define RECALC_BALANCE(sacc) { \
|
/* RECALC_BALANCE recomputes the balance shown in
|
||||||
Account * xfer_acc; \
|
* the register window, if its is visible
|
||||||
RegWindow * xfer_reg; \
|
*/
|
||||||
xfer_acc = (Account *) (sacc); \
|
|
||||||
if (xfer_acc) { \
|
#define RECALC_BALANCE(sacc) { \
|
||||||
xfer_reg = (RegWindow *) (xfer_acc->regData); \
|
Account * xfer_acc; \
|
||||||
if (xfer_reg) { \
|
RegWindow * xfer_reg; \
|
||||||
regRecalculateBalance (xfer_reg); \
|
xfer_acc = (Account *) (sacc); \
|
||||||
} \
|
if (xfer_acc) { \
|
||||||
} \
|
xfer_reg = (RegWindow *) (xfer_acc->regData); \
|
||||||
|
if (xfer_reg) { \
|
||||||
|
regRecalculateBalance (xfer_reg); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* REFRESH_REGISTER redisplays the register window,
|
||||||
|
* if it is visible
|
||||||
|
*/
|
||||||
|
#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) { \
|
||||||
|
regRefresh (xfer_reg); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* DATE_REORDER 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 DATE_REORDER(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; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* REMOVE_TRANS will not only remove a transaction from an account,
|
||||||
|
* but it will also delete the appropriate rows from the register
|
||||||
|
* window, if the register window is visible
|
||||||
|
*/
|
||||||
|
#define REMOVE_TRANS(sacc,trans) { \
|
||||||
|
Account *otherAcc = (Account *) (sacc); \
|
||||||
|
if (otherAcc) { \
|
||||||
|
RegWindow *otherRegData = otherAcc -> regData; \
|
||||||
|
int n = getNumOfTransaction (otherAcc, trans); \
|
||||||
|
\
|
||||||
|
/* remove the transaction */ \
|
||||||
|
xaccRemoveTransaction( otherAcc, trans ); \
|
||||||
|
\
|
||||||
|
/* remove the rows from the matrix */ \
|
||||||
|
if (otherRegData) { \
|
||||||
|
int otherrow = 2*n + 1; \
|
||||||
|
XbaeMatrixDeleteRows( otherRegData->reg, otherrow, 2 ); \
|
||||||
|
XbaeMatrixRefresh( otherRegData->reg); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regSaveTransaction( RegWindow *regData, int position )
|
regSaveTransaction( RegWindow *regData, int position )
|
||||||
{
|
{
|
||||||
/* save transaction structure... in order to speed this up,
|
/* save transaction structure... in order to speed this up,
|
||||||
* regData->changed is a bitfield that keeps track of things
|
* regData->changed is a bitfield that keeps track of things
|
||||||
* that might have changed, so we only have to save the stuff
|
* that might have changed, so we only have to save the stuff
|
||||||
* that has changed */
|
* that has changed */
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
int newPosition;
|
|
||||||
int row = (position * 2) + 1;
|
int row = (position * 2) + 1;
|
||||||
Account *acc;
|
Account *acc = regData->acc;
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
|
|
||||||
acc = regData->acc;
|
/* If nothing has changed, we have nothing to do */
|
||||||
|
if (MOD_NONE == regData->changed) return;
|
||||||
|
|
||||||
|
/* Be sure to prompt the user to save to disk after changes are made! */
|
||||||
|
acc->data->saved = False;
|
||||||
|
|
||||||
trans = getTransaction( acc, position );
|
trans = getTransaction( acc, position );
|
||||||
|
|
||||||
/* If anything changes, we have to set this flag, so we
|
|
||||||
* remember to prompt the user to save! */
|
|
||||||
if( MOD_NONE != regData->changed )
|
|
||||||
data->saved = False;
|
|
||||||
|
|
||||||
if( trans == NULL )
|
if( trans == NULL )
|
||||||
{
|
{
|
||||||
/* This must be a new transaction */
|
/* This must be a new transaction */
|
||||||
DEBUG("New Transaction");
|
DEBUG("New Transaction");
|
||||||
|
|
||||||
/* If nothing has changed, we don't want to save this */
|
|
||||||
if( !(regData->changed & MOD_ALL) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
trans = mallocTransaction();
|
trans = mallocTransaction();
|
||||||
trans->credit = (struct _account *) acc;
|
trans->credit = (struct _account *) acc;
|
||||||
|
|
||||||
|
/* insert the transaction now. If we later discover that
|
||||||
|
* the user hs not made any entries, we will remove it again.
|
||||||
|
* However, for some of the itntermediate processing, we must
|
||||||
|
* have a valid transaction present in the account.
|
||||||
|
*/
|
||||||
|
insertTransaction (acc, trans);
|
||||||
regData->changed = MOD_ALL;
|
regData->changed = MOD_ALL;
|
||||||
}
|
}
|
||||||
if( regData->changed & MOD_NUM )
|
if( regData->changed & MOD_NUM )
|
||||||
@ -517,6 +591,34 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
trans->num = XtNewString( XbaeMatrixGetCell(regData->reg,row,NUM_CELL_C) );
|
trans->num = XtNewString( XbaeMatrixGetCell(regData->reg,row,NUM_CELL_C) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( regData->changed & MOD_XFER )
|
||||||
|
{
|
||||||
|
/* ... the transfer ... */
|
||||||
|
char * name;
|
||||||
|
Account *xfer_acct = xaccGetOtherAccount (acc, trans);
|
||||||
|
DEBUG("MOD_XFER");
|
||||||
|
|
||||||
|
if (xfer_acct) {
|
||||||
|
/* remove the transaction from wherever it used to be */
|
||||||
|
REMOVE_TRANS (xfer_acct, trans);
|
||||||
|
|
||||||
|
/* recalculate the balance and redisplay the window for the old acct */
|
||||||
|
RECALC_BALANCE (xfer_acct);
|
||||||
|
REFRESH_REGISTER (xfer_acct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the new account name */
|
||||||
|
name = XbaeMatrixGetCell(regData->reg,row+XFER_CELL_R, XFER_CELL_C);
|
||||||
|
|
||||||
|
/* get the new account from the name */
|
||||||
|
xfer_acct = xaccGetPeerAccountFromName (acc, name);
|
||||||
|
|
||||||
|
if (xfer_acct) {
|
||||||
|
/* insert the transaction into the new account */
|
||||||
|
insertTransaction (xfer_acct, trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( regData->changed & MOD_DESC )
|
if( regData->changed & MOD_DESC )
|
||||||
{
|
{
|
||||||
DEBUG("MOD_DESC");
|
DEBUG("MOD_DESC");
|
||||||
@ -533,34 +635,13 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
DEBUG("MOD_MEMO");
|
DEBUG("MOD_MEMO");
|
||||||
/* ... the memo ... */
|
/* ... the memo ... */
|
||||||
XtFree( trans->memo );
|
XtFree( trans->memo );
|
||||||
|
tmp = XbaeMatrixGetCell(regData->reg,row+MEMO_CELL_R,MEMO_CELL_C);
|
||||||
tmp = XbaeMatrixGetCell(regData->reg,row+1,MEMO_CELL_C);
|
trans->memo = XtNewString( tmp );
|
||||||
|
|
||||||
/* if its a transfer, indicate where its from ... */
|
|
||||||
/* hack alert -- this algorithm is fundamentally broken if
|
|
||||||
* memo field is repeatedly edited ... */
|
|
||||||
if ((NULL != trans->debit) && (NULL != trans->credit)) {
|
|
||||||
Account *fromAccount = NULL;
|
|
||||||
if (acc == ((Account *) trans->debit) ) {
|
|
||||||
fromAccount = (Account *) trans->credit;
|
|
||||||
} else {
|
|
||||||
fromAccount = (Account *) trans->debit;
|
|
||||||
}
|
|
||||||
/* Get the memo, and add the "from" account name to it */
|
|
||||||
memo = (String)malloc (strlen(tmp)+
|
|
||||||
strlen(fromAccount->accountName)+
|
|
||||||
strlen("[From: ] ") );
|
|
||||||
|
|
||||||
sprintf( memo, "[From: %s] %s\0", fromAccount->accountName, tmp);
|
|
||||||
|
|
||||||
XbaeMatrixSetCell( regData->reg, row+1, MEMO_CELL_C, memo );
|
|
||||||
trans->memo = memo;
|
|
||||||
} else {
|
|
||||||
trans->memo = XtNewString( tmp );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( regData->changed & MOD_ACTN )
|
/* ignore MOD_ACTN for non-stock accounts */
|
||||||
|
if( (regData->changed & MOD_ACTN) &&
|
||||||
|
((MUTUAL == acc->type) || (PORTFOLIO==acc->type)) )
|
||||||
{
|
{
|
||||||
String actn = NULL;
|
String actn = NULL;
|
||||||
DEBUG("MOD_ACTN");
|
DEBUG("MOD_ACTN");
|
||||||
@ -575,10 +656,6 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
DEBUG("MOD_RECN");
|
DEBUG("MOD_RECN");
|
||||||
/* ...the reconciled flag (char)... */
|
/* ...the reconciled flag (char)... */
|
||||||
trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,RECN_CELL_C))[0];
|
trans->reconciled = (XbaeMatrixGetCell(regData->reg,row,RECN_CELL_C))[0];
|
||||||
|
|
||||||
/* Remember, we need to recalculate the reconciled balance now! */
|
|
||||||
RECALC_BALANCE ((trans->credit));
|
|
||||||
RECALC_BALANCE ((trans->debit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( regData->changed & MOD_AMNT )
|
if( regData->changed & MOD_AMNT )
|
||||||
@ -603,7 +680,7 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
/* Reset so there is only one field filled */
|
/* Reset so there is only one field filled */
|
||||||
if( 0.0 > themount )
|
if( 0.0 > themount )
|
||||||
{
|
{
|
||||||
/* hack alert -- keep 3 digits for share amounts */
|
/* hack alert -- should keep 3 digits for share amounts */
|
||||||
sprintf( buf, "%.2f ", -themount );
|
sprintf( buf, "%.2f ", -themount );
|
||||||
XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, buf );
|
XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, buf );
|
||||||
XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, "" );
|
XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, "" );
|
||||||
@ -614,12 +691,9 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, "" );
|
XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, "" );
|
||||||
XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, buf );
|
XbaeMatrixSetCell( regData->reg, row, DEP_CELL_C, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
RECALC_BALANCE ((trans->credit));
|
|
||||||
RECALC_BALANCE ((trans->debit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ignore MOD_PRIC if for non-stock accounts */
|
/* ignore MOD_PRIC for non-stock accounts */
|
||||||
if( (regData->changed & MOD_PRIC) &&
|
if( (regData->changed & MOD_PRIC) &&
|
||||||
((MUTUAL == acc->type) || (PORTFOLIO==acc->type)) )
|
((MUTUAL == acc->type) || (PORTFOLIO==acc->type)) )
|
||||||
{
|
{
|
||||||
@ -635,91 +709,70 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
|
|
||||||
sprintf( buf, "%.2f ", trans->share_price );
|
sprintf( buf, "%.2f ", trans->share_price );
|
||||||
XbaeMatrixSetCell( regData->reg, row, PRIC_CELL_C, buf );
|
XbaeMatrixSetCell( regData->reg, row, PRIC_CELL_C, buf );
|
||||||
|
|
||||||
/* Remember, we need to recalculate the reconciled balance now! */
|
|
||||||
RECALC_BALANCE ((trans->credit));
|
|
||||||
RECALC_BALANCE ((trans->debit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before we check the date, and possibly insert the new
|
if( regData->changed & MOD_DATE )
|
||||||
* transaction, we need to make sure that, if this is a
|
|
||||||
* new transaction, that the user actually entered some
|
|
||||||
* data! Otherwise, it would be lame to add this. */
|
|
||||||
if( regData->changed & MOD_NEW )
|
|
||||||
{
|
{
|
||||||
|
Boolean outOfOrder = False;
|
||||||
|
|
||||||
|
DEBUG("MOD_DATE");
|
||||||
|
/* read in the date stuff... */
|
||||||
|
sscanf( XbaeMatrixGetCell(regData->reg,row+DATE_CELL_R,DATE_CELL_C),"%d/%d",
|
||||||
|
&(trans->date.month),
|
||||||
|
&(trans->date.day) );
|
||||||
|
|
||||||
|
trans->date.year = atoi(XbaeMatrixGetCell(regData->reg,row+YEAR_CELL_R,YEAR_CELL_C));
|
||||||
|
|
||||||
|
/* take care of re-ordering implications on the register.
|
||||||
|
* If the date changed on a double-entry (transfer) transaction,
|
||||||
|
* then make sure that both register windows are updated .. */
|
||||||
|
outOfOrder = xaccCheckDateOrderDE (trans);
|
||||||
|
if( outOfOrder )
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
DATE_REORDER ((trans->credit));
|
||||||
|
DATE_REORDER ((trans->debit));
|
||||||
|
|
||||||
|
/* Scroll to the new location of the reordered transaction;
|
||||||
|
* but do this only for this register, not any other register
|
||||||
|
* windows. */
|
||||||
|
pos = getNumOfTransaction (acc, trans);
|
||||||
|
XbaeMatrixMakeCellVisible( regData->reg, 2*pos+1, DESC_CELL_C );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is a new transaction, and the user did not
|
||||||
|
* actually enter any data, then we should not really
|
||||||
|
* consider this to be a new transaction! */
|
||||||
|
if (regData->changed & MOD_NEW) {
|
||||||
if( (strcmp("",trans->num) == 0) &&
|
if( (strcmp("",trans->num) == 0) &&
|
||||||
(strcmp("",trans->description) == 0) &&
|
(strcmp("",trans->description) == 0) &&
|
||||||
(strcmp("",trans->memo) == 0) &&
|
(strcmp("",trans->memo) == 0) &&
|
||||||
(strcmp("",trans->action) == 0) &&
|
(strcmp("",trans->action) == 0) &&
|
||||||
(0 == trans->catagory) &&
|
(0 == trans->catagory) &&
|
||||||
|
(NULL == xaccGetOtherAccount (acc, trans)) &&
|
||||||
|
(NULL == trans->debit) &&
|
||||||
(1.0 == trans->share_price) &&
|
(1.0 == trans->share_price) &&
|
||||||
(0.0 == trans->damount) )
|
(0.0 == trans->damount) )
|
||||||
{
|
{
|
||||||
_free(trans);
|
xaccRemoveTransaction (acc, trans);
|
||||||
|
freeTransaction (trans);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( regData->changed & MOD_DATE )
|
/* For many, but not all changes, we need to
|
||||||
{
|
* recalculate the balances */
|
||||||
Transaction *prevTrans;
|
if( regData->changed & (MOD_XFER | MOD_RECN | MOD_AMNT | MOD_PRIC | MOD_NEW)) {
|
||||||
Transaction *nextTrans;
|
|
||||||
Boolean outOfOrder = False;
|
|
||||||
prevTrans = getTransaction( acc, position-1 );
|
|
||||||
nextTrans = getTransaction( acc, position+1 );
|
|
||||||
|
|
||||||
DEBUG("MOD_DATE");
|
|
||||||
/* read in the date stuff... */
|
|
||||||
sscanf( XbaeMatrixGetCell(regData->reg,row,DATE_CELL_C),"%d/%d",
|
|
||||||
&(trans->date.month),
|
|
||||||
&(trans->date.day) );
|
|
||||||
|
|
||||||
trans->date.year = atoi(XbaeMatrixGetCell(regData->reg,row+1,DATE_CELL_C));
|
|
||||||
|
|
||||||
/* figure out if the transactions are out of order */
|
|
||||||
outOfOrder = xaccCheckDateOrderDE (trans);
|
|
||||||
|
|
||||||
/* take care of re-ordering implications on the register, if necessary */
|
|
||||||
if( outOfOrder )
|
|
||||||
{
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
if( !(regData->changed & MOD_NEW) )
|
|
||||||
{
|
|
||||||
int lastRow = (2 * newPosition) + 1 + DESC_CELL_C;
|
|
||||||
XbaeMatrixMakeCellVisible( regData->reg, lastRow, DESC_CELL_C );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* recalculate the balances, but only after re-ordering cells */
|
|
||||||
RECALC_BALANCE ((trans->credit));
|
RECALC_BALANCE ((trans->credit));
|
||||||
RECALC_BALANCE ((trans->debit));
|
RECALC_BALANCE ((trans->debit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REFRESH_REGISTER ((trans->credit));
|
||||||
|
REFRESH_REGISTER ((trans->debit));
|
||||||
|
|
||||||
/* reset the "changed" bitfield */
|
/* reset the "changed" bitfield */
|
||||||
regData->changed = 0;
|
regData->changed = 0;
|
||||||
|
|
||||||
@ -738,7 +791,7 @@ regSaveTransaction( RegWindow *regData, int position )
|
|||||||
REFRESH_RECONCILE_WIN ((trans->debit));
|
REFRESH_RECONCILE_WIN ((trans->debit));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* regWindow *
|
* regWindow *
|
||||||
@ -812,7 +865,7 @@ regWindow( Widget parent, Account *acc )
|
|||||||
XmNmarginWidth, 1,
|
XmNmarginWidth, 1,
|
||||||
XmNallowResize, True,
|
XmNallowResize, True,
|
||||||
XmNpaneMaximum, 200,
|
XmNpaneMaximum, 200,
|
||||||
XmNpaneMinimum, 200,
|
XmNpaneMinimum, 800,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
/* Setup the menubar at the top of the window */
|
/* Setup the menubar at the top of the window */
|
||||||
@ -867,7 +920,7 @@ regWindow( Widget parent, Account *acc )
|
|||||||
activityMenu[2].callback_data=(XtPointer)regData;
|
activityMenu[2].callback_data=(XtPointer)regData;
|
||||||
activityMenu[3].callback_data=(XtPointer)regData;
|
activityMenu[3].callback_data=(XtPointer)regData;
|
||||||
activityMenu[6].callback_data=(XtPointer)regData;
|
activityMenu[6].callback_data=(XtPointer)regData;
|
||||||
activityMenu[8].callback_data=(XtPointer)(regData->dialog);
|
activityMenu[8].callback_data=(XtPointer)(regData->dialog); /* destroy callback */
|
||||||
|
|
||||||
menubar = XmCreateMenuBar( pane, "menubar", NULL, 0 );
|
menubar = XmCreateMenuBar( pane, "menubar", NULL, 0 );
|
||||||
|
|
||||||
@ -932,13 +985,13 @@ regWindow( Widget parent, Account *acc )
|
|||||||
/* ----------------------------------- */
|
/* ----------------------------------- */
|
||||||
/* set up column widths */
|
/* set up column widths */
|
||||||
|
|
||||||
acc -> colWidths[DATE_CELL_C] = 5; /* the widths of columns */
|
acc -> colWidths[DATE_CELL_C] = 5; /* also YEAR_CELL_C */
|
||||||
acc -> colWidths[NUM_CELL_C] = 4; /* the widths of columns */
|
acc -> colWidths[NUM_CELL_C] = 8; /* also XFER_CELL_C */
|
||||||
acc -> colWidths[DESC_CELL_C] = 35; /* the widths of columns */
|
acc -> colWidths[DESC_CELL_C] = 35; /* also MEMO_CELL_C */
|
||||||
acc -> colWidths[RECN_CELL_C] = 1; /* the widths of columns */
|
acc -> colWidths[RECN_CELL_C] = 1; /* the widths of columns */
|
||||||
acc -> colWidths[PAY_CELL_C] = 8; /* the widths of columns */
|
acc -> colWidths[PAY_CELL_C] = 12; /* the widths of columns */
|
||||||
acc -> colWidths[DEP_CELL_C] = 8; /* the widths of columns */
|
acc -> colWidths[DEP_CELL_C] = 12; /* the widths of columns */
|
||||||
acc -> colWidths[BALN_CELL_C] = 8; /* $ balance */
|
acc -> colWidths[BALN_CELL_C] = 12; /* dollar balance */
|
||||||
|
|
||||||
switch(acc->type)
|
switch(acc->type)
|
||||||
{
|
{
|
||||||
@ -960,7 +1013,7 @@ regWindow( Widget parent, Account *acc )
|
|||||||
/* set up column alignments */
|
/* set up column alignments */
|
||||||
|
|
||||||
acc -> alignments[DATE_CELL_C] = XmALIGNMENT_END;
|
acc -> alignments[DATE_CELL_C] = XmALIGNMENT_END;
|
||||||
acc -> alignments[NUM_CELL_C] = XmALIGNMENT_END;
|
acc -> alignments[NUM_CELL_C] = XmALIGNMENT_BEGINNING; /* need XFER to be visible */
|
||||||
acc -> alignments[DESC_CELL_C] = XmALIGNMENT_BEGINNING;
|
acc -> alignments[DESC_CELL_C] = XmALIGNMENT_BEGINNING;
|
||||||
acc -> alignments[RECN_CELL_C] = XmALIGNMENT_CENTER;
|
acc -> alignments[RECN_CELL_C] = XmALIGNMENT_CENTER;
|
||||||
acc -> alignments[PAY_CELL_C] = XmALIGNMENT_END;
|
acc -> alignments[PAY_CELL_C] = XmALIGNMENT_END;
|
||||||
@ -1078,8 +1131,11 @@ regWindow( Widget parent, Account *acc )
|
|||||||
|
|
||||||
|
|
||||||
/* create action box for the first time */
|
/* create action box for the first time */
|
||||||
regData->ab = actionBox (reg);
|
regData->actbox = actionBox (reg);
|
||||||
|
|
||||||
|
/* create the xfer account box for the first time */
|
||||||
|
regData->xferbox = xferBox (reg, data);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************\
|
/******************************************************************\
|
||||||
* The button area... also contains balance fields *
|
* The button area... also contains balance fields *
|
||||||
@ -1197,8 +1253,9 @@ regWindow( Widget parent, Account *acc )
|
|||||||
|
|
||||||
XtPopup( regData->dialog, XtGrabNone );
|
XtPopup( regData->dialog, XtGrabNone );
|
||||||
|
|
||||||
/* unmanage the action box, until it is needed */
|
/* unmanage the ComboBoxes, until they are needed */
|
||||||
SetActionBox (regData->ab, -1, -1);
|
SetPopBox (regData->actbox, -1, -1);
|
||||||
|
SetPopBox (regData->xferbox, -1, -1);
|
||||||
|
|
||||||
unsetBusyCursor( parent );
|
unsetBusyCursor( parent );
|
||||||
|
|
||||||
@ -1219,12 +1276,16 @@ void
|
|||||||
closeRegWindow( Widget mw, XtPointer cd, XtPointer cb )
|
closeRegWindow( Widget mw, XtPointer cd, XtPointer cb )
|
||||||
{
|
{
|
||||||
RegWindow *regData = (RegWindow *)cd;
|
RegWindow *regData = (RegWindow *)cd;
|
||||||
Account *acc = regData->acc;
|
Account *acc;
|
||||||
|
|
||||||
|
acc = regData->acc;
|
||||||
|
|
||||||
/* Save any unsaved changes */
|
/* Save any unsaved changes */
|
||||||
XbaeMatrixCommitEdit( regData->reg, False );
|
XbaeMatrixCommitEdit( regData->reg, False );
|
||||||
regSaveTransaction( regData, regData->lastTrans );
|
regSaveTransaction( regData, regData->lastTrans );
|
||||||
|
|
||||||
|
/* hack alert -- free the ComboBox popup boxes data structures too */
|
||||||
|
|
||||||
_free(regData);
|
_free(regData);
|
||||||
acc->regData = NULL;
|
acc->regData = NULL;
|
||||||
|
|
||||||
@ -1291,24 +1352,6 @@ recordCB( Widget mw, XtPointer cd, XtPointer cb )
|
|||||||
* Return: none *
|
* 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
|
void
|
||||||
deleteCB( Widget mw, XtPointer cd, XtPointer cb )
|
deleteCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||||
{
|
{
|
||||||
@ -1362,7 +1405,7 @@ cancelCB( Widget mw, XtPointer cd, XtPointer cb )
|
|||||||
* add an undo/cancel modifications feature *
|
* add an undo/cancel modifications feature *
|
||||||
* *
|
* *
|
||||||
* Args: mw - the widget that called us *
|
* Args: mw - the widget that called us *
|
||||||
* cd - regData - the data struct for this register *
|
* cd - regData - the data struct for this register *
|
||||||
* cb - *
|
* cb - *
|
||||||
* Return: none *
|
* Return: none *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
@ -1409,6 +1452,7 @@ 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) &&
|
||||||
|
!IN_XFER_CELL(row,col) &&
|
||||||
!((PORTFOLIO == acc->type) && IN_PRIC_CELL(row,col)) &&
|
!((PORTFOLIO == acc->type) && IN_PRIC_CELL(row,col)) &&
|
||||||
!((MUTUAL == acc->type) && IN_PRIC_CELL(row,col)) &&
|
!((MUTUAL == acc->type) && IN_PRIC_CELL(row,col)) &&
|
||||||
!((PORTFOLIO == acc->type) && IN_ACTN_CELL(row,col)) &&
|
!((PORTFOLIO == acc->type) && IN_ACTN_CELL(row,col)) &&
|
||||||
@ -1444,9 +1488,16 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
|||||||
else if( ((PORTFOLIO == acc->type) && IN_ACTN_CELL(row,col)) ||
|
else if( ((PORTFOLIO == acc->type) && IN_ACTN_CELL(row,col)) ||
|
||||||
((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) )
|
((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) )
|
||||||
{
|
{
|
||||||
SetActionBox (regData->ab, row, col);
|
SetPopBox (regData->actbox, row, col);
|
||||||
regData->changed |= MOD_ACTN;
|
regData->changed |= MOD_ACTN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* otherwise, move the XFER widget */
|
||||||
|
else if( IN_XFER_CELL(row,col) )
|
||||||
|
{
|
||||||
|
SetPopBox (regData->xferbox, row, col);
|
||||||
|
regData->changed |= MOD_XFER;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1618,7 +1669,15 @@ regCB( Widget mw, XtPointer cd, XtPointer cb )
|
|||||||
((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) ) {
|
((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) ) {
|
||||||
regData->changed |= MOD_ACTN;
|
regData->changed |= MOD_ACTN;
|
||||||
}
|
}
|
||||||
|
/* Note: for cell widgets, this callback will never
|
||||||
|
* indicate a row,col with a cell widget in it.
|
||||||
|
* Thus, the following if statment will never be true
|
||||||
|
*/
|
||||||
|
if( IN_XFER_CELL(row,col) )
|
||||||
|
regData->changed |= MOD_XFER;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XbaeTraverseCellReason:
|
case XbaeTraverseCellReason:
|
||||||
DEBUG("XbaeTraverseCellReason");
|
DEBUG("XbaeTraverseCellReason");
|
||||||
/* This ensure that whenever the user hits TAB, they go to the
|
/* This ensure that whenever the user hits TAB, they go to the
|
||||||
@ -1863,11 +1922,11 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs, int do_y
|
|||||||
|
|
||||||
if( changed )
|
if( changed )
|
||||||
{
|
{
|
||||||
sprintf( buf,"%2d/%2d\0\0", date.month, date.day );
|
sprintf( buf,"%2d/%2d", date.month, date.day );
|
||||||
XbaeMatrixSetCell( mw, row, col, buf );
|
XbaeMatrixSetCell( mw, row, col, buf );
|
||||||
XbaeMatrixRefreshCell( mw, row, col );
|
XbaeMatrixRefreshCell( mw, row, col );
|
||||||
|
|
||||||
sprintf( buf,"%4d\0", date.year );
|
sprintf( buf,"%4d", date.year );
|
||||||
XbaeMatrixSetCell( mw, row+1, col, buf );
|
XbaeMatrixSetCell( mw, row+1, col, buf );
|
||||||
XbaeMatrixRefreshCell( mw, row+1, col );
|
XbaeMatrixRefreshCell( mw, row+1, col );
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ initTransaction( Transaction * trans )
|
|||||||
trans->debit = 0x0;
|
trans->debit = 0x0;
|
||||||
trans->credit = 0x0;
|
trans->credit = 0x0;
|
||||||
|
|
||||||
trans->num = NULL;
|
trans->num = XtNewString("");
|
||||||
trans->description = NULL;
|
trans->description = XtNewString("");
|
||||||
trans->memo = NULL;
|
trans->memo = XtNewString("");
|
||||||
trans->action = NULL;
|
trans->action = XtNewString("");
|
||||||
trans->catagory = 0;
|
trans->catagory = 0;
|
||||||
trans->reconciled = NREC;
|
trans->reconciled = NREC;
|
||||||
trans->damount = 0.0;
|
trans->damount = 0.0;
|
||||||
@ -88,6 +88,7 @@ freeTransaction( Transaction *trans )
|
|||||||
XtFree(trans->num);
|
XtFree(trans->num);
|
||||||
XtFree(trans->description);
|
XtFree(trans->description);
|
||||||
XtFree(trans->memo);
|
XtFree(trans->memo);
|
||||||
|
XtFree(trans->action);
|
||||||
|
|
||||||
initTransaction (trans); /* just in case someone looks up freed memory ... */
|
initTransaction (trans); /* just in case someone looks up freed memory ... */
|
||||||
_free(trans);
|
_free(trans);
|
||||||
|
56
src/XferBox.c
Normal file
56
src/XferBox.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/********************************************************************\
|
||||||
|
* XferBox.c -- account transfers for xacc (X-Accountant) *
|
||||||
|
* 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 *
|
||||||
|
* published by the Free Software Foundation; either version 2 of *
|
||||||
|
* the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License*
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||||
|
* *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
|
#include "Data.h"
|
||||||
|
#include "PopBox.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* xferBox *
|
||||||
|
* creates the xfer widget *
|
||||||
|
* *
|
||||||
|
* Args: parent - the parent of this window *
|
||||||
|
* Return: PopBox - the xfer GUI structure *
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
PopBox *
|
||||||
|
xferBox (Widget parent, Data *dayta)
|
||||||
|
{
|
||||||
|
PopBox *popGUI;
|
||||||
|
Account * acc;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
popGUI = popBox (parent);
|
||||||
|
|
||||||
|
/* build the xfer menu out of account names */
|
||||||
|
n = 0;
|
||||||
|
acc = getAccount (dayta, n);
|
||||||
|
while (acc) {
|
||||||
|
AddPopBoxMenuItem (popGUI, acc->accountName);
|
||||||
|
n++;
|
||||||
|
acc = getAccount (dayta, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return popGUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************* END OF FILE ******************************/
|
@ -94,7 +94,7 @@ String fbRes[] = {
|
|||||||
"*recn*cellMarginWidth: 0",
|
"*recn*cellMarginWidth: 0",
|
||||||
"*recn*cellMarginHeight: 0",
|
"*recn*cellMarginHeight: 0",
|
||||||
/* combobox -- don't want the cell to be outlined */
|
/* combobox -- don't want the cell to be outlined */
|
||||||
"*reg*actionbox*shadowThickness: 0",
|
"*reg*popbox*shadowThickness: 0",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user