home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / mush / part22 < prev    next >
Internet Message Format  |  1991-04-22  |  42KB

  1. From: argv@zipcode.com (Dan Heller)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i079:  mush - Mail User's Shell, Part22/22
  4. Message-ID: <1991Apr22.154030.590@sparky.IMD.Sterling.COM>
  5. Date: 22 Apr 91 15:40:30 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 22f7e3fa 6cb410e2 2c25aca5 2ce9f6fd
  8.  
  9. Submitted-by: Dan Heller <argv@zipcode.com>
  10. Posting-number: Volume 18, Issue 79
  11. Archive-name: mush/part22
  12. Supersedes: mush: Volume 12, Issue 28-47
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file tool_help continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 22; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping tool_help'
  32. else
  33. echo 'x - continuing file tool_help'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'tool_help' &&
  35. a menu of things to do then. Included in the menu, is a help item
  36. which describes the selections in the menu.
  37. %%
  38. X
  39. %Menu Read%
  40. When pointing at a message header in the header subwindow, hold down
  41. the RIGHT mouse button and select "Read" from the menu.  A new window
  42. will open containing the text of the message.  In this way, you can
  43. display more than one message at a time.
  44. X
  45. This operation sometimes fails on SunOS 3.5 systems due to limitations
  46. on the number of windows Mush can open at once.  When all the available
  47. windows are in use, the selected message is displayed in the message
  48. subwindow at the bottom of the main window.
  49. %%
  50. X
  51. %preserve%
  52. Usually, after you read mail and you "update" or quit  Mushview, unread
  53. messages are copied back into your system mailbox, deleted messages are
  54. removed, and messages which have been read but not deleted are saved in
  55. your "mbox" file.  Specifying "hold" prevents this from ever happening,
  56. but you can mark specific messages to be held in your system mailbox by
  57. preserving them.
  58. %%
  59. X
  60. %compose%
  61. When you start to compose a letter for mailing, you will be prompted
  62. for a recipient (To:) and other optional mail headers.  The cursor for
  63. the text subwindow will look like a bent arrow to indicate that when
  64. you hit RETURN, the cursor will automatically forward to the next
  65. header (the Subject: line, for example).
  66. X
  67. When the cursor resumes its original shape, the RETURN key enters new
  68. lines as normal.
  69. X
  70. There must be a recipient specified in order to send a message.  The
  71. recipient may be a user or a file or program name.
  72. %%
  73. X
  74. %next%
  75. You can page through all your messages by selecting  "Next" after reading
  76. each message. The same effect is gotten when you select the "Delete" item
  77. when the option,  "autoprint" is set to be true  (see "opts") except that
  78. the current message is deleted before the next one is displayed. Deleting
  79. mail which is  not important  helps the  efficiency of Mushview and reduces
  80. unnecessary use of system resources.
  81. X
  82. In the Header Window, you will notice the cursor looks like the mouse you
  83. use.  The blinking buttons on the mouse image remind you that you can use
  84. any of the  three buttons  at any  time.  When you  move the mouse over a
  85. message and choose a button, the message under the  mouse is going to be
  86. the one affected.  Choosing left button will read the message, the middle
  87. button will delete it, and the right button will give you a menu.
  88. %%
  89. X
  90. %aliases%
  91. Aliases are used as a method of mailing to users with long addresses using
  92. short names. For example, if you wanted to mail to
  93. X    argv@sun.com
  94. but didn't want to type that all the time, then you could make an alias by
  95. selecting the alias menu item that specifies "adding alias" and then TYPE:
  96. X    Dan argv@sun.com
  97. If you want to mail to a list of people and do so frequently enough to want
  98. an alias name for the whole list, then  you would type something like this:
  99. X    project-group fred mary bob@foo-bar herb sly@baz.bitnet
  100. X
  101. To mail to an "alias" you would compose a letter and address the letter:
  102. X
  103. To: Dan
  104. Subject: Alias example
  105. Cc: project-group
  106. (rest of letter)
  107. %%
  108. X
  109. %alts%
  110. "Alternates" are alternate names for YOU.  In messages you receive,
  111. your account will appear on the "To" or "Cc" list.  When you REPLY to
  112. those messages, Mushview will construct a message header for your
  113. letter which will contain the To and Cc lists of recipients from the
  114. original message. You would probably want your name taken off the list
  115. so you do not mail yourself a copy of your own message. If you have
  116. other account names or accounts on other machines, you can let Mushview
  117. know what those mail addresses are so they can be removed from the
  118. lists as well.
  119. X
  120. Note, that if YOU add your name MANUALLY (type it yourself) to either
  121. of the lists, it will not be removed.
  122. X
  123. You can set such a list in your .mailrc file in your home directory by
  124. adding the line:
  125. X
  126. alts hostname1 hostname2 ...
  127. X
  128. If you prefer to not have your name removed from lists when responding
  129. to mail, set the option "metoo"; this prevents the need for alternates
  130. and your name will never be removed.
  131. %%
  132. X
  133. %options%
  134. To set or unset options and their values, move the mouse over the
  135. option of your choice and select the LEFT button to toggle true/false
  136. values. If an option requires a string value, you must type the value,
  137. so select the LEFT button to reference the option, and then type away.
  138. X
  139. NOTE: You must use a Carriage Return to enter the final value for the
  140. option or the value will not change.
  141. %%
  142. X
  143. %ignore%
  144. When reading mail, the message "headers" may clutter up the
  145. window with information you are not interested in.  For
  146. example, you may not be interested in the "Received" or
  147. "Message-Id" field of the mail message. You would find that
  148. in time, it will become annoying to see these uninteresting
  149. message headers.
  150. X
  151. You can specify which message headers should not be shown,
  152. thus shortening the appearance of the length of the message.
  153. X
  154. Typical settings:
  155. X    Received
  156. X    Message-Id
  157. X    Status
  158. %%
  159. X
  160. %printer%
  161. This item will send the current message, or the message specified on
  162. the range item, to the printer.  The printer used is given by the
  163. variable $printer.  To specify a different printer, change the printer
  164. option by selecting the item "Options" in the Main Panel Window, moving
  165. the mouse over the "printer" option, selecting the LEFT mouse button
  166. and typing the name of the printer which you'd like to use.
  167. X
  168. Be sure to set this option before printing because the DEFAULT option
  169. may not be what you want.
  170. X
  171. You can print messages that are NOT the current message by moving the
  172. mouse into the Header Window and selecting the RIGHT mouse button on
  173. top of the message you want to print and selecting the PRINT menu
  174. option.
  175. %%
  176. X
  177. %windows%
  178. "Windows" are the boxes which contain items, text, or graphic
  179. images.  There are two "panel" windows. A panel window is one
  180. which contains items,  which are the little boxes  with words
  181. that you can place the mouse over and click the left or mouse
  182. button.
  183. X
  184. Each  window has a separate  function for different purposes.
  185. Starting at the top of the main "tool" (contains all windows)
  186. we have the "header panel." Everything in this panel pertains
  187. to the message headers, only.  The panel in the middle of the
  188. tool is the "mail panel" which is more general and applies to
  189. just about everything. For a description of each of the items
  190. within any panel, select the  "Help"  option  from  the  menu
  191. you get by selecting the RIGHT mouse button.
  192. %%
  193. X
  194. %message range%
  195. You can specify a large group of messages using a combination of special
  196. symbols in addition to numbers.  For example, if you wish to save all of
  197. the messages, then you can use `*' to represent them all. If you were to
  198. type the  "star" and select the Save  menu option for "save range", then
  199. you would save ALL the messages you have (including deleted ones).
  200. X
  201. If you would like to save messages 4 through 9, then you would specify:
  202. X      4-9
  203. If you want to specify the messages between 2 and 32 except for messages
  204. 6, 8 and message 12-14, you would type:
  205. X      2-32 {6,8,12-14}
  206. Commas or spaces can be used to separate numbers.
  207. X
  208. Note that you cannot specify negated messages without first specifying
  209. normal messages; e.g. {2-5} 1-11   doesn't make sense.
  210. %%
  211. X
  212. %sort%
  213. Sorting messages can   be accomplished by  selecting one  of the
  214. menu items in this panel item.  By default (using the LEFT mouse
  215. button),  sorting is  done by  message status.  New messages are
  216. first, followed  by unread messages,  old/read messages, replied
  217. to  messages,  and  finally deleted messages.  You may also sort
  218. messages by author, date, or subject by selecting the menu item.
  219. %%
  220. X
  221. %include%
  222. To include a message in your letter, first enter the number of the
  223. message you wish to include in the  Range:  item of the main  mush
  224. frame.  Then select  Include  from the composition window panel by
  225. pressing the LEFT mouse button.    If you do not specify a message
  226. in the  Range:  item, the current message will be included.
  227. X
  228. To forward a message, choose the message to be forwarded as above,
  229. use the RIGHT mouse button on the  Include item and select Forward
  230. Message from the menu.
  231. %%
  232. X
  233. %mark%
  234. Marks can be used to tag messages for later reference.  They are
  235. temporary and will not be saved when the folder is updated.  A
  236. priority setting beteween A and E may also be set on message(s).
  237. Priorities are saved across updated folders.  Sorting by marks
  238. and priorities is also available (marks having highest priority,
  239. followed by A, B, etc.).
  240. X
  241. Marks are set on the current message only while priorities are set
  242. (or unset) on the message list specified in the Range: text field.
  243. X
  244. Messages may have both a temporary mark and a priority, but may not
  245. have more than one priority.  The presence of a mark or a priority
  246. setting is shown by a `+' character immediately following the message
  247. number in the "headers" command display.
  248. %%
  249. X
  250. %close%
  251. There  are various  ways in which  you  may be  finished with  the
  252. compose window. The most commonly used method is to simply "close"
  253. the window to an iconic form.  This means that you  haven't really
  254. quit,  but you  have merely put  it on "hold" till later.  It will
  255. become an icon on the  side or corner of the  screen and appear to
  256. sit  and do  nothing.  To close the window to icon form, there are
  257. two methods. Both methods will have the same effect.
  258. X
  259. The first method is to select  this panel item with the left mouse
  260. button. The second method is to use the tool manager around the
  261. perimeter of the window and select "close".
  262. X
  263. There are two equally similar methods of removing the compose win-
  264. dow rather than just closing to an icon: you may select the second
  265. menu item in  the menu given by this panel item or you may use the
  266. tool manager "quit" item.
  267. %%
  268. SHAR_EOF
  269. echo 'File tool_help is complete' &&
  270. chmod 0644 tool_help ||
  271. echo 'restore of tool_help failed'
  272. Wc_c="`wc -c < 'tool_help'`"
  273. test 18926 -eq "$Wc_c" ||
  274.     echo 'tool_help: original size 18926, current size' "$Wc_c"
  275. rm -f _shar_wnt_.tmp
  276. fi
  277. # ============= tooledit.c ==============
  278. if test -f 'tooledit.c' -a X"$1" != X"-c"; then
  279.     echo 'x - skipping tooledit.c (File already exists)'
  280.     rm -f _shar_wnt_.tmp
  281. else
  282. > _shar_wnt_.tmp
  283. echo 'x - extracting tooledit.c (Text)'
  284. sed 's/^X//' << 'SHAR_EOF' > 'tooledit.c' &&
  285. /* @(#)tooledit.c    (c) copyright    2/14/90 (Dan Heller) */
  286. X
  287. /*
  288. X * intercept events in the compose window for auto-
  289. X *    positioning and tilde command recognition.
  290. X */
  291. #include "mush.h"
  292. X
  293. static short dat_bentarrow[] = {
  294. X    0x007F, 0x007F, 0x007F, 0x0007, 0x0407, 0x0C07, 0x1C07, 0x3807, 
  295. X    0x7FFF, 0xFFFF, 0x7FFF, 0x3800, 0x1C00, 0x0C00, 0x0400, 0x0000
  296. };
  297. mpr_static(bent_arrow, 16, 16, 1, dat_bentarrow);
  298. Cursor bentarrow;
  299. X
  300. extern void do_send(), do_edit();
  301. X
  302. /* Return the byte position in the textsw of the header specified */
  303. Textsw_index
  304. header_position(textsw, str)
  305. Textsw textsw;
  306. char *str;
  307. {
  308. X    char buf[256];
  309. X    register char *p = buf, *p2;
  310. X    int contd_hdr = 0, add_newline = 0;
  311. X    Textsw_index pos = 0L, ret_pos = 0L;
  312. X
  313. X    buf[0] = 0;
  314. X    for (;;) {
  315. X    /* get a line at a time from the textsw */
  316. X    (void) window_get(textsw, TEXTSW_CONTENTS, pos, buf, 256);
  317. X    if (p = index(buf, '\n'))
  318. X        *p = 0;
  319. X    else
  320. X        add_newline++;
  321. X    p = buf;
  322. X    skipspaces(0);
  323. X    if (!*p) /* newline alone -- end of headers */
  324. X        break;
  325. X    pos += strlen(buf) + 1; /* advance position to next line */
  326. X    if (*p != ' ' && *p != '\t') {
  327. X        contd_hdr = 0;
  328. X        /* strcmp ignoring case */
  329. X        for (p2 = str; *p && *p2 && lower(*p2) == lower(*p); ++p, ++p2)
  330. X        ;
  331. X        /* MATCH is true if p2 is at the end of str and *p is ':' */
  332. X        if (*p2 || *p != ':') {
  333. X        if (!*p2 && isspace(*any(p, ": \t"))) {
  334. X            /* Not a legal or continued header */
  335. X            pos -= strlen(buf) + 1; /* go back to beginning of line */
  336. X            break;
  337. X        }
  338. X        continue;
  339. X        } else {
  340. X        contd_hdr = 1;
  341. X        ret_pos = pos - 1;
  342. X        }
  343. X    } else if (!contd_hdr)
  344. X        continue;
  345. X    }
  346. X    if (!ret_pos) {
  347. X    /* coudn't find the header -- add it */
  348. X    window_set(textsw, TEXTSW_INSERTION_POINT, pos, NULL);
  349. X    p = buf;
  350. X    if (add_newline)
  351. X        *p++ = '\n', pos--;
  352. X    for (p2 = str; *p2; ++p2) {
  353. X        if (p2 == str || p2[-1] == '-')
  354. X        *p++ = upper(*p2);
  355. X        else
  356. X        *p++ = *p2;
  357. X    }
  358. X    *p++ = ':', *p++ = ' ', *p++ = '\n', *p = 0;
  359. X    textsw_insert(textsw, buf, strlen(buf));
  360. X    ret_pos = pos + strlen(buf) - 1;
  361. X    }
  362. X    return ret_pos;
  363. }
  364. X
  365. /* position_flags indicates which header to go to when uses tilde commands */
  366. static u_long position_flags;
  367. static char *tilde_hdrs[] = {
  368. #define POSITION_TO    ULBIT(0)
  369. X    "to",
  370. #define POSITION_SUBJ    ULBIT(1)
  371. X    "subject",
  372. #define POSITION_CC    ULBIT(2)
  373. X    "cc",
  374. #define POSITION_BCC    ULBIT(3)
  375. X    "bcc",
  376. #define POSITION_FCC    ULBIT(4)
  377. X    "fcc"
  378. };
  379. #define POSITION_ALL \
  380. X    ((POSITION_TO) | (POSITION_SUBJ) | (POSITION_CC) | (POSITION_BCC))
  381. #define POSITION_END    ULBIT(5)
  382. #define TOTAL_POSITIONS    6
  383. X
  384. /*
  385. X * position_flags identifies which header is requested by the calling func.
  386. X * use header_position to find the position of the header associated with
  387. X * with the flags.
  388. X */
  389. static void
  390. go_to_next_pos(textsw)
  391. Textsw textsw;
  392. {
  393. X    Textsw_index pos;
  394. X    int i = 0;
  395. X
  396. X    while (i < TOTAL_POSITIONS && isoff(position_flags, ULBIT(i)))
  397. X    i++;
  398. X    if (i == TOTAL_POSITIONS)
  399. X    return;
  400. X    if (i < ArraySize(tilde_hdrs))
  401. X    pos = header_position(textsw, tilde_hdrs[i]);
  402. X    else
  403. X    pos = (Textsw_index)window_get(textsw, TEXTSW_LENGTH);
  404. X    turnoff(position_flags, ULBIT(i));
  405. X    if (!position_flags)
  406. X    /* restore old cursor */
  407. X    window_set(textsw,WIN_CURSOR, window_get(mfprint_sw, WIN_CURSOR), NULL);
  408. X    else
  409. X    window_set(textsw, WIN_CURSOR, bentarrow, NULL);
  410. X    window_set(textsw, TEXTSW_INSERTION_POINT, pos, NULL);
  411. X    textsw_normalize_view(textsw, (Textsw_index)0);
  412. }
  413. X
  414. tilde_from_menu(item, value, event)
  415. Panel_item item;
  416. int value;
  417. Event    *event;
  418. {
  419. X    Textsw textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
  420. X    PANEL_CLIENT_DATA);
  421. X    if (value == 0 || event_id(event) == MS_LEFT)
  422. X    position_flags = POSITION_ALL;
  423. X    else
  424. X    turnon(position_flags, ULBIT(value - 1));
  425. X    panel_set_value(item, 0);
  426. X    go_to_next_pos(textsw);
  427. }
  428. X
  429. /*
  430. X * This interpose function is here to parse for tilde escapes.
  431. X * Note: this is a (currently) undocumented feature and is intended
  432. X * as an accelerator for advanced users.  Supported tilde escapes
  433. X * are: t,s,c,b,x,e and v.
  434. X */
  435. Notify_value
  436. edit_msg_textwin(textsw, event, arg, type)
  437. Textsw    textsw;
  438. Event    *event;
  439. Notify_arg    arg;
  440. Notify_event_type    type;
  441. {
  442. X    char buf[2];
  443. X    static char do_tilde;
  444. X    Textsw_index pos;
  445. X
  446. X    if (do_tilde == 1 && event_is_ascii(event) &&
  447. X        /* make sure we are going to catch this switch */
  448. X        index("bschetv", event_id(event))) {
  449. X    textsw_erase(textsw,
  450. X        (unsigned)window_get(textsw, TEXTSW_INSERTION_POINT)-1,
  451. X        (unsigned)window_get(textsw, TEXTSW_INSERTION_POINT));
  452. X    switch (event_id(event)) {
  453. X        case 'h':
  454. X        turnon(position_flags, POSITION_ALL);
  455. X        when 't':
  456. X        turnon(position_flags, POSITION_TO);
  457. X        when 's':
  458. X        turnon(position_flags, POSITION_SUBJ);
  459. X        when 'c':
  460. X        turnon(position_flags, POSITION_CC);
  461. X        when 'b':
  462. X        turnon(position_flags, POSITION_BCC);
  463. X        when 'e' : case 'v' : {
  464. X        /* shouldn't use global -- hack for now */
  465. X        extern Panel_item edit_item;
  466. X        do_edit(edit_item);
  467. X        return NOTIFY_DONE;
  468. X        }
  469. X    }
  470. X    do_tilde = 0;
  471. X    go_to_next_pos(textsw);
  472. X    return NOTIFY_DONE;
  473. X    }
  474. X    do_tilde = 0;
  475. X    /* check to see if this is a potential tilde escape */
  476. X    if (event_id(event) == *escape) {
  477. X    /* get previous character entered */
  478. X    pos = (Textsw_index)window_get(textsw, TEXTSW_INSERTION_POINT);
  479. X    if (pos > 0)
  480. X        (void) window_get(textsw, TEXTSW_CONTENTS, pos-1, buf, 1);
  481. X    /* test to see if ~ came at the beginning of a line */
  482. X    if (pos < 1 || buf[0] == '\n')
  483. X        do_tilde = 1;
  484. X    }
  485. X    /* check for auto-next-header .. e.g. when you hit CR on To: go to Subj:
  486. X     * special case backspace keys since textsw_start_of_display_line() has
  487. X     * a bug where it gets the line # wrong when backspacing.
  488. X     */
  489. X    if (position_flags != 0L && ID != CTRL('H') && ID != 127) {
  490. X    Notify_value val;
  491. X    if (ID == '\n' || ID == '\r') {
  492. X        go_to_next_pos(textsw);
  493. X        return NOTIFY_DONE; /* don't process event */
  494. X    }
  495. X    /* we're still processing this header -- continue to do so unless
  496. X     * the event in question changes the line# of the insertion point.
  497. X     * first get current position...
  498. X     */
  499. X    pos = (Textsw_index)window_get(textsw, TEXTSW_INSERTION_POINT);
  500. X    /* now let the event be processed... */
  501. X    val = notify_next_event_func(textsw, event, arg, type);
  502. X    /* see if the line # for the new insertion point has changed. */
  503. X    if (textsw_start_of_display_line(textsw, pos) !=
  504. X        textsw_start_of_display_line(textsw,
  505. X        (Textsw_index)window_get(textsw, TEXTSW_INSERTION_POINT))) {
  506. X        /* the event (mouse button, ACTION_??), changed the line # */
  507. X        position_flags = 0L; /* disable auto-next-header */
  508. X        /* restore cursor */
  509. X        window_set(textsw,
  510. X        WIN_CURSOR, window_get(mfprint_sw, WIN_CURSOR),
  511. X        NULL);
  512. X    }
  513. X    return val;
  514. X    }
  515. X    return notify_next_event_func(textsw, event, arg, type);
  516. }
  517. X
  518. /*
  519. X * start the compose textsw.  This is here because we need position_flags
  520. X * and the tilde-bits to set the insertion point at the To: line if
  521. X * do_position is true.
  522. X */
  523. void
  524. start_textsw_edit(textsw, do_position)
  525. Textsw textsw;
  526. {
  527. X    extern char *hfile;
  528. X    char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
  529. X    Textsw_index first, last, to_index;
  530. X    int        i;
  531. X
  532. X    strdup(file, hfile);
  533. #ifdef SUN_4_0 /* SunOS 4.0+ */
  534. X    window_set(textsw,
  535. X    TEXTSW_CLIENT_DATA,        file,
  536. X    TEXTSW_FILE_CONTENTS,        hfile,
  537. X    TEXTSW_READ_ONLY,        FALSE,
  538. X    TEXTSW_STORE_CHANGES_FILE,    FALSE,
  539. X    NULL);
  540. #else /* SUN_4_0 */
  541. X    textsw_load_file(textsw, hfile, 1, 0, 0);
  542. X    window_set(textsw,
  543. X    TEXTSW_CLIENT_DATA,        file,
  544. X    TEXTSW_READ_ONLY,        FALSE,
  545. X    TEXTSW_STORE_CHANGES_FILE,    FALSE,
  546. X    NULL);
  547. #endif /* SUN_4_0 */
  548. X    position_flags = 0L;
  549. X    if (do_position) {
  550. X    turnon(position_flags, POSITION_TO);
  551. X    if (do_set(set_options, "ask") || do_set(set_options, "asksub"))
  552. X        turnon(position_flags, POSITION_SUBJ);
  553. X    if (do_set(set_options, "askcc"))
  554. X        turnon(position_flags, POSITION_CC);
  555. X    }
  556. X    turnon(position_flags, POSITION_END);
  557. X    go_to_next_pos(textsw);
  558. X    (void) unlink(hfile);
  559. X    xfree(hfile), hfile = NULL;
  560. }
  561. X
  562. /*ARGSUSED*/
  563. void
  564. do_edit(item, value, event)
  565. Panel_item item;
  566. int value;
  567. register Event *event;
  568. {
  569. X    int argc;
  570. X    char *file, **argv, *edit, cmd[MAXPATHLEN];
  571. X    Panel_item next;
  572. X    Panel panel = (Panel)panel_get(item, PANEL_PARENT_PANEL);
  573. X    Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
  574. X
  575. X    file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
  576. X    if (textsw_store_file(textsw, file, 0, 0)) {
  577. X    error("Can't start editor");
  578. X    return;
  579. X    }
  580. X    if ((!(edit = do_set(set_options, "visual")) || !*edit) &&
  581. X    (!(edit = do_set(set_options, "editor")) || !*edit))
  582. X    edit = DEF_EDITOR;
  583. X    (void) sprintf(cmd, "%s %s", edit, file);
  584. X    argc = 0;
  585. X    if (!(argv = mk_argv(cmd, &argc, FALSE))) {
  586. X    unlink(file);
  587. X    return;
  588. X    }
  589. X    if (tool_edit_letter(textsw, argv) > -1) {
  590. X    /* skip first panel item */
  591. X    item = (Panel_item) panel_get(panel, PANEL_FIRST_ITEM);
  592. X    for (item = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
  593. X         item; item = next) {
  594. X         next = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
  595. X         (void) panel_set(item, PANEL_SHOW_ITEM, FALSE, NULL);
  596. X    }
  597. X    position_flags = 0L;
  598. X    window_set(textsw,WIN_CURSOR, window_get(mfprint_sw,WIN_CURSOR), NULL);
  599. X    }
  600. X    free_vec(argv);
  601. }
  602. SHAR_EOF
  603. chmod 0644 tooledit.c ||
  604. echo 'restore of tooledit.c failed'
  605. Wc_c="`wc -c < 'tooledit.c'`"
  606. test 9136 -eq "$Wc_c" ||
  607.     echo 'tooledit.c: original size 9136, current size' "$Wc_c"
  608. rm -f _shar_wnt_.tmp
  609. fi
  610. # ============= version.h ==============
  611. if test -f 'version.h' -a X"$1" != X"-c"; then
  612.     echo 'x - skipping version.h (File already exists)'
  613.     rm -f _shar_wnt_.tmp
  614. else
  615. > _shar_wnt_.tmp
  616. echo 'x - extracting version.h (Text)'
  617. sed 's/^X//' << 'SHAR_EOF' > 'version.h' &&
  618. /* @(#)version.h    (c) Copyright 1989, 1990, 1991 (Dan Heller) */
  619. X
  620. #define MUSHNAME    "Mail User's Shell"
  621. #define RELEASE_DATE    "4/12/91"
  622. #define RELEASE        7
  623. #define REVISION    "2"
  624. #define PATCHLEVEL    2
  625. SHAR_EOF
  626. chmod 0644 version.h ||
  627. echo 'restore of version.h failed'
  628. Wc_c="`wc -c < 'version.h'`"
  629. test 194 -eq "$Wc_c" ||
  630.     echo 'version.h: original size 194, current size' "$Wc_c"
  631. rm -f _shar_wnt_.tmp
  632. fi
  633. # ============= viewopts.c ==============
  634. if test -f 'viewopts.c' -a X"$1" != X"-c"; then
  635.     echo 'x - skipping viewopts.c (File already exists)'
  636.     rm -f _shar_wnt_.tmp
  637. else
  638. > _shar_wnt_.tmp
  639. echo 'x - extracting viewopts.c (Text)'
  640. sed 's/^X//' << 'SHAR_EOF' > 'viewopts.c' &&
  641. /* @(#)viewopts.c    (c) copyright    10/18/86 (Dan Heller) */
  642. X
  643. #include "mush.h"
  644. X
  645. struct viewopts {
  646. X    char *v_opt;
  647. X    char *v_prompt;
  648. X    char *v_description;
  649. #ifdef SUNTOOL
  650. X    Panel_item v_choice;
  651. X    Panel_item v_text;
  652. #endif /* SUNTOOL */
  653. };
  654. X
  655. #ifdef SUNTOOL
  656. short dat_cycle_cursor[] = {
  657. X    0x07C0, 0x0FE0, 0x1834, 0x301C, 0x601C, 0x203C, 0x0000, 0x0000,
  658. X    0x7808, 0x700C, 0x7018, 0x5830, 0x0FE0, 0x07C0, 0x0000, 0x0000
  659. X
  660. };
  661. mpr_static(cycle,           16, 16, 1, dat_cycle_cursor);
  662. #endif /* SUNTOOL */
  663. X
  664. /*
  665. X * struct contains the option, a prompt if it has a string value, whether
  666. X * or not it applies to non suntools, line mode, or both, and a
  667. X * string describing what the option does. If the prompt string starts
  668. X * with a minus sign, then the value can be set without a value. This
  669. X * is there to indicate to option_line to print a toggle (cycle) pixrect
  670. X * and to print TRUE/FALSE telling whether the value is on or off regardless
  671. X * of it's "string" value.
  672. X */
  673. struct viewopts viewopts[] = {
  674. X    { "alwaysignore", NULL,
  675. X    "Always ignore the message headers on the 'ignored' list." },
  676. X    { "ask", NULL,
  677. X    "Prompts for a subject on outgoing mail." },
  678. X    { "askcc", NULL,
  679. X    "Ask for list of Carbon Copy recipients whenever sending mail." },
  680. X    { "autodelete", NULL,
  681. X    "Automatically delete ALL READ messages whenever you update mail." },
  682. X    { "autoedit", NULL,
  683. X    "Automatically enter editor for REPLIES only (not toolmode)." },
  684. X    { "autoinclude", NULL,
  685. X    "Include a copy of author's message each time you reply to mail." },
  686. X    { "autoprint", NULL,
  687. X    "Display the next message on the list when you delete a message." },
  688. X    { "auto_route", "-Host/Path:",
  689. X    "Remove redundant uucp addresses when replying to messages." },
  690. X    { "autosign", "-Filename:",
  691. X    "Add file (~/.signature if set but no value) at end of all letters." },
  692. X    { "autosign2", "Addr:File:",
  693. X    "Signature to use for specific addresses. \"addr, ... : <signature>\""},
  694. X    { "cdpath", "Path:",
  695. X    "Path to search for directories when the \"cd\" command is issued." },
  696. X    { "cmd_help", "Path:",
  697. X    "Location of the general help file for line and curses modes." },
  698. X    { "complete", "Character:",
  699. X    "The character typed to cause a word completion to occur." },
  700. X    { "compose_icon", "-Filename:",
  701. X    "Alternate pixmap to use when compose window is closed to an icon." },
  702. X    { "crt", "Lines:",
  703. X    "The number of lines a message must have for 'pager' to be invoked." },
  704. X    { "crt_win", "Lines:",
  705. X    "Lines in the tool mode text subwindow for paging messages." },
  706. X    { "curses_help", "-Commands:",
  707. X    "List of curses commands whose bindings appear in the help display." },
  708. X    { "date_received", NULL,
  709. X    "Time displayed for message headers shows date received (or sent)." },
  710. X    { "dead", "Filename:",
  711. X    "The name of the file to store dead mail (default = ~/dead.letter)." },
  712. X    { "domain_route", "-Host/Path:",
  713. X    "Cause short-circuiting of domain addresses when auto-routing." },
  714. X    { "dot", NULL,
  715. X    "Allow \".\" on a line by itself to send letter." },
  716. X    { "edit_hdrs", NULL,
  717. X    "Allow headers of messages to be edited using your editor." },
  718. X    { "editor", "Editor:",
  719. X    "Editor for message editing (default = env EDITOR or \"vi\")." },
  720. X    { "escape", "Character:",
  721. X    "Escape character for extended editing commands (default = ~)." },
  722. X    { "fignore", "Patterns:",
  723. X    "Filename extensions or patterns ignored in completions." },
  724. X    { "folder", "Pathname:",
  725. X    "Full pathname to the directory where personal folders are kept." },
  726. X    { "fortune", "-Flag:",
  727. X    "Add fortune to end of letters.  Flag to \"fortune\" is optional." },
  728. X    { "fortunates", "Users:",
  729. X    "Those who will receive fortunes if fortune is set (default: All)." },
  730. X    { "hdr_format", "Format:",
  731. X    "Formatting string for headers.  \"headers -?\" or help hdr_format." },
  732. X    { "history", "Number:",
  733. X    "How many commands to remember (like csh)." },
  734. X    { "hold", NULL,
  735. X    "Read but not deleted messages are saved in spool -- not mbox." },
  736. X    { "home", "Directory:",
  737. X    "The user's home directory." },
  738. X    { "hostname", "Hostname:",
  739. X    "User-definable name for the name of your machine." },
  740. X    { "ignore_bang", NULL,
  741. X    "Ignore '!' as a history reference.  Otherwise, escape by: \\!" },
  742. X    { "ignoreeof", "-Command:",
  743. X    "Ignores ^D as exit, or (if set), execute \"command\"." },
  744. X    { "indent_str", "String:",
  745. X    "String to offset included messages within your letters." },
  746. X    { "in_reply_to", "-String:",
  747. X    "When responding to mail, add In-Reply-To: to message headers." },
  748. X    { "keepsave", NULL,
  749. X    "Prevents messages from being marked as `deleted' when you `save'." },
  750. X    { "known_hosts", "Host list:",
  751. X    "List of hosts that your site is known to uucp mail to." },
  752. X    { "logfile", "Filename:",
  753. X    "Log outgoing mail headers only.  Message text not logged." },
  754. X    { "mail_icon", "Filename:",
  755. X    "Alternate pixmap to use when tool is closed to an icon." },
  756. X    { "mbox", "Filename:",
  757. X    "Filename to use instead of ~/mbox for default mailbox." },
  758. X    { "metoo", NULL,
  759. X    "When replying to mail, metoo preserves your name on mailing list." },
  760. X    { "mil_time", NULL,
  761. X    "24-hour military time format is used whenever a time is printed." },
  762. X    { "msg_win", "Lines:",
  763. X    "Number of lines in the message composition window for tool mode." },
  764. X    { "newline", "-Command:",
  765. X    "Ignore RETURN.  If set to a command, execute that command." },
  766. X    { "newmail_icon", "Filename:",
  767. X    "Alternate icon shown when new mail is available." },
  768. X    { "no_expand", NULL,
  769. X    "Prevents expansion of Mush aliases in outgoing mail headers." },
  770. X    { "no_hdrs", NULL,
  771. X    "If set, personalized headers are NOT inserted to outgoing mail." },
  772. X    { "no_reverse", NULL,
  773. X    "Disables reverse video in curses mode -- uses \"bold\" in tool mode."},
  774. X    { "nonobang", NULL,
  775. X    "Suppresses errors from unsuccessful history references." },
  776. X    { "nosave", NULL,
  777. X    "Prevents aborted mail from being saved in $dead." },
  778. X    { "output", NULL,
  779. X    "The message list produced as output of the last command." },
  780. X    { "pager", "Program:",
  781. X    "Program name to be used as a pager for messages longer than crt." },
  782. X    { "pre_indent_str", "String:",
  783. X    "String to precede message text interpolated into message body." },
  784. X    { "post_indent_str", "String:",
  785. X    "String to succeed message text interpolated into message body." },
  786. X    { "print_cmd", "Program:",
  787. X    "Alternate program to use to send messages to the printer." },
  788. X    { "printer", "Printer:",
  789. X    "Printer to send messages to (default = environment PRINTER)." },
  790. X    { "prompt", "String:",
  791. X    "Your prompt.  \"help prompt\" for more information." },
  792. X    { "quiet", "-Conditions:",
  793. X    "Turn off verbose messages and error bells in various conditions." },
  794. X    { "realname", "Name:",
  795. X    "Your real name." },
  796. X    { "record", "Filename:",
  797. X    "Save all outgoing mail in specified filename." },
  798. X    { "reply_to_hdr", "Headers:",
  799. X    "List of headers use to construct reply addresses from a message." },
  800. X    { "save_empty", NULL,
  801. X    "Folders which have all messages deleted are NOT removed on updates." },
  802. X    { "screen", "# of Headers:",
  803. X    "Number of headers to print in non-suntools (text) mode." },
  804. X    { "screen_win", "# of Headers:",
  805. X    "Set the size of the header window for the tool mode only." },
  806. X    { "show_deleted", NULL,
  807. X    "Show deleted messages in headers listings (unused in curses mode)." },
  808. X    { "show_hdrs", "Headers:",
  809. X    "When displaying a message, show list of \"headers\" only." },
  810. X    { "sendmail", "Program:",
  811. X    "Program to use to deliver mail instead of using the default."},
  812. X    { "sort", "-Option:",
  813. X    "Pre-sorting of messages on mush startup (set to valid sort option)." },
  814. X    { "squeeze", NULL,
  815. X    "When reading messages, squeeze all blank lines into one." },
  816. X    { "status", NULL,
  817. X    "The success or failure status of the most recent command." },
  818. X    { "thisfolder", "Folder:",
  819. X    "This read-only variable gives the current folder name." },
  820. X    { "tool_help", "Path:",
  821. X    "Location of the help file for tool mode."  },
  822. X    { "toplines", "Lines:",
  823. X    "Number of lines to print of a message for the 'top' command."  },
  824. X    { "tmpdir", "Directory:",
  825. X    "Directory to use for temporary files used by Mush." },
  826. X    { "unix", NULL,
  827. X    "Non-mush commands are considered to be UNIX commands." },
  828. X    { "verify", NULL,
  829. X    "Verify before acting in various situations, such as sending mail." },
  830. X    { "visual", "Visual editor:",
  831. X    "Visual editor for messages (default = $editor or env VISUAL)."},
  832. X    { "warning", NULL,
  833. X    "Print warning messages for non-fatal errors." },
  834. X    { "wrap", NULL,
  835. X    "After referencing last message, message pointer wraps to start." },
  836. X    { "wrapcolumn", "-Column to wrap [78]:",
  837. X    "Column at which to wrap lines when composing messages." },
  838. };
  839. X
  840. #ifdef SUNTOOL
  841. X
  842. #define OPTIONS_PANEL_WIDTH    550
  843. X
  844. int set_value(), toggle_value(), help_opt();
  845. X
  846. Frame opts_frame;
  847. Panel opts_panel;
  848. Panel_item desc_msg;
  849. Panel_item file_text_item;
  850. X
  851. static void
  852. frame_done()
  853. {
  854. #ifdef SUN_4_0 /* SunOS 4.0+ */
  855. X    window_set(opts_frame, WIN_SHOW, FALSE, NULL);
  856. #else /* SUN_4_0 */
  857. X    /* not enough fd's to keep it lying around for SunOS 3.X */
  858. X    window_destroy(opts_frame);
  859. X    opts_frame = (Frame) 0;
  860. #endif /* SUN_4_0 */
  861. }
  862. X
  863. static void
  864. opts_help()
  865. {
  866. X    help(0, "options", tool_help);
  867. }
  868. X
  869. static void
  870. opts_save_load(item)
  871. Panel_item item;
  872. {
  873. X    int (*func)() = (int (*)())panel_get(item, PANEL_CLIENT_DATA);
  874. X    int result;
  875. X    char buf[MAXPATHLEN];
  876. X    char *argv[3], *file = panel_get_value(file_text_item);
  877. X
  878. X    if (!*file) {
  879. X    result = (*func)(0, DUBL_NULL);
  880. X    file = ".mushrc";
  881. X    } else {
  882. X    argv[1] = file;
  883. X    argv[2] = NULL;
  884. X    result = (*func)(2, argv);
  885. X    }
  886. X    switch (result) {
  887. X    case 0:
  888. X        sprintf(buf, "%s %s",
  889. X        (func == source)? "Loaded options from" : "Saved options to",
  890. X        file);
  891. X    when -1:
  892. X        sprintf(buf, "%s: %s", file, sys_errlist[errno]);
  893. X    when -2:
  894. X        sprintf(buf, "%s is a directory.", file);
  895. X    when -3:
  896. X        /* save_opts() returns -3 if user doesn't confirm overwrite */
  897. X        strcpy(buf, "Save operation aborted.");
  898. X    }
  899. X    panel_set(desc_msg, PANEL_LABEL_STRING, buf, NULL);
  900. }
  901. X
  902. static void
  903. unset_opts()
  904. {
  905. X    cmd_line("unset *", NULL);
  906. }
  907. X
  908. static void
  909. reset_opts()
  910. {
  911. X    source(0, DUBL_NULL);
  912. }
  913. X
  914. /*
  915. X * Public routine which creates a subframe which contains two panels.
  916. X * The first contains options for loading and saving options from a
  917. X * file (text item) and so on... the second panel contains all the items
  918. X * which correspond to each mush variable that exists.
  919. X */
  920. void
  921. view_options()
  922. {
  923. X    extern Notify_value fkey_interposer();
  924. X    register char *p;
  925. X    int count;
  926. X
  927. X    if (opts_frame) {
  928. X    window_set(opts_frame, WIN_SHOW, TRUE, NULL);
  929. X    opts_panel_item(NULL);
  930. X    return;
  931. X    }
  932. #ifdef SUN_3_5
  933. X    if (nopenfiles(0) < 3) {
  934. X    ok_box("Too many frames; close one first!\n");
  935. X    return;
  936. X    }
  937. #endif /* SUN_3_5 */
  938. X
  939. X    opts_frame = window_create(tool, FRAME,
  940. X    FRAME_DONE_PROC,    frame_done,
  941. X    FRAME_LABEL,        "Mush Options",
  942. X    FRAME_NO_CONFIRM,    TRUE,
  943. X    FRAME_SHOW_LABEL,    TRUE,
  944. X    WIN_WIDTH,        OPTIONS_PANEL_WIDTH,
  945. X    NULL);
  946. X
  947. X    opts_panel = window_create(opts_frame, PANEL,
  948. X    WIN_WIDTH,        OPTIONS_PANEL_WIDTH,
  949. X    NULL);
  950. X    (void) notify_interpose_event_func(opts_panel,
  951. X    fkey_interposer, NOTIFY_SAFE);
  952. X    panel_create_item(opts_panel, PANEL_BUTTON,
  953. X    PANEL_LABEL_IMAGE,
  954. X        panel_button_image(opts_panel, "Done", 4, mush_font),
  955. X    PANEL_NOTIFY_PROC,    frame_done,
  956. X    NULL);
  957. X    panel_create_item(opts_panel, PANEL_BUTTON,
  958. X    PANEL_LABEL_IMAGE,
  959. X        panel_button_image(opts_panel, "Help", 4, mush_font),
  960. X    PANEL_NOTIFY_PROC,    opts_help,
  961. X    NULL);
  962. X    panel_create_item(opts_panel, PANEL_BUTTON,
  963. X    PANEL_LABEL_IMAGE,
  964. X        panel_button_image(opts_panel, "Save", 4, mush_font),
  965. X    PANEL_NOTIFY_PROC,    opts_save_load,
  966. X    PANEL_CLIENT_DATA,    save_opts,
  967. X    NULL);
  968. X    panel_create_item(opts_panel, PANEL_BUTTON,
  969. X    PANEL_LABEL_IMAGE,
  970. X        panel_button_image(opts_panel, "Load", 4, mush_font),
  971. X    PANEL_NOTIFY_PROC,    opts_save_load,
  972. X    PANEL_CLIENT_DATA,    source,
  973. X    NULL);
  974. X    panel_create_item(opts_panel, PANEL_BUTTON,
  975. X    PANEL_LABEL_IMAGE,
  976. X        panel_button_image(opts_panel, "Clear", 5, mush_font),
  977. X    PANEL_NOTIFY_PROC,    unset_opts,
  978. X    NULL);
  979. X    panel_create_item(opts_panel, PANEL_BUTTON,
  980. X    PANEL_LABEL_IMAGE,
  981. X        panel_button_image(opts_panel, "Restart", 7, mush_font),
  982. X    PANEL_NOTIFY_PROC,    reset_opts,
  983. X    NULL);
  984. X    file_text_item = panel_create_item(opts_panel, PANEL_TEXT,
  985. X    PANEL_LABEL_STRING,    "Save/Load File:",
  986. X    PANEL_VALUE_DISPLAY_LENGTH, 30,
  987. X    NULL);
  988. X    desc_msg = panel_create_item(opts_panel, PANEL_MESSAGE,
  989. X    PANEL_LABEL_STRING,    "Help Descriptions -- Click on Variable Name",
  990. X    NULL);
  991. X    window_fit_height(opts_panel);
  992. X
  993. X    /* reuse opts_panel -- we don't need the other one */
  994. X    opts_panel = window_create(opts_frame, PANEL,
  995. X    WIN_BELOW,            opts_panel,
  996. X    WIN_X,                0,
  997. X    WIN_COLUMN_GAP,            120,
  998. X    WIN_TOP_MARGIN,            10,
  999. X    WIN_LEFT_MARGIN,        10,
  1000. X    WIN_WIDTH,            OPTIONS_PANEL_WIDTH,
  1001. X    PANEL_VERTICAL_SCROLLBAR,    scrollbar_create(NULL),
  1002. X    NULL);
  1003. X    (void) notify_interpose_event_func(opts_panel,
  1004. X    fkey_interposer, NOTIFY_SAFE);
  1005. X
  1006. X    for (count = 0; count < ArraySize(viewopts); count++) {
  1007. X    panel_create_item(opts_panel, PANEL_MESSAGE,
  1008. X        PANEL_ITEM_X,    ATTR_COL(0),
  1009. X        PANEL_ITEM_Y,    ATTR_ROW(count),
  1010. X        PANEL_LABEL_STRING,    viewopts[count].v_opt,
  1011. X        PANEL_NOTIFY_PROC,    help_opt,
  1012. X        PANEL_CLIENT_DATA,    count,
  1013. X        NULL);
  1014. X
  1015. X    if (!(p = viewopts[count].v_prompt) || *p == '-') {
  1016. X        if (p && *p)
  1017. X        p++;
  1018. X        viewopts[count].v_choice = panel_create_item(opts_panel,
  1019. X        PANEL_CHOICE,
  1020. X        PANEL_LABEL_IMAGE,    &cycle,
  1021. X        PANEL_LAYOUT,        PANEL_HORIZONTAL,
  1022. X        PANEL_CHOICE_STRINGS,    "False", "True", NULL,
  1023. X        PANEL_DISPLAY_LEVEL,    PANEL_CURRENT,
  1024. X        PANEL_ITEM_X,        ATTR_COL(1),
  1025. X        PANEL_ITEM_Y,        ATTR_ROW(count),
  1026. X        PANEL_NOTIFY_PROC,    toggle_value,
  1027. X        PANEL_CLIENT_DATA,    count,
  1028. X        NULL);
  1029. X    }
  1030. X    if (p) {
  1031. X        viewopts[count].v_text = panel_create_item(opts_panel, PANEL_TEXT,
  1032. X        PANEL_VALUE_DISPLAY_LENGTH,    10,
  1033. X        PANEL_VALUE_UNDERLINED,        TRUE,
  1034. X        PANEL_LABEL_STRING,        p,
  1035. X        PANEL_ITEM_X,            ATTR_COL(2),
  1036. X        PANEL_ITEM_Y,            ATTR_ROW(count),
  1037. X        PANEL_NOTIFY_PROC,        set_value,
  1038. X        PANEL_CLIENT_DATA,        count,
  1039. X        NULL);
  1040. X    }
  1041. X    }
  1042. X    /* set the panel items' values */
  1043. X    opts_panel_item(NULL);
  1044. X
  1045. X    window_set(opts_panel,
  1046. X    WIN_HEIGHT,    400,
  1047. X    WIN_FIT_HEIGHT,    0,
  1048. X    NULL);
  1049. X    window_set(opts_frame, WIN_SHOW, TRUE, NULL);
  1050. }
  1051. X
  1052. /*
  1053. X * Sets the items in the panels to reflect that variable's value.
  1054. X * If "var" is NULL, do it for all the items.
  1055. X */
  1056. void
  1057. opts_panel_item(var)
  1058. char *var;
  1059. {
  1060. X    int count;
  1061. X    char *value;
  1062. X
  1063. X    if (!opts_frame)
  1064. X    return;
  1065. X
  1066. X    for (count = 0; count < ArraySize(viewopts); count++) {
  1067. X    if (var && strcmp(var, viewopts[count].v_opt))
  1068. X        continue;
  1069. X    value = do_set(set_options, viewopts[count].v_opt);
  1070. X
  1071. X    if (!viewopts[count].v_prompt || *viewopts[count].v_prompt == '-')
  1072. X        panel_set_value(viewopts[count].v_choice, value != NULL);
  1073. X    if (viewopts[count].v_prompt)
  1074. X        panel_set_value(viewopts[count].v_text, value? value : "");
  1075. X    if (var)
  1076. X        break;
  1077. X    }
  1078. }
  1079. X
  1080. /*
  1081. X * Callback for choice items -- for variables that have boolean settings.
  1082. X * CLIENT_DATA is the index in the viewopts array.
  1083. X */
  1084. static
  1085. toggle_value(item, value)
  1086. Panel_item item;
  1087. int value;
  1088. {
  1089. X    int count = (int) panel_get(item, PANEL_CLIENT_DATA);
  1090. X    char *p, *argv[4];
  1091. X    char *text_value = NULL;
  1092. X
  1093. X    if (check_internal(viewopts[count].v_opt)) {
  1094. X    panel_set(desc_msg, PANEL_LABEL_STRING,
  1095. X        "This is an internal variable which cannot be changed.",
  1096. X        NULL);
  1097. X    /* can't change it - restore previous setting */
  1098. X    panel_set_value(viewopts[count].v_choice, !value);
  1099. X    return -1;
  1100. X    }
  1101. X
  1102. X    if (p = viewopts[count].v_prompt) /* set equal */
  1103. X    text_value = panel_get_value(viewopts[count].v_text);
  1104. X
  1105. X    if (!value) {
  1106. X    if (un_set(&set_options, viewopts[count].v_opt) == -1) {
  1107. X        /* can't change it - restore previous setting */
  1108. X        panel_set_value(viewopts[count].v_choice, !value);
  1109. X        return -1;
  1110. X    }
  1111. X    } else {
  1112. X    /* Turn it on if it's entirely boolean or bool/str, but no str value */
  1113. X    if (!p || text_value && !*text_value) {
  1114. X        argv[0] = viewopts[count].v_opt; /* it's a boolean */
  1115. X        argv[1] = NULL;
  1116. X    } else {
  1117. X        /* string value -- determine the text from the typed in value */
  1118. X        argv[0] = viewopts[count].v_opt;
  1119. X        argv[1] = "=";
  1120. X        argv[2] = text_value;
  1121. X        argv[3] = NULL;
  1122. X    }
  1123. X    if (add_option(&set_options, argv) != 1) {
  1124. X        /* can't change it - restore previous setting */
  1125. X        panel_set_value(viewopts[count].v_choice, !value);
  1126. X        return -1;
  1127. X    }
  1128. X    }
  1129. X
  1130. X    if (!strcmp(viewopts[count].v_opt, "no_reverse") ||
  1131. X    !strcmp(viewopts[count].v_opt, "show_deleted"))
  1132. X    do_hdrs(0, DUBL_NULL, NULL);
  1133. X
  1134. X    return 0;
  1135. }
  1136. X
  1137. /* callback for text items -- set vars to the string typed. */
  1138. static
  1139. set_value(item, event)
  1140. Panel_item item;
  1141. Event *event;
  1142. {
  1143. X    int count = (int)panel_get(item, PANEL_CLIENT_DATA);
  1144. X    char *p, *argv[4], *value;
  1145. X
  1146. X    if (event_id(event) == '\t')
  1147. X    return (int) PANEL_NEXT;
  1148. X
  1149. X    p = viewopts[count].v_prompt;
  1150. X    value = panel_get_value(item);
  1151. X
  1152. X    if (check_internal(viewopts[count].v_opt)) {
  1153. X    panel_set(desc_msg, PANEL_LABEL_STRING,
  1154. X        "This is an internal variable which cannot be changed.",
  1155. X        NULL);
  1156. X    return (int) PANEL_NONE;
  1157. X    }
  1158. X
  1159. X    /*
  1160. X     * You can "unset" string-only values by entering a blank string.
  1161. X     * If the "prompt" starts with a -, then you can only "unset" the
  1162. X     * variable by setting the associated choice item to false.
  1163. X     */
  1164. X    if (*p != '-' && !*value) {
  1165. X    (void) un_set(&set_options, viewopts[count].v_opt);
  1166. X    return (int) PANEL_NONE; /* do not advance caret */
  1167. X    }
  1168. X    /* Turn it on, but not to a value */
  1169. X    if (!*value) {
  1170. X    argv[0] = viewopts[count].v_opt; /* it's a boolean */
  1171. X    argv[1] = NULL;
  1172. X    } else {
  1173. X    /* string value -- determine the text from the typed in value */
  1174. X    argv[0] = viewopts[count].v_opt;
  1175. X    argv[1] = "=";
  1176. X    argv[2] = value;
  1177. X    argv[3] = NULL;
  1178. X    }
  1179. X
  1180. X    if (add_option(&set_options, argv) == 1 && p && *p == '-')
  1181. X    panel_set_value(viewopts[count].v_choice, TRUE);
  1182. X
  1183. X    return (int) PANEL_NONE;
  1184. }
  1185. X
  1186. /* when user clicks on variable label itself */
  1187. static
  1188. help_opt(item, event)
  1189. Panel_item item;
  1190. Event *event;
  1191. {
  1192. X    int count = (int)panel_get(item, PANEL_CLIENT_DATA);
  1193. X
  1194. X    panel_set(desc_msg,
  1195. X    PANEL_LABEL_STRING, viewopts[count].v_description,
  1196. X    NULL);
  1197. X    return 0;
  1198. }
  1199. X
  1200. #endif /* SUNTOOL */
  1201. X
  1202. /*
  1203. X * return a string describing a variable.
  1204. X * parameters: count, str, buf.
  1205. X * If str != NULL, check str against ALL variables
  1206. X * in viewopts array.  The one that matches, set count to it and 
  1207. X * print up all the stuff from the viewopts[count] into the buffer
  1208. X * space in "buf" and return it.
  1209. X */
  1210. char *
  1211. variable_stuff(count, str, buf)
  1212. register char *str, *buf;
  1213. {
  1214. X    if (str)
  1215. X    for (count = 0; count < ArraySize(viewopts); count++)
  1216. X        if (!strcmp(str, viewopts[count].v_opt))
  1217. X        break;
  1218. X    if (count >= ArraySize(viewopts)) {
  1219. X    (void) sprintf(buf, "%s: Not a default %s variable.",
  1220. X               str? str : itoa(count), prog_name);
  1221. X    return NULL;
  1222. X    }
  1223. X    return sprintf(buf, "%s: %s",
  1224. X    viewopts[count].v_opt, viewopts[count].v_description);
  1225. }
  1226. SHAR_EOF
  1227. chmod 0644 viewopts.c ||
  1228. echo 'restore of viewopts.c failed'
  1229. Wc_c="`wc -c < 'viewopts.c'`"
  1230. test 18782 -eq "$Wc_c" ||
  1231.     echo 'viewopts.c: original size 18782, current size' "$Wc_c"
  1232. rm -f _shar_wnt_.tmp
  1233. fi
  1234. rm -f _shar_seq_.tmp
  1235. echo You have unpacked the last part
  1236. exit 0
  1237. exit 0 # Just in case...
  1238. -- 
  1239. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1240. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1241. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1242. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1243.