home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xephem / part20 / listmenu.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  13KB  |  511 lines

  1. /* code to manage the stuff on the "listing" menu.
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include <math.h>
  7. #if defined(__STDC__)
  8. #include <stdlib.h>
  9. #endif
  10. #include <X11/Xlib.h>
  11. #include <Xm/Xm.h>
  12. #include <Xm/Form.h>
  13. #include <Xm/DrawingA.h>
  14. #include <Xm/LabelG.h>
  15. #include <Xm/PushB.h>
  16. #include <Xm/ToggleB.h>
  17. #include <Xm/Separator.h>
  18. #include <Xm/RowColumn.h>
  19. #include <Xm/Text.h>
  20.  
  21.  
  22. #if defined(__STDC__) || defined(__cplusplus)
  23. #define P_(s) s
  24. #else
  25. #define P_(s) ()
  26. #endif
  27.  
  28. extern int access();    /* don't know whether to include unistd.h */
  29.  
  30. extern void all_selection_mode P_((int whether));
  31. extern void f_string P_((Widget w, char *s));
  32. extern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  33. extern void query P_((Widget tw, char *msg, char *label1, char *label2, char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
  34. extern void set_xmstring P_((Widget w, char *resource, char *txt));
  35. extern void xe_msg P_((char *msg, int app_modal));
  36.  
  37. void lst_manage P_((void));
  38. void lst_selection P_((char *name));
  39. void lst_log P_((char *name, char *str));
  40. void listing P_((void));
  41. int listing_ison P_((void));
  42. void lst_cursor P_((Cursor c));
  43. static void lst_select P_((int whether));
  44. static void lst_create_form P_((void));
  45. static void lst_activate_cb P_((Widget w, XtPointer client, XtPointer call));
  46. static void lst_close_cb P_((Widget w, XtPointer client, XtPointer call));
  47. static void lst_help_cb P_((Widget w, XtPointer client, XtPointer call));
  48. static void lst_reset P_((void));
  49. static void lst_stop_selecting P_((void));
  50. static void lst_turn_off P_((void));
  51. static void lst_try_append P_((void));
  52. static void lst_try_overwrite P_((void));
  53. static void lst_try_cancel P_((void));
  54. static void lst_try_turn_on P_((void));
  55. static void lst_turn_on P_((char *how));
  56.  
  57. #undef P_
  58.  
  59. extern Widget toplevel_w;
  60.  
  61. #ifdef VMS
  62. #include <perror.h>
  63. #include <errno.h>
  64. #else
  65. extern char *sys_errlist[];
  66. extern errno;
  67. #endif
  68.  
  69. #define    errsys    (sys_errlist[errno])
  70.  
  71. /* max number of fields we can keep track of at once to list */
  72. #define MAXLSTFLDS    10
  73. #define MAXLSTSTR    32    /* longest string we can list */
  74. #define MAXFLDNAM    32    /* longest allowed field name */
  75.  
  76. static Widget lstform_w;
  77. static Widget select_w, active_w, prompt_w;
  78. static Widget title_w, filename_w;
  79. static Widget table_w[MAXLSTFLDS];    /* row indeces follow.. */
  80.  
  81. #define    DEF_LSTFN    "ephem.lst"    /* default plot file name */
  82. static FILE *lst_fp;            /* the listing file; == 0 means don't plot */
  83.  
  84.  
  85. /* lst_activate_cb client values. */
  86. #define    SELECT    0
  87. #define    ACTIVE    1
  88.  
  89. /* store the name and string value of each field to track.
  90.  * we get the label straight from the Text widget in the table as needed.
  91.  */
  92. typedef struct {
  93.     char l_name[MAXFLDNAM];    /* name of field we are listing */
  94.     char l_str[MAXLSTSTR];    /* last know string value of field */
  95. } LstFld;
  96. static LstFld lstflds[MAXLSTFLDS];
  97. static int nlstflds;        /* number of lstflds[] in actual use */
  98.  
  99. /* called when the list menu is activated via the main menu pulldown.
  100.  * if never called before, create and manage all the widgets as a child of a
  101.  * form. otherwise, just toggle whether the form is managed.
  102.  */
  103. void
  104. lst_manage ()
  105. {
  106.     if (!lstform_w)
  107.         lst_create_form();
  108.     
  109.     if (XtIsManaged(lstform_w))
  110.         XtUnmanageChild (lstform_w);
  111.     else
  112.         XtManageChild (lstform_w);
  113. }
  114.  
  115. /* called by the other menus (data, etc) as their buttons are
  116.  * selected to inform us that that button is to be included in a listing.
  117.  */
  118. void
  119. lst_selection (name)
  120. char *name;
  121. {
  122.     Widget tw;
  123.  
  124.  
  125.     if (!lstform_w
  126.         || !XtIsManaged(lstform_w)
  127.         || !XmToggleButtonGetState(select_w))
  128.             return;
  129.  
  130.     tw = table_w[nlstflds];
  131.     set_xmstring (tw, XmNlabelString, name);
  132.     XtManageChild (tw);
  133.  
  134.     (void) strncpy (lstflds[nlstflds].l_name, name, MAXFLDNAM);
  135.     if (++nlstflds == MAXLSTFLDS)
  136.         lst_stop_selecting();
  137. }
  138.  
  139. /* called as each different field is written -- just save in lstflds[]
  140.  * if we are potentially interested.
  141.  */
  142. void
  143. lst_log (name, str)
  144. char *name;
  145. char *str;
  146. {
  147.     if (listing_ison()) {
  148.         LstFld *lp;
  149.         for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
  150.         if (strcmp (name, lp->l_name) == 0) {
  151.             (void) strncpy (lp->l_str, str, MAXLSTSTR-1);
  152.             break;
  153.         }
  154.     }
  155. }
  156.  
  157. /* called when all fields have been updated and it's time to
  158.  * write the active listing to the current listing file, if one is open.
  159.  */
  160. void
  161. listing()
  162. {
  163.     if (lst_fp) {
  164.         /* list in order of original selection */
  165.         LstFld *lp;
  166.         for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
  167.         (void) fprintf (lst_fp, "%s  ", lp->l_str);
  168.         (void) fprintf (lst_fp, "\n");
  169.     }
  170. }
  171.  
  172. listing_ison()
  173. {
  174.     return (lst_fp != 0);
  175. }
  176.  
  177. /* called to put up or remove the watch cursor.  */
  178. void
  179. lst_cursor (c)
  180. Cursor c;
  181. {
  182.     Window win;
  183.  
  184.     if (lstform_w && (win = XtWindow(lstform_w))) {
  185.         Display *dsp = XtDisplay(lstform_w);
  186.         if (c)
  187.         XDefineCursor (dsp, win, c);
  188.         else
  189.         XUndefineCursor (dsp, win);
  190.     }
  191. }
  192.  
  193. /* inform the other menues whether we are setting up for them to tell us
  194.  * what fields to list.
  195.  */
  196. static void
  197. lst_select(whether)
  198. int whether;
  199. {
  200.     all_selection_mode(whether);
  201. }
  202.  
  203. static void
  204. lst_create_form()
  205. {
  206.     static struct {
  207.         char *title;
  208.         int cb_data;
  209.         Widget *wp;
  210.     } tbs[] = {
  211.         {"Select fields", SELECT, &select_w},
  212.         {"List to file", ACTIVE, &active_w}
  213.     };
  214.     XmString str;
  215.     Widget w, rc_w, f_w;
  216.     Arg args[20];
  217.     char *deffn;
  218.     int i, n;
  219.  
  220.     /* create form dialog */
  221.     n = 0;
  222.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  223.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  224.     lstform_w = XmCreateFormDialog (toplevel_w, "List", args, n);
  225.  
  226.     n = 0;
  227.     XtSetArg (args[n], XmNtitle, "xephem Listing Control"); n++;
  228.     XtSetValues (XtParent(lstform_w), args, n);
  229.  
  230.     /* make a RowColumn to hold everything */
  231.  
  232.     n = 0;
  233.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  234.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  235.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  236.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  237.     XtSetArg (args[n], XmNisAligned, False); n++;
  238.     XtSetArg (args[n], XmNadjustMargin, False); n++;
  239.     rc_w = XmCreateRowColumn (lstform_w, "ListRC", args, n);
  240.     XtManageChild (rc_w);
  241.  
  242.     /* make the control toggle buttons */
  243.  
  244.     for (i = 0; i < XtNumber(tbs); i++) {
  245.         str = XmStringCreate(tbs[i].title, XmSTRING_DEFAULT_CHARSET);
  246.         n = 0;
  247.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  248.         XtSetArg (args[n], XmNlabelString, str); n++;
  249.         w = XmCreateToggleButton(rc_w, "ListTB", args, n);
  250.         XmStringFree (str);
  251.         XtManageChild (w);
  252.         XtAddCallback(w, XmNvalueChangedCallback, lst_activate_cb,
  253.                             (XtPointer)tbs[i].cb_data);
  254.         if (tbs[i].wp)
  255.         *tbs[i].wp = w;
  256.     }
  257.  
  258.     /* create filename text area and its label */
  259.  
  260.     n = 0;
  261.     str = XmStringCreate("File name:", XmSTRING_DEFAULT_CHARSET);
  262.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  263.     XtSetArg (args[n], XmNlabelString, str); n++;
  264.     w = XmCreateLabel (rc_w, "ListFnL", args, n);
  265.     XmStringFree (str);
  266.     XtManageChild (w);
  267.  
  268.     n = 0;
  269.     filename_w = XmCreateText (rc_w, "Filename", args, n);
  270.     deffn = XmTextGetString (filename_w);
  271.     if (strlen(deffn) == 0)
  272.         XmTextSetString (filename_w, DEF_LSTFN);
  273.     XtFree (deffn);
  274.     XtManageChild (filename_w);
  275.  
  276.     /* create title text area and its label */
  277.  
  278.     n = 0;
  279.     str = XmStringCreate("Title:", XmSTRING_DEFAULT_CHARSET);
  280.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  281.     XtSetArg (args[n], XmNlabelString, str); n++;
  282.     w = XmCreateLabel (rc_w, "ListTL", args, n);
  283.     XtManageChild (w);
  284.     XmStringFree (str);
  285.  
  286.     n = 0;
  287.     title_w = XmCreateText (rc_w, "ListTitle", args, n);
  288.     XtManageChild (title_w);
  289.  
  290.     /* create prompt line -- it will be managed as necessary */
  291.  
  292.     n = 0;
  293.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  294.     prompt_w = XmCreateLabel (rc_w, "ListPrompt", args, n);
  295.  
  296.     /* make the field name table, but don't manage them now */
  297.     for (i = 0; i < MAXLSTFLDS; i++) {
  298.         n = 0;
  299.         table_w[i] = XmCreateLabel(rc_w, "ListLabel", args, n);
  300.     }
  301.  
  302.     /* create a separator */
  303.  
  304.     n = 0;
  305.     w = XmCreateSeparator (rc_w, "Sep", args, n);
  306.     XtManageChild (w);
  307.  
  308.     /* make a form to hold the close and help buttons evenly */
  309.  
  310.     n = 0;
  311.     XtSetArg (args[n], XmNfractionBase, 7); n++;
  312.     f_w = XmCreateForm (rc_w, "ListCF", args, n);
  313.     XtManageChild(f_w);
  314.  
  315.         n = 0;
  316.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  317.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  318.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  319.         XtSetArg (args[n], XmNleftPosition, 1); n++;
  320.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  321.         XtSetArg (args[n], XmNrightPosition, 3); n++;
  322.         w = XmCreatePushButton (f_w, "Close", args, n);
  323.         XtAddCallback (w, XmNactivateCallback, lst_close_cb, 0);
  324.         XtManageChild (w);
  325.  
  326.         n = 0;
  327.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  328.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  329.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  330.         XtSetArg (args[n], XmNleftPosition, 4); n++;
  331.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  332.         XtSetArg (args[n], XmNrightPosition, 6); n++;
  333.         w = XmCreatePushButton (f_w, "Help", args, n);
  334.         XtAddCallback (w, XmNactivateCallback, lst_help_cb, 0);
  335.         XtManageChild (w);
  336. }
  337.  
  338. /* callback from any of the listing menu toggle buttons being activated.
  339.  */
  340. /* ARGSUSED */
  341. static void
  342. lst_activate_cb (w, client, call)
  343. Widget w;
  344. XtPointer client;
  345. XtPointer call;
  346. {
  347.     XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  348.     int what = (int) client;
  349.  
  350.     switch (what) {
  351.     case SELECT:
  352.         if (t->set) {
  353.         /* first turn off listing, if on, while we change things */
  354.         if (XmToggleButtonGetState(active_w))
  355.             XmToggleButtonSetState(active_w, False, True);
  356.         lst_reset();    /* reset lstflds array and unmanage the table*/
  357.         lst_select(1);    /* inform other menus to inform us of fields */
  358.         XtManageChild (prompt_w);
  359.         f_string (prompt_w, "Select quantity for next column...");
  360.         } else
  361.         lst_stop_selecting();
  362.         break;
  363.     case ACTIVE:
  364.         if (t->set) {
  365.         /* first turn off selecting, if on */
  366.         if (XmToggleButtonGetState(select_w))
  367.             XmToggleButtonSetState(select_w, False, True);
  368.         lst_try_turn_on();
  369.         } else
  370.         lst_turn_off();
  371.         break;
  372.     }
  373. }
  374.  
  375. /* callback from the Close button.
  376.  */
  377. /* ARGSUSED */
  378. static void
  379. lst_close_cb (w, client, call)
  380. Widget w;
  381. XtPointer client;
  382. XtPointer call;
  383. {
  384.     XtUnmanageChild (lstform_w);
  385. }
  386.  
  387. /* callback from the Help
  388.  */
  389. /* ARGSUSED */
  390. static void
  391. lst_help_cb (w, client, call)
  392. Widget w;
  393. XtPointer client;
  394. XtPointer call;
  395. {
  396.     static char *msg[] = {
  397. "Select fields to become each column of a listing, then run xephem. Each step",
  398. "will yield one line in the output file. The filename may be specified in the",
  399. "text area provided."
  400. };
  401.  
  402.     hlp_dialog ("Listing", msg, sizeof(msg)/sizeof(msg[0]));
  403. }
  404.  
  405. /* forget our list, and unmanage the table.
  406.  */
  407. static void
  408. lst_reset()
  409. {
  410.     int i;
  411.  
  412.     for (i = 0; i < nlstflds; i++)
  413.         XtUnmanageChild (table_w[i]);
  414.  
  415.     nlstflds = 0;
  416. }
  417.  
  418. /* stop selecting: tell everybody else to drop their buttons, make sure toggle
  419.  * is off.
  420.  */
  421. static void
  422. lst_stop_selecting()
  423. {
  424.     XmToggleButtonSetState (select_w, False, False);
  425.     lst_select(0);
  426.     XtUnmanageChild (prompt_w);
  427. }
  428.  
  429. static void
  430. lst_turn_off ()
  431. {
  432.     if (lst_fp) {
  433.         (void) fclose (lst_fp);
  434.         lst_fp = 0;
  435.     }
  436. }
  437.  
  438. /* called from the query routine when want to append to an existing list file.*/
  439. static void
  440. lst_try_append()
  441. {
  442.     lst_turn_on("a");
  443. }
  444.  
  445. /* called from the query routine when want to overwrite to an existing list
  446.  * file.
  447.  */
  448. static void
  449. lst_try_overwrite()
  450. {
  451.     lst_turn_on("w");
  452. }
  453.  
  454. /* called from the query routine when decided not to make a listing file.  */
  455. static void
  456. lst_try_cancel()
  457. {
  458.     XmToggleButtonSetState (active_w, False, False);
  459. }
  460.  
  461. /* attempt to open file for use as a listing file.
  462.  * if it doesn't exist, then go ahead and make it.
  463.  * but if it does, first ask wheher to append or overwrite.
  464.  */
  465. static void
  466. lst_try_turn_on()
  467. {
  468.     char *txt = XmTextGetString (filename_w);
  469.     if (access (txt, 0) == 0) {
  470.         char *buf;
  471.         buf = XtMalloc (strlen(txt)+100);
  472.         (void) sprintf (buf, "%s exists: Append or Overwrite?", txt);
  473.         query (toplevel_w, buf, "Append", "Overwrite", "Cancel",
  474.                 lst_try_append, lst_try_overwrite, lst_try_cancel);
  475.         XtFree (buf);
  476.     } else
  477.         lst_turn_on("w");
  478.     XtFree (txt);
  479. }
  480.  
  481. /* turn on listing facility.
  482.  * establish a file to use (and thereby set lst_fp, the "listing-is-on" flag).
  483.  */
  484. static void
  485. lst_turn_on (how)
  486. char *how;    /* fopen how argument */
  487. {
  488.     char *txt;
  489.  
  490.     /* listing is on if file opens ok */
  491.     txt = XmTextGetString (filename_w);
  492.     lst_fp = fopen (txt, how);
  493.     if (!lst_fp) {
  494.         char *buf;
  495.         XmToggleButtonSetState (active_w, False, False);
  496.         buf = XtMalloc (strlen(txt)+100);
  497.         (void) sprintf (buf, "Can not open %s: %s", txt, errsys);
  498.         xe_msg (buf, 1);
  499.         XtFree (buf);
  500.     }
  501.     XtFree (txt);
  502.     
  503.     if (lst_fp) {
  504.         /* add a title if desired */
  505.         txt = XmTextGetString (title_w);
  506.         if (txt[0] != '\0')
  507.         (void) fprintf (lst_fp, "* %s\n", txt);
  508.         XtFree (txt);
  509.     }
  510. }
  511.