/* Written by Dan Heller and Paula Ferguson.
* Copyright 1994, O'Reilly & Associates, Inc.
* Permission to use, copy, and modify this program without
* restriction is hereby granted, as long as this copyright
* notice appears in each copy of the program source code.
* This program is freely distributable without licensing fees and
* is provided without guarantee or warrantee expressed or implied.
* This program is -not- in the public domain.
*/
/* ask_user.c -- the user is presented with two pushbuttons.
* The first creates a file (/tmp/foo) and the second removes it.
* In each case, a dialog pops up asking for verification of the action.
*
* This program is intended to demonstrate an advanced implementation
* of the AskUser() function. This time, the function is passed the
* strings to use for the OK button and the Cancel button as well as
* the button to use as the default value.
*/
#include <Xm/DialogS.h>
#include <Xm/SelectioB.h>
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#define YES 1
#define NO 2
/* Generalize the question/answer process by creating a data structure
* that has the necessary labels, questions and everything needed to
* execute a command.
*/
typedef struct {
char *label; /* label for pushbutton used to invoke cmd */
char *question; /* question for dialog box to confirm cmd */
char *yes; /* what the "OK" button says */
char *no; /* what the "Cancel" button says */
int dflt; /* which should be the default answer */
char *cmd; /* actual command to execute (using system()) */
} QandA;
QandA touch_foo = {
"Create", "Create /tmp/foo?", "Yes", "No", YES, "touch /tmp/foo"
};
QandA rm_foo = {
"Remove", "Remove /tmp/foo?", "Yes", "No", NO, "rm /tmp/foo"
};
XtAppContext app;
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, button, rowcolumn;
XmString label;
void pushed();
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
rowcolumn = XtVaCreateManagedWidget ("rowcolumn",
xmRowColumnWidgetClass, toplevel, NULL);
label = XmStringCreateLocalized (touch_foo.label);
button = XtVaCreateManagedWidget ("button",
xmPushButtonWidgetClass, rowcolumn,
XmNlabelString, label,
NULL);
XtAddCallback (button, XmNactivateCallback, pushed, &touch_foo);
XmStringFree (label);
label = XmStringCreateLocalized (rm_foo.label);
button = XtVaCreateManagedWidget ("button",
xmPushButtonWidgetClass, rowcolumn,
XmNlabelString, label,
NULL);
XtAddCallback (button, XmNactivateCallback, pushed, &rm_foo);
XmStringFree (label);
XtManageChild (rowcolumn);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* pushed() --when a button is pressed, ask the question described
* by the QandA parameter (client_data). Execute the cmd if YES.
*/
void
pushed(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
QandA *quest = (QandA *) client_data;
if (AskUser (widget, quest->question, quest->yes, quest->no,
quest->dflt) == YES) {
printf ("Executing: %s\n", quest->cmd);
system (quest->cmd);
} else
printf ("Not executing: %s\n", quest->cmd);
}
/*
* AskUser() -- a generalized routine that asks the user a question
* and returns a response. Parameters are: the question, the labels
* for the "Yes" and "No" buttons, and the default selection to use.
*/
int AskUser(parent, question, ans1, ans2, default_ans)
Widget parent;
char *question, *ans1, *ans2;
int default_ans;
{
static Widget dialog; /* static to avoid multiple creation */
XmString text, yes, no;
static int answer;
extern void response();
if (!dialog) {
dialog = XmCreateQuestionDialog (parent, "dialog", NULL, 0);
XtVaSetValues (dialog,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
XtSetSensitive (
XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON),
False);
XtAddCallback (dialog, XmNokCallback, response, &answer);
XtAddCallback (dialog, XmNcancelCallback, response, &answer);
}
answer = 0;
text = XmStringCreateLocalized (question);
yes = XmStringCreateLocalized (ans1);
no = XmStringCreateLocalized (ans2);
XtVaSetValues (dialog,
XmNmessageString, text,
XmNokLabelString, yes,
XmNcancelLabelString, no,
XmNdefaultButtonType, default_ans == YES ?
XmDIALOG_OK_BUTTON : XmDIALOG_CANCEL_BUTTON,
NULL);
XmStringFree (text);
XmStringFree (yes);
XmStringFree (no);
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
while (answer == 0)
XtAppProcessEvent (app, XtIMAll);
XtPopdown (XtParent (dialog));
/* make sure the dialog goes away before returning. Sync with server
* and update the display.
*/
XSync (XtDisplay (dialog), 0);
XmUpdateDisplay (parent);
return answer;
}
/* response() --The user made some sort of response to the
* question posed in AskUser(). Set the answer (client_data)
* accordingly.
*/
void
response(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
int *answer = (int *) client_data;
XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
if (cbs->reason == XmCR_OK)
*answer = YES;
else if (cbs->reason == XmCR_CANCEL)
*answer = NO;
}