Nothing like a "minor" bug fix that escalates out of control

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@103 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1997-11-22 10:42:02 +00:00
parent 39ffc1b878
commit dbcdbccfaa
9 changed files with 462 additions and 230 deletions

View File

@ -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; i<NUM_ACCOUNT_TYPES; i++) {
@ -645,7 +690,7 @@ createCB( Widget mw, XtPointer cd, XtPointer cb )
}
/********************************************************************\
* editCB -- records the edits made in the editAccWindow *
* finishEditCB -- records the edits made in the editAccWindow *
* *
* Args: mw - the widget that called us *
* cd - editAccData - the struct of data associated with *
@ -655,7 +700,7 @@ createCB( Widget mw, XtPointer cd, XtPointer cb )
* Global: data - the data from the datafile *
\********************************************************************/
static void
editCB( Widget mw, XtPointer cd, XtPointer cb )
finishEditCB( Widget mw, XtPointer cd, XtPointer cb )
{
EditAccWindow *editAccData = (EditAccWindow *)cd;
String name = XmTextGetString(editAccData->name);
@ -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 *********************************\
\********************************************************************/

View File

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

View File

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

View File

@ -35,7 +35,9 @@
#include <Xm/Text.h>
#include <Xbae/Matrix.h>
#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;

View File

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

View File

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

View File

@ -169,6 +169,15 @@ extern Pixel negPixel;
/********************************************************************/
/********************************************************************\
\********************************************************************/
void
xaccDestroyRegWindow (RegWindow *regData)
{
if (!regData) return;
XtDestroyWidget(regData->dialog);
}
/********************************************************************\
* regRefresh *

266
src/TextBox.c Normal file
View File

@ -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 <X11/X.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/PanedW.h>
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Xm/DialogS.h>
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xbae/Matrix.h>
#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 ********************************\
\********************************************************************/

View File

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