home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / tass.lzh / select.c < prev    next >
Text File  |  1993-01-24  |  22KB  |  633 lines

  1.  
  2. #include       <stdio.h>
  3. #include       <signal.h>
  4. #ifdef REGEXP
  5. #include       <regexp.h>
  6. #endif /* REGEXP */
  7. #include       "tass.h"
  8.  
  9.  
  10. int first_group_on_screen;
  11. int last_group_on_screen;
  12. int cur_groupnum = 0;
  13. extern int index_point;
  14. int space_mode;
  15. extern char *cvers;
  16.  
  17. char group_search_string[LEN+1];
  18.  
  19.  
  20.  
  21. #ifdef SIGTSTP
  22. void
  23. select_susp(i)
  24. int i;
  25. {
  26.  
  27.        Raw(FALSE);
  28.        putchar('\n');
  29.        signal(SIGTSTP, SIG_DFL);
  30.        kill(0, SIGTSTP);
  31.  
  32.        signal(SIGTSTP, select_susp);
  33.        Raw(TRUE);
  34.        mail_setup();
  35.        group_selection_page(-1, FALSE);
  36. }
  37. #endif
  38.  
  39.  
  40. selection_index()
  41. {
  42.        char ch;
  43.        int n;
  44.        int i;
  45.        char buf[200];
  46.  
  47.        group_selection_page(-1, FALSE);        /* display group selection page */
  48.  
  49.        while (1) {
  50.                if ((n = ReadCh()) == EOF)
  51.                        longjmp (jmp_buffer, 1);
  52.                ch = (char) n;
  53.        
  54.                if (ch > '0' && ch <= '9') {
  55.                        prompt_group_num(ch);
  56.                } else switch (ch) {
  57.                        case 'c':       /* catchup--mark all articles as read */
  58.                            if (prompt_yn("Mark group as read? (y/n): ")) {
  59.                                unread[cur_groupnum] = 0;
  60.                                mark_group_read(
  61.                                            active[my_group[cur_groupnum]].name,
  62.                                            my_group[cur_groupnum]);
  63.                                group_selection_page(cur_groupnum, TRUE);
  64.                            }
  65.                            break;
  66.  
  67.                        case ctrl('K'):
  68.                                if (local_top <= 0) {
  69.                                        info_message("No groups to delete");
  70.                                        break;
  71.                                }
  72.  
  73.                                delete_group(
  74.                                        active[my_group[cur_groupnum]].name);
  75.                                active[my_group[cur_groupnum]].flag = NOTGOT;
  76.  
  77.                                local_top--;
  78.                                for (i = cur_groupnum; i < local_top; i++) {
  79.                                        my_group[i] = my_group[i+1];
  80.                                        unread[i] = unread[i+1];
  81.                                }
  82.                                if (cur_groupnum >= local_top)
  83.                                        cur_groupnum = local_top - 1;
  84.  
  85.                                group_selection_page(cur_groupnum, FALSE);
  86.                                break;
  87.  
  88.                        case ctrl('Y'):
  89.                                undel_group();
  90.                                group_selection_page(cur_groupnum, FALSE);
  91.                                break;
  92.  
  93.                        case 'I':               /* toggle inverse video */
  94.                                inverse_okay = !inverse_okay;
  95.                                if (inverse_okay)
  96.                                        info_message("Inverse video enabled");
  97.                                else
  98.                                        info_message("Inverse video disabled");
  99.                                break;
  100.  
  101.                        case ctrl('R'): /* reset .newsrc */
  102.                            if (prompt_yn("Reset newsrc? (y/n): ")) {
  103.                                reset_newsrc();
  104.                                cur_groupnum = 0;
  105.                                group_selection_page(-1, FALSE);
  106.                            }
  107.                            break;
  108.  
  109.                        case '$':       /* reread .newsrc, no unsub groups */
  110.                                cur_groupnum = 0;
  111.                                local_top = 0;
  112.                                for (i = 0; i < num_active; i++)
  113.                                        active[i].flag = NOTGOT;
  114.                                read_newsrc(TRUE);
  115.                                group_selection_page(-1, FALSE);
  116.                                break;
  117.  
  118.                        case 's':       /* subscribe to current group */
  119.                            MoveCursor(INDEX_TOP +
  120.                                (cur_groupnum-first_group_on_screen), 3);
  121.                            putchar(' ');
  122.                            fflush(stdout);
  123.                            MoveCursor(LINES, 0);
  124.  
  125.                            subscribe(active[my_group[cur_groupnum]].name,
  126.                                        ':', my_group[cur_groupnum], FALSE);
  127.                            sprintf(buf, "subscribed to %s",
  128.                                        active[my_group[cur_groupnum]].name);
  129.                            info_message(buf);
  130.                            break;
  131.  
  132.                        case 'u':       /* unsubscribe to current group */
  133.                            MoveCursor(INDEX_TOP +
  134.                                (cur_groupnum-first_group_on_screen), 3);
  135.                            putchar('u');
  136.                            fflush(stdout);
  137.                            MoveCursor(LINES, 0);
  138.  
  139.                            subscribe(active[my_group[cur_groupnum]].name,
  140.                                        '!', my_group[cur_groupnum], FALSE);
  141.                            sprintf(buf, "unsubscribed to %s",
  142.                                        active[my_group[cur_groupnum]].name);
  143.                            info_message(buf);
  144.                            break;
  145.  
  146.                        case ' ':
  147.                                clear_message();
  148.                                break;
  149.  
  150.                        case '\t':
  151.                                for (i = cur_groupnum; i < local_top; i++)
  152.                                        if (unread[i] != 0)
  153.                                                break;
  154.                                if (i >= local_top) {
  155.                                        info_message("No more groups to read");
  156.                                        break;
  157.                                }
  158.  
  159.                                erase_group_arrow();
  160.                                cur_groupnum = i;
  161.                                if (cur_groupnum >= last_group_on_screen)
  162.                                        group_selection_page(-1, FALSE);
  163.                                else
  164.                                        draw_group_arrow();
  165.                                space_mode = TRUE;
  166.                                goto go_into_group;
  167.  
  168.                        case 'g':       /* prompt for a new group name */
  169.                                n = choose_new_group();
  170.                                if (n >= 0) {
  171.                                        erase_group_arrow();
  172.                                        cur_groupnum = n;
  173.                                        if (cur_groupnum < first_group_on_screen
  174.                                        || cur_groupnum >= last_group_on_screen)
  175.                                                group_selection_page(-1, FALSE);
  176.                                        else
  177.                                                draw_group_arrow();
  178.                                }
  179.                                break;
  180.  
  181. #ifdef USE_ARROW
  182.                        case 27:        /* (ESC) common arrow keys */
  183.                                ch = ReadCh();
  184.                                if (ch == '[' || ch == 'O')
  185.                                        ch = ReadCh();
  186.                                switch (ch) {
  187.                                case 'A':
  188.                                case 'D':
  189.                                case 'i':
  190.                                        goto select_up;
  191.  
  192.                                case 'B':
  193.                                case 'I':
  194.                                case 'C':
  195.                                        goto select_down;
  196.                                }
  197.                                break;
  198. #endif /* USE_ARROW */
  199.  
  200.                        case 'y':       /* pull in rest of groups from active */
  201.                                n = local_top;
  202.                                for (i = 0; i < num_active; i++)
  203.                                        active[i].flag = NOTGOT;
  204.                                read_newsrc(FALSE);
  205.                                for (i = 0; i < num_active; i++)
  206.                                        if (active[i].flag & NOTGOT) {
  207.                                                active[i].flag &= ~NOTGOT;
  208.                                                my_group[local_top] = i;
  209.                                                unread[local_top] = -1;
  210.                                                local_top++;
  211.                                        }
  212.                                if (n < local_top) {
  213.                                        sprintf(buf, "Added %d group%s",
  214.                                                local_top - n,
  215.                                                local_top - n == 1 ? "" : "s");
  216.                                        group_selection_page(-1, FALSE);
  217.                                        info_message(buf);
  218.                                } else
  219.                                    info_message("No more groups to yank in");
  220.                                break;
  221.  
  222.                        case ctrl('U'):         /* page up */
  223.                        case ctrl('Z'):         /* full page up */
  224.                                erase_group_arrow();
  225.                                cur_groupnum -= (ch == ctrl('Z')) ?
  226.                                                NOTESLINES :
  227.                                                NOTESLINES / 2;
  228.                                if (cur_groupnum < 0)
  229.                                        cur_groupnum = 0;
  230.                                if (cur_groupnum < first_group_on_screen
  231.                                ||  cur_groupnum >= last_group_on_screen)
  232.                                        group_selection_page(-1, FALSE);
  233.                                else
  234.                                        draw_group_arrow();
  235.                                break;
  236.  
  237.                        case ctrl('D'):         /* page down */
  238.                        case ctrl('V'):         /* full page down */
  239.                                erase_group_arrow();
  240.                                cur_groupnum += (ch == ctrl ('V')) ?
  241.                                                NOTESLINES :
  242.                                                NOTESLINES / 2;
  243.                                if (cur_groupnum >= local_top)
  244.                                        cur_groupnum = local_top - 1;
  245.  
  246.                                if (cur_groupnum <= first_group_on_screen
  247.                                ||  cur_groupnum >= last_group_on_screen)
  248.                                        group_selection_page(-1, FALSE);
  249.                                else
  250.                                        draw_group_arrow();
  251.                                break;
  252.  
  253.                        case '!':
  254.                                shell_escape();
  255.                                group_selection_page(-1, FALSE);
  256.                                break;
  257.  
  258.                        case 'v':
  259.                                info_message(cvers);
  260.                                break;
  261.  
  262.                        case ctrl('N'):         /* line down */
  263.                        case 'j':
  264. #ifdef USE_ARROW
  265. select_down:
  266. #endif /* USE_ARROW */
  267.                                if (cur_groupnum + 1 >= local_top)
  268.                                        break;
  269.  
  270.                                if (cur_groupnum + 1 >= last_group_on_screen) {
  271.                                        cur_groupnum++;
  272.                                        group_selection_page(-1, FALSE);
  273.                                } else {
  274.                                        erase_group_arrow();
  275.                                        cur_groupnum++;
  276.                                        draw_group_arrow();
  277.                                }
  278.                                break;
  279.  
  280.                        case ctrl('P'):         /* line up */
  281.                        case 'k':
  282. #ifdef USE_ARROW
  283. select_up:
  284. #endif /* USE_ARROW */
  285.                                if (!cur_groupnum)
  286.                                        break;
  287.  
  288.                                if (cur_groupnum <= first_group_on_screen) {
  289.                                        cur_groupnum--;
  290.                                        group_selection_page(-1, FALSE);
  291.                                } else {
  292.                                        erase_group_arrow();
  293.                                        cur_groupnum--;
  294.                                        draw_group_arrow();
  295.                                }
  296.                                break;
  297.  
  298.                        case 't':               /* redraw */
  299.                        case ctrl('W'):
  300.                        case ctrl('L'):
  301.                                group_selection_page(-1, FALSE);
  302.                                break;
  303.  
  304. #ifndef        OSK
  305.                        case '\r':      /* go into group */
  306. #else  /* OSK */
  307.                        case '\l':      /* go into group */
  308. #endif /* OSK */
  309.                        case '\n':
  310.                        case ctrl('F'): /* cursor key */
  311.                                space_mode = FALSE;
  312. go_into_group:
  313.                                clear_message();
  314.                                index_point = -1;
  315.                                do {
  316.                                        group_page(
  317.                                          active[my_group[cur_groupnum]].name);
  318.                                } while (index_point == -3);
  319.                                group_selection_page(-1, FALSE);
  320.                                break;
  321.  
  322.                        case '/':       /* search forward */
  323.                                search_group(TRUE);
  324.                                break;
  325.  
  326.                        case '?':       /* search backward */
  327.                                search_group(FALSE);
  328.                                break;
  329.  
  330.                        case 'q':       /* quit */
  331.                        case ctrl('B'): /* cursor key */
  332.                                tass_done(0);
  333.  
  334.                        case 'h':
  335.                                tass_select_help();
  336.                                group_selection_page(-1, FALSE);
  337.                                break;
  338.  
  339.                        default:
  340.                            info_message("Bad command.  Type 'h' for help.");
  341.                }
  342.        }
  343. }
  344.  
  345.  
  346. group_selection_page(ind, justone) 
  347. int ind;
  348. int justone;
  349. {
  350.        int i;
  351.        int n;
  352.        char new[10];
  353.        char subs;
  354.  
  355. #ifdef SIGTSTP
  356.        signal(SIGTSTP, select_susp);
  357. #endif
  358.  
  359.        if (ind < 0) {
  360.                ClearScreen();
  361.                printf("%s\r\012", nice_time()); /* print time in upper left */
  362.        }
  363.  
  364.        show_mail ();
  365.  
  366.        if (ind < 0)
  367.                center_line(1, "Group Selection");
  368.        MoveCursor(INDEX_TOP, 0);
  369.  
  370.        first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
  371.  
  372.        last_group_on_screen = first_group_on_screen + NOTESLINES;
  373.        if (last_group_on_screen >= local_top)
  374.                last_group_on_screen = local_top;
  375.  
  376.        for (i = first_group_on_screen; i < last_group_on_screen; i++) {
  377.                if ((ind >= 0) && (ind > i))
  378.                        continue;
  379.                switch (unread[i]) {
  380.                case -2:
  381.                        strcpy(new, "?   ");
  382.                        break;
  383.  
  384.                case -1:
  385.                        strcpy(new, "-   ");
  386.                        break;
  387.  
  388.                case 0:
  389.                        strcpy(new, "    ");
  390.                        break;
  391.  
  392.                default:
  393.                        sprintf(new, "%-4d", unread[i]);
  394.                }
  395.  
  396.                n = my_group[i];
  397.                if (active[n].flag & SUBS)      /* subscribed? */
  398.                        subs = ' ';
  399.                else
  400.                        subs = 'u';     /* u next to unsubscribed groups */
  401.  
  402.                MoveCursor (INDEX_TOP + i - first_group_on_screen, 3);
  403.                printf("%c %4d", subs, i+1);
  404.                if (!justone)
  405.                        printf (" %s", active[n].name);
  406.                MoveCursor (INDEX_TOP + i - first_group_on_screen, COLS - 8);
  407.                printf (" %s", new);
  408.                CleartoEOLN ();
  409.                if ((ind >= 0) && justone && (ind == i))
  410.                        break;
  411.        }
  412.  
  413.        if (last_group_on_screen < first_group_on_screen + NOTESLINES) {
  414.                MoveCursor (INDEX_TOP + last_group_on_screen + 1 - first_group_on_screen, 0);
  415.                CleartoEOLN ();
  416.        }
  417.  
  418.        draw_group_arrow();
  419. }
  420.  
  421.  
  422. prompt_group_num(ch)
  423. char ch;
  424. {
  425. int num;
  426.  
  427.        clear_message();
  428.  
  429.        if ((num = parse_num(ch, "Select group> ")) == -1) {
  430.                clear_message();
  431.                return FALSE;
  432.        }
  433.        num--;          /* index from 0 (internal) vs. 1 (user) */
  434.  
  435.        if (num >= local_top)
  436.                num = local_top - 1;
  437.  
  438.        if (num >= first_group_on_screen
  439.        &&  num < last_group_on_screen) {
  440.                erase_group_arrow();
  441.                cur_groupnum = num;
  442.                draw_group_arrow();
  443.        } else {
  444.                cur_groupnum = num;
  445.                group_selection_page(-1, FALSE);
  446.        }
  447.  
  448.        return TRUE;
  449. }
  450.  
  451. erase_group_arrow() {
  452.        erase_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
  453. }
  454.  
  455. draw_group_arrow() {
  456.        draw_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
  457. }
  458.  
  459. void
  460. search_group(forward)
  461. int forward;
  462. {
  463.        char buf[LEN+1];
  464.        int i;
  465. #ifndef        REGEXP
  466.        extern char *regcmp();
  467.        extern char *regex();
  468.        char *re;
  469. #else  /* REGEXP */
  470.        regexp *re;
  471. #endif /* REGEXP */
  472.        char *prompt;
  473.  
  474.        clear_message();
  475.  
  476.        if (forward)
  477.                prompt = "/";
  478.        else
  479.                prompt = "?";
  480.  
  481.        if (!parse_string(prompt, buf))
  482.                return;
  483.  
  484.        if (strlen(buf))
  485.                strcpy(group_search_string, buf);
  486.        else if (!strlen(group_search_string)) {
  487.                info_message("No search pattern");
  488.                return;
  489.        }
  490.  
  491.        i = cur_groupnum;
  492.  
  493.        glob_name(group_search_string, buf);
  494.  
  495. #ifndef        REGEXP
  496.        if ((re = regcmp(buf, NULL)) == NULL) {
  497. #else  /* REGEXP */
  498.        if ((re = regcomp (buf)) == NULL) {
  499. #endif /* REGEXP */
  500.                info_message("Bad search pattern");
  501.                return;
  502.        }
  503.  
  504.        do {
  505.                if (forward)
  506.                        i++;
  507.                else
  508.                        i--;
  509.  
  510.                if (i >= local_top)
  511.                        i = 0;
  512.                if (i < 0)
  513.                        i = local_top - 1;
  514.  
  515. #ifndef        REGEXP
  516.                if (regex(re, active[my_group[i]].name) != NULL) {
  517. #else  /* REGEXP */
  518.                if (regexec (re, active[my_group[i]].name)) {
  519. #endif /* REGEXP */
  520.                        if (i >= first_group_on_screen
  521.                        &&  i < last_group_on_screen) {
  522.                                erase_group_arrow();
  523.                                cur_groupnum = i;
  524.                                draw_group_arrow();
  525.                        } else {
  526.                                cur_groupnum = i;
  527.                                group_selection_page(-1, FALSE);
  528.                        }
  529.                        return;
  530.                }
  531.        } while (i != cur_groupnum);
  532.  
  533.        info_message("No match");
  534. }
  535.  
  536.  
  537. tass_select_help() {
  538.  
  539.        ClearScreen();
  540.        center_line(0, TASS_HEADER);
  541.        center_line(1, "Group Selection Commands");
  542.  
  543.        MoveCursor(3, 0);
  544.  
  545.        printf("4        Select group 4\r\012");
  546.        printf("^D, ^V   half / full Page down\r\012");
  547.        printf("^R       Reset .newsrc\r\012");
  548.        printf("^U, ^Z   half / full Page up\r\012");
  549.        printf("^K       Delete group\r\012");
  550.        printf("^Y       Undelete group\r\012");
  551.        printf("<CR>     Read current group\r\012");
  552.        printf("<TAB>    View next unread group\r\012");
  553.        printf("c        Mark group as all read\r\012");
  554.        printf("g        Choose a new group by name\r\012");
  555.        printf("j        Down a line\r\012");
  556.        printf("k        Up a line\r\012");
  557.        printf("q        Quit\r\012");
  558.        printf("s        Subscribe to current group\r\012");
  559.        printf("u        Unsubscribe to current group\r\012");
  560.        printf("y        Yank in groups that are not in the .newsrc\r\012");
  561.        printf("$        Reread group list from .newsrc\r\012");
  562.        printf("/        Search forward for group\r\012");
  563.        printf("?        Search backward for group\r\012");
  564.  
  565.        center_line(LINES, "-- hit any key --");
  566.        ReadCh();
  567. }
  568.  
  569.  
  570. choose_new_group() {
  571.        char buf[LEN+1];
  572.        char *p;
  573.        int ret;
  574.  
  575.        if (!parse_string("Newsgroup> ", buf))
  576.                return -1;
  577.  
  578.        for (p = buf; *p && (*p == ' ' || *p == '\t'); p++) ;
  579.        if (*p == '\0')
  580.                return -1;
  581.  
  582.        ret = add_group(p, TRUE);
  583.        if (ret < 0)
  584.                info_message("Group not found in active file");
  585.  
  586.        return ret;
  587. }
  588.  
  589.  
  590. /*
  591.  *  Add a group to the selection list (my_group[])
  592.  *  Return the index of my_group[] if group is added or was already
  593.  *  there.  Return -1 if named group is not in active[].
  594.  */
  595.  
  596. add_group(s, get_unread)
  597. char *s;
  598. int get_unread;                        /* look in .newsrc for sequencer unread info? */
  599. {
  600.        long h;
  601.        int i, j;
  602.  
  603.        {                       /* find the hash of the group name */
  604.                char *t = s;
  605.  
  606.                h = *t++;
  607.                while (*t)
  608.                        h = (h * 64 + *t++) % TABLE_SIZE;
  609.        }
  610.  
  611.        for (i = group_hash[h]; i >= 0; i = active[i].next)
  612.                if (strcmp(s, active[i].name) == 0) {
  613.                        for (j = 0; j < local_top; j++)
  614.                                if (my_group[j] == i)
  615.                                        return j;
  616.  
  617.                        active[i].flag &= ~NOTGOT;   /* mark that we got it */
  618.                        my_group[local_top] = i;
  619.  
  620.                        if (get_unread)
  621.                                unread[local_top] = get_line_unread(s, i);
  622.                        else
  623.                                unread[local_top] = -2;
  624.  
  625.                        local_top++;
  626.                        return local_top - 1;
  627.                }
  628.  
  629.        return -1;
  630. }
  631.  
  632.  
  633.