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

  1. /* this file contains the code to put up help messages.
  2.  * the messages come from a file or, if no file is found or there is no
  3.  * help entry for the requested subject, a small default text is provided.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <math.h>
  9. #if defined(__STDC__)
  10. #include <stdlib.h>
  11. #endif
  12. #include <X11/Xlib.h>
  13. #include <Xm/Xm.h>
  14. #include <Xm/Form.h>
  15. #include <Xm/PushB.h>
  16. #include <Xm/Text.h>
  17.  
  18. #if defined(__STDC__) || defined(__cplusplus)
  19. #define P_(s) s
  20. #else
  21. #define P_(s) ()
  22. #endif
  23.  
  24. extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  25. extern void set_something P_((Widget w, char *resource, char *value));
  26. extern void xe_msg P_((char *msg, int app_modal));
  27.  
  28. void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  29. void references_help P_((void));
  30. void intro_help P_((void));
  31. void config_help P_((void));
  32. void mainmenu_help P_((void));
  33. void datetime_help P_((void));
  34. void operation_help P_((void));
  35. void notes_help P_((void));
  36. static Widget hlp_create_dialog P_((char *tag));
  37. static void hlp_ok_cb P_((Widget w, XtPointer client, XtPointer call));
  38. static FILE *hlp_openfile P_((char *tag));
  39. static hlp_fillfromfile P_((char *tag, Widget txt_w, int l));
  40. static void hlp_fillfromstrings P_((char *msg[], int nmsg, Widget txt_w));
  41.  
  42. #undef P_
  43.  
  44.  
  45. extern Widget toplevel_w;
  46. #define    XtD XtDisplay(toplevel_w)
  47. extern char *myclass;
  48.  
  49. #define    MAXLINE        128    /* longest allowable help file line */
  50. #define    HLP_TAG        '@'    /* help file tag marker */
  51. #define    HLP_NEST    '+'    /* help file nested tag marker */
  52.  
  53. static char hlpfdef[] = "xephem.hlp";    /* default help file name */
  54.  
  55. /* put up a help dialog. it contains a scrolled text area and an Ok button.
  56.  * make a new dialog each time so we can have several up at once.
  57.  * this means we need an explicit callback on the Ok button to destroy it
  58.  * again (rather than being able to use the autoUnmanage feature).
  59.  * if can't find any help, say so.
  60.  */
  61. void
  62. hlp_dialog (tag, deflt, ndeflt)
  63. char *tag;    /* tag to look for in help file - also dialog title */
  64. char *deflt[];    /* help text to use if tag not found */
  65. int ndeflt;    /* number of strings in deflt[] */
  66. {
  67.     Widget txt_w, form_w;
  68.  
  69.     txt_w = hlp_create_dialog (tag);
  70.     form_w = XtParent(XtParent(txt_w));
  71.  
  72.     if (hlp_fillfromfile(tag, txt_w, 0) < 0) {
  73.         if (!deflt || ndeflt == 0) {
  74.         char buf[MAXLINE];
  75.         (void) sprintf (buf, "No help for %s", tag);
  76.         xe_msg (buf, 0);
  77.         XtDestroyWidget (form_w);
  78.         return;
  79.         } else
  80.         hlp_fillfromstrings(deflt, ndeflt, txt_w);
  81.     }
  82.  
  83.     XtManageChild (form_w);
  84.     /* everything gets destroyed when the Ok button is selected */
  85. }
  86.  
  87. void
  88. references_help()
  89. {
  90.     static char *msg[] = {
  91. "Many formulas and tables are based, with permission, on material found in",
  92. "\"Astronomy with your Personal Computer\" by Dr. Peter Duffett-Smith,",
  93. "Cambridge University Press, (c) 1985."
  94. };
  95.  
  96.     hlp_dialog ("Credits", msg, XtNumber(msg));
  97. }
  98.  
  99. void
  100. intro_help()
  101. {
  102.     static char *msg[] = {
  103. "Xephem computes all sorts of information about the planets, some moons and",
  104. "two user defined objects. The program displays this in a variety of tabular",
  105. "and graphical formats. It can also solve a user defined function built from",
  106. "this data and save values in plot and listing files for later display.",
  107. "",
  108. "Many dialogs have further \"Help\" of their own as well."
  109. };
  110.  
  111.     hlp_dialog ("Intro", msg, XtNumber(msg));
  112. }
  113.  
  114. void
  115. config_help()
  116. {
  117.     static char *msg[] = {
  118. "When xephem starts up it looks for a file named ephem.cfg. The name may be",
  119. "changed with the -c option or the EPHEMCFG environ variable. The file",
  120. "contains initialization information in the form of keyword=value pairs.",
  121. "The same keyword=value pairs can be used from the command line as well."
  122. };
  123.  
  124.     hlp_dialog ("Initialization", msg, XtNumber(msg));
  125. }
  126.  
  127. void
  128. mainmenu_help()
  129. {
  130.     static char *msg[] = {
  131. "The Main xephem menu displays the current circumstances and controls",
  132. "runtime behavior.",
  133. "See the Help for Operation for more information."
  134. };
  135.  
  136.     hlp_dialog ("MainMenu", msg, XtNumber(msg));
  137. }
  138.  
  139. void
  140. datetime_help()
  141. {
  142.     static char *msg[] = {
  143. "Dates formats depend on the DATE_FORMAT resource. But regardless you need",
  144. "only specify what changes. Dates can also be given as decimal years.",
  145. "Times are hh:mm:ss - again, only specify what changes."
  146. };
  147.  
  148.     hlp_dialog ("Date/time", msg, XtNumber(msg));
  149. }
  150.  
  151. void
  152. operation_help()
  153. {
  154.     static char *msg[] = {
  155. "Set location details, starting date and time, step size and number of steps,",
  156. "select desired views, then select \"Update\" to run.",
  157. };
  158.  
  159.     hlp_dialog ("Operation", msg, XtNumber(msg));
  160. }
  161.  
  162. void
  163. notes_help()
  164. {
  165.     static char *msg[] = {
  166. "floating point errors are not trapped gracefully. especially be careful not",
  167. "  to turn on Objx/y before they are properly defined.",
  168. "",
  169. "planet magnitudes are not very accurate."
  170. };
  171.  
  172.     hlp_dialog ("Notes", msg, XtNumber(msg));
  173. }
  174.  
  175. /* create the help dialog with a scrolled text area and an Ok button.
  176.  * return the text area widget; when ready to view, manage its parent's parent:
  177.  *   dialog -> form -> scrolled_window -> text.
  178.  * pass the dialog widget as the client parameter of the ok activate callback
  179.  *   so it can destroy it.
  180.  */
  181. static Widget
  182. hlp_create_dialog (tag)
  183. char *tag;
  184. {
  185.     Widget hlp_w;
  186.     Widget t_w, cb_w;
  187.     Arg args[20];
  188.     char title[MAXLINE];
  189.     int n;
  190.  
  191.     /* make the help shell form-dialog widget */
  192.  
  193.     n = 0;
  194.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  195.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  196.     XtSetArg (args[n], XmNfractionBase, 9); n++;
  197.     hlp_w = XmCreateFormDialog (toplevel_w, "Help", args, n);
  198.     XtAddCallback (hlp_w, XmNmapCallback, prompt_map_cb, NULL);
  199.  
  200.     (void) sprintf (title, "xephem Help on %s", tag);
  201.     set_something (XtParent(hlp_w), XmNtitle, title);
  202.  
  203.     /* make the Ok button */
  204.  
  205.     n = 0;
  206.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  207.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  208.     XtSetArg (args[n], XmNleftPosition, 3); n++;
  209.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  210.     XtSetArg (args[n], XmNrightPosition, 6); n++;
  211.     cb_w = XmCreatePushButton (hlp_w, "Ok", args, n);
  212.     XtAddCallback (cb_w, XmNactivateCallback, hlp_ok_cb,
  213.                             (XtPointer)hlp_w);
  214.     XtManageChild (cb_w);
  215.  
  216.     /* make the scrolled text area to help the help text */
  217.  
  218.     n = 0;
  219.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  220.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  221.     XtSetArg (args[n], XmNbottomWidget, cb_w); n++;
  222.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  223.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  224.     XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  225.     XtSetArg (args[n], XmNeditable, False); n++;
  226.     XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
  227.     t_w = XmCreateScrolledText (hlp_w, "ScrolledText", args, n);
  228.     XtManageChild (t_w);
  229.  
  230.     return (t_w);
  231. }
  232.  
  233. /* ARGSUSED */
  234. static void
  235. hlp_ok_cb (w, client, call)
  236. Widget w;
  237. XtPointer client;
  238. XtPointer call;
  239. {
  240.     Widget d_w = (Widget) client;
  241.  
  242.     XtDestroyWidget (d_w);
  243. }
  244.  
  245. /* open the help file and position at first line after we see "@tag\n".
  246.  * use HELPFILE resource or hlpfdef.
  247.  * if successfull return a FILE *, else return 0.
  248.  */
  249. static FILE *
  250. hlp_openfile (tag)
  251. char *tag;
  252. {
  253.     static char *fn;
  254.     char buf[MAXLINE];
  255.     char tagline[MAXLINE];
  256.     FILE *fp;
  257.  
  258.     if (!fn) {
  259.         fn = XGetDefault (XtD, myclass, "HELPFILE");
  260.         if (!fn)
  261.         fn = hlpfdef;
  262.     }
  263.  
  264.     fp = fopen (fn, "r");
  265.     if (!fp)
  266.         return ((FILE *)0);
  267.  
  268.     (void) sprintf (tagline, "%c%s\n", HLP_TAG, tag);
  269.     while (fgets (buf, sizeof(buf), fp))
  270.         if (strcmp (buf, tagline) == 0)
  271.         return (fp);
  272.  
  273.     (void) fclose (fp);
  274.     return ((FILE *)0);
  275. }
  276.  
  277. /* search help file for tag entry, then copy that entry into txt_w.
  278.  * l is the number of chars already in txt_w.
  279.  * also recursively follow any NESTed entries found.
  280.  * return new length of txt_w, else -1 if error.
  281.  */
  282. static
  283. hlp_fillfromfile(tag, txt_w, l)
  284. char *tag;
  285. Widget txt_w;
  286. int l;
  287. {
  288.     FILE *fp;
  289.     char buf[MAXLINE];
  290.     
  291.     fp = hlp_openfile (tag);
  292.     if (!fp)
  293.         return (-1);
  294.  
  295.     while (fgets (buf, sizeof(buf), fp)) {
  296.         if (buf[0] == HLP_TAG)
  297.         break;
  298.         else if (buf[0] == HLP_NEST) {
  299.         int newl;
  300.         buf[strlen(buf)-1] = '\0';    /* remove trailing \n */
  301.         newl = hlp_fillfromfile (buf+1, txt_w, l);
  302.         if (newl > l)
  303.             l = newl;
  304.         } else {
  305.         /* buf already includes a trailing \n */
  306.         XmTextReplace (txt_w, l, l, buf);
  307.         l += strlen (buf);
  308.         }
  309.     }
  310.  
  311.     (void) fclose (fp);
  312.     return (l);
  313. }
  314.  
  315. static void
  316. hlp_fillfromstrings(msg, nmsg, txt_w)
  317. char *msg[];
  318. int nmsg;
  319. Widget txt_w;
  320. {
  321.     static char nohelpwarn[] = 
  322.         "No HELP file found. Set XEphem.HELPFILE. Minimal Help only:\n\n";
  323.     int i, l;
  324.  
  325.     l = 0;
  326.  
  327.     XmTextReplace (txt_w, l, l, nohelpwarn);
  328.     l += strlen (nohelpwarn);
  329.  
  330.     for (i = 0; i < nmsg; i++) {
  331.         XmTextReplace (txt_w, l, l, msg[i]);
  332.         l += strlen (msg[i]);
  333.         XmTextReplace (txt_w, l, l, "\n");
  334.         l += 1;
  335.     }
  336. }
  337.