home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XSRC_117.ZIP / AENTRY.C next >
Encoding:
C/C++ Source or Header  |  1990-11-18  |  12.9 KB  |  555 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*   XBBS SOURCE CODE copyright (c) 1990 by M. Kimes                        */
  4. /*   All Rights Reserved                                                    */
  5. /*                                                                          */
  6. /*    For complete details of the licensing restrictions, please refer      */
  7. /*    to the License agreement, which is published in its entirety in       */
  8. /*    the in the file LICENSE.XBS.                                          */
  9. /*                                                                          */
  10. /*    USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE      */
  11. /*    XBBS LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF            */
  12. /*    THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO       */
  13. /*    NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT M. KIMES         */
  14. /*    AT THE ADDRESS LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO USE   */
  15. /*    THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE XBBS LICENSING     */
  16. /*    AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE ABLE TO REACH WITH      */
  17. /*    M. KIMES                                                              */
  18. /*                                                                          */
  19. /*                                                                          */
  20. /* You can contact M. Kimes at the following address:                       */
  21. /*                                                                          */
  22. /* M. Kimes                         1:380/16.0@FidoNet                      */
  23. /* 542 Merrick                      (318)222-3455 data                      */
  24. /* Shreveport, LA  71104                                                    */
  25. /*                                                                          */
  26. /*                                                                          */
  27. /* Please feel free to contact me at any time to share your comments about  */
  28. /* my software and/or licensing policies.                                   */
  29. /*                                                                          */
  30. /*--------------------------------------------------------------------------*/
  31.  
  32. /* aentry.c */
  33.  
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <stdlib.h>
  37. #include <alloc.h>
  38. #include <mem.h>
  39. #include <string.h>
  40. #include <conio.h>
  41. #include "awindow.h"
  42. #include "xkeys.h"
  43.  
  44. extern unsigned int baud;
  45.  
  46. #define FIELDCHAR '_'
  47. int insert_mode=FALSE;
  48. extern int helpkey;
  49.  
  50. #ifdef USEMOUSE
  51.     extern int hcount,vcount,hysterisis;
  52. #endif
  53.  
  54. /* Local prototypes */
  55. extern void pascal print_clock(void);
  56. void pascal addfield(WINDOW *wnd,FIELD *fld);
  57. void pascal data_value(WINDOW *wnd,FIELD *fld);
  58. void pascal insert_status(void);
  59. int pascal read_field(WINDOW *wnd,FIELD *fld);
  60. void pascal right_justify(char *s);
  61. void pascal right_justify_zero_fill(char *s);
  62. int pascal validate_date(char *s);
  63. int pascal endstroke(int c);
  64. int pascal spaces(char *c);
  65.  
  66. /* Initialize a template */
  67. void pascal init_template (WINDOW *wnd) {
  68.  
  69.     FIELD *fld,*fl;
  70.  
  71.     fld=FHEAD;
  72.     while (fld) {
  73.         fl=fld->fnxt;
  74.         ffree(fld);
  75.         fld=fl;
  76.     }
  77.     FHEAD=NULL;
  78. }
  79.  
  80. /* Establish a field in a template */
  81. FIELD * pascal establish_field (wnd,cl,rw,msk,bf,ty)
  82.  
  83.     WINDOW *wnd;
  84.     int rw;
  85.     int cl;
  86.     char *msk;
  87.     char *bf;
  88.     int ty;
  89. {
  90.  
  91.     FIELD *fld;
  92.  
  93.     if ((fld=mmalloc(sizeof(FIELD)))==NULL) return NULL;
  94.     fld->fmask=msk;
  95.     fld->frow=rw;
  96.     fld->fcol=cl;
  97.     fld->fbuff=bf;
  98.     fld->ftype=ty;
  99.     fld->fprot=0;
  100.     fld->fnxt=fld->fprv=NULL;
  101.     fld->fvalid=NULL;
  102.     fld->fhelp=NULL;
  103.     fld->fhwin=NULL;
  104.     fld->flx=fld->fly=0;
  105.     addfield(wnd,fld);
  106.     return fld;
  107. }
  108.  
  109. /* Add a field to the end of the list */
  110. static void pascal addfield (WINDOW *wnd,FIELD *fld) {
  111.  
  112.     if (FTAIL) {
  113.         fld->fprv=FTAIL;
  114.         FTAIL->fnxt=fld;
  115.     }
  116.     FTAIL=fld;
  117.     if(!FHEAD) FHEAD=fld;
  118. }
  119.  
  120. /* Display a data field */
  121. static void pascal disp_field (WINDOW *wnd,char *bf,char *msk) {
  122.  
  123.     while (*msk) {
  124.         wputcharaw (wnd,*msk !=FIELDCHAR ? *msk : *bf++);
  125.         msk++;
  126.     }
  127. }
  128.  
  129. /* Display the data value in a field */
  130. static void pascal data_value (WINDOW *wnd,FIELD *fld) {
  131.  
  132.     wcursor(wnd,fld->fcol,fld->frow);
  133.     disp_field(wnd,fld->fbuff,fld->fmask);
  134. }
  135.  
  136. /* Display all the fields in a window */
  137. void pascal field_tally (WINDOW *wnd) {
  138.  
  139.     FIELD *fld;
  140.  
  141.     fld=FHEAD;
  142.     while(fld != NULL) {
  143.         data_value(wnd,fld);
  144.         fld=fld->fnxt;
  145.     }
  146. }
  147.  
  148. /* Set a field's help window */
  149. void pascal field_window (FIELD *fld,char *hwin,int x,int y) {
  150.  
  151.     fld->fhwin=hwin;
  152.     fld->flx=x;
  153.     fld->fly=y;
  154. }
  155.  
  156. /* Clear a template to all blanks */
  157. void pascal clear_template (WINDOW *wnd) {
  158.  
  159.     FIELD *fld;
  160.     char *bf,*msk;
  161.  
  162.     fld=FHEAD;
  163.     while (fld != NULL) {
  164.         bf=fld->fbuff;
  165.         msk=fld->fmask;
  166.         while (*msk) {
  167.             if(*msk==FIELDCHAR)
  168.                 *bf++=' ';
  169.             msk++;
  170.         }
  171.         fld=fld->fnxt;
  172.     }
  173.     field_tally(wnd);
  174. }
  175.  
  176. /* Prepare a template to end in blanks */
  177. void pascal prep_template (WINDOW *wnd) {
  178.  
  179.     FIELD *fld;
  180.     char *bf,*msk;
  181.  
  182.     fld=FHEAD;
  183.     while (fld != NULL) {
  184.         bf=fld->fbuff;
  185.         msk=fld->fmask;
  186.         while((*bf!=0) && (*msk!=0)) {
  187.             if (*msk!=FIELDCHAR) {
  188.                 msk++;
  189.                 continue;
  190.             }
  191.             if (*msk==0) {
  192.                 break;
  193.             }
  194.             bf++;
  195.             msk++;
  196.         }
  197.         while (*msk) {
  198.             if(*msk==FIELDCHAR) *bf++=' ';
  199.             msk++;
  200.         }
  201.         *bf=0;
  202.         fld=fld->fnxt;
  203.     }
  204.     field_tally(wnd);
  205. }
  206.  
  207. /* Set insert/exchange cursor shape */
  208. static void pascal insert_status (void) {
  209.     set_cursor_type(insert_mode ? 0x0106 : 0x0607);
  210. }
  211.  
  212. /* Read a field from the keyboard */
  213. static int pascal read_field (WINDOW *wnd,FIELD *fld) {
  214.  
  215.     char *mask=fld->fmask,*buff=fld->fbuff;
  216.     int done=FALSE,c,column;
  217. #ifdef USEMOUSE
  218.     int temph,tempv;
  219. #endif
  220.  
  221. #ifdef USEMOUSE
  222.     temph=hcount;
  223.     tempv=vcount;
  224.     hcount=2*hysterisis;
  225.     vcount=2*hysterisis;
  226. #endif
  227.  
  228.     column=fld->fcol;
  229.     while(*mask!=FIELDCHAR) {
  230.         column++;
  231.         mask++;
  232.     }
  233.     while (TRUE) {
  234.         wcursor(wnd,column,fld->frow);
  235.         c=get_char();
  236.         if(fld->ftype=='A' || fld->ftype=='O')
  237.             c=toupper(c);
  238.         clear_message();
  239.         switch(c) {
  240.             case 8:
  241.             case BS:
  242.                 if(buff==fld->fbuff) {
  243.                     done=c==BS;
  244.                     break;
  245.                 }
  246.                 --buff;
  247.                 do {
  248.                     --mask;
  249.                     --column;
  250.                 } while (*mask !=FIELDCHAR);
  251.                 if (c==BS) break;
  252.             case DEL:
  253.                 if(fld->ftype!='O') {
  254.                     movmem(buff+1,buff,strlen(buff));
  255.                     *(buff+strlen(buff))=' ';
  256.                     wcursor(wnd,column,fld->frow);
  257.                     disp_field(wnd,buff,mask);
  258.                 }
  259.                 break;
  260.             case CTRL_Y:
  261.                 strset(buff,' ');
  262.                 disp_field(wnd,buff,mask);
  263.                 break;
  264.             case CTRL_RIGHT:
  265.                 do {
  266.                     column++;
  267.                     mask++;
  268.                     if(*mask==FIELDCHAR)buff++;
  269.                 } while(*buff==' ' && *mask);
  270.                 if(*mask) {
  271.                     do {
  272.                         column++;
  273.                         mask++;
  274.                         if(*mask==FIELDCHAR)buff++;
  275.                     }    while(*buff!=' ' && *mask);
  276.                 }
  277.                 break;
  278.             case CTRL_LEFT:
  279.                 if(mask>fld->fmask) {
  280.                     do {
  281.                         --column;
  282.                         --mask;
  283.                         if(*mask==FIELDCHAR)--buff;
  284.                     } while(*buff==' ' && mask>fld->fmask);
  285.                 }
  286.                 if(mask>fld->fmask) {
  287.                     do {
  288.                         --column;
  289.                         --mask;
  290.                         if(*mask==FIELDCHAR)--buff;
  291.                     } while(*buff!=' ' && mask>fld->fmask);
  292.                 }
  293.                 break;
  294.             case END:
  295.             case CTRL_END:
  296.                 column=fld->fcol;
  297.                 mask=fld->fmask;
  298.                 buff=fld->fbuff;
  299.                 do {
  300.                     column++;
  301.                     mask++;
  302.                     if(*mask==FIELDCHAR)buff++;
  303.                 } while(*mask);
  304.                 while(*buff==' ' && mask>fld->fmask) {
  305.                     --column;
  306.                     --mask;
  307.                     if(*mask==FIELDCHAR)--buff;
  308.                 }
  309.                 if(*buff!=' ') buff++;
  310.                 break;
  311.             case HOME:
  312.             case CTRL_HOME:
  313.                 column=fld->fcol;
  314.                 mask=fld->fmask;
  315.                 buff=fld->fbuff;
  316.                 while(*mask!=FIELDCHAR) {
  317.                     column++;
  318.                     mask++;
  319.                 }
  320.                 break;
  321.             case FWD:
  322.                 do {
  323.                     column++;
  324.                     mask++;
  325.                 } while(*mask && *mask!=FIELDCHAR);
  326.                 buff++;
  327.                 break;
  328.             case INS:
  329.             case ALT_I:
  330.                 insert_mode ^= TRUE;
  331.                 insert_status();
  332.                 break;
  333.             case '.':
  334.                 if (fld->ftype=='C') {
  335.                     if (*mask++ && *buff==' ') {
  336.                         *buff++='0';
  337.                         if (*mask++ && *buff==' ') *buff++='0';
  338.                     }
  339.                     right_justify(fld->fbuff);
  340.                     wcursor(wnd,fld->fcol,fld->frow);
  341.                     disp_field(wnd,fld->fbuff,fld->fmask);
  342.                     column=fld->fcol+strlen(fld->fmask)-2;
  343.                     mask=fld->fmask+strlen(fld->fmask)-2;
  344.                     buff=fld->fbuff+strlen(fld->fbuff)-2;
  345.                     break;
  346.                 }
  347.             default:
  348.                 if (endstroke(c)) {
  349.                     done=TRUE;
  350.                     break;
  351.                 }
  352.                 if (toupper(fld->ftype)!='A'&&toupper(fld->ftype)!='O'&&!isdigit(c)) {
  353.                     error_message("Numbers only");
  354.                     break;
  355.                 }
  356.                 if (toupper(fld->ftype)=='O'&& c!='X') c='-';
  357.                 if (insert_mode && fld->ftype!='O') {
  358.                     movmem(buff,buff+1,strlen(buff)-1);
  359.                     disp_field(wnd,buff,mask);
  360.                     wcursor(wnd,column,fld->frow);
  361.                 }
  362.                 *buff++=c;
  363.                 wputcharaw(wnd,c);
  364.                 do {
  365.                     column++;
  366.                     mask++;
  367.                 } while(*mask && *mask!=FIELDCHAR);
  368.                 if(!*mask) c=FWD;
  369.                 break;
  370.             }
  371.             if (!*mask) done=TRUE;
  372.  
  373.             if(done) {
  374.                 if(fld->ftype=='D' && (c!=ESC && c!=CTRL_K) && validate_date(fld->fbuff)!=OK) {
  375. #ifdef USEMOUSE
  376.                   hcount=temph;
  377.                   vcount=tempv;
  378. #endif
  379.                   return ERROR;
  380.                 }
  381.                 break;
  382.             }
  383.         }
  384.         if((c!=CTRL_K && c!=ESC) && toupper(fld->ftype)!='A') {
  385.             if(fld->ftype=='C') {
  386.                 if(*mask++ && *buff==' ') {
  387.                     *buff++='0';
  388.                     if(*mask++ && *buff==' ')
  389.                         *buff++='0';
  390.                 }
  391.             }
  392.             if (fld->ftype=='Z' || fld->ftype=='D') right_justify_zero_fill(fld->fbuff);
  393.             else right_justify(fld->fbuff);
  394.             wcursor(wnd,fld->fcol,fld->frow);
  395.             disp_field(wnd,fld->fbuff,fld->fmask);
  396.         }
  397. #ifdef USEMOUSE
  398.         hcount=temph;
  399.         vcount=tempv;
  400. #endif
  401.         return c;
  402. }
  403.  
  404. /* Test C for an ending keystroke */
  405. static int pascal endstroke (int c) {
  406.  
  407.     switch(c) {
  408.         case 0:
  409.         case '\r':
  410.         case '\n':
  411.         case '\t':
  412.         case ESC:
  413.         case CTRL_K:
  414.         case PGUP:
  415.         case PGDN:
  416.         case UP:
  417.         case DN:
  418.             return TRUE;
  419.         default:
  420.             return FALSE;
  421.     }
  422. }
  423.  
  424. /* Right justify, space fill */
  425. static void pascal right_justify (char *s) {
  426.  
  427.     int len;
  428.  
  429.     len=strlen(s);
  430.  
  431. /*    while(*s==' ' || *s=='0' && len) {
  432. */
  433.  
  434.     while(*s==' '&& len) {
  435.         len--;
  436.         *s++=' ';
  437.     }
  438.  
  439. /*
  440.     if(len)
  441.         while(*(s+(len-1)) == ' ') {
  442.             movmem(s,s+1,len-1);
  443.             *s=' ';
  444.         }
  445. */
  446.  
  447. }
  448.  
  449. /* Right justify,zero fill */
  450. static void pascal right_justify_zero_fill (char *s) {
  451.  
  452.     int len;
  453.  
  454.     if(spaces(s))
  455.         return;
  456.     len=strlen(s);
  457.     while(*(s+len-1)==' ') {
  458.         movmem(s,s+1,len-1);
  459.         *s='0';
  460.     }
  461. }
  462.  
  463. /* Test for spaces */
  464. int pascal spaces (char *c) {
  465.  
  466.     while(*c==' ')
  467.         c++;
  468.     return !*c;
  469. }
  470.  
  471. /* Validate a date */
  472. static int pascal validate_date (char *s) {
  473.  
  474.     static char days[]={31,28,31,30,31,30,31,31,30,31,30,31};
  475.     char date[15];
  476.     int mo;
  477.  
  478.     strcpy(date,s);
  479.     if(spaces(date)) return OK;
  480.     days[1] = (char)atoi(date+4%4) ? 28 : 29;
  481.     *(date+4) = 0;
  482.     mo=atoi(date+3);
  483.     *(date+2) = 0;
  484.     if(mo && mo<13 && atoi(date) && (char)atoi(date)<=days[mo-1]) return OK;
  485.     error_message("Invalid date");
  486.     return ERROR;
  487. }
  488.  
  489. /* Process data entry for a screen template */
  490. int pascal data_entry (WINDOW *wnd) {
  491.  
  492.     FIELD *fld;
  493.     int exitcode,isvalid,done=FALSE,oldhelpkey=helpkey;
  494.  
  495.     field_tally(wnd);
  496.     fld=FHEAD;
  497.     /* Collect data from keyboard into screen */
  498.     while(fld!=NULL && done==FALSE) {
  499. /*        set_help(fld->fhwin,fld->flx,fld->fly);
  500.         helpkey=(fld->fhelp) ? 0 : oldhelpkey;      */
  501.         wcursor(wnd,fld->fcol,fld->frow);
  502.         if(fld->fprot==FALSE) {
  503.             reverse_video(wnd);
  504.             data_value(wnd,fld);
  505.             wcursor(wnd,fld->fcol,fld->frow);
  506.             exitcode=read_field(wnd,fld);
  507.             isvalid=((exitcode != ESC && exitcode!=CTRL_K) && fld->fvalid) ? (*(fld->fvalid))(fld->fbuff) : OK;
  508.         }
  509.         else {
  510.             exitcode=FWD;
  511.             isvalid=OK;
  512.         }
  513.         if(isvalid == OK) {
  514.             normal_video(wnd);
  515.             data_value(wnd,fld);
  516.             switch(exitcode) {     /* Passed edit */
  517.                 case F1:    if (fld->fhelp) {
  518.                                 (*(fld->fhelp))(fld->fbuff);
  519.                                 data_value(wnd,fld);
  520.                             }
  521.                             break;
  522.                 case DN:
  523.                 case '\r':
  524.                 case 0:
  525.                 case FWD:    fld=fld->fnxt;
  526.                             if(fld==NULL) {
  527.                                 if (exitcode=='\r' || exitcode==0) {
  528.                                     exitcode=F10;
  529.                                     done=TRUE;
  530.                                 }
  531.                                 else fld=FHEAD;
  532.                             }
  533.                             break;
  534.                 case UP:
  535.                 case BS:    fld=fld->fprv;
  536.                             if(fld==NULL)
  537.                                 fld=FTAIL;
  538.                             break;
  539.                 default:    done=endstroke(exitcode);
  540.                             break;
  541.             }
  542.         }
  543.     }
  544.     helpkey=oldhelpkey;
  545.     return(exitcode);
  546. }
  547.  
  548.  
  549. /* Display a window prompt */
  550. void pascal wprompt (WINDOW *wnd,int x,int y,char *s) {
  551.  
  552.     wcursor(wnd,x,y);
  553.     wprintfraw(wnd,s);
  554. }
  555.