home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume19
/
xephem
/
part20
/
listmenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-15
|
13KB
|
511 lines
/* code to manage the stuff on the "listing" menu.
*/
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#if defined(__STDC__)
#include <stdlib.h>
#endif
#include <X11/Xlib.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/DrawingA.h>
#include <Xm/LabelG.h>
#include <Xm/PushB.h>
#include <Xm/ToggleB.h>
#include <Xm/Separator.h>
#include <Xm/RowColumn.h>
#include <Xm/Text.h>
#if defined(__STDC__) || defined(__cplusplus)
#define P_(s) s
#else
#define P_(s) ()
#endif
extern int access(); /* don't know whether to include unistd.h */
extern void all_selection_mode P_((int whether));
extern void f_string P_((Widget w, char *s));
extern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
extern void query P_((Widget tw, char *msg, char *label1, char *label2, char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
extern void set_xmstring P_((Widget w, char *resource, char *txt));
extern void xe_msg P_((char *msg, int app_modal));
void lst_manage P_((void));
void lst_selection P_((char *name));
void lst_log P_((char *name, char *str));
void listing P_((void));
int listing_ison P_((void));
void lst_cursor P_((Cursor c));
static void lst_select P_((int whether));
static void lst_create_form P_((void));
static void lst_activate_cb P_((Widget w, XtPointer client, XtPointer call));
static void lst_close_cb P_((Widget w, XtPointer client, XtPointer call));
static void lst_help_cb P_((Widget w, XtPointer client, XtPointer call));
static void lst_reset P_((void));
static void lst_stop_selecting P_((void));
static void lst_turn_off P_((void));
static void lst_try_append P_((void));
static void lst_try_overwrite P_((void));
static void lst_try_cancel P_((void));
static void lst_try_turn_on P_((void));
static void lst_turn_on P_((char *how));
#undef P_
extern Widget toplevel_w;
#ifdef VMS
#include <perror.h>
#include <errno.h>
#else
extern char *sys_errlist[];
extern errno;
#endif
#define errsys (sys_errlist[errno])
/* max number of fields we can keep track of at once to list */
#define MAXLSTFLDS 10
#define MAXLSTSTR 32 /* longest string we can list */
#define MAXFLDNAM 32 /* longest allowed field name */
static Widget lstform_w;
static Widget select_w, active_w, prompt_w;
static Widget title_w, filename_w;
static Widget table_w[MAXLSTFLDS]; /* row indeces follow.. */
#define DEF_LSTFN "ephem.lst" /* default plot file name */
static FILE *lst_fp; /* the listing file; == 0 means don't plot */
/* lst_activate_cb client values. */
#define SELECT 0
#define ACTIVE 1
/* store the name and string value of each field to track.
* we get the label straight from the Text widget in the table as needed.
*/
typedef struct {
char l_name[MAXFLDNAM]; /* name of field we are listing */
char l_str[MAXLSTSTR]; /* last know string value of field */
} LstFld;
static LstFld lstflds[MAXLSTFLDS];
static int nlstflds; /* number of lstflds[] in actual use */
/* called when the list menu is activated via the main menu pulldown.
* if never called before, create and manage all the widgets as a child of a
* form. otherwise, just toggle whether the form is managed.
*/
void
lst_manage ()
{
if (!lstform_w)
lst_create_form();
if (XtIsManaged(lstform_w))
XtUnmanageChild (lstform_w);
else
XtManageChild (lstform_w);
}
/* called by the other menus (data, etc) as their buttons are
* selected to inform us that that button is to be included in a listing.
*/
void
lst_selection (name)
char *name;
{
Widget tw;
if (!lstform_w
|| !XtIsManaged(lstform_w)
|| !XmToggleButtonGetState(select_w))
return;
tw = table_w[nlstflds];
set_xmstring (tw, XmNlabelString, name);
XtManageChild (tw);
(void) strncpy (lstflds[nlstflds].l_name, name, MAXFLDNAM);
if (++nlstflds == MAXLSTFLDS)
lst_stop_selecting();
}
/* called as each different field is written -- just save in lstflds[]
* if we are potentially interested.
*/
void
lst_log (name, str)
char *name;
char *str;
{
if (listing_ison()) {
LstFld *lp;
for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
if (strcmp (name, lp->l_name) == 0) {
(void) strncpy (lp->l_str, str, MAXLSTSTR-1);
break;
}
}
}
/* called when all fields have been updated and it's time to
* write the active listing to the current listing file, if one is open.
*/
void
listing()
{
if (lst_fp) {
/* list in order of original selection */
LstFld *lp;
for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
(void) fprintf (lst_fp, "%s ", lp->l_str);
(void) fprintf (lst_fp, "\n");
}
}
listing_ison()
{
return (lst_fp != 0);
}
/* called to put up or remove the watch cursor. */
void
lst_cursor (c)
Cursor c;
{
Window win;
if (lstform_w && (win = XtWindow(lstform_w))) {
Display *dsp = XtDisplay(lstform_w);
if (c)
XDefineCursor (dsp, win, c);
else
XUndefineCursor (dsp, win);
}
}
/* inform the other menues whether we are setting up for them to tell us
* what fields to list.
*/
static void
lst_select(whether)
int whether;
{
all_selection_mode(whether);
}
static void
lst_create_form()
{
static struct {
char *title;
int cb_data;
Widget *wp;
} tbs[] = {
{"Select fields", SELECT, &select_w},
{"List to file", ACTIVE, &active_w}
};
XmString str;
Widget w, rc_w, f_w;
Arg args[20];
char *deffn;
int i, n;
/* create form dialog */
n = 0;
XtSetArg (args[n], XmNautoUnmanage, False); n++;
XtSetArg (args[n], XmNdefaultPosition, False); n++;
lstform_w = XmCreateFormDialog (toplevel_w, "List", args, n);
n = 0;
XtSetArg (args[n], XmNtitle, "xephem Listing Control"); n++;
XtSetValues (XtParent(lstform_w), args, n);
/* make a RowColumn to hold everything */
n = 0;
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNisAligned, False); n++;
XtSetArg (args[n], XmNadjustMargin, False); n++;
rc_w = XmCreateRowColumn (lstform_w, "ListRC", args, n);
XtManageChild (rc_w);
/* make the control toggle buttons */
for (i = 0; i < XtNumber(tbs); i++) {
str = XmStringCreate(tbs[i].title, XmSTRING_DEFAULT_CHARSET);
n = 0;
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
XtSetArg (args[n], XmNlabelString, str); n++;
w = XmCreateToggleButton(rc_w, "ListTB", args, n);
XmStringFree (str);
XtManageChild (w);
XtAddCallback(w, XmNvalueChangedCallback, lst_activate_cb,
(XtPointer)tbs[i].cb_data);
if (tbs[i].wp)
*tbs[i].wp = w;
}
/* create filename text area and its label */
n = 0;
str = XmStringCreate("File name:", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
XtSetArg (args[n], XmNlabelString, str); n++;
w = XmCreateLabel (rc_w, "ListFnL", args, n);
XmStringFree (str);
XtManageChild (w);
n = 0;
filename_w = XmCreateText (rc_w, "Filename", args, n);
deffn = XmTextGetString (filename_w);
if (strlen(deffn) == 0)
XmTextSetString (filename_w, DEF_LSTFN);
XtFree (deffn);
XtManageChild (filename_w);
/* create title text area and its label */
n = 0;
str = XmStringCreate("Title:", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
XtSetArg (args[n], XmNlabelString, str); n++;
w = XmCreateLabel (rc_w, "ListTL", args, n);
XtManageChild (w);
XmStringFree (str);
n = 0;
title_w = XmCreateText (rc_w, "ListTitle", args, n);
XtManageChild (title_w);
/* create prompt line -- it will be managed as necessary */
n = 0;
XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
prompt_w = XmCreateLabel (rc_w, "ListPrompt", args, n);
/* make the field name table, but don't manage them now */
for (i = 0; i < MAXLSTFLDS; i++) {
n = 0;
table_w[i] = XmCreateLabel(rc_w, "ListLabel", args, n);
}
/* create a separator */
n = 0;
w = XmCreateSeparator (rc_w, "Sep", args, n);
XtManageChild (w);
/* make a form to hold the close and help buttons evenly */
n = 0;
XtSetArg (args[n], XmNfractionBase, 7); n++;
f_w = XmCreateForm (rc_w, "ListCF", args, n);
XtManageChild(f_w);
n = 0;
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg (args[n], XmNleftPosition, 1); n++;
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg (args[n], XmNrightPosition, 3); n++;
w = XmCreatePushButton (f_w, "Close", args, n);
XtAddCallback (w, XmNactivateCallback, lst_close_cb, 0);
XtManageChild (w);
n = 0;
XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg (args[n], XmNleftPosition, 4); n++;
XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg (args[n], XmNrightPosition, 6); n++;
w = XmCreatePushButton (f_w, "Help", args, n);
XtAddCallback (w, XmNactivateCallback, lst_help_cb, 0);
XtManageChild (w);
}
/* callback from any of the listing menu toggle buttons being activated.
*/
/* ARGSUSED */
static void
lst_activate_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
int what = (int) client;
switch (what) {
case SELECT:
if (t->set) {
/* first turn off listing, if on, while we change things */
if (XmToggleButtonGetState(active_w))
XmToggleButtonSetState(active_w, False, True);
lst_reset(); /* reset lstflds array and unmanage the table*/
lst_select(1); /* inform other menus to inform us of fields */
XtManageChild (prompt_w);
f_string (prompt_w, "Select quantity for next column...");
} else
lst_stop_selecting();
break;
case ACTIVE:
if (t->set) {
/* first turn off selecting, if on */
if (XmToggleButtonGetState(select_w))
XmToggleButtonSetState(select_w, False, True);
lst_try_turn_on();
} else
lst_turn_off();
break;
}
}
/* callback from the Close button.
*/
/* ARGSUSED */
static void
lst_close_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
XtUnmanageChild (lstform_w);
}
/* callback from the Help
*/
/* ARGSUSED */
static void
lst_help_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
static char *msg[] = {
"Select fields to become each column of a listing, then run xephem. Each step",
"will yield one line in the output file. The filename may be specified in the",
"text area provided."
};
hlp_dialog ("Listing", msg, sizeof(msg)/sizeof(msg[0]));
}
/* forget our list, and unmanage the table.
*/
static void
lst_reset()
{
int i;
for (i = 0; i < nlstflds; i++)
XtUnmanageChild (table_w[i]);
nlstflds = 0;
}
/* stop selecting: tell everybody else to drop their buttons, make sure toggle
* is off.
*/
static void
lst_stop_selecting()
{
XmToggleButtonSetState (select_w, False, False);
lst_select(0);
XtUnmanageChild (prompt_w);
}
static void
lst_turn_off ()
{
if (lst_fp) {
(void) fclose (lst_fp);
lst_fp = 0;
}
}
/* called from the query routine when want to append to an existing list file.*/
static void
lst_try_append()
{
lst_turn_on("a");
}
/* called from the query routine when want to overwrite to an existing list
* file.
*/
static void
lst_try_overwrite()
{
lst_turn_on("w");
}
/* called from the query routine when decided not to make a listing file. */
static void
lst_try_cancel()
{
XmToggleButtonSetState (active_w, False, False);
}
/* attempt to open file for use as a listing file.
* if it doesn't exist, then go ahead and make it.
* but if it does, first ask wheher to append or overwrite.
*/
static void
lst_try_turn_on()
{
char *txt = XmTextGetString (filename_w);
if (access (txt, 0) == 0) {
char *buf;
buf = XtMalloc (strlen(txt)+100);
(void) sprintf (buf, "%s exists: Append or Overwrite?", txt);
query (toplevel_w, buf, "Append", "Overwrite", "Cancel",
lst_try_append, lst_try_overwrite, lst_try_cancel);
XtFree (buf);
} else
lst_turn_on("w");
XtFree (txt);
}
/* turn on listing facility.
* establish a file to use (and thereby set lst_fp, the "listing-is-on" flag).
*/
static void
lst_turn_on (how)
char *how; /* fopen how argument */
{
char *txt;
/* listing is on if file opens ok */
txt = XmTextGetString (filename_w);
lst_fp = fopen (txt, how);
if (!lst_fp) {
char *buf;
XmToggleButtonSetState (active_w, False, False);
buf = XtMalloc (strlen(txt)+100);
(void) sprintf (buf, "Can not open %s: %s", txt, errsys);
xe_msg (buf, 1);
XtFree (buf);
}
XtFree (txt);
if (lst_fp) {
/* add a title if desired */
txt = XmTextGetString (title_w);
if (txt[0] != '\0')
(void) fprintf (lst_fp, "* %s\n", txt);
XtFree (txt);
}
}