From a9d89726749ee0dd1273ac808f90ddf0dc299bc8 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Sun, 16 Nov 1997 08:37:38 +0000 Subject: [PATCH] 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 --- Makefile | 1 + README | 6 +- src/AccWindow.c | 8 +- src/Account.c | 190 ++++++++++++--------- src/Action.c | 156 ++--------------- src/Data.c | 24 +++ src/MainWindow.c | 2 +- src/Makefile | 4 +- src/PopBox.c | 185 +++++++++++++++++++++ src/QuickFill.c | 24 +-- src/RegWindow.c | 415 ++++++++++++++++++++++++++-------------------- src/Transaction.c | 9 +- src/XferBox.c | 56 +++++++ src/main.c | 2 +- 14 files changed, 662 insertions(+), 420 deletions(-) create mode 100644 src/PopBox.c create mode 100644 src/XferBox.c diff --git a/Makefile b/Makefile index 11e46f2aad..bd6e13be95 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,7 @@ CFLAGS = $(LFLAGS) -I../include -I../libhtmlw -I../Xbae-4.6.2-linas \ # -DUSEQUICKFILL # -DUSE_NO_COLOR -DDEBUGMEMORY -DUSEDEBUG 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 -lefence ###################################################################### diff --git a/README b/README index 93ba0e3b91..8425bec0f0 100644 --- a/README +++ b/README @@ -39,11 +39,15 @@ sorry, no "make install" yet. Status: ------- -As of version 0.9j: +As of version 0.9k: Bugs: +-- Cash distributions & cash dividends on stock not handled properly -- tabbing between fields for mutual funds does not work correctly. -- should add "number of shares" to transfer popup when transferring 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 diff --git a/src/AccWindow.c b/src/AccWindow.c index e7a56027d0..0c7e00fa0f 100644 --- a/src/AccWindow.c +++ b/src/AccWindow.c @@ -662,12 +662,12 @@ Do you want to continue anyway?\n"); /* Add an opening balance transaction (as the first transaction) */ trans = mallocTransaction(); + initTransaction(trans); todaysDate( &(trans->date) ); - trans->num = XtNewString(""); - trans->description = XtNewString("Opening Balance\0"); - trans->memo = XtNewString(""); - + XtFree (trans->description); + trans->description = XtNewString("Opening Balance"); + /* add the new transaction to the account */ insertTransaction( acc, trans ); diff --git a/src/Account.c b/src/Account.c index 7c26abcd36..298267f75b 100644 --- a/src/Account.c +++ b/src/Account.c @@ -23,11 +23,11 @@ * Huntington Beach, CA 92648-4632 * \********************************************************************/ -#include "util.h" -#include "main.h" -#include "Data.h" #include "Account.h" +#include "Data.h" #include "date.h" +#include "main.h" +#include "util.h" extern Data *data; int next_free_unique_account_id = 0; @@ -94,13 +94,14 @@ freeAccount( Account *acc ) /* free the transaction only if its not * a part of a double entry */ - if (trans->credit == _acc) trans->credit = NULL; - if (trans->debit == _acc) trans->debit = NULL; + if (_acc == trans->credit) trans->credit = NULL; + if (_acc == trans->debit) trans->debit = NULL; if ( (NULL == trans->debit) && (NULL == trans->credit) ) { freeTransaction( trans ); } } + /* free the array of pointers */ _free( acc->transaction ); _free(acc); @@ -142,7 +143,6 @@ removeTransaction( Account *acc, int num ) if( acc != NULL ) { int i,j; - struct _account * _acc = (struct _account *) acc; Transaction **oldTrans = acc->transaction; /* check for valid number */ @@ -173,104 +173,138 @@ removeTransaction( Account *acc, int num ) /* if this is a double-entry transaction, be sure to * unmark it. */ - if (trans->credit == _acc) trans->credit = NULL; - if (trans->debit == _acc) trans->debit = NULL; + if (((Account *)trans->credit) == acc) trans->credit = NULL; + if (((Account *)trans->debit) == acc) trans->debit = NULL; } return trans; } +/********************************************************************\ +\********************************************************************/ + +void +xaccRemoveTransaction( Account *acc, Transaction *trans) +{ + int i = getNumOfTransaction (acc, trans); + if (0 <= i) { + removeTransaction (acc, i); + } +} + /********************************************************************\ \********************************************************************/ int insertTransaction( Account *acc, Transaction *trans ) { 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; - Date *dj,*dt; - int inserted = False; - 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"); - } - } + printf ("Internal Error: insertTransaction(): \n"); + printf ("can't insert a transaction more than twice! \n"); + printf ("This error should not occur, please report it \n"); } + } - /* mark the data file as needing to be saved: */ - if( data != NULL ) - data->saved = False; - - acc->numTrans++; - 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 - * the new transaction before the first transaction of the same - * or later date. The !inserted bit is a bit of a kludge to - * make sure we only insert the new transaction once! */ - dt = &(trans->date); - for( i=0,j=0; inumTrans; i++,j++ ) + /* mark the data file as needing to be saved: */ + if( data != NULL ) + data->saved = False; + + acc->numTrans++; + oldTrans = acc->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 + * the new transaction before the first transaction of the same + * or later date. The !inserted bit is a bit of a kludge to + * make sure we only insert the new transaction once! */ + dt = &(trans->date); + for( i=0,j=0; inumTrans; 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 - * last spot in the array, we would walk off the end of the - * old array, which is no good! */ - if( j>=(acc->numTrans-1) ) + position = i; + acc->transaction[i] = trans; + break; + } + else + { + dj = &(oldTrans[j]->date); + if( (datecmp(dj,dt) > 0) & !inserted ) { position = i; acc->transaction[i] = trans; - break; + j--; + inserted = True; } else - { - 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]; - } + acc->transaction[i] = oldTrans[j]; } - - _free(oldTrans); } + _free(oldTrans); + if( position != -1 ) qfInsertTransaction( acc->qfRoot, trans ); 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; 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; + printf ("Internal Error: xaccCheckDateOrder(): \n"); + printf ("transaction not present in the account !\n"); + return 0; } prevTrans = getTransaction( acc, position-1 ); diff --git a/src/Action.c b/src/Action.c index d1ccd58812..70a40f8b96 100644 --- a/src/Action.c +++ b/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 * * * * This program is free software; you can redistribute it and/or * @@ -19,161 +19,37 @@ \********************************************************************/ #include -#include -#include + #include "Action.h" +#include "PopBox.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 * * creates the action widget * * * * Args: parent - the parent of this window * - * Return: actionData - the action GUI structure * + * Return: PopBox - the action GUI structure * \********************************************************************/ -#define ADD_MENU_ITEM(menustr) { \ - str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET); \ - XmComboBoxAddItem(combobox, str, 0); XmStringFree(str); \ -} - - -ActionBox * +PopBox * actionBox (Widget parent) { - Widget combobox; - XmString str; - ActionBox *actionData; + PopBox *popGUI; - /* malloc the action GUI structure */ - 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; + popGUI = popBox (parent); /* build the action menu */ - ADD_MENU_ITEM("Buy"); - ADD_MENU_ITEM("Sell"); - ADD_MENU_ITEM("Price"); - ADD_MENU_ITEM("Div"); - ADD_MENU_ITEM("LTCG"); - ADD_MENU_ITEM("STCG"); - ADD_MENU_ITEM("Dist"); - ADD_MENU_ITEM("Split"); + AddPopBoxMenuItem (popGUI, "Buy"); + AddPopBoxMenuItem (popGUI, "Sell"); + AddPopBoxMenuItem (popGUI, "Price"); + AddPopBoxMenuItem (popGUI, "Div"); + AddPopBoxMenuItem (popGUI, "LTCG"); + AddPopBoxMenuItem (popGUI, "STCG"); + AddPopBoxMenuItem (popGUI, "Dist"); + AddPopBoxMenuItem (popGUI, "Split"); - /* add callbacks to detect a selection */ - XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)actionData); - XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)actionData); - - - return actionData; + return popGUI; } -/********************************************************************\ -\********************************************************************/ - -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 ******************************/ diff --git a/src/Data.c b/src/Data.c index 7b05acd26c..0f208080ff 100644 --- a/src/Data.c +++ b/src/Data.c @@ -108,6 +108,30 @@ xaccGetPeerAccountFromID ( Account *acc, int acc_id ) 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; inumAcc; i++) { + peer_acc = data->account[i]; + if (!strcmp(peer_acc->accountName, name)) return peer_acc; + } + + return NULL; +} + /********************************************************************\ \********************************************************************/ Account * diff --git a/src/MainWindow.c b/src/MainWindow.c index a833b1ea1e..7636e06031 100644 --- a/src/MainWindow.c +++ b/src/MainWindow.c @@ -415,7 +415,7 @@ mainWindow( Widget parent ) /********************************************************************\ * closeMainWindow * - * frees memory allocated for an regWindow, and other cleanup * + * frees memory allocated for an mainWindow, and other cleanup * * stuff * * * * Args: mw - the widget that called us * diff --git a/src/Makefile b/src/Makefile index 50e89c527b..695242a511 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,9 +27,9 @@ # DO NOT EDIT THE STUFF BELOW THIS LINE! # 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 \ - Transaction.o util.o XferWindow.o + Transaction.o util.o XferBox.o XferWindow.o SRCS = ${OBJS:.o=.c} diff --git a/src/PopBox.c b/src/PopBox.c new file mode 100644 index 0000000000..243c6702b0 --- /dev/null +++ b/src/PopBox.c @@ -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 +#include +#include +#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 ******************************/ diff --git a/src/QuickFill.c b/src/QuickFill.c index dc4cd9f275..517af98caa 100644 --- a/src/QuickFill.c +++ b/src/QuickFill.c @@ -113,17 +113,21 @@ qfInsertTransactionRec( QuickFill *qf, Transaction *trans, int depth ) { if( qf != NULL ) { - if( trans->description[depth] != '\0' ) + if( trans->description ) { - int index = CHAR_TO_INDEX( trans->description[depth] ); - - if( qf->qf[index] == NULL ) - qf->qf[index] = mallocQuickFill(); - - qf->qf[index]->trans = trans; - - qfInsertTransactionRec( qf->qf[index], trans, ++depth ); + if( trans->description[depth] != '\0' ) + { + int index = CHAR_TO_INDEX( trans->description[depth] ); + + if( qf->qf[index] == NULL ) + qf->qf[index] = mallocQuickFill(); + + qf->qf[index]->trans = trans; + + qfInsertTransactionRec( qf->qf[index], trans, ++depth ); + } } } } - +/********************** END OF FILE *********************************\ +\********************************************************************/ diff --git a/src/RegWindow.c b/src/RegWindow.c index fd388959d9..d78e5a4b5a 100644 --- a/src/RegWindow.c +++ b/src/RegWindow.c @@ -35,13 +35,14 @@ #include #include "Account.h" -#include "ActionBox.h" +#include "Action.h" #include "AdjBWindow.h" #include "BuildMenu.h" #include "Data.h" #include "date.h" #include "main.h" #include "MainWindow.h" +#include "PopBox.h" #include "QuickFill.h" #include "RecnWindow.h" #include "Transaction.h" @@ -62,7 +63,8 @@ typedef struct _RegWindow { QuickFill *qf; /* keeps track of current quickfill node. * * Reset to Account->qfRoot when entering * * a new transaction */ - ActionBox *ab; + PopBox *actbox; /* ComboBox for actions */ + PopBox *xferbox; /* ComboBox for transfers */ } RegWindow; @@ -106,8 +108,9 @@ extern Pixel negPixel; #define MOD_PRIC 0x40 #define MOD_MEMO 0x80 #define MOD_ACTN 0x100 -#define MOD_NEW 0x200 -#define MOD_ALL 0x3ff +#define MOD_XFER 0x200 +#define MOD_NEW 0x400 +#define MOD_ALL 0x7ff /* These defines are indexes into the column location array */ #define DATE_COL_ID 0 @@ -141,10 +144,14 @@ extern Pixel negPixel; #define SHRS_CELL_C (acc->columnLocation[SHRS_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_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_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 */ @@ -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_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_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]; String **data = NULL; String **newData; - Account *acc; + Account *acc, *xfer_acc; double themount; /* amount */ XtVaGetValues( regData->reg, XmNrows, &nrows, NULL ); @@ -214,7 +222,7 @@ regRefresh( RegWindow *regData ) /* and fill in the data for the matrix: */ i=-1; - while( (trans=getTransaction(regData->acc,++i)) != NULL ) + while( (trans = getTransaction (acc,++i)) != NULL ) { int row = i*2+1; @@ -222,25 +230,29 @@ regRefresh( RegWindow *regData ) trans->date.month, trans->date.day ); newData[row][DATE_CELL_C] = XtNewString(buf); - 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 ); 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 ); newData[row][DESC_CELL_C] = XtNewString(buf); - sprintf( buf, "%s", trans->memo ); newData[row+1][DESC_CELL_C] = XtNewString(buf); sprintf( buf, "%c", trans->reconciled ); newData[row][RECN_CELL_C] = XtNewString(buf); - newData[row+1][RECN_CELL_C] = XtNewString(""); /* ----------------------------------- */ @@ -463,50 +475,112 @@ regRecalculateBalance( RegWindow *regData ) * 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); \ - } \ - } \ +/* RECALC_BALANCE recomputes the balance shown in + * the register window, if its is visible + */ + +#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); \ + } \ + } \ +} + +/* 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 regSaveTransaction( RegWindow *regData, int position ) - { +{ /* save transaction structure... in order to speed this up, * 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 */ char buf[BUFSIZE]; - int newPosition; int row = (position * 2) + 1; - Account *acc; + Account *acc = regData->acc; 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 ); - /* 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 ) { /* This must be a 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->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; } if( regData->changed & MOD_NUM ) @@ -517,6 +591,34 @@ regSaveTransaction( RegWindow *regData, int position ) 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 ) { DEBUG("MOD_DESC"); @@ -533,34 +635,13 @@ regSaveTransaction( RegWindow *regData, int position ) DEBUG("MOD_MEMO"); /* ... the memo ... */ XtFree( trans->memo ); - - tmp = XbaeMatrixGetCell(regData->reg,row+1,MEMO_CELL_C); - - /* 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 ); - } + tmp = XbaeMatrixGetCell(regData->reg,row+MEMO_CELL_R,MEMO_CELL_C); + 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; DEBUG("MOD_ACTN"); @@ -575,10 +656,6 @@ regSaveTransaction( RegWindow *regData, int position ) DEBUG("MOD_RECN"); /* ...the reconciled flag (char)... */ 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 ) @@ -603,7 +680,7 @@ regSaveTransaction( RegWindow *regData, int position ) /* Reset so there is only one field filled */ 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 ); XbaeMatrixSetCell( regData->reg, row, PAY_CELL_C, buf ); 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, 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) && ((MUTUAL == acc->type) || (PORTFOLIO==acc->type)) ) { @@ -635,91 +709,70 @@ regSaveTransaction( RegWindow *regData, int position ) sprintf( buf, "%.2f ", trans->share_price ); 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 - * 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 ) + if( regData->changed & MOD_DATE ) { + 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) && (strcmp("",trans->description) == 0) && (strcmp("",trans->memo) == 0) && (strcmp("",trans->action) == 0) && (0 == trans->catagory) && + (NULL == xaccGetOtherAccount (acc, trans)) && + (NULL == trans->debit) && (1.0 == trans->share_price) && - (0.0 == trans->damount) ) + (0.0 == trans->damount) ) { - _free(trans); + xaccRemoveTransaction (acc, trans); + freeTransaction (trans); return; } } - if( regData->changed & MOD_DATE ) - { - Transaction *prevTrans; - 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 */ + /* For many, but not all changes, we need to + * recalculate the balances */ + if( regData->changed & (MOD_XFER | MOD_RECN | MOD_AMNT | MOD_PRIC | MOD_NEW)) { RECALC_BALANCE ((trans->credit)); RECALC_BALANCE ((trans->debit)); - } - + } + + REFRESH_REGISTER ((trans->credit)); + REFRESH_REGISTER ((trans->debit)); + /* reset the "changed" bitfield */ regData->changed = 0; @@ -738,7 +791,7 @@ regSaveTransaction( RegWindow *regData, int position ) REFRESH_RECONCILE_WIN ((trans->debit)); return; - } +} /********************************************************************\ * regWindow * @@ -812,7 +865,7 @@ regWindow( Widget parent, Account *acc ) XmNmarginWidth, 1, XmNallowResize, True, XmNpaneMaximum, 200, - XmNpaneMinimum, 200, + XmNpaneMinimum, 800, NULL ); /* 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[3].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 ); @@ -932,13 +985,13 @@ regWindow( Widget parent, Account *acc ) /* ----------------------------------- */ /* set up column widths */ - 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[DATE_CELL_C] = 5; /* also YEAR_CELL_C */ + acc -> colWidths[NUM_CELL_C] = 8; /* also XFER_CELL_C */ + acc -> colWidths[DESC_CELL_C] = 35; /* also MEMO_CELL_C */ acc -> colWidths[RECN_CELL_C] = 1; /* the widths of columns */ - acc -> colWidths[PAY_CELL_C] = 8; /* the widths of columns */ - acc -> colWidths[DEP_CELL_C] = 8; /* the widths of columns */ - acc -> colWidths[BALN_CELL_C] = 8; /* $ balance */ + acc -> colWidths[PAY_CELL_C] = 12; /* the widths of columns */ + acc -> colWidths[DEP_CELL_C] = 12; /* the widths of columns */ + acc -> colWidths[BALN_CELL_C] = 12; /* dollar balance */ switch(acc->type) { @@ -960,7 +1013,7 @@ regWindow( Widget parent, Account *acc ) /* set up column alignments */ 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[RECN_CELL_C] = XmALIGNMENT_CENTER; acc -> alignments[PAY_CELL_C] = XmALIGNMENT_END; @@ -1078,8 +1131,11 @@ regWindow( Widget parent, Account *acc ) /* 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 * @@ -1197,8 +1253,9 @@ regWindow( Widget parent, Account *acc ) XtPopup( regData->dialog, XtGrabNone ); - /* unmanage the action box, until it is needed */ - SetActionBox (regData->ab, -1, -1); + /* unmanage the ComboBoxes, until they are needed */ + SetPopBox (regData->actbox, -1, -1); + SetPopBox (regData->xferbox, -1, -1); unsetBusyCursor( parent ); @@ -1219,12 +1276,16 @@ void closeRegWindow( Widget mw, XtPointer cd, XtPointer cb ) { RegWindow *regData = (RegWindow *)cd; - Account *acc = regData->acc; + Account *acc; + + acc = regData->acc; /* Save any unsaved changes */ XbaeMatrixCommitEdit( regData->reg, False ); regSaveTransaction( regData, regData->lastTrans ); + /* hack alert -- free the ComboBox popup boxes data structures too */ + _free(regData); acc->regData = NULL; @@ -1291,24 +1352,6 @@ recordCB( Widget mw, XtPointer cd, XtPointer 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 ) { @@ -1362,7 +1405,7 @@ cancelCB( Widget mw, XtPointer cd, XtPointer cb ) * add an undo/cancel modifications feature * * * * Args: mw - the widget that called us * - * cd - regData - the data struct for this register * + * cd - regData - the data struct for this register * * cb - * * Return: none * \********************************************************************/ @@ -1409,6 +1452,7 @@ regCB( Widget mw, XtPointer cd, XtPointer cb ) if( !IN_DATE_CELL(row,col) && !IN_NUM_CELL(row,col) && !IN_DESC_CELL(row,col) && !IN_PAY_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)) && !((MUTUAL == acc->type) && IN_PRIC_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)) || ((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) ) { - SetActionBox (regData->ab, row, col); + SetPopBox (regData->actbox, row, col); 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; } @@ -1618,7 +1669,15 @@ regCB( Widget mw, XtPointer cd, XtPointer cb ) ((MUTUAL == acc->type) && IN_ACTN_CELL(row,col)) ) { 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; + case XbaeTraverseCellReason: DEBUG("XbaeTraverseCellReason"); /* 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 ) { - sprintf( buf,"%2d/%2d\0\0", date.month, date.day ); + sprintf( buf,"%2d/%2d", date.month, date.day ); XbaeMatrixSetCell( mw, row, col, buf ); XbaeMatrixRefreshCell( mw, row, col ); - sprintf( buf,"%4d\0", date.year ); + sprintf( buf,"%4d", date.year ); XbaeMatrixSetCell( mw, row+1, col, buf ); XbaeMatrixRefreshCell( mw, row+1, col ); } diff --git a/src/Transaction.c b/src/Transaction.c index 6cecf5d4da..57619e2de7 100644 --- a/src/Transaction.c +++ b/src/Transaction.c @@ -46,10 +46,10 @@ initTransaction( Transaction * trans ) trans->debit = 0x0; trans->credit = 0x0; - trans->num = NULL; - trans->description = NULL; - trans->memo = NULL; - trans->action = NULL; + trans->num = XtNewString(""); + trans->description = XtNewString(""); + trans->memo = XtNewString(""); + trans->action = XtNewString(""); trans->catagory = 0; trans->reconciled = NREC; trans->damount = 0.0; @@ -88,6 +88,7 @@ freeTransaction( Transaction *trans ) XtFree(trans->num); XtFree(trans->description); XtFree(trans->memo); + XtFree(trans->action); initTransaction (trans); /* just in case someone looks up freed memory ... */ _free(trans); diff --git a/src/XferBox.c b/src/XferBox.c new file mode 100644 index 0000000000..91ec48f6d8 --- /dev/null +++ b/src/XferBox.c @@ -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 + +#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 ******************************/ diff --git a/src/main.c b/src/main.c index 13045900ae..dc6aeb09aa 100644 --- a/src/main.c +++ b/src/main.c @@ -94,7 +94,7 @@ String fbRes[] = { "*recn*cellMarginWidth: 0", "*recn*cellMarginHeight: 0", /* combobox -- don't want the cell to be outlined */ - "*reg*actionbox*shadowThickness: 0", + "*reg*popbox*shadowThickness: 0", NULL, };