mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
39ffc1b878
commit
dbcdbccfaa
172
src/AccWindow.c
172
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; 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 *********************************\
|
||||
\********************************************************************/
|
||||
|
@ -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;
|
||||
|
@ -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 ***********************************\
|
||||
\********************************************************************/
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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 *
|
||||
|
@ -169,6 +169,15 @@ extern Pixel negPixel;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccDestroyRegWindow (RegWindow *regData)
|
||||
{
|
||||
if (!regData) return;
|
||||
XtDestroyWidget(regData->dialog);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* regRefresh *
|
||||
|
266
src/TextBox.c
Normal file
266
src/TextBox.c
Normal 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 ********************************\
|
||||
\********************************************************************/
|
181
src/util.c
181
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 ******************************\
|
||||
\********************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user