home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / database / cdbms / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-01  |  8.0 KB  |  415 lines

  1. /* ----------------- screen.c ------------------------- */
  2. #include <stdio.h>
  3. #include "cdata.h"
  4. #include "keys.h"
  5.  
  6. int insert_mode = FALSE;       /* insert mode, TRUE/FALSE */
  7. extern int prev_col, prev_row; /* current cursor location */
  8. extern int screen_displayed;   /* template displayed flag */
  9. #define FIELDCHAR '_'           /* field filler character  */
  10.  
  11. struct {
  12.     int prot;
  13.     int (*edits)();
  14. } sb [MXELE];
  15.  
  16. int *elist;
  17. char *bf;
  18. char *tname;
  19. void right_justify(),
  20.      right_justify_zero_fill(), left_justify_zero_fill(),
  21.      disp_element(), insert_status(),
  22.      put_fchar(), data_coord();
  23.  
  24. /* ----------- initialize the screen process ------------- */
  25. void init_screen(name, els, bfr)
  26. char *name;
  27. int *els;
  28. char *bfr;
  29. {
  30.     tname = name;
  31.     elist = els;
  32.     bf = bfr;
  33. }
  34.  
  35. /* ------- set the protect flag for a screen field ------- */
  36. void protect(el, tf)
  37. int el, tf;
  38. {
  39.     sb[elp(el)].prot = tf;
  40. }
  41.  
  42. /* ---- set the field edit function for a screen field --- */
  43. void edit(el, func)
  44. int el, (*func)();
  45. {
  46.     sb[elp(el)].edits = func;
  47. }
  48.  
  49. /* ---- compute the relative position
  50.             of an element on a screen ------ */
  51. static int elp(el)
  52. int el;
  53. {
  54.     int i;
  55.  
  56.     for (i = 0; *(elist + i); i++)
  57.         if (el == *(elist + i))
  58.             break;
  59.     return i;
  60. }
  61.  
  62. /* ----------- Display the crt template ----------- */
  63. void display_template()
  64. {
  65.     int i, el, ct;
  66.     char detag[16], *cp1, *cp2;
  67.  
  68.     clear_screen();
  69.     screen_displayed = TRUE;
  70.     ct = no_flds();
  71.     printf("\n                   --- %s ---\n", tname);
  72.     for (i = 0; i < ct; i++)    {
  73.         el = *(elist + i) - 1;
  74.         cp1 = denames[el];
  75.         cp2 = detag;
  76.         while (*cp1 && cp2 < detag + sizeof detag - 1)    {
  77.             *cp2++ = *cp1 == '_' ? ' ' : *cp1;
  78.             cp1++;
  79.         }
  80.         *cp2 = '\0';
  81.         printf("\n%-16.16s %s",detag, elmask[el]);
  82.     }
  83.     printf("\n");
  84.     insert_status();
  85. }
  86.  
  87. /* ----- Process data entry for a screen template. ---- */
  88. int data_entry()
  89. {
  90.     int (*validfunct)();
  91.     int field_ctr, exitcode, el;
  92.     int field_ptr = 0, done = FALSE, isvalid;
  93.     char *bfptr;
  94.  
  95.     if (screen_displayed == 0)
  96.         display_template();
  97.     tally();
  98.     field_ctr = no_flds();
  99.     /* ---- collect data from keyboard into screen ---- */
  100.     while (done == FALSE)    {
  101.         bfptr = bf + epos(elist[field_ptr], elist);;
  102.         el = *(elist + field_ptr) - 1;
  103.         validfunct = sb[field_ptr].edits;
  104.         data_coord(el + 1);
  105.         if (sb[field_ptr].prot == FALSE)    {
  106.             exitcode =
  107.                 read_element(eltype[el], elmask[el], bfptr);
  108.             isvalid = (exitcode != ESC && validfunct) ? 
  109.                         (*validfunct)(bfptr,exitcode) : OK;
  110.         }
  111.         else    {
  112.             exitcode = FWD;
  113.             isvalid = OK;
  114.         }
  115.         if (isvalid == OK)
  116.             switch (exitcode)    {        /* passed edit */
  117.                 case DN:                /* cursor down key */
  118.                 case '\r':                /* enter/return */
  119.                 case '\t':                /* horizontal tab */
  120.                 case FWD:                /* -> */
  121.                     if (field_ptr+1 == field_ctr)
  122.                         field_ptr = 0;
  123.                     else
  124.                         field_ptr++;
  125.                     break;
  126.                 case UP:                /* cursor up key */
  127.                 case BS:                /* back space */
  128.                     if (field_ptr == 0)
  129.                         field_ptr = field_ctr - 1;
  130.                     else
  131.                         field_ptr--;
  132.                     break;
  133.                 default:
  134.                     done = endstroke(exitcode);
  135.                     break;
  136.             }
  137.     }
  138.     return (exitcode);
  139. }
  140.  
  141. /* ----- Compute the number of fields on a template ------ */
  142. static int no_flds()
  143. {
  144.     int ct = 0;
  145.  
  146.     while (*(elist + ct))
  147.         ct++;
  148.     return ct;
  149. }
  150.  
  151. /* ------ compute data element field coordinates --------- */
  152. static void data_coord(el)
  153. int el;
  154. {
  155.     prev_col = 17;
  156.     prev_row = elp(el) + 3;
  157. }
  158.  
  159.  
  160.  
  161. /* ------- read data element from keyboard ------------- */
  162. static int read_element(type, msk, bfr)
  163. char type, *msk, *bfr;
  164. {
  165.     char *mask = msk, *buff = bfr;
  166.     int done = FALSE, c, column = prev_col;
  167.  
  168.     while (*mask != FIELDCHAR)    {
  169.         prev_col++;
  170.         mask++;
  171.     }
  172.     while (TRUE)    {
  173.         cursor(prev_col, prev_row);
  174.         c = get_char();
  175.         clear_notice();
  176.         switch (c)    {
  177.             case '\b':
  178.             case BS:
  179.                 if (buff == bfr)    {
  180.                     done = c == BS;
  181.                     break;
  182.                 }
  183.                 --buff;
  184.                 do    {
  185.                     --mask;
  186.                     --prev_col;
  187.                 } while (*mask != FIELDCHAR);
  188.                 if (c == BS)
  189.                     break;
  190.             case DEL:
  191.                 mov_mem(buff+1, buff, strlen(buff));
  192.                 *(buff+strlen(buff)) = ' ';
  193.                 cursor(prev_col, prev_row);
  194.                 disp_element(buff,mask);
  195.                 break;
  196.             case FWD:
  197.                 do    {
  198.                     prev_col++;
  199.                     mask++;
  200.                 } while (*mask && *mask != FIELDCHAR);
  201.                 buff++;
  202.                 break;
  203.             case INS:
  204.                 insert_mode ^= TRUE;
  205.                 insert_status();
  206.                 break;
  207.             case '.':
  208.                 if (type == 'C')    {
  209.                     if (*mask++ && *buff == ' ')    {
  210.                         *buff++ = '0';
  211.                         if (*mask++ && *buff == ' ')
  212.                             *buff++ = '0';
  213.                     }
  214.                     right_justify(bfr);
  215.                     cursor(column, prev_row);
  216.                     disp_element(bfr, msk);
  217.                     prev_col = column + strlen(msk)-2;
  218.                     mask = msk + strlen(msk)-2;
  219.                     buff = bfr + strlen(bfr)-2;
  220.                     break;
  221.                 }
  222.             default:
  223.                 if (endstroke(c))    {
  224.                     done = TRUE;
  225.                     break;
  226.                 }
  227.                 if (type != 'A' && !isdigit(c))    {
  228.                     error_message("Numbers only");
  229.                     break;
  230.                 }
  231.                 if (insert_mode)    {
  232.                     mov_mem(buff, buff+1, strlen(buff)-1);
  233.                     disp_element(buff,mask);
  234.                 }
  235.                 *buff++ = c;
  236.                 put_fchar(c);
  237.                 do    {
  238.                     prev_col++;
  239.                     mask++;
  240.                 } while (*mask && *mask != FIELDCHAR);
  241.                 if (!*mask)
  242.                     c = FWD;
  243.                 break;
  244.         }
  245.         if (!*mask)
  246.             done = TRUE;
  247.         if (done)    {
  248.             if (type == 'D' &&
  249.                 c != ESC &&
  250.                     validate_date(bfr) != OK)
  251.                 return -1;
  252.             break;
  253.         }
  254.     }
  255.     if (c != ESC && type != 'A')    {
  256.         if (type == 'C')    {
  257.             if (*mask++ && *buff == ' ')    {
  258.                 *buff++ = '0';
  259.                 if (*mask++ && *buff == ' ')
  260.                     *buff++ = '0';
  261.             }
  262.         }
  263.         if (type == 'Z' || type == 'D')
  264.             right_justify_zero_fill(bfr);
  265.         else
  266.             right_justify(bfr);
  267.         cursor(column, prev_row);
  268.         disp_element(bfr,msk);
  269.     }
  270.     return (c);
  271. }
  272.  
  273. /* ---------- test c for an ending keystroke ----------- */
  274. endstroke(c)
  275. {
  276.     switch (c)    {
  277.         case '\r':
  278.         case '\n':
  279.         case '\t':
  280.         case ESC:
  281.         case F1:
  282.         case F2:
  283.         case F3:
  284.         case F4:
  285.         case F5:
  286.         case F6:
  287.         case F7:
  288.         case F8:
  289.         case F9:
  290.         case F10:
  291.         case PGUP:
  292.         case PGDN:
  293.         case HOME:
  294.         case END:
  295.         case UP:
  296.         case DN:
  297.             return TRUE;
  298.         default:
  299.             return FALSE;
  300.     }
  301. }
  302.  
  303. /* ------- right justify, space fill -------- */
  304. static void right_justify(s)
  305. char *s;
  306. {
  307.     int len;
  308.  
  309.     len = strlen(s);
  310.     while (*s == ' ' || *s == '0' && len)    {
  311.         len--;
  312.         *s++ = ' ';
  313.     }
  314.     if (len)
  315.         while (*(s+(len-1)) == ' ')    {
  316.             mov_mem(s, s+1, len-1);
  317.             *s = ' ';
  318.         }
  319. }
  320.  
  321. /* ---------- right justify, zero fill --------------- */
  322. static void right_justify_zero_fill(s)
  323. char *s;
  324. {
  325.     int len;
  326.  
  327.     if (spaces(s))
  328.         return;
  329.     len = strlen(s);
  330.     while (*(s + len - 1) == ' ')    {
  331.         mov_mem(s, s + 1, len-1);
  332.         *s = '0';
  333.     }
  334. }
  335.  
  336. /* ----------- test for spaces -------- */
  337. int spaces(c)
  338. char *c;
  339. {
  340.     while (*c == ' ')
  341.         c++;
  342.     return !*c;
  343. }
  344.  
  345. /* -------------- validate a date ----------------- */
  346. static int validate_date(s)
  347. char *s;
  348. {
  349.     static int days [] =
  350.         { 31,28,31,30,31,30,31,31,30,31,30,31 };
  351.     char date [7];
  352.     int mo;
  353.  
  354.     strcpy(date, s);
  355.     if (spaces(date))
  356.         return OK;
  357.     if (!atoi(date + 4))
  358.         days[1]++;
  359.     *(date + 4) = '\0';
  360.     mo = atoi(date+2);
  361.     *(date+2) = '\0';
  362.     if (mo && mo < 13 && atoi(date) &&
  363.                 atoi(date) <= days [mo - 1])
  364.         return OK;
  365.     error_message("Invalid date");
  366.     return ERROR;
  367. }
  368.  
  369. /* ---- display all the fields on a screen ------ */
  370. void tally()
  371. {
  372.     int *els = elist;
  373.  
  374.     while (*els)
  375.         put_field(*els++);
  376. }
  377.  
  378. /* ------- write a data element on the screen --------- */
  379. void put_field(el)
  380. int el;
  381. {
  382.     data_coord(el);
  383.     cursor(prev_col, prev_row);
  384.     disp_element(bf + epos(el, elist), elmask[el - 1]);
  385. }
  386.  
  387. /* ---------- display a data element -------- */
  388. static void disp_element(b, msk)
  389. char *b, *msk;
  390. {
  391.     while (*msk)    {
  392.         put_fchar(*msk != FIELDCHAR ? *msk : *b++);
  393.         msk++;
  394.     }
  395.     cursor(prev_col,prev_row);
  396. }
  397.  
  398.  
  399.  
  400.  
  401. /* ---------- display insert mode status ------------------ */
  402. static void insert_status()
  403. {
  404.     cursor(65,24);
  405.     printf(insert_mode ? "[INS]" : "     ");
  406.     cursor(prev_col,prev_row);
  407. }
  408.  
  409. /* --------- write a field character --------- */
  410. static void put_fchar(c)
  411. int c;
  412. {
  413.     put_char(c == ' ' ? '_' : c);
  414. }
  415.