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:
Linas Vepstas 1997-11-16 08:37:38 +00:00
parent f4b8273650
commit a9d8972674
14 changed files with 662 additions and 420 deletions

View File

@ -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
######################################################################

6
README
View File

@ -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

View File

@ -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 );

View File

@ -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; i<acc->numTrans; 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; 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
* 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 );

View File

@ -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 <Xm/Xm.h>
#include <ComboBox.h>
#include <Xbae/Matrix.h>
#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 ******************************/

View File

@ -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; i<data->numAcc; i++) {
peer_acc = data->account[i];
if (!strcmp(peer_acc->accountName, name)) return peer_acc;
}
return NULL;
}
/********************************************************************\
\********************************************************************/
Account *

View File

@ -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 *

View File

@ -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}

185
src/PopBox.c Normal file
View 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 ******************************/

View File

@ -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 *********************************\
\********************************************************************/

View File

@ -35,13 +35,14 @@
#include <Xbae/Matrix.h>
#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 );
}

View File

@ -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);

56
src/XferBox.c Normal file
View 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 ******************************/

View File

@ -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,
};