diff --git a/src/AccWindow.c b/src/AccWindow.c index 208329a164..0437af25a3 100644 --- a/src/AccWindow.c +++ b/src/AccWindow.c @@ -40,12 +40,10 @@ #include "AccountMenu.h" #include "Data.h" #include "main.h" +#include "TextBox.h" #include "util.h" -/* NOTE: notes has to be at the beginning of the struct! Order is - * important -- hack alert -- why is order important ?? */ typedef struct _accwindow { - String notes; /* The text from the "Notes" window */ /* The account type buttons: */ Widget dialog; @@ -56,29 +54,41 @@ typedef struct _accwindow { Widget desc; /* Account description text field */ AccountMenu *accMenu; + + Account *newacc; /* tmp account for editing */ + } AccWindow; -/* NOTE: notes has to be at the beginning of the struct! Order is - * important -- hack alert -- why is order important ?? */ typedef struct _editaccwindow { - String notes; /* The text from the "Notes" window */ + Widget dialog; /* The text fields: */ Widget name; /* The account name text field */ Widget desc; /* Account description text field */ Account *account; /* The account to edit */ + } EditAccWindow; +typedef struct _editnoteswindow { + TextBox *tb; + Account *account; /* The account to edit */ + +} EditNotesWindow; + /** GLOBALS *********************************************************/ extern Widget toplevel; /** PROTOTYPES ******************************************************/ -void closeAccWindow ( Widget mw, XtPointer cd, XtPointer cb ); -void closeEditAccWindow ( Widget mw, XtPointer cd, XtPointer cb ); -static void notesCB ( Widget mw, XtPointer cd, XtPointer cb ); -static void createCB ( Widget mw, XtPointer cd, XtPointer cb ); -static void editCB ( Widget mw, XtPointer cd, XtPointer cb ); -static void selectAccountCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void closeAccWindow ( Widget mw, XtPointer cd, XtPointer cb ); +static void closeEditAccWindow ( Widget mw, XtPointer cd, XtPointer cb ); +static void notesCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void editNotesCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void createCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void finishEditCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void selectAccountCB ( Widget mw, XtPointer cd, XtPointer cb ); +static void closeEditNotesWindow( Widget mw, XtPointer cd, XtPointer cb ); + +EditNotesWindow * editNotesWindow (Account *acc); /********************************************************************\ * accWindow * @@ -88,7 +98,7 @@ static void selectAccountCB ( Widget mw, XtPointer cd, XtPointer cb ); * Args: parent - the parent of the window to be created * * Return: none * \********************************************************************/ -void +AccWindow * accWindow( Widget parent ) { int i; @@ -100,7 +110,8 @@ accWindow( Widget parent ) setBusyCursor( parent ); accData = (AccWindow *)_malloc(sizeof(AccWindow)); - accData->notes = XtNewString(""); + + accData->newacc = mallocAccount(); /* force the size of the dialog so it is not resizable */ dialog = XtVaCreatePopupShell( "dialog", @@ -329,6 +340,8 @@ accWindow( Widget parent ) XtPopup( dialog, XtGrabNone ); unsetBusyCursor( parent ); + + return accData; } /********************************************************************\ @@ -342,16 +355,27 @@ accWindow( Widget parent ) * cb - * * Return: none * \********************************************************************/ -void +static void closeAccWindow( Widget mw, XtPointer cd, XtPointer cb ) { AccWindow *accData = (AccWindow *)cd; - + + if(accData->newacc) freeAccount (accData->newacc); + xaccFreeAccountMenu (accData->accMenu); _free(accData); DEBUG("close AccWindow"); } +/********************************************************************\ +\********************************************************************/ + +void xaccDestroyEditAccWindow (EditAccWindow *editAccData) +{ + if (!editAccData) return; + XtDestroyWidget (editAccData->dialog); +} + /********************************************************************\ * editAccWindow * * opens up a window to edit an account * @@ -360,22 +384,20 @@ closeAccWindow( Widget mw, XtPointer cd, XtPointer cb ) * account - the account to edit * * Return: none * \********************************************************************/ -void +EditAccWindow * editAccWindow( Widget parent, Account *account ) { + Widget dialog, form, widget, label, buttonform; EditAccWindow *editAccData; - /* hack alert -- if no account selected for editing, - * put up a popup and tell the user to pick something. - * for the moment, we just no-op. */ - if (0x0 == account) return; + if (0x0 == account) return 0x0; /* internal error, really */ setBusyCursor( parent ); editAccData = (EditAccWindow *)_malloc(sizeof(EditAccWindow)); - editAccData->notes = account->notes; editAccData->account = account; + account->editAccData = editAccData; /* force the size of the dialog so it is not resizable */ dialog = XtVaCreatePopupShell( "dialog", @@ -392,6 +414,7 @@ editAccWindow( Widget parent, Account *account ) XmNallowShellResize, FALSE, XmNtransient, FALSE, /* allow window to be repositioned */ NULL ); + editAccData->dialog = dialog; XtAddCallback( dialog, XmNdestroyCallback, closeEditAccWindow, (XtPointer)editAccData ); @@ -481,7 +504,7 @@ editAccWindow( Widget parent, Account *account ) NULL ); XtAddCallback( widget, XmNactivateCallback, - notesCB, (XtPointer)editAccData ); + editNotesCB, (XtPointer)editAccData ); /* The "Cancel" button */ widget = @@ -513,7 +536,7 @@ editAccWindow( Widget parent, Account *account ) NULL ); XtAddCallback( widget, XmNactivateCallback, - editCB, (XtPointer)editAccData ); + finishEditCB, (XtPointer)editAccData ); /* We need to do something to clean up memory too! */ XtAddCallback( widget, XmNactivateCallback, destroyShellCB, (XtPointer)dialog ); @@ -526,6 +549,8 @@ editAccWindow( Widget parent, Account *account ) XtPopup( dialog, XtGrabNone ); unsetBusyCursor( parent ); + + return editAccData; } /********************************************************************\ @@ -539,14 +564,12 @@ editAccWindow( Widget parent, Account *account ) * cb - * * Return: none * \********************************************************************/ -void +static void closeEditAccWindow( Widget mw, XtPointer cd, XtPointer cb ) { EditAccWindow *editAccData = (EditAccWindow *)cd; -printf ("close edit acc window %x %s \n", editAccData, -editAccData->notes); - + editAccData->account->editAccData = NULL; _free(editAccData); DEBUG("close EditAccWindow"); } @@ -562,14 +585,35 @@ editAccData->notes); \********************************************************************/ static void notesCB( Widget mw, XtPointer cd, XtPointer cb ) - { +{ AccWindow *accData = (AccWindow *)cd; - - /* hack alert -- isn't this a memory leak ????? */ -printf ("orig notes are %x %s \n", accData, accData->notes); - accData->notes = textBox( toplevel, "Notes", accData->notes, True ); -printf ("new notes are %s \n", accData->notes); + Account *acc = accData -> newacc; + if (NULL == acc->editNotesData) { + editNotesWindow (acc); } + /* hack alert -- else, should raise window to the top */ +} + +/********************************************************************\ + * editNotesCB -- called when the user presses the "Notes" Button * + * * + * Args: mw - the widget that called us * + * cd - accData - the struct that has the notes text in it * + * cb - * + * Return: none * + * Global: toplevel - the toplevel widget * +\********************************************************************/ +static void +editNotesCB( Widget mw, XtPointer cd, XtPointer cb ) +{ + EditAccWindow *editAccData = (EditAccWindow *)cd; + Account *acc = editAccData -> account; + + if (NULL == acc->editNotesData) { + editNotesWindow (acc); + } + /* hack alert -- else, should raise window to the top */ +} /********************************************************************\ * createCB -- creates the new account from data in the newaccount * @@ -601,11 +645,12 @@ createCB( Widget mw, XtPointer cd, XtPointer cb ) return; } - acc = mallocAccount(); + acc = accData->newacc; + accData->newacc = NULL; + acc->flags = 0; acc->accountName = name; acc->description = desc; - acc->notes = accData->notes; /* figure out account type */ for (i=0; iname); @@ -844,5 +889,56 @@ selectAccountCB( Widget mw, XtPointer cd, XtPointer cb ) } } +/********************************************************************\ + * * +\********************************************************************/ + +EditNotesWindow * +editNotesWindow (Account *acc) +{ + EditNotesWindow *editNotesData; + + if (!acc) return 0x0; + + editNotesData = (EditNotesWindow *) malloc (sizeof (EditNotesWindow)); + editNotesData->account = acc; + acc -> editNotesData = editNotesData; + + editNotesData->tb = textBox( toplevel, "Notes", + &(acc->notes), + closeEditNotesWindow, editNotesData); + + return editNotesData; +} + +/********************************************************************\ +\********************************************************************/ + +void +xaccDestroyEditNotesWindow (EditNotesWindow *editNotesData) +{ + if (!editNotesData) return; + + editNotesData->account->editNotesData = NULL; + xaccDestroyTextBox (editNotesData->tb); + _free(editNotesData); +} + +/********************************************************************\ +\********************************************************************/ + +static void +closeEditNotesWindow( Widget mw, XtPointer cd, XtPointer cb ) + { + EditNotesWindow *editNotesData = (EditNotesWindow *) cd; + + editNotesData->account->editNotesData = NULL; + + xaccDestroyTextBox (editNotesData->tb); + + _free(editNotesData); + DEBUG("close EditNotesWindow"); + } + /********************** END OF FILE *********************************\ \********************************************************************/ diff --git a/src/Account.c b/src/Account.c index 53fb54eae5..b9bd6edbce 100644 --- a/src/Account.c +++ b/src/Account.c @@ -67,11 +67,13 @@ mallocAccount( void ) * array */ /* private data */ - acc->arrowb = NULL; - acc->expand = 0; - acc->regData = NULL; - acc->recnData = NULL; - acc->adjBData = NULL; + acc->arrowb = NULL; + acc->expand = 0; + acc->regData = NULL; + acc->recnData = NULL; + acc->adjBData = NULL; + acc->editAccData = NULL; + acc->editNotesData = NULL; acc->qfRoot = mallocQuickFill(); return acc; diff --git a/src/AdjBWindow.c b/src/AdjBWindow.c index cb53ab87ec..8fd61785ea 100644 --- a/src/AdjBWindow.c +++ b/src/AdjBWindow.c @@ -50,10 +50,20 @@ typedef struct _AdjBWindow /** PROTOTYPES ******************************************************/ -void adjBOkCB( Widget mw, XtPointer cd, XtPointer cb ); -void adjBClose( Widget mw, XtPointer cd, XtPointer cb ); +static void adjBOkCB( Widget mw, XtPointer cd, XtPointer cb ); +static void adjBClose( Widget mw, XtPointer cd, XtPointer cb ); +/********************************************************************\ +\********************************************************************/ + +void +xaccDestroyAdjBWindow (AdjBWindow *adjBData) +{ + if (!adjBData) return; + XtDestroyWidget (adjBData->dialog); +} + /********************************************************************\ * adjBWindow * * opens up the window to adjust the balance * @@ -240,7 +250,7 @@ adjBWindow( Widget parent, Account *acc ) * cb - * * Return: none * \********************************************************************/ -void +static void adjBClose( Widget mw, XtPointer cd, XtPointer cb ) { AdjBWindow *adjBData = (AdjBWindow *)cd; @@ -262,7 +272,7 @@ adjBClose( Widget mw, XtPointer cd, XtPointer cb ) * cb - * * Return: none * \********************************************************************/ -void +static void adjBOkCB( Widget mw, XtPointer cd, XtPointer cb ) { AdjBWindow *adjBData = (AdjBWindow *)cd; @@ -314,3 +324,6 @@ adjBOkCB( Widget mw, XtPointer cd, XtPointer cb ) refreshMainWindow(); } + +/******************** END OF FILE ***********************************\ +\********************************************************************/ diff --git a/src/MainWindow.c b/src/MainWindow.c index e3f9fe088f..aa44f9bf1b 100644 --- a/src/MainWindow.c +++ b/src/MainWindow.c @@ -35,7 +35,9 @@ #include #include +#include "AdjBWindow.h" #include "Account.h" +#include "AccWindow.h" #include "BuildMenu.h" #include "Data.h" #include "FileBox.h" @@ -43,6 +45,7 @@ #include "HelpWindow.h" #include "main.h" #include "MainWindow.h" +#include "RecnWindow.h" #include "RegWindow.h" #include "util.h" #include "XferWindow.h" @@ -963,10 +966,20 @@ accountMenubarCB( Widget mw, XtPointer cd, XtPointer cb ) errorBox (toplevel, ACC_DEL_MSG); } else { char msg[1000]; - sprintf (msg, - "Are you sure you want to delete the %s account?", - acc->accountName); + sprintf (msg, ACC_DEL_SURE_MSG, acc->accountName); if( verifyBox(toplevel,msg) ) { + + /* before deleting the account, make + * sure that we close any misc register + * windows, if they are open */ + /* hack alert -- this should be done for + * any child accounts this account might have .. */ + xaccDestroyRegWindow (selected_acc->regData); + xaccDestroyRecnWindow (selected_acc->recnData); + xaccDestroyAdjBWindow (selected_acc->adjBData); + xaccDestroyEditAccWindow (selected_acc->editAccData); + xaccDestroyEditNotesWindow (selected_acc->editNotesData); + xaccRemoveAccount (selected_acc); freeAccount (selected_acc); selected_acc = NULL; diff --git a/src/Makefile b/src/Makefile index 83f80f9d85..73f4d91fad 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,7 +30,7 @@ OBJS = Account.o AccountMenu.o AccWindow.o Action.o AdjBWindow.o \ BuildMenu.o Data.o date.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 XferBox.o XferWindow.o + TextBox.o Transaction.o util.o XferBox.o XferWindow.o SRCS = ${OBJS:.o=.c} diff --git a/src/RecnWindow.c b/src/RecnWindow.c index 5b182f9733..324c8ee726 100644 --- a/src/RecnWindow.c +++ b/src/RecnWindow.c @@ -65,6 +65,16 @@ extern XtAppContext app; /********************************************************************/ +/********************************************************************\ +\********************************************************************/ + +void +xaccDestroyRecnWindow (RecnWindow *recnData) +{ + if (!recnData) return; + XtDestroyWidget (recnData->dialog); +} + /********************************************************************\ * recnRefresh * * refreshes the transactions in the reconcile window * diff --git a/src/RegWindow.c b/src/RegWindow.c index aefb4f64b1..8b19e67585 100644 --- a/src/RegWindow.c +++ b/src/RegWindow.c @@ -169,6 +169,15 @@ extern Pixel negPixel; /********************************************************************/ +/********************************************************************\ +\********************************************************************/ + +void +xaccDestroyRegWindow (RegWindow *regData) +{ + if (!regData) return; + XtDestroyWidget(regData->dialog); +} /********************************************************************\ * regRefresh * diff --git a/src/TextBox.c b/src/TextBox.c new file mode 100644 index 0000000000..718388bc7c --- /dev/null +++ b/src/TextBox.c @@ -0,0 +1,266 @@ +/********************************************************************\ + * TextBox.c -- Text Box utility function * + * xacc (X-Accountant) * + * Copyright (C) 1997 Robin D. Clark * + * Copyright (C) 1997 Linas Vepstas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * 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. * + * * + * Author: Rob Clark * + * Internet: rclark@cs.hmc.edu * + * Address: 609 8th Street * + * Huntington Beach, CA 92648-4632 * +\********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + +/********************************************************************\ + **************** TEXTBOX STUFF ************************************* +\********************************************************************/ + +typedef struct _textbox { + Widget dialog; + Widget textfield; + char **pmodifytext; +} TextBox; + +static void textBoxCB ( Widget mw, XtPointer cd, XtPointer cb ); + +/********************************************************************\ +\********************************************************************/ + +void +xaccDestroyTextBox (TextBox *tb) +{ + if (!tb) return; + XtDestroyWidget (tb->dialog); +} + +/********************************************************************\ + * textBox * + * opens up a text box, and displays text * + * * + * NOTE: This function does not return until the textBox is closed * + * * + * Args: parent - the parent widget * + * title - the title of the window * + * text - the initial text to display * + * editable - can this text be edited by the user? * + * Return: none * +\********************************************************************/ +TextBox * +textBox( Widget parent, char *title, char **pmodifytext, + XtCallbackProc userCB, XtPointer userData) + { + Boolean editable = True; + Widget dialog, + pane, + controlform, + actionform, + widget; + Arg args[20]; + TextBox *textData = (TextBox *)_malloc(sizeof(TextBox)); + + textData->pmodifytext = pmodifytext; + + setBusyCursor( parent ); + + /* Create the dialog box... XmNdeleteResponse is set to + * XmDESTROY so the dialog's memory is freed when it is closed */ + dialog = XtVaCreatePopupShell( "dialog", + xmDialogShellWidgetClass, parent, + XmNdialogStyle, XmDIALOG_APPLICATION_MODAL, + XmNtitle, title, + XmNdeleteResponse, XmDESTROY, + XmNminWidth, 150, + XmNminHeight, 200, + XmNtransient, FALSE, /* allow window to be repositioned */ + NULL ); + + textData->dialog = dialog; + + /* Create a PanedWindow Manager for the dialog box... the child + * of optiondialog the paned window is the parent of the two + * forms which comprise the two areas of the dialog box... + * The sash is set to minimun size to make it invisible */ + pane = XtVaCreateWidget( "pane", + xmPanedWindowWidgetClass, dialog, + XmNsashWidth, 1, + XmNsashHeight, 1, + XmNtraversalOn, False, + NULL ); + + /** CONTROLFORM **************************************** + * Create a controlform for control area of dialog box */ + controlform = XtVaCreateWidget( "controlform", + xmFormWidgetClass, pane, + NULL ); + + /* Create a text widget as child of controlform */ + XtSetArg( args[0], XmNeditMode, XmMULTI_LINE_EDIT ); + XtSetArg( args[1], XmNwordWrap, True ); + XtSetArg( args[2], XmNrows, 12 ); + XtSetArg( args[3], XmNcolumns, 70 ); + XtSetArg( args[4], XmNeditable, editable ); + XtSetArg( args[5], XmNscrollHorizontal, False ); + XtSetArg( args[6], XmNtopAttachment, XmATTACH_FORM ); + XtSetArg( args[7], XmNbottomAttachment, XmATTACH_FORM ); + XtSetArg( args[8], XmNleftAttachment, XmATTACH_FORM ); + XtSetArg( args[9], XmNrightAttachment, XmATTACH_FORM ); + + textData->textfield = + XmCreateScrolledText( controlform, "text", args, 10 ); + + XtManageChild( textData->textfield ); + + XmTextSetString( textData->textfield, *pmodifytext ); + + XtManageChild( controlform ); + + /** ACTIONFORM ******************************************** + * Create a Form actionform for action area of dialog box */ + { + int fb = editable ? 5 : 3; + actionform = XtVaCreateWidget( "actionform", + xmFormWidgetClass, pane, + XmNfractionBase, fb, + NULL ); + } + /* The OK button is anchored to the form, between divider 1 & 2 + * (in the fraction base) */ + widget = XtVaCreateManagedWidget( "Ok", + xmPushButtonWidgetClass, actionform, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 1, + XmNrightAttachment, XmATTACH_POSITION, + XmNrightPosition, 2, + XmNshowAsDefault, True, + NULL ); + + /* Add callback function to Ok.. calls textBoxCB to save the text, + * and destroyOptionDialog to kill option dialog box */ + XtAddCallback( widget, XmNactivateCallback, textBoxCB, textData ); + if (userCB) { + XtAddCallback( widget, XmNactivateCallback, userCB, userData ); + } + XtAddCallback( widget, XmNactivateCallback, destroyShellCB, dialog ); + + if( editable ) + { + /* If it is editable, provide a cancel button too! */ + widget = XtVaCreateManagedWidget( "Cancel", + xmPushButtonWidgetClass, actionform, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 3, + XmNrightAttachment, XmATTACH_POSITION, + XmNrightPosition, 4, + XmNshowAsDefault, True, + NULL ); + + /* Add callback function to Cancel.. calls destroyOptionDialog to + * kill option dialog box */ + XtAddCallback( widget, XmNactivateCallback, destroyShellCB, dialog ); + if (userCB) { + XtAddCallback( widget, XmNactivateCallback, userCB, userData ); + } + } + + /* Fix action area of the pane to its current size, and not let it + * resize. */ + XtManageChild( actionform ); + + { + Dimension h; + XtVaGetValues( widget, XmNheight, &h, NULL ); + XtVaSetValues( actionform, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL ); + } + + XtManageChild( pane ); + XtPopup( dialog, XtGrabNone ); + + unsetBusyCursor( parent ); + +#ifdef __EMULATE_MAIN_LOOP + /* while the user hasn't pushed "Ok", simulate XtMainLoop. + * When textData->text changes from NULL, it means the user + * has pressed "Ok". Don't break loop until XtAppPending() + * also returns False to assure widget destruction. */ + + /* DANGER WARNING: + * While emulating the main loop may be OK for the verify + * boxes as long as thier use is limited, it can become + * *extremely dangerous* for more complex uses, such as text + * boxes. The basic problem is that this resembles + * multi-threaded programming: while we are spinning in this + * loop, all sorts of other things can be created and + * destroyed. In particular, the memory location which is + * supposed to contain the results of the TextBox might get + * deleted, resulting in a core dump when text box returns! + * Owwwww!!. + * + * In fact, the same can happen for the verify box as well, + * although as long as the user respondsto the verify box + * immediately, and desn't monkey around with anything else, + * its safe. Although I don't like it. Some sort of grab + * should probably be done, blocking the user from doing + * anything else until they've ansered the question. + */ + + while( textData->newtext == NULL || XtAppPending(app) ) + XtAppProcessEvent( app, XtIMAll ); + return textData->newtext; + +#endif /* __EMULATE_MAIN_LOOP */ + + return textData; + } + +/********************************************************************\ + * textBoxCB * + * callback that saves the data in the the buffer before textBox * + * can return * + * * + * Args: mw - the widget that called us * + * cd - textData * + * cb - * + * Return: none * +\********************************************************************/ +static void +textBoxCB( Widget mw, XtPointer cd, XtPointer cb ) + { + TextBox *textData = (TextBox *)cd; + + *(textData->pmodifytext) = XmTextGetString( textData->textfield ); + } + +/*********************** END OF FILE ********************************\ +\********************************************************************/ diff --git a/src/util.c b/src/util.c index eb34b4f551..b746722529 100644 --- a/src/util.c +++ b/src/util.c @@ -241,185 +241,6 @@ unsetBusyCursor( Widget w ) } } -/********************************************************************\ - **************** TEXTBOX STUFF ************************************* -\********************************************************************/ -typedef struct _textbox { - Widget textfield; - char *text; -} TextBox; - -void textBoxCB( Widget mw, XtPointer cd, XtPointer cb ); - -/********************************************************************\ - * textBox * - * opens up a text box, and displays text * - * * - * NOTE: This function does not return until the textBox is closed * - * * - * Args: parent - the parent widget * - * title - the title of the window * - * text - the initial text to display * - * editable - can this text be edited by the user? * - * Return: none * -\********************************************************************/ -char * -textBox( Widget parent, char *title, char *text, Boolean editable ) - { - Widget dialog, - pane, - controlform, - actionform, - widget; - Arg args[10]; - TextBox *textData = (TextBox *)_malloc(sizeof(TextBox)); - textData->text = NULL; - - setBusyCursor( parent ); - - /* Create the dialog box... XmNdeleteResponse is set to - * XmDESTROY so the dialog's memory is freed when it is closed */ - dialog = XtVaCreatePopupShell( "dialog", - xmDialogShellWidgetClass, parent, - XmNdialogStyle, XmDIALOG_APPLICATION_MODAL, - XmNtitle, title, - XmNdeleteResponse, XmDESTROY, - XmNminWidth, 150, - XmNminHeight, 200, - XmNtransient, FALSE, /* allow window to be repositioned */ - NULL ); - - /* Create a PanedWindow Manager for the dialog box... the child - * of optiondialog the paned window is the parent of the two - * forms which comprise the two areas of the dialog box... - * The sash is set to minimun size to make it invisible */ - pane = XtVaCreateWidget( "pane", - xmPanedWindowWidgetClass, dialog, - XmNsashWidth, 1, - XmNsashHeight, 1, - XmNtraversalOn, False, - NULL ); - - /** CONTROLFORM **************************************** - * Create a controlform for control area of dialog box */ - controlform = XtVaCreateWidget( "controlform", - xmFormWidgetClass, pane, - NULL ); - - /* Create a text widget as child of controlform */ - XtSetArg( args[0], XmNeditMode, XmMULTI_LINE_EDIT ); - XtSetArg( args[1], XmNwordWrap, True ); - XtSetArg( args[2], XmNrows, 12 ); - XtSetArg( args[3], XmNcolumns, 70 ); - XtSetArg( args[4], XmNeditable, editable ); - XtSetArg( args[5], XmNscrollHorizontal, False ); - XtSetArg( args[6], XmNtopAttachment, XmATTACH_FORM ); - XtSetArg( args[7], XmNbottomAttachment, XmATTACH_FORM ); - XtSetArg( args[8], XmNleftAttachment, XmATTACH_FORM ); - XtSetArg( args[9], XmNrightAttachment, XmATTACH_FORM ); - - textData->textfield = - XmCreateScrolledText( controlform, "text", args, 10 ); - - XtManageChild( textData->textfield ); - - XmTextSetString( textData->textfield, text ); - - XtManageChild( controlform ); - - /** ACTIONFORM ******************************************** - * Create a Form actionform for action area of dialog box */ - { - int fb = editable ? 5 : 3; - actionform = XtVaCreateWidget( "actionform", - xmFormWidgetClass, pane, - XmNfractionBase, fb, - NULL ); - } - /* The OK button is anchored to the form, between divider 1 & 2 - * (in the fraction base) */ - widget = XtVaCreateManagedWidget( "Ok", - xmPushButtonWidgetClass, actionform, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 1, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 2, - XmNshowAsDefault, True, - NULL ); - - /* Add callback function to Ok.. calls textBoxCB to save the text, - * and destroyOptionDialog to kill option dialog box */ - XtAddCallback( widget, XmNactivateCallback, textBoxCB, textData ); - XtAddCallback( widget, XmNactivateCallback, destroyShellCB, dialog ); - - if( editable ) - { - /* If it is editable, provide a cancel button too! */ - widget = XtVaCreateManagedWidget( "Cancel", - xmPushButtonWidgetClass, actionform, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 3, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 4, - XmNshowAsDefault, True, - NULL ); - - /* Add callback function to Cancel.. calls destroyOptionDialog to - * kill option dialog box */ - XtAddCallback( widget, XmNactivateCallback, destroyShellCB, dialog ); - } - - /* Fix action area of the pane to its current size, and not let it - * resize. */ - XtManageChild( actionform ); - - { - Dimension h; - XtVaGetValues( widget, XmNheight, &h, NULL ); - XtVaSetValues( actionform, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL ); - } - - XtManageChild( pane ); - XtPopup( dialog, XtGrabNone ); - - unsetBusyCursor( parent ); - - /* while the user hasn't pushed "Ok", simulate XtMainLoop. - * When textData->text changes from NULL, it means the user - * has pressed "Ok". Don't break loop until XtAppPending() - * also returns False to assure widget destruction. */ - while( textData->text == NULL || XtAppPending(app) ) - XtAppProcessEvent( app, XtIMAll ); - - return textData->text; - } - -/********************************************************************\ - * textBoxCB * - * callback that saves the data in the the buffer before textBox * - * can return * - * * - * Args: mw - the widget that called us * - * cd - textData * - * cb - * - * Return: none * -\********************************************************************/ -void -textBoxCB( Widget mw, XtPointer cd, XtPointer cb ) - { - TextBox *textData = (TextBox *)cd; - - textData->text = XmTextGetString( textData->textfield ); - } - -/********************************************************************\ -********************************************************************* -\********************************************************************/ - /********************************************************************\ **************** VERIFYBOX STUFF *********************************** \********************************************************************/ @@ -590,3 +411,5 @@ errorBox( Widget parent, char *message ) } } +/************************* END OF FILE ******************************\ +\********************************************************************/