home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0020 - 0029 / ibm0020-0029 / ibm0028.tar / ibm0028 / INSTALL2.TD0 / SOURCES.LIF / LIST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-27  |  13.1 KB  |  537 lines

  1. /*=============================================================================
  2.  
  3.      The INSTALL program source code, object code, sample  script files,
  4.      executable  program,  and  documentation  are  subject to copyright
  5.      protection under the laws of the United States and other countries.
  6.  
  7.      This software is licensed, not sold, and may only be  redistributed
  8.      in  executable format and only in accordance with the provisions of
  9.      the INSTALL Source Code License Agreement.
  10.  
  11.         INSTALL is Copyright(C) 1987-1990 by Knowledge Dynamics Corp
  12.        Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
  13.               512-964-3994 (Voice)   512-964-3958 (24-hr FAX)
  14.  
  15.                       All rights reserved worldwide.
  16.  
  17. ===============================================================================
  18.  
  19. FILENAME:
  20.     list.c
  21.  
  22. AUTHOR:
  23.     eric jon heflin
  24.  
  25. PUBLIC FUNCTIONS:
  26.     select_m() -  "pushes" window, selects item, then "pops" window back
  27.  
  28. LOCAL FUNCTIONS:
  29.     list_io()  -  handles all of the cursor and arrow key functions
  30.  
  31. DESCRIPTION:
  32.     This file contains functions to display a list on the screen and allow
  33.     the user to use the arrow keys to select an item from the list.
  34.  
  35. REVISION HISTORY:
  36.     DATE:    AUTHOR:            DESCRIPTION OF CHANGES:
  37.     891203    allyn jordan    documentation
  38.     900321    ejh                Added code to handle "all off" state and "all on"
  39.                             state of elements.
  40.  
  41. ==============================================================================*/
  42.  
  43. #include "install.h"
  44. #include "control.h"
  45. #include "keys.h"
  46. #include <ctype.h>
  47. #include <string.h>
  48. #include "lint.h"
  49. #if defined(__TURBOC__)
  50. #include <mem.h>
  51. #endif
  52. #define  SPACEBAR   (0x20)
  53. #define  PLUS       (0x2b)
  54. #define  MINUS      (0x2d)
  55. #define  ASTERISK   (0x2a)
  56.  
  57. #define  ONBIT0     (0x01)
  58. #define  ONBIT1     (0x02)
  59. #define  ONBIT2     (0x04)
  60. #define  ONBIT3     (0x08)
  61. #define  ONBIT4     (0x10)
  62. #define  ONBIT5     (0x20)
  63. #define  ONBIT6     (0x40)
  64. #define  ONBIT7     (0x80)
  65.  
  66. #define  ONALLBIT   (0xff)
  67. #define  OFFALLBIT  (0x00)
  68.  
  69.  
  70. /* prototypes */
  71. static int list_io(P8(byte **, word, word, word, word, int, int, int));
  72. static int tags(P8(byte **, int, int, int, int, int, int, int));
  73. static void trim_list(byte **list, word list_max);
  74. int is_set(word n);
  75.  
  76. /* static variables */
  77. static int test = 0;
  78. static byte vector[500];
  79. static byte *yes = " YES", *no = " NO ";
  80.  
  81. #define TAG_ALL     (1)
  82. #define TAG_ONE     (2)
  83. #define TOGGLE         (3)
  84. #define FORCE         (4)
  85. #define YES            (5)
  86. #define NO            (6)
  87.  
  88. static bool first_tag = TRUE;
  89. static byte maskbit[10] =
  90.     {
  91.     ONBIT7,
  92.     ONBIT6,
  93.     ONBIT5,
  94.     ONBIT4,
  95.     ONBIT3,
  96.     ONBIT2,
  97.     ONBIT1,
  98.     ONBIT0,
  99.     ONALLBIT,
  100.     OFFALLBIT
  101.     };
  102.  
  103.  
  104. int select_m(list, min_row, min_col, max_row, max_col, max, start, tagyn)
  105. byte **list;
  106. word min_row, min_col;    /* location of ulhc of window */
  107. word max_row, max_col;    /* location of lrhc of window */
  108. int max;                /* total number of entries in the list */
  109. int start;                /* initial cursor position */
  110. int tagyn;                /* enable/disable tagging routine (TRUE/FALSE) */
  111.     {
  112.     int ret = 2;
  113.  
  114.     /* save area about to be overwritten */
  115.     scr_push(min_row - 1, min_col - 1, max_row + 1, max_col + 1);
  116.  
  117.     /* hide cursor */
  118.     scr_nocur();
  119.  
  120.     /* let user select element */
  121.     ret = list_io(list, min_row, min_col, max_row, max_col, max, start, tagyn);
  122.  
  123.     /* restore screen */
  124.     scr_pop();
  125.  
  126.     return ret;
  127.     }
  128.  
  129. /*
  130.  *    returns: -1 if user pressed ESC,
  131.  *                entry number if user pressed CR
  132.  */
  133.  
  134. static byte blanks[80] = "                                                                               ";
  135.  
  136. /*
  137.  *    Interpret the user keystroke and update the display.
  138.  */
  139.  
  140. static int list_io(list, min_row, min_col, max_row, max_col, max, start, tagyn)
  141. byte **list;
  142. word min_row, min_col;    /* location of ulhc of window */
  143. word max_row, max_col;    /* location of lrhc of window */
  144. int max;                /* total number of entries in the list */
  145. int start;                /* initial highlighted element */
  146.     {                    /* list */
  147.     int i, c, len;
  148.     /* current selected element number */
  149.     int current = start;
  150.     /* prior selected element */
  151.     int last_current = start;
  152.     int first = TRUE;
  153.  
  154.     /* prior selected window top */
  155.     int last_top = 0;
  156.     int last_row = min_row + start;
  157.     /* change from current position to next position of window top */
  158.     int delta_top = 0;
  159.     /* change from current position to next position of bounce bar */
  160.     int delta_current = 0;
  161.     /* the index w/i element[] of first entry displayed in widow */
  162.     int top = 0;
  163.     /* the number of rows in the window */
  164.     int w_size = max_row - min_row;
  165.  
  166.     if (top + w_size < start)
  167.         top = start - w_size;
  168.  
  169.     if (last_row > min_row + w_size)
  170.         last_row = top + w_size;
  171.     if (max < 0)
  172.         return -1;
  173.     c = 0;
  174.  
  175.     while (c != ESC && c != CR)
  176.         {
  177.         if (!first)
  178.             {
  179.             if ((c = sgetch()) == 0)
  180.                 c = sgetch();
  181.             }
  182.         else
  183.             {
  184.             blanks[max_col - min_col] = '\0';
  185.             box(min_row - 1, min_col - 1, max_row + 1, max_col + 1, block, get_attr());
  186.             c = 0;
  187.             if (tagyn == TRUE)
  188.                 {
  189.                 first = TRUE;
  190.                 start = max;
  191.                 memset(vector, '\0', sizeof (vector));
  192.                 tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, NO);
  193.                 }        /* end tagyn if */
  194.             }            /* end else */
  195.         switch (toupper(c))
  196.             {
  197.         case CTRL_A:
  198.         case '7':
  199.         case HOME:
  200.             top = 0;
  201.             current = 0;
  202.             delta_top = 0;
  203.             delta_current = 0;
  204.             break;
  205.         case 'S':
  206.             /*
  207.              *    Toggle
  208.              */
  209.             if (tagyn == TRUE)
  210.                 {
  211.                 first = TRUE;
  212.                 start = max;
  213.                 tags(list, max, current, max_col, min_col, TOGGLE, TAG_ALL, TOGGLE);
  214.                 }        /* end tagyn if */
  215.             break;
  216.         case 'T':
  217.         case 'Y':
  218.             /*
  219.              *    Tag
  220.              */
  221.             if (tagyn == TRUE)
  222.                 {
  223.                 first = TRUE;
  224.                 start = max;
  225.                 tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, YES);
  226.                 }        /* end tagyn if */
  227.             break;
  228.         case 'U':
  229.         case 'N':
  230.             /*
  231.              *    Untag
  232.              */
  233.             if (tagyn == TRUE)
  234.                 {
  235.                 first = TRUE;
  236.                 start = max;
  237.                 tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, NO);
  238.                 }        /* end tagyn if */
  239.             break;
  240.         case CTRL_F:
  241.         case '1':
  242.         case END:
  243.             top = max - w_size;
  244.             current = max;
  245.             delta_top = 0;
  246.             delta_current = 0;
  247.             break;
  248.         case CTRL_W:
  249.         case CTRL_R:
  250.         case '9':
  251.         case PGUP:
  252.             delta_top = -w_size;
  253.             delta_current = -w_size;
  254.             break;
  255.         case CTRL_C:
  256.         case '3':
  257.         case PGDN:
  258.         case CTRL_Z:
  259.             delta_top = w_size;
  260.             delta_current = w_size;
  261.             break;
  262.         case CTRL_E:
  263.         case CTRL_S:
  264.         case '8':
  265.         case UPARROW:
  266.             if (current == top)
  267.                 delta_top = -1;
  268.             delta_current = -1;
  269.             break;
  270.         case ASTERISK:
  271.         case SPACEBAR:
  272.             if (tagyn == TRUE)
  273.                 tags(list, max, current, max_col, min_col, TOGGLE, TAG_ONE, TOGGLE);
  274.             if (current + 1 > top + w_size)
  275.                 delta_top = 1;
  276.             delta_current = 1;
  277.             break;
  278.         case MINUS:
  279.             if (tagyn == TRUE)
  280.                 tags(list, max, current, max_col, min_col, FORCE, TAG_ONE, NO);
  281.             if (current + 1 > top + w_size)
  282.                 delta_top = 1;
  283.             delta_current = 1;
  284.             break;
  285.         case PLUS:
  286.             if (tagyn == TRUE)
  287.                 tags(list, max, current, max_col, min_col, FORCE, TAG_ONE, YES);
  288.             break;
  289.         case CTRL_D:
  290.         case CTRL_X:
  291.         case '2':
  292.         case DOWNARROW:
  293.             if (current + 1 > top + w_size)
  294.                 delta_top = 1;
  295.             delta_current = 1;
  296.             break;
  297.             }            /* switch */
  298.  
  299.         top += delta_top;
  300.         current += delta_current;
  301.         if (top > max - w_size)
  302.             top = max - w_size;
  303.         if (top < 0)
  304.             top = 0;
  305.         if (current < top)
  306.             current = top;
  307.         if (current > top + w_size)
  308.             current = top + w_size;
  309.         if (current > max)
  310.             current = max;
  311.         delta_top = 0;
  312.         delta_current = 0;
  313.         if (!first && top == last_top)
  314.             {
  315.             /* no scroll */
  316.             len = strlen(list[last_current]);
  317.             blanks[0] = blanks[1] = ' ';
  318.             strcpy(blanks + 2, list[last_current]);
  319.             memset(blanks + len + 2, ' ', 80 - len - 4);
  320.             blanks[max_col - min_col + 1] = '\0';
  321.             colors(last_row, min_col, blanks, WHITE_F | BRITE);
  322.             /* erase last current */
  323.             len = strlen(list[current]);
  324.             blanks[0] = blanks[1] = ' ';
  325.             strcpy(blanks + 2, list[current]);
  326.             memset(blanks + len + 2, ' ', 80 - len - 4);
  327.             blanks[max_col - min_col + 1] = '\0';
  328.             colors(min_row - top + current, min_col, blanks, WHITE_B | FLASH);
  329.             last_row = (min_row - top) + current;
  330.             }
  331.         else
  332.             {
  333.             /* scroll update display w/i window */
  334.             first = FALSE;
  335.             for (i = top;  i <= top + w_size;  ++i)
  336.                 {
  337.                 if (i > max)
  338.                     {
  339.                     memset(blanks, ' ', sizeof (blanks));
  340.                     blanks[max_col - min_col + 1] = '\0';
  341.                     colors((min_row + i) - top, min_col, blanks, WHITE_F | BRITE);
  342.                     }
  343.                 else if (i != current)
  344.                     {
  345.                     len = strlen(list[i]);
  346.                     blanks[0] = blanks[1] = ' ';
  347.                     strcpy(blanks + 2, list[i]);
  348.                     memset(blanks + len + 2, ' ', 80 - len - 4);
  349.                     blanks[max_col - min_col + 1] = '\0';
  350.                     colors((min_row + i) - top, min_col, blanks, WHITE_F | BRITE);
  351.                     }
  352.                 else
  353.                     {
  354.                     len = strlen(list[i]);
  355.                     blanks[0] = blanks[1] = ' ';
  356.                     strcpy(blanks + 2, list[i]);
  357.                     memset(blanks + len + 2, ' ', 80 - len - 4);
  358.                     blanks[max_col - min_col + 1] = '\0';
  359.                     colors((min_row + i) - top, min_col, blanks, WHITE_B | FLASH);
  360.                     last_row = (min_row + i) - top;
  361.                     }
  362.                 }
  363.             }            /* scroll */
  364.         last_current = current;
  365.         last_top = top;
  366.         }                /*  while */
  367.     test = is_set(0);
  368.     test = is_set(2);
  369.     if (tagyn)
  370.         trim_list(list, max);
  371.     if (c != ESC)
  372.         return current;
  373.     if (max_col == 0)
  374.         ;                /* quiet lint */
  375.     return -1;
  376.     }                    /* list */
  377.  
  378.  
  379. /*
  380.  *    tag or untag selected menu items
  381.  */
  382.  
  383. static int tags(list, max, current, max_col, min_col, f_or_t, a_or_o, y_or_n)
  384. byte **list;
  385. int max, current, max_col, min_col;
  386. int f_or_t, a_or_o, y_or_n;
  387.     {
  388.     int bytenum = current / 8, bitnum = current % 8;
  389.     int yes_offset = max_col - min_col - 2 - strlen(yes);
  390.     int no_offset = max_col - min_col - 2 - strlen(no);
  391.     int line_len = max_col - min_col;    /* number of positions in line */
  392.     int i;
  393.  
  394.     if (f_or_t == TOGGLE)    /* TOGGLE instead of FORCE */
  395.         {
  396.         if (a_or_o == TAG_ONE)    /* TOGGLE only one */
  397.             {
  398.             vector[bytenum] ^= maskbit[bitnum];    /* TOGGLE state */
  399.             if (vector[bytenum] & maskbit[bitnum])
  400.                 {
  401.                 strcpy(list[current] + yes_offset, yes);
  402.                 return 1;
  403.                 }
  404.             else
  405.                 {
  406.                 strcpy(list[current] + no_offset, no);
  407.                 return 2;
  408.                 }
  409.             }            /* end TOGGLE one */
  410.         else             /* TOGGLE states for all members */
  411.             {
  412.             for (i = 0; i <= max; ++i)
  413.                 {
  414.                 bytenum = i / 8;
  415.                 bitnum = i % 8;
  416.                 vector[bytenum] ^= maskbit[bitnum];
  417.                 if (vector[bytenum] & maskbit[bitnum])
  418.                     strcpy(list[i] + yes_offset, yes);
  419.                 else
  420.                     strcpy(list[i] + no_offset, no);
  421.                 }    /* end for  */
  422.             return 3;
  423.             }    /* end TOGGLE all */
  424.         }    /* end TOGGLE */
  425.     else
  426.         {        /* FORCE to one state or another (not TOGGLE) */
  427.         if (y_or_n == YES)    /* FORCE to "on state" */
  428.             {
  429.             if (a_or_o == TAG_ALL)    /* FORCE all to "on state"  */
  430.                 {
  431.                 if (first_tag == TRUE)
  432.                     {
  433.                     memset(vector, '\xff', sizeof (vector));
  434.                     for (i = 0; i <= max; ++i)
  435.                         {
  436.                         /* pad line with spaces */
  437.                         memset(list[i] + strlen(list[i]), ' ', line_len - strlen(list[i]));
  438.                         strcpy(list[i] + no_offset, yes);
  439.                         }
  440.                     }
  441.                 else
  442.                     {
  443.                     memset(vector, '\0', sizeof (vector));
  444.                     for (i = 0; i <= max; ++i)
  445.                         strcpy(list[i] + no_offset, no);
  446.                     }
  447.                 return 4;
  448.                 }        /* end FORCE all */
  449.             else
  450.                 {
  451.                 vector[bytenum] |= maskbit[bitnum];
  452.                 strcpy(list[current] + yes_offset, yes);
  453.                 return 5;
  454.                 }        /* end FORCE one */
  455.             }            /* end of "on states " */
  456.         else             /* begin of FORCEd "off states"  */
  457.             {
  458.             if (a_or_o == TAG_ALL)    /* FORCE all to "off state"  */
  459.                 {
  460.                 if (first_tag == TRUE)
  461.                     {
  462.                     memset(vector, '\0', sizeof (vector));
  463.                     for (i = 0; i <= max; ++i)
  464.                         {
  465.                         /* pad line with spaces */
  466.                         memset(list[i] + strlen(list[i]), ' ', line_len - strlen(list[i]));
  467.                         strcpy(list[i] + no_offset, no);
  468.                         }
  469.                     return 6;
  470.                     }
  471.                 else
  472.                     {
  473.                     memset(vector, '\0', sizeof (vector));
  474.                     for (i = 0; i <= max; ++i)
  475.                         strcpy(list[i] + no_offset, no);
  476.                     return 7;
  477.                     }
  478.                 }        /* end FORCE all */
  479.             else
  480.                 {
  481.                 vector[bytenum] ^= maskbit[bitnum];
  482.                 strcpy(list[current] + no_offset, no);
  483.                 return 8;
  484.                 }    /* end FORCE one */
  485.             }    /* end of "off states " */
  486.         }    /* end of FORCE */
  487.     }                    /* tags  */
  488.  
  489.  
  490. /*
  491.  * is_set() returns zero if the item passed is selected, non-zero otherwise.
  492.  */
  493.  
  494. int is_set(word n)
  495.     {                   /* is_set */
  496.     /* n/8 == byte offset, n%8 == bit offset */
  497.     return vector[n / 8] & maskbit[n % 8];
  498.     }                    /* is_set */
  499.  
  500.  
  501. /*
  502.  *    Return the input list to its original value by removing the "YES/NO"
  503.  *    text at the end of each element.
  504.  */
  505.  
  506. static void trim_list(byte **list, word list_max)
  507.     {                    /* trim_list */
  508.     int i;
  509.     byte *s;
  510.  
  511.     for (i = 0;  i < list_max;  ++i)
  512.         {
  513.         /* skip tag */
  514.         for (s = list[i] + strlen(list[i]) - 1;  s > list[i];  --s)
  515.             {
  516.             if (! isspace(*s))
  517.                 break;
  518.             }
  519.         /* skip tag */
  520.         for (;s > list[i];  --s)
  521.             {
  522.             if (isspace(*s))
  523.                 break;
  524.             }
  525.         /* trim spaces */
  526.         for (;s > list[i];  --s)
  527.             {
  528.             if (! isspace(*s))
  529.                 break;
  530.             }
  531.         *++s = 0;
  532.         }
  533.     }                    /* trim_list */
  534.  
  535.  
  536. /* end-of-file */
  537.