home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / tin / part07 / select.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-20  |  23.9 KB  |  1,082 lines

  1. /*
  2.  *  Project   : tin - a threaded Netnews reader
  3.  *  Module    : select.c
  4.  *  Author    : I.Lea & R.Skrenta
  5.  *  Created   : 01-04-91
  6.  *  Updated   : 11-05-92
  7.  *  Notes     :
  8.  *  Copyright : (c) Copyright 1991-92 by Iain Lea & Rich Skrenta
  9.  *              You may  freely  copy or  redistribute  this software,
  10.  *              so  long as there is no profit made from its use, sale
  11.  *              trade or  reproduction.  You may not change this copy-
  12.  *              right notice, and it must be included in any copy made
  13.  */
  14.  
  15. #include    "tin.h"
  16.  
  17.  
  18. extern char cvers[LEN];
  19. extern int index_point;
  20. extern int reread_active_file;
  21.  
  22. char default_goto_group[LEN];
  23. int default_move_group;
  24. int cur_groupnum = 0;
  25. int first_group_on_screen;
  26. int last_group_on_screen;
  27. int space_mode;
  28. int yank_active_file = TRUE;
  29.  
  30.  
  31. void selection_index (start_groupnum)
  32.     int start_groupnum;
  33. {
  34. #ifndef INDEX_DAEMON
  35.  
  36.     char buf[LEN];
  37.     char post_group[LEN];
  38.     char ch;
  39.     int i, n;
  40.     int patlen;
  41.     int posted;
  42.     int scroll_lines;
  43.     int subscribe_num;
  44.     int time_remaining;
  45.     
  46.     cur_groupnum = start_groupnum;
  47.     
  48.     mail_setup ();        /* record mailbox size for "you have mail" */
  49.  
  50. #ifdef READ_CHAR_HACK
  51.     setbuf (stdin, 0);
  52. #endif
  53.  
  54. #ifndef USE_CLEARSCREEN
  55.     ClearScreen();
  56. #endif
  57.  
  58.     set_groupname_len (FALSE);    /* find longest subscribedto groupname */
  59.     group_selection_page ();    /* display group selection page */
  60.     set_alarm_signal ();        /* set alarm signal for resync_active_file () */
  61.     
  62.     while (TRUE) {
  63. #ifndef NO_RESYNC_ACTIVE_FILE
  64.         resync_active_file ();    /* reread active file if alarm set */
  65. #endif
  66.         ch = (char) ReadCh ();
  67. #ifndef NO_RESYNC_ACTIVE_FILE
  68.         resync_active_file ();    /* reread active file if alarm set */
  69. #endif
  70.  
  71.         if (ch > '0' && ch <= '9') {
  72.             prompt_group_num (ch);
  73.             continue;
  74.         }
  75.         switch (ch) {
  76.             case ESC:    /* (ESC) common arrow keys */
  77.                 switch (get_arrow_key ()) {
  78.                     case KEYMAP_UP:
  79.                         goto select_up;
  80.  
  81.                     case KEYMAP_DOWN:
  82.                         goto select_down;
  83.  
  84.                     case KEYMAP_PAGE_UP:
  85.                         goto select_page_up;
  86.  
  87.                     case KEYMAP_PAGE_DOWN:
  88.                         goto select_page_down;
  89.  
  90.                     case KEYMAP_HOME:
  91.                         if (cur_groupnum != 0) {
  92.                             if (0 < first_group_on_screen) {
  93. #ifndef USE_CLEARSCREEN
  94.                                 erase_group_arrow();
  95. #endif                    
  96.                                 cur_groupnum = 0;
  97.                                 group_selection_page();
  98.                             } else {
  99.                                 erase_group_arrow();
  100.                                 cur_groupnum = 0;
  101.                                 draw_group_arrow();
  102.                             }
  103.                         }
  104.                         break;
  105.                     
  106.                     case KEYMAP_END:
  107.                         goto end_of_list;
  108.                 }
  109.                 break;
  110.  
  111. #ifndef NO_SHELL_ESCAPE
  112.             case '!':
  113.                 shell_escape ();
  114.                 group_selection_page ();
  115.                 break;
  116. #endif
  117.  
  118.             case '$':    /* show last page of groups */
  119. end_of_list:
  120.                 if (cur_groupnum != group_top - 1) {
  121.                     if (group_top - 1 > last_group_on_screen) {
  122. #ifndef USE_CLEARSCREEN
  123.                         erase_group_arrow();
  124. #endif                    
  125.                         cur_groupnum = group_top - 1;
  126.                         group_selection_page();
  127.                     } else {
  128.                         erase_group_arrow();
  129.                         cur_groupnum = group_top - 1;
  130.                         draw_group_arrow();
  131.                     }
  132.                 }
  133.                 break;
  134.  
  135.             case '/':    /* search forward */
  136.             case '?':    /* search backward */
  137.                 i = (ch == '/');
  138.                 search_group (i);
  139.                 break;
  140.  
  141.             case '\r':    /* go into group */
  142.             case '\n':
  143.                 if (group_top == 0) {
  144.                     info_message (txt_no_groups);
  145.                     break;
  146.                 }
  147.                 
  148.                 n = my_group[cur_groupnum];
  149.                 if (active[n].min <= active[n].max) {
  150.                     space_mode = pos_first_unread;
  151.                     clear_message();
  152.                     index_point = -1;
  153.                     do {
  154.                         n = my_group[cur_groupnum];
  155.                         group_page (active[n].name);
  156.                     } while (index_point == -3);
  157. #ifndef NO_RESYNC_ACTIVE_FILE                    
  158.                     if (! reread_active_file)
  159. #endif                    
  160.                         group_selection_page ();
  161.                 } else {
  162.                     info_message (txt_no_arts);
  163.                 }
  164.                 break;
  165.  
  166.             case '\t':    /* enter next group containing unread articles */
  167.             case 'n':
  168.                 next_unread_group (TRUE);
  169.                 break;
  170.  
  171.             case ' ':            /* page down */
  172.             case ctrl('D'):        /* vi style */
  173.             case ctrl('V'):        /* emacs style */
  174. select_page_down:
  175.                 if (! group_top) {
  176.                     break;
  177.                 }
  178.                 if (cur_groupnum == group_top - 1) {
  179. #ifdef NO_LOOP_AROUND
  180.                     break;
  181. #else
  182.                     if (0 < first_group_on_screen) {
  183. #    ifndef USE_CLEARSCREEN
  184.                         erase_group_arrow();
  185. #    endif                    
  186.                         cur_groupnum = 0;
  187.                         group_selection_page();
  188.                     } else {
  189.                         erase_group_arrow();
  190.                         cur_groupnum = 0;
  191.                         draw_group_arrow();
  192.                     }
  193.                     break;
  194. #endif                    
  195.                 }
  196.                 erase_group_arrow ();
  197.                 scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  198.                 cur_groupnum = ((cur_groupnum + scroll_lines) / scroll_lines) * scroll_lines;
  199.                 if (cur_groupnum >= group_top) {
  200.                     cur_groupnum = (group_top / scroll_lines) * scroll_lines;
  201.                     if (cur_groupnum < group_top - 1) {
  202.                         cur_groupnum = group_top - 1;
  203.                     }
  204.                 }
  205.  
  206.                 if (cur_groupnum <= first_group_on_screen
  207.                 ||  cur_groupnum >= last_group_on_screen)
  208.                     group_selection_page ();
  209.                 else
  210.                     draw_group_arrow ();
  211.                 break;
  212.  
  213.             case ctrl('K'):        /* delete group */
  214.                 if (group_top <= 0) {
  215.                     info_message (txt_no_groups_to_delete);
  216.                     break;
  217.                 }
  218.  
  219.                 sprintf (buf, active[my_group[cur_groupnum]].name);
  220.                 sprintf (msg, txt_del_group_in_newsrc, buf);
  221.                 if (prompt_yn (LINES, msg, 'y')) {
  222.                     delete_group (active[my_group[cur_groupnum]].name);
  223.                     active[my_group[cur_groupnum]].flag = UNSUBSCRIBED;    
  224.  
  225.                     group_top--;
  226.                     for (i = cur_groupnum; i < group_top; i++) {
  227.                         my_group[i] = my_group[i+1];
  228.                         unread[i] = unread[i+1];
  229.                     }
  230.                     if (cur_groupnum >= group_top)
  231.                         cur_groupnum = group_top - 1;    
  232.  
  233.                     set_groupname_len (FALSE);    
  234.                     group_selection_page ();
  235.                     sprintf (msg, txt_group_deleted, buf);
  236.                     info_message (msg);
  237.                 }
  238.                 break;
  239.  
  240.             case ctrl('L'):        /* redraw */
  241. #ifndef USE_CLEARSCREEN
  242.                 ClearScreen ();
  243. #endif
  244.                 group_selection_page ();
  245.                 break;
  246.  
  247.             case ctrl('N'):        /* line down */
  248.             case 'j':
  249. select_down:
  250.                 if (group_top == 0) {
  251.                     break;
  252.                 }
  253.                 if (cur_groupnum + 1 >= group_top) {
  254. #ifdef NO_LOOP_AROUND
  255.                     break;
  256. #else
  257.                     if (0 < first_group_on_screen) {
  258. #    ifndef USE_CLEARSCREEN
  259.                         erase_group_arrow();
  260. #    endif                    
  261.                         cur_groupnum = 0;
  262.                         group_selection_page();
  263.                     } else {
  264.                         erase_group_arrow();
  265.                         cur_groupnum = 0;
  266.                         draw_group_arrow();
  267.                     }
  268.                     break;
  269. #endif                    
  270.                 }
  271.                 if (cur_groupnum + 1 >= last_group_on_screen) {
  272. #ifndef USE_CLEARSCREEN
  273.                     erase_group_arrow();
  274. #endif                    
  275.                     cur_groupnum++;
  276.                     group_selection_page();
  277.                 } else {
  278.                     erase_group_arrow();
  279.                     cur_groupnum++;
  280.                     draw_group_arrow();
  281.                 }
  282.                 break;
  283.  
  284.             case ctrl('P'):        /* line up */
  285.             case 'k':
  286. select_up:
  287.                 if (! group_top || cur_groupnum == 0) {
  288. #ifdef NO_LOOP_AROUND
  289.                     break;
  290. #else
  291.                     if (group_top > last_group_on_screen) {
  292.                         cur_groupnum = group_top - 1;
  293.                         group_selection_page ();
  294.                     } else {
  295.                         erase_group_arrow ();
  296.                         cur_groupnum = group_top - 1;
  297.                         draw_group_arrow ();
  298.                     }
  299.                     break;
  300. #endif                    
  301.                 }
  302.                 if (cur_groupnum <= first_group_on_screen) {
  303.                     cur_groupnum--;
  304.                     group_selection_page ();
  305.                 } else {
  306.                     erase_group_arrow ();
  307.                     cur_groupnum--;
  308.                     draw_group_arrow ();
  309.                 }
  310.                 break;
  311.  
  312.             case ctrl('R'):    /* reset .newsrc */
  313.                 if (prompt_yn (LINES, txt_reset_newsrc, 'n')) {
  314.                     reset_newsrc ();
  315.                     cur_groupnum = 0;
  316.                     group_selection_page ();
  317.                 }
  318.                 break;
  319.  
  320.             case ctrl('U'):        /* page up */
  321.             case 'b':
  322. select_page_up:
  323.                 if (! group_top) {
  324.                     break;
  325.                 }
  326.                 if (cur_groupnum == 0) {
  327. #ifdef NO_LOOP_AROUND
  328.                     break;
  329. #else
  330.                     if (group_top > last_group_on_screen) {
  331.                         cur_groupnum = group_top - 1;
  332.                         group_selection_page ();
  333.                     } else {
  334.                         erase_group_arrow ();
  335.                         cur_groupnum = group_top - 1;
  336.                         draw_group_arrow ();
  337.                     }
  338.                     break;
  339. #endif                    
  340.                 }
  341.                 erase_group_arrow ();
  342.                 scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  343.                 if ((n = cur_groupnum % scroll_lines) > 0) {
  344.                     cur_groupnum = cur_groupnum - n;
  345.                 } else {
  346.                     cur_groupnum = ((cur_groupnum - scroll_lines) / scroll_lines) * scroll_lines;
  347.                 }
  348.                 if (cur_groupnum < 0) {
  349.                     cur_groupnum = 0;
  350.                 }
  351.                 if (cur_groupnum < first_group_on_screen
  352.                 ||  cur_groupnum >= last_group_on_screen)
  353.                     group_selection_page ();
  354.                 else
  355.                     draw_group_arrow ();
  356.                 break;
  357.  
  358.             case 'B':    /* bug/gripe/comment mailed to author */
  359.                 mail_bug_report ();
  360. #ifndef USE_CLEARSCREEN
  361.                 ClearScreen ();
  362. #endif
  363.                 group_selection_page ();
  364.                 break;
  365.                 
  366.             case 'c':    /* catchup--mark all articles as read */
  367.             case 'C':    /* catchup & goto next unread group */
  368.                 if (group_top == 0) {
  369.                     break;
  370.                 }
  371.                 catchup_group ((ch == 'C'));
  372.                 break;
  373.  
  374.             case 'g':    /* prompt for a new group name */
  375.                 if ((n = choose_new_group ()) >= 0) {
  376.                     if (active[my_group[n]].flag != SUBSCRIBED) {
  377.                         subscribe (active[my_group[n]].name, ':',
  378.                             my_group[n], FALSE);
  379.                     }
  380.                     erase_group_arrow ();
  381.                     cur_groupnum = reposition_group (active[my_group[n]].name,
  382.                                     (n ? n : cur_groupnum));
  383.                     set_groupname_len (FALSE);                
  384.                     if (cur_groupnum < first_group_on_screen ||
  385.                         cur_groupnum >= last_group_on_screen ||
  386.                         cur_groupnum != n) {
  387.                         group_selection_page();
  388.                     } else {
  389.                         clear_message ();
  390.                         draw_group_arrow();
  391.                     }
  392.                 }
  393.                 break;
  394.  
  395.             case 'h':    /* help */
  396.                 show_info_page (HELP_INFO, help_select, txt_group_select_com);
  397.                 group_selection_page ();
  398.                 break;
  399.  
  400.             case 'I':    /* toggle inverse video */
  401.                 erase_group_arrow ();
  402.                 toggle_inverse_video ();
  403.                 group_selection_page ();
  404.                 break;
  405.  
  406.             case 'l':    /* list available spooldirs */
  407.                 if (spooldir_index ()) {
  408.                     group_selection_page ();
  409.                 }    
  410.                 break;
  411.  
  412.             case 'm':    /* reposition group within group list */
  413.                 if (active[my_group[cur_groupnum]].flag == SUBSCRIBED) {
  414.                     n = cur_groupnum;
  415.                     cur_groupnum = reposition_group (active[my_group[n]].name, n);
  416.                     if (cur_groupnum < first_group_on_screen ||
  417.                         cur_groupnum >= last_group_on_screen ||
  418.                         cur_groupnum != n) {
  419.                         group_selection_page ();
  420.                     } else {
  421.                         i = cur_groupnum;
  422.                         cur_groupnum = n;
  423.                         erase_group_arrow ();
  424.                         cur_groupnum = i;
  425.                         clear_message ();
  426.                         draw_group_arrow ();
  427.                     }
  428.                 }
  429.                 break;
  430.  
  431.             case 'M':    /* options menu */
  432. #ifndef NO_RESYNC_ACTIVE_FILE
  433.                 time_remaining = alarm (0);
  434. #endif
  435.                 change_rcfile ("", TRUE);
  436.                 group_selection_page ();
  437. #ifndef NO_RESYNC_ACTIVE_FILE
  438.                 alarm (time_remaining);
  439. #endif
  440.                 break;
  441.  
  442.             case 'N':    /* goto next unread group */
  443.                 next_unread_group (FALSE);
  444.                 break;
  445.  
  446.             case 'q':    /* quit */
  447.             case 'Q':    /* quit */
  448.                 write_rcfile ();
  449.                 tin_done (0);
  450.                 break;
  451.  
  452.             case 's':    /* subscribe to current group */
  453.                 if (group_top == 0) {
  454.                     break;
  455.                 }
  456.                 if (active[my_group[cur_groupnum]].flag != SUBSCRIBED) {
  457.                     MoveCursor (INDEX_TOP + (cur_groupnum-first_group_on_screen), 3);
  458.                     if (draw_arrow_mark) {
  459.                         fputc (' ', stdout);
  460.                     } else {
  461.                         screen[cur_groupnum-first_group_on_screen].col[3] = ' ';
  462.                         draw_group_arrow ();
  463.                     }
  464.                     fflush (stdout);
  465.                     MoveCursor (LINES, 0);    
  466.  
  467.                     subscribe (active[my_group[cur_groupnum]].name,
  468.                         ':', my_group[cur_groupnum], FALSE);
  469.                     sprintf (buf, txt_subscribed_to, active[my_group[cur_groupnum]].name);
  470.                     info_message (buf);
  471.                 }
  472.                 break;
  473.  
  474.             case 'S':    /* subscribe to groups matching pattern */
  475.                 if (prompt_string (txt_subscribe_pattern, buf) && buf[0]) {
  476.                     wait_message (txt_subscribing);
  477.                     patlen = strlen (buf);
  478.                     for (subscribe_num=0, i=0 ; i < group_top ; i++) {
  479. #ifdef NO_REGEX 
  480.                         if (str_str (active[my_group[i]].name, buf, patlen)) {
  481. #else        
  482.                         if (wildmat (active[my_group[i]].name, buf)) {
  483. #endif        
  484.                                 if (active[my_group[i]].flag != SUBSCRIBED) {
  485. #ifndef SLOW_SCREEN_UPDATE
  486.                                 sprintf (msg, txt_subscribing_to, active[my_group[i]].name);
  487.                                 wait_message (msg);
  488. #endif                                
  489.                                 subscribe (active[my_group[i]].name,
  490.                                     ':', my_group[i], FALSE);
  491.                             }
  492.                             subscribe_num++;
  493.                         }
  494.                     }
  495.                     if (subscribe_num) {
  496.                         group_selection_page ();    
  497.                         sprintf (buf, txt_subscribed_num_groups, subscribe_num);
  498.                         info_message (buf);
  499.                     } else {
  500.                         info_message (txt_no_match);
  501.                     }
  502.                 } else {
  503.                     clear_message ();
  504.                 }
  505.                 break;
  506.  
  507.             case 'u':    /* unsubscribe to current group */
  508.                 if (group_top == 0) {
  509.                     break;
  510.                 }
  511.                 if (active[my_group[cur_groupnum]].flag == SUBSCRIBED) {
  512.                     MoveCursor(INDEX_TOP + (cur_groupnum-first_group_on_screen), 3);
  513.                     if (draw_arrow_mark) {
  514.                         fputc ('u', stdout);
  515.                     } else {
  516.                         screen[cur_groupnum-first_group_on_screen].col[3] = 'u';
  517.                         draw_group_arrow ();
  518.                     }
  519.                     fflush(stdout);
  520.                     MoveCursor(LINES, 0);
  521.  
  522.                     subscribe(active[my_group[cur_groupnum]].name,
  523.                         '!', my_group[cur_groupnum], FALSE);
  524.                     sprintf(buf, txt_unsubscribed_to,active[my_group[cur_groupnum]].name);
  525.                     info_message(buf);
  526.                 }
  527.                 break;
  528.  
  529.             case 'U':    /* unsubscribe to groups matching pattern */
  530.                 if (prompt_string (txt_unsubscribe_pattern, buf) && buf[0]) {    
  531.                     wait_message (txt_unsubscribing);
  532.                     patlen = strlen (buf);    
  533.                     for (subscribe_num=0, i=0 ; i < group_top ; i++) {        
  534. #ifdef NO_REGEX
  535.                         if (str_str (active[my_group[i]].name, buf, patlen)) {
  536. #else        
  537.                         if (wildmat (active[my_group[i]].name, buf)) {
  538. #endif        
  539.                                 if (active[my_group[i]].flag == SUBSCRIBED) {
  540. #ifndef SLOW_SCREEN_UPDATE
  541.                                 sprintf (msg, txt_unsubscribing_from, active[my_group[i]].name);
  542.                                 wait_message (msg);
  543. #endif                                
  544.                                 subscribe (active[my_group[i]].name,
  545.                                     '!', my_group[i], FALSE);
  546.                             }
  547.                             subscribe_num++;
  548.                         }
  549.                     }
  550.                     if (subscribe_num) {
  551.                         group_selection_page ();    
  552.                         sprintf (buf, txt_unsubscribed_num_groups, subscribe_num);
  553.                         info_message (buf);
  554.                     } else {
  555.                         info_message (txt_no_match);
  556.                     }
  557.                 } else {
  558.                     clear_message ();
  559.                 }
  560.                 break;
  561.  
  562.             case 'v':    /* show tin version */
  563.                 info_message (cvers);
  564.                 break;
  565.  
  566.             case 'w':    /* post a basenote */
  567.                 if (! can_post) {
  568.                     info_message (txt_cannot_post);
  569.                     break;
  570.                 }
  571.                 if (group_top == 0) {
  572.                     if (! prompt_string (txt_post_newsgroup, buf)) 
  573.                         break;
  574.                     if (buf[0] == '\0')
  575.                         break;
  576.                     strcpy (post_group, buf);
  577.                 } else {
  578.                     strcpy (post_group, active[my_group[cur_groupnum]].name);
  579.                 }
  580.                 if (post_base (post_group, &posted)) {
  581.                     group_selection_page ();
  582.                 }
  583.                 break;
  584.  
  585.             case 'W':    /* display messages posted by user */
  586.                 if (user_posted_messages ()) {
  587.                     group_selection_page ();
  588.                 }
  589.                 break;
  590.  
  591.             case 'y':    /* pull in rest of groups from active */
  592.                 if (yank_active_file) {
  593.                     wait_message (txt_yanking_all_groups);
  594.                     n = group_top;
  595.                     for (i = 0; i < num_active; i++) {
  596.                         active[i].flag = UNSUBSCRIBED;
  597.                     }
  598.                     read_newsrc (FALSE);
  599.                     for (i = 0; i < num_active; i++) {
  600.                         if (active[i].flag & UNSUBSCRIBED) {
  601.                             active[i].flag &= ~UNSUBSCRIBED;
  602.                             my_group[group_top] = i;
  603.                             unread[group_top] = -1;
  604.                             group_top++;
  605.                         }
  606.                     }
  607.                     if (n < group_top) {
  608.                         sprintf (buf, txt_added_groups, group_top - n,
  609.                             group_top - n == 1 ? "" : txt_plural);
  610.                         set_groupname_len (yank_active_file);
  611.                         group_selection_page ();
  612.                         info_message (buf);
  613.                     } else {
  614.                         info_message (txt_no_groups_to_yank_in);
  615.                     }
  616.                     yank_active_file = FALSE;
  617.                 } else {
  618.                     wait_message (txt_yanking_sub_groups);
  619.                     read_newsrc (TRUE);
  620.                     cur_groupnum = group_top - 1;
  621.                     set_groupname_len (yank_active_file);
  622.                     group_selection_page ();
  623.                     yank_active_file = TRUE;
  624.                 }
  625.                 break;
  626.  
  627.             case 'Y':    /* yank active file to see if any new news */
  628.                 reread_active_file = TRUE;
  629.                 resync_active_file ();
  630.                 break;
  631.  
  632.             case 'z':    /* mark group unread */
  633.                 if (group_top == 0) {
  634.                     break;
  635.                 }
  636.                 n = cur_groupnum;
  637.                 update_newsrc (active[my_group[n]].name, my_group[n], TRUE);
  638.                 cur_groupnum = 0;
  639.                 group_top = 0;
  640.                 read_newsrc (TRUE);            
  641.                 cur_groupnum = n;
  642.                 if (unread[cur_groupnum]) {
  643.                     sprintf (msg, "%d", unread[cur_groupnum]);
  644.                 } else {    
  645.                     strcpy (msg, "     ");
  646.                 }    
  647.                 mark_screen (SELECT_LEVEL, cur_groupnum - first_group_on_screen,
  648.                     groupname_len + 15, msg);
  649.  
  650.                 break;
  651.                 
  652.             case 'Z':    /* undelete groups deleted by ctrl-K */
  653.                 if (undel_group ()) {
  654.                     set_groupname_len (FALSE);
  655.                     group_selection_page ();
  656.                     info_message (txt_group_undeleted);
  657.                 }
  658.                 break;
  659.  
  660.             default:
  661.                 info_message(txt_bad_command);
  662.         }
  663.     }
  664.  
  665. #endif /* INDEX_DAEMON */
  666. }
  667.  
  668.  
  669. void group_selection_page ()
  670. {
  671. #ifndef INDEX_DAEMON
  672.  
  673.     char buf[LEN];
  674.     char new[10];
  675.     char subs;
  676.     int i, j, n;
  677.     int blank_len;
  678.  
  679.     set_signals_select ();
  680.  
  681. #ifdef USE_CLEARSCREEN
  682.     ClearScreen ();
  683. #else
  684.     MoveCursor (0, 0);        /* top left corner */
  685.     CleartoEOLN ();
  686. #endif
  687.  
  688.     if (xspooldir_supported) {
  689.         sprintf (buf, "%s (%s  %d)", txt_group_selection, spooldir_alias, group_top);
  690.     } else {
  691.         sprintf (buf, "%s (%d)", txt_group_selection, group_top);
  692.     }    
  693.     show_title (buf);
  694.  
  695. #ifndef USE_CLEARSCREEN
  696.     MoveCursor (1, 0);
  697.     CleartoEOLN ();
  698. #endif
  699.  
  700.     MoveCursor (INDEX_TOP, 0);
  701.  
  702.     if (cur_groupnum >= group_top) {
  703.         cur_groupnum = group_top - 1;
  704.     }
  705.     if (cur_groupnum < 0) {
  706.         cur_groupnum = 0;
  707.     }
  708.  
  709.     if (NOTESLINES <= 0) {
  710.         first_group_on_screen = 0;
  711.     } else {
  712.         first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  713.         if (first_group_on_screen < 0) {
  714.             first_group_on_screen = 0;
  715.         }
  716.     }
  717.  
  718.     last_group_on_screen = first_group_on_screen + NOTESLINES;
  719.  
  720.     if (last_group_on_screen >= group_top) {
  721.         last_group_on_screen = group_top;
  722.         first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  723.  
  724.         if (first_group_on_screen == last_group_on_screen ||
  725.             first_group_on_screen < 0) {
  726.             if (first_group_on_screen < 0) {
  727.                 first_group_on_screen = 0;
  728.             } else {
  729.                 first_group_on_screen = last_group_on_screen - NOTESLINES;    
  730.             }
  731.         }    
  732.     }
  733.  
  734.     if (group_top == 0) {
  735.         first_group_on_screen = 0;
  736.         last_group_on_screen = 0;
  737.     }
  738.  
  739.     blank_len = COLS - (groupname_len + SELECT_MISC_COLS);
  740.     
  741.     for (j=0, i = first_group_on_screen; i < last_group_on_screen; i++,j++) {
  742.         switch (unread[i]) {
  743.             case -2:
  744.                 sprintf (new, "?    ");
  745.                 break;
  746.  
  747.             case -1:
  748.                 sprintf (new, "-    ");
  749.                 break;
  750.  
  751.             case 0:
  752.                 sprintf (new, "     ");
  753.                 break;
  754.  
  755.             default:
  756.                 sprintf (new, "%-5.d", unread[i]);
  757.         }
  758.         
  759.         n = my_group[i];
  760.         if (active[n].flag & SUBSCRIBED) {    /* subscribed? */
  761.             subs = ' ';
  762.         } else {
  763.             subs = 'u';    /* u next to unsubscribed groups */
  764.         }
  765.         
  766.         if (draw_arrow_mark) {
  767.             sprintf (screen[j].col, "   %c %4.d  %-*.*s    %s\r\n",
  768.                    subs, i+1, groupname_len, groupname_len, active[n].name, new);
  769.         } else {
  770.             sprintf (screen[j].col, "   %c %4.d  %-*.*s    %s%*s\r\n",
  771.                 subs, i+1, groupname_len, groupname_len, active[n].name, new,
  772.                 blank_len, " ");
  773.         }
  774.         fputs (screen[j].col, stdout);
  775.     }
  776. #ifndef USE_CLEARSCREEN
  777.     CleartoEOS ();
  778. #endif
  779.  
  780.     if (group_top <= 0) {
  781.         info_message (txt_no_groups);
  782.         return;
  783.     } else if (last_group_on_screen == group_top) {
  784.         info_message (txt_end_of_groups);
  785.     }
  786.     
  787.     draw_group_arrow ();
  788.  
  789. #endif /* INDEX_DAEMON */
  790. }
  791.  
  792.  
  793. int prompt_group_num (ch)
  794.     char ch;
  795. {
  796.     int num;
  797.  
  798.     clear_message ();
  799.  
  800.     if ((num = prompt_num (ch, txt_select_group)) == -1) {
  801.         clear_message ();
  802.         return FALSE;
  803.     }
  804.     num--;        /* index from 0 (internal) vs. 1 (user) */
  805.  
  806.     if (num < 0) {
  807.         num = 0;
  808.     }
  809.     if (num >= group_top) {
  810.         num = group_top - 1;
  811.     }
  812.  
  813.     if (num >= first_group_on_screen
  814.     &&  num < last_group_on_screen) {
  815.         erase_group_arrow ();
  816.         cur_groupnum = num;
  817.         draw_group_arrow ();
  818.     } else {
  819. #ifndef USE_CLEARSCREEN
  820.         erase_group_arrow ();
  821. #endif        
  822.         cur_groupnum = num;
  823.         group_selection_page ();
  824.     }
  825.  
  826.     return TRUE;
  827. }
  828.  
  829.  
  830. void erase_group_arrow ()
  831. {
  832.     erase_arrow (INDEX_TOP + (cur_groupnum-first_group_on_screen));
  833. }
  834.  
  835.  
  836. void draw_group_arrow()
  837. {
  838.     draw_arrow (INDEX_TOP + (cur_groupnum-first_group_on_screen));
  839. }
  840.  
  841.  
  842. int choose_new_group ()
  843. {
  844.     char buf[LEN];
  845.     char *p;
  846.     int ret;
  847.  
  848.     sprintf (msg, txt_newsgroup, default_goto_group);
  849.  
  850.     if (! prompt_string (msg, buf)) {
  851.         return -1;
  852.     }
  853.     
  854.     if (strlen (buf)) {
  855.         strcpy (default_goto_group, buf);
  856.     } else {
  857.         if (default_goto_group[0]) {
  858.             strcpy (buf, default_goto_group);
  859.         } else {
  860.             return -1;
  861.         }
  862.     }
  863.  
  864.     for (p = buf; *p && (*p == ' ' || *p == '\t'); p++)
  865.         continue;
  866.     if (*p == '\0')
  867.         return -1;
  868.  
  869.     clear_message ();
  870.  
  871.     if ((ret = add_group (p, TRUE)) < 0) {
  872.         sprintf (msg, txt_not_in_active_file, p);
  873.         info_message (msg);
  874.     }
  875.  
  876.     return ret;
  877. }
  878.  
  879. /*
  880.  *  Add a group to the selection list (my_group[])
  881.  *  Return the index of my_group[] if group is added or was already
  882.  *  there.  Return -1 if named group is not in active[].
  883.  */
  884.  
  885. int add_group (s, get_unread)
  886.     char *s;
  887.     int get_unread;            /* look in .newsrc for sequencer unread info? */
  888. {
  889.     long h;
  890.     int i, j;
  891.  
  892.     h = hash_groupname (s);
  893.  
  894.     for (i = group_hash[h]; i >= 0; i = active[i].next) {
  895.         if (strcmp (s, active[i].name) == 0) {
  896.             for (j = 0; j < group_top; j++) {
  897.                 if (my_group[j] == i) {
  898.                     return j;
  899.                 }
  900.             }
  901.  
  902.             active[i].flag &= ~UNSUBSCRIBED;   /* mark that we got it */
  903.             my_group[group_top] = i;
  904.  
  905.             if (get_unread)
  906.                 unread[group_top] = get_line_unread (s, i);
  907.             else
  908.                 unread[group_top] = -2;
  909.  
  910.             group_top++;
  911.             return group_top - 1;
  912.         }
  913.     }
  914.  
  915.     return -1;
  916. }
  917.  
  918.  
  919. int reposition_group (group, default_num)
  920.     char *group;
  921.     int default_num;
  922. {
  923.     char buf[LEN];
  924.     char pos[LEN];
  925.     int pos_num = 0;
  926.  
  927.     sprintf (buf, txt_newsgroup_position, group, 
  928.         (default_move_group ? default_move_group : default_num+1));
  929.     
  930.     if (! prompt_string (buf, pos)) {
  931.         return default_num;
  932.     }    
  933.  
  934.     if (strlen (pos)) {
  935.         if (pos[0] == '$') {
  936.             pos_num = group_top;
  937.         } else {
  938.             pos_num = atoi (pos);
  939.         }    
  940.     } else {
  941.         if (default_move_group) {
  942.             pos_num = default_move_group;
  943.         } else {
  944.             return default_num;
  945.         }
  946.     }
  947.         
  948.     if (pos_num > group_top) {
  949.         pos_num = group_top;
  950.     } else if (pos_num <= 0) {
  951.         pos_num = 1;
  952.     }
  953.  
  954.     sprintf (buf, txt_moving, group);
  955.     wait_message (buf);
  956.     
  957.     if (pos_group_in_newsrc (group, pos_num)) {
  958.         read_newsrc (TRUE);
  959.         default_move_group = pos_num;
  960.         return (pos_num-1);
  961.     } else {
  962.         default_move_group = default_num + 1;
  963.         return (default_num);
  964.     }
  965. }
  966.  
  967.  
  968. void catchup_group (goto_next_unread_group)
  969.     int goto_next_unread_group;
  970. {    
  971.     int i;
  972.             
  973.     sprintf (msg, txt_mark_group_read, active[my_group[cur_groupnum]].name);
  974.     if (!confirm_action || prompt_yn (LINES, msg, 'y')) {
  975.         unread[cur_groupnum] = 0;
  976.         mark_group_read (active[my_group[cur_groupnum]].name,
  977.                         my_group[cur_groupnum]);
  978.  
  979.     mark_screen (SELECT_LEVEL, cur_groupnum - first_group_on_screen,
  980.         groupname_len + 15, "     ");
  981. /*
  982.         if (draw_arrow_mark) {    
  983.             MoveCursor (INDEX_TOP+(cur_groupnum - first_group_on_screen), offset);
  984.             fputs ("     ", stdout);
  985.             MoveCursor (LINES, 0);
  986.             fflush (stdout);
  987.         } else {
  988.             i = cur_groupnum - first_group_on_screen;
  989.             screen[i].col[offset++] = ' ';
  990.             screen[i].col[offset++] = ' ';
  991.             screen[i].col[offset++] = ' ';
  992.             screen[i].col[offset++] = ' ';
  993.             screen[i].col[offset++] = ' ';
  994.         }
  995. */
  996.         if (cur_groupnum+1 < last_group_on_screen) {
  997.             erase_group_arrow ();
  998.             cur_groupnum++;
  999.             draw_group_arrow ();
  1000.         } else {
  1001.             cur_groupnum++;
  1002.             group_selection_page ();
  1003.         }
  1004.         if (goto_next_unread_group) {
  1005.             next_unread_group (FALSE);    
  1006.         }
  1007.     }
  1008. }
  1009.  
  1010.  
  1011. void next_unread_group (enter_group)
  1012.     int enter_group;
  1013. {
  1014.     int i;
  1015.     
  1016.     for (i = cur_groupnum; i < group_top; i++) {
  1017.         if (unread[i] != 0) {
  1018.             break;
  1019.         }
  1020.     }
  1021.     if (i >= group_top) {
  1022.         info_message (txt_no_groups_to_read);
  1023.         return;
  1024.     }
  1025.  
  1026.     erase_group_arrow ();
  1027.     cur_groupnum = i;
  1028.     if (cur_groupnum >= last_group_on_screen) {
  1029.         group_selection_page ();
  1030.     } else {
  1031.         draw_group_arrow ();
  1032.     }
  1033.     space_mode = pos_first_unread;
  1034.  
  1035.     if (enter_group) {
  1036.         clear_message ();
  1037.         index_point = -1;
  1038.         do {
  1039.             group_page (active[my_group[cur_groupnum]].name);
  1040.         } while (index_point == -3);
  1041.         group_selection_page ();
  1042.     }
  1043. }
  1044.  
  1045. /*
  1046.  *  Calculate max length of groupname field for group selection level.
  1047.  *  If all_group is TRUE check all groups in active file otherwise
  1048.  *  just subscribed to groups.
  1049.  */
  1050.  
  1051. void set_groupname_len (all_groups)
  1052.     int all_groups;
  1053. {
  1054.     int len;
  1055.     register int i;
  1056.  
  1057.     groupname_len = 0;
  1058.     
  1059.     if (all_groups) {
  1060.         for (i = 0 ; i < num_active ; i++) {
  1061.             len = strlen (active[i].name);
  1062.             if (len > groupname_len) {
  1063.                 groupname_len = len;
  1064.             }
  1065.         }
  1066.     } else {
  1067.         for (i = 0 ; i < group_top ; i++) {
  1068.             len = strlen (active[my_group[i]].name);
  1069.             if (len > groupname_len) {
  1070.                 groupname_len = len;
  1071.             }
  1072.         }
  1073.     }
  1074.     
  1075.     if (groupname_len > (COLS - SELECT_MISC_COLS)) {
  1076.         groupname_len = COLS - SELECT_MISC_COLS;
  1077.         if (groupname_len < 0) {
  1078.             groupname_len = 0;
  1079.         }    
  1080.     }    
  1081. }
  1082.