home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / tc-book.zip / ENTRY.C < prev    next >
Text File  |  1987-08-20  |  9KB  |  408 lines

  1. /* --------- entry.c ---------- */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #include <alloc.h>
  7. #include <mem.h>
  8. #include <string.h>
  9. #include "twindow.h"
  10. #include "keys.h"
  11.  
  12. #define FIELDCHAR '_'
  13. int insert_mode = FALSE;       /* insert mode, TRUE/FALSE */
  14. extern int helpkey;
  15.  
  16. /* -------- local prototypes -------- */
  17. void addfield(WINDOW *wnd, FIELD *fld);
  18. void disp_field(WINDOW *wnd, char *bf, char *msk);
  19. void data_value(WINDOW *wnd, FIELD *fld);
  20. void insert_status(void);
  21. int read_field(WINDOW *wnd, FIELD *fld);
  22. void right_justify(char *s);
  23. void right_justify_zero_fill(char *s);
  24. int validate_date(char *s);
  25. int endstroke(int c);
  26. int spaces(char *c);
  27.  
  28. /* -------- initialize a template --------- */
  29. void init_template(WINDOW *wnd)
  30. {
  31.     FIELD *fld, *fl;
  32.  
  33.     fld = FHEAD;
  34.     while (fld)    {
  35.         fl = fld->fnxt;
  36.         free(fld);
  37.         fld = fl;
  38.     }
  39.     FHEAD = NULL;
  40. }
  41. /* ------ establish a field in a template ------- */
  42. FIELD *establish_field(wnd, cl, rw, msk, bf, ty)
  43. WINDOW *wnd;
  44. int rw;
  45. int cl;
  46. char *msk;
  47. char *bf;
  48. int ty;
  49. {
  50.     FIELD *fld;
  51.  
  52.     if ( (fld = malloc(sizeof(FIELD))) == NULL)
  53.         return NULL;
  54.     fld->fmask = msk;
  55.     fld->frow = rw;
  56.     fld->fcol = cl;
  57.     fld->fbuff = bf;
  58.     fld->ftype = ty;
  59.     fld->fprot = 0;
  60.     fld->fnxt = fld->fprv = NULL;
  61.     fld->fvalid = NULL;
  62.     fld->fhelp = NULL;
  63.     fld->fhwin = NULL;
  64.     fld->flx = fld->fly = 0;
  65.     addfield(wnd, fld);
  66.     return fld;
  67. }
  68.  
  69. /* ----- add a field to the end of the list ------ */
  70. static void addfield(WINDOW *wnd, FIELD *fld)
  71. {
  72.     if (FTAIL)    {
  73.         fld->fprv = FTAIL;
  74.         FTAIL->fnxt = fld;
  75.     }
  76.     FTAIL = fld;
  77.     if (!FHEAD)
  78.         FHEAD = fld;
  79. }
  80.  
  81. /* -------- display a data field ------ */
  82. static void disp_field(WINDOW *wnd, char *bf, char *msk)
  83. {
  84.     while (*msk)    {
  85.         wputchar(wnd, *msk != FIELDCHAR ? *msk : *bf++);
  86.         msk++;
  87.     }
  88. }
  89.  
  90. /* ------- display the data value in a field ------ */
  91. static void data_value(WINDOW *wnd, FIELD *fld)
  92. {
  93.     wcursor(wnd, fld->fcol, fld->frow);
  94.     disp_field(wnd, fld->fbuff, fld->fmask);
  95. }
  96.  
  97. /* ------ display all the fields in a window ------- */
  98. void field_tally(WINDOW *wnd)
  99. {
  100.     FIELD *fld;
  101.  
  102.     fld = FHEAD;
  103.     while (fld != NULL)    {
  104.         data_value(wnd, fld);
  105.         fld = fld->fnxt;
  106.     }
  107. }
  108.  
  109. /* ----- set a field's help window ------- */
  110. void field_window(FIELD *fld, char *hwin, int x, int y)
  111. {
  112.     fld->fhwin=hwin;
  113.     fld->flx = x;
  114.     fld->fly = y;
  115. }
  116. /*page*/
  117. /* ------- clear a template to all blanks ------ */
  118. void clear_template(WINDOW *wnd)
  119. {
  120.     FIELD *fld;
  121.     char *bf, *msk;
  122.  
  123.     fld = FHEAD;
  124.     while (fld != NULL)    {
  125.         bf = fld->fbuff;
  126.         msk = fld->fmask;
  127.         while (*msk)    {
  128.             if (*msk == FIELDCHAR)
  129.                 *bf++ = ' ';
  130.             msk++;
  131.         }
  132.         fld = fld->fnxt;
  133.     }
  134.     field_tally(wnd);
  135. }
  136.  
  137. /* ---------- set insert/exchange cursor shape ----------- */
  138. static void insert_status()
  139. {
  140.     set_cursor_type(insert_mode ? 0x0106 : 0x0607);
  141. }
  142. /*page*/
  143. /* ------- read a field from the keyboard ------------- */
  144. static int read_field(WINDOW *wnd, FIELD *fld)
  145. {
  146.     char *mask = fld->fmask, *buff = fld->fbuff;
  147.     int done = FALSE, c, column;
  148.  
  149.     column = fld->fcol;
  150.     while (*mask != FIELDCHAR)    {
  151.         column++;
  152.         mask++;
  153.     }
  154.     while (TRUE)    {
  155.         wcursor(wnd, column, fld->frow);
  156.         c = get_char();
  157.         if (fld->ftype == 'A')
  158.             c = toupper(c);
  159.         clear_message();
  160.         switch (c)    {
  161.             case '\b':
  162.             case BS:
  163.                 if (buff == fld->fbuff)    {
  164.                     done = c == BS;
  165.                     break;
  166.                 }
  167.                 --buff;
  168.                 do    {
  169.                     --mask;
  170.                     --column;
  171.                 } while (*mask != FIELDCHAR);
  172.                 if (c == BS)
  173.                     break;
  174.             case DEL:
  175.                 movmem(buff+1, buff, strlen(buff));
  176.                 *(buff+strlen(buff)) = ' ';
  177.                 wcursor(wnd, column, fld->frow);
  178.                 disp_field(wnd, buff, mask);
  179.                 break;
  180.             case FWD:
  181.                 do    {
  182.                     column++;
  183.                     mask++;
  184.                 } while (*mask && *mask != FIELDCHAR);
  185.                 buff++;
  186.                 break;
  187.             case INS:
  188.                 insert_mode ^= TRUE;
  189.                 insert_status();
  190.                 break;
  191.             case '.':
  192.                 if (fld->ftype == 'C')    {
  193.                     if (*mask++ && *buff == ' ')    {
  194.                         *buff++ = '0';
  195.                         if (*mask++ && *buff == ' ')
  196.                             *buff++ = '0';
  197.                     }
  198.                     right_justify(fld->fbuff);
  199.                     wcursor(wnd, fld->fcol, fld->frow);
  200.                     disp_field(wnd, fld->fbuff, fld->fmask);
  201.                     column = fld->fcol+strlen(fld->fmask)-2;
  202.                     mask = fld->fmask+strlen(fld->fmask)-2;
  203.                     buff = fld->fbuff+strlen(fld->fbuff)-2;
  204.                     break;
  205.                 }
  206.             default:
  207.                 if (endstroke(c))    {
  208.                     done = TRUE;
  209.                     break;
  210.                 }
  211.                 if (toupper(fld->ftype)!='A'&&!isdigit(c))    {
  212.                     error_message("Numbers only");
  213.                     break;
  214.                 }
  215.                 if (insert_mode)    {
  216.                     movmem(buff, buff+1, strlen(buff)-1);
  217.                     disp_field(wnd, buff, mask);
  218.                     wcursor(wnd, column, fld->frow);
  219.                 }
  220.                 *buff++ = c;
  221.                 wputchar(wnd, c);
  222.                 do    {
  223.                     column++;
  224.                     mask++;
  225.                 } while (*mask && *mask != FIELDCHAR);
  226.                 if (!*mask)
  227.                     c = FWD;
  228.                 break;
  229.         }
  230.         if (!*mask)
  231.             done = TRUE;
  232.         if (done)    {
  233.             if (fld->ftype == 'D' &&
  234.                     c != ESC &&
  235.                         validate_date(fld->fbuff) != OK)
  236.                 return ERROR;
  237.             break;
  238.         }
  239.     }
  240.     if (c != ESC && toupper(fld->ftype) != 'A')    {
  241.         if (fld->ftype == 'C')    {
  242.             if (*mask++ && *buff == ' ')    {
  243.                 *buff++ = '0';
  244.                 if (*mask++ && *buff == ' ')
  245.                     *buff++ = '0';
  246.             }
  247.         }
  248.         if (fld->ftype == 'Z' || fld->ftype == 'D')
  249.             right_justify_zero_fill(fld->fbuff);
  250.         else
  251.             right_justify(fld->fbuff);
  252.         wcursor(wnd, fld->fcol, fld->frow);
  253.         disp_field(wnd, fld->fbuff, fld->fmask);
  254.     }
  255.     return c;
  256. }
  257. /*page*/
  258. /* ---------- test c for an ending keystroke ----------- */
  259. static int endstroke(int c)
  260. {
  261.     switch (c)    {
  262.         case '\r':
  263.         case '\n':
  264.         case '\t':
  265.         case ESC:
  266.         case F1:
  267.         case F2:
  268.         case F3:
  269.         case F4:
  270.         case F5:
  271.         case F6:
  272.         case F7:
  273.         case F8:
  274.         case F9:
  275.         case F10:
  276.         case PGUP:
  277.         case PGDN:
  278.         case HOME:
  279.         case END:
  280.         case UP:
  281.         case DN:
  282.             return TRUE;
  283.         default:
  284.             return FALSE;
  285.     }
  286. }
  287. /*page*/
  288. /* ------- right justify, space fill -------- */
  289. static void right_justify(char *s)
  290. {
  291.     int len;
  292.  
  293.     len = strlen(s);
  294.     while (*s == ' ' || *s == '0' && len)    {
  295.         len--;
  296.         *s++ = ' ';
  297.     }
  298.     if (len)
  299.         while (*(s+(len-1)) == ' ')    {
  300.             movmem(s, s+1, len-1);
  301.             *s = ' ';
  302.         }
  303. }
  304.  
  305. /* ---------- right justify, zero fill --------------- */
  306. static void right_justify_zero_fill(char *s)
  307. {
  308.     int len;
  309.  
  310.     if (spaces(s))
  311.         return;
  312.     len = strlen(s);
  313.     while (*(s + len - 1) == ' ')    {
  314.         movmem(s, s + 1, len-1);
  315.         *s = '0';
  316.     }
  317. }
  318.  
  319. /* ----------- test for spaces -------- */
  320. int spaces(char *c)
  321. {
  322.     while (*c == ' ')
  323.         c++;
  324.     return !*c;
  325. }
  326. /*page*/
  327. /* -------------- validate a date ----------------- */
  328. static int validate_date(char *s)
  329. {
  330.     static int days [] =
  331.         { 31,28,31,30,31,30,31,31,30,31,30,31 };
  332.     char date [7];
  333.     int mo;
  334.  
  335.     strcpy(date, s);
  336.     if (spaces(date))
  337.         return OK;
  338.     days[1] = (atoi(date+4)%4) ? 28 : 29;
  339.     *(date + 4) = '\0';
  340.     mo = atoi(date+2);
  341.     *(date+2) = '\0';
  342.     if (mo && mo<13 && atoi(date) && atoi(date)<=days[mo-1])
  343.         return OK;
  344.     error_message("Invalid date");
  345.     return ERROR;
  346. }
  347.  
  348. /* ----- Process data entry for a screen template. ---- */
  349. int data_entry(WINDOW *wnd)
  350. {
  351.     FIELD *fld;
  352.     int exitcode, isvalid, done=FALSE, oldhelpkey=helpkey;
  353.     field_tally(wnd);
  354.     fld = FHEAD;
  355.     /* ---- collect data from keyboard into screen ---- */
  356.     while (fld != NULL && done == FALSE)    {
  357.         set_help(fld->fhwin, fld->flx, fld->fly);
  358.         helpkey = (fld->fhelp) ? 0 : oldhelpkey;
  359.         wcursor(wnd, fld->fcol, fld->frow);
  360.         if (fld->fprot == FALSE)    {
  361.             reverse_video(wnd);
  362.             data_value(wnd, fld);
  363.             wcursor(wnd, fld->fcol, fld->frow);
  364.             exitcode = read_field(wnd, fld);
  365.             isvalid = (exitcode != ESC && fld->fvalid) ?
  366.                         (*(fld->fvalid))(fld->fbuff) : OK;
  367.         }
  368.         else    {
  369.             exitcode = FWD;
  370.             isvalid = OK;
  371.         }
  372.         if (isvalid == OK)    {
  373.             normal_video(wnd);
  374.             data_value(wnd, fld);
  375.             switch (exitcode)    {        /* passed edit */
  376.                 case F1:    if (fld->fhelp)    {
  377.                                 (*(fld->fhelp))(fld->fbuff);
  378.                                 data_value(wnd, fld);
  379.                             }
  380.                             break;
  381.                 case DN:
  382.                 case '\r':
  383.                 case '\t':
  384.                 case FWD:    fld = fld->fnxt;
  385.                             if (fld == NULL)
  386.                                 fld = FHEAD;
  387.                             break;
  388.                 case UP:
  389.                 case BS:    fld = fld->fprv;
  390.                             if (fld == NULL)
  391.                                 fld = FTAIL;
  392.                             break;
  393.                 default:    done = endstroke(exitcode);
  394.                             break;
  395.             }
  396.         }
  397.     }
  398.     helpkey = oldhelpkey;
  399.     return (exitcode);
  400. }
  401. /* --------- display a window prompt -------- */
  402. void wprompt(WINDOW *wnd, int x, int y, char *s)
  403. {
  404.     wcursor(wnd, x, y);
  405.     wprintf(wnd, s);
  406. }
  407.  
  408.