home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 135 / af135a.adf / AmiCheck.lzx / AmiCheck / Source / printPanel.c < prev    next >
C/C++ Source or Header  |  2012-04-18  |  25KB  |  1,042 lines

  1. /* printPanel.c 
  2.  *
  3.  *  defines the GUIFront characteristics of the print panel
  4.  */
  5. #include <exec/types.h>
  6. #include <exec/lists.h>
  7. #include <exec/nodes.h>
  8. #include <exec/memory.h>
  9. #include <stdio.h>  
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <intuition/gadgetclass.h>
  13. #include <clib/exec_protos.h>
  14. #include <clib/intuition_protos.h>
  15. #include "amiCheck.h"
  16. #include "printPanel.h"
  17. #include "dataBase.h"
  18. #include "enterPanel.h"
  19. #include "regGadget.h"
  20.  
  21. /* prototypes */
  22. BOOL PrintHandleGadget(struct IntuiMessage *);
  23. void PrintInit(void);
  24. void PrintBuildImage(entryNode *entry, checkForm *form,BOOL test);
  25. void PrintClipImage(void);
  26. BOOL PrintCheckImage(FILE *out,checkForm *fc, BOOL vouch, BOOL first, BOOL *page1);
  27. void PrintBuildVoucher(entryNode *entry,checkForm *form,BOOL test);
  28. void PrintBuildAmntStr(entryNode *entry, char *dest);
  29. void PrintAutoVoid(entryNode *);
  30. BOOL PrintGoodbye(struct IntuiMessage *);
  31. void PrintGo(void);
  32. filterNode *PrintCheckFind(int check);
  33.  
  34. printControl localPrint;
  35. BOOL printEm;
  36. BOOL needFeed;
  37. /*
  38. __far char checkImage[MAXCHECKLINES][MAXCHECKCOLS+1];
  39. */
  40.  
  41. ULONG alloccolumns;
  42. char *checkImage;
  43.  
  44. char tempstr[MAXCHECKCOLS+1];
  45. struct Window *printWin = NULL;
  46. GUIFront *printGUI;
  47. static BOOL done;
  48. entryNode autovoid;
  49.  
  50. /* quick configure of some gadgets */
  51. STRPTR prlabels[] =
  52. {
  53.     "Print Checks",
  54.     "Mark As Printed",
  55.     NULL,
  56. };
  57.  
  58. struct TagItem  prcytags[] = {
  59.     {GTCY_Labels,prlabels},
  60.     {TAG_DONE},
  61. };
  62.  
  63.  
  64. /* define gadgetspec */
  65. GadgetSpec PRgadgetspecs[] = 
  66. {
  67.     {CYCLE_KIND,10,0,{0,0,0,0,"_Mode:",NULL, GID_PRPRINTMODE,
  68.         PLACETEXT_LEFT}, prcytags, GS_DefaultTags},
  69.  
  70.     {CHECKBOX_KIND,0,0,{0,0,0,0,"Auto_Void",NULL,GID_PRAUTOVOID,
  71.         PLACETEXT_RIGHT},NULL,GS_DefaultTags},
  72.  
  73.     {INTEGER_KIND,4,0,{0,0,0,0,"Checks _First Sheet:", NULL, GID_PRCHECKPAGE,         
  74.                 PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},
  75.  
  76.     {INTEGER_KIND,4,0,{0,0,0,0,"_Starting Check:", NULL, GID_PRCHECKSTART,         
  77.                 PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},
  78.  
  79.     {BUTTON_KIND,0,0, {0,0,0,0,"_OK",NULL,GID_PROK,
  80.         PLACETEXT_IN},NULL,GS_DefaultTags},
  81.  
  82.     {BUTTON_KIND,0,0, {0,0,0,0,"_Cancel",NULL,GID_PRCANCEL,
  83.         PLACETEXT_IN},NULL,GS_DefaultTags},
  84. };
  85.  
  86. /* set up array of pointers to our specs */
  87. GadgetSpec *PR_PrintSpecs[] =
  88. {
  89.         &PRgadgetspecs[0],
  90.         &PRgadgetspecs[1],
  91.         &PRgadgetspecs[2],
  92.         &PRgadgetspecs[3],
  93.         &PRgadgetspecs[4],
  94.         &PRgadgetspecs[5],
  95.         NULL,
  96. };
  97.  
  98.  
  99. /* define the layout of this panel */
  100. ULONG PR_PrintPanel[] =
  101. {
  102.    GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth,
  103.                                           
  104.     GUIL_HorizGroup, 1,
  105.         GUIL_Flags, GUILF_PropShare | GUILF_EqualHeight,
  106.     GUIL_FrameType, GUILFT_Recess,
  107.  
  108.         GUIL_VertGroup,1,
  109.             GUIL_Flags, GUILF_LabelAlign | GUILF_EqualWidth,
  110.             GUIL_FrameType, GUILFT_Ridge,
  111.             GUIL_FrameHeadline, "Print Options",
  112.     
  113.             GUIL_GadgetSpecID, GID_PRPRINTMODE,
  114.             GUIL_GadgetSpecID, GID_PRCHECKSTART,
  115.         TAG_DONE,
  116.  
  117.         GUIL_VertGroup,1,
  118.             GUIL_Flags, GUILF_EqualWidth,
  119.             GUIL_FrameType, GUILFT_Ridge,
  120.             GUIL_FrameHeadline, "Sheet Feed Options",
  121.  
  122.             GUIL_GadgetSpecID, GID_PRAUTOVOID,
  123.             GUIL_GadgetSpecID, GID_PRCHECKPAGE,
  124.         TAG_DONE,
  125.     TAG_DONE,
  126.     
  127.     GUIL_HorizGroup,1,
  128.         GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
  129.         
  130.            GUIL_GadgetSpecID, GID_PROK,
  131.        GUIL_GadgetSpecID, GID_PRCANCEL,
  132.            
  133.     TAG_DONE,                                  
  134.  TAG_DONE,       
  135. };
  136.  
  137. char amounts[31][10] = {
  138.     "Zero",
  139.     "One",
  140.     "Two",
  141.     "Three",
  142.     "Four",
  143.     "Five",
  144.     "Six",
  145.     "Seven",
  146.     "Eight",
  147.     "Nine",
  148.     "Ten",
  149.     "Eleven",
  150.     "Twelve",
  151.     "Thirteen",
  152.     "Fourteen",
  153.     "Fifteen",
  154.     "Sixteen",
  155.     "Seventeen",
  156.     "Eightteen",
  157.     "Nineteen",
  158.     "Twenty",
  159.     "Thirty",
  160.     "Forty",
  161.     "Fifty",
  162.     "Sixty",
  163.     "Seventy",
  164.     "Eighty",
  165.     "Ninety",
  166.     "Hundred",
  167.     "Thousand",
  168.     "Million",
  169. };
  170.  
  171. /****************************************************
  172. * PrintGUI
  173. *
  174. *    create gui for this panel
  175. *****************************************************/
  176. void PrintGUI(void)
  177. {
  178.  UWORD ordinal;
  179.  BOOL noreply; 
  180.  ULONG signal;
  181.  
  182.    done = FALSE;
  183.  
  184.    AmiLock();
  185.  
  186.    /* bring up this gui */
  187.    GF_SetGUIAttr(printGUI, GUI_OpenGUI, TRUE, TAG_DONE);
  188.    
  189.    /* grab window */
  190.    GF_GetGUIAttr(printGUI,GUI_Window,&printWin,TAG_DONE);
  191.  
  192.    PrintInit();
  193.  
  194.    /* Process input events */
  195.     while (!done)
  196.        {
  197.          struct IntuiMessage *imsg;
  198.                     /* Wait for an event to occur */
  199.  
  200.                     signal = GF_Wait(guiapp,AmigaGuideSignal(agc));
  201.            if (signal & AmigaGuideSignal(agc)) {
  202.             AmiHelpMsg();
  203.             continue;
  204.             }
  205.  
  206.                     /* We only bother to listen for CLOSEWINDOW events.
  207.                      * Of course, in a real application, you would be
  208.                      * examining the Class field for IDCMP_GADGETUP
  209.                      * messages and act accordingly.
  210.                      */
  211.  
  212.                     while (imsg = GF_GetIMsg(guiapp))
  213.                     {
  214.             noreply = TRUE;
  215.                         switch (imsg->Class) {
  216.                 case IDCMP_REFRESHWINDOW:
  217.                     RegRefresh(TRUE);
  218.                     break;
  219.  
  220.                                 case IDCMP_CLOSEWINDOW:
  221.                                         done = TRUE;
  222.                                         break;
  223.  
  224.                 case IDCMP_RAWKEY:
  225.                     AmiHelpKey(imsg,PRINT_PANEL);
  226.                     break;
  227.  
  228.                 case IDCMP_GADGETUP:
  229.                     noreply = FALSE;
  230.                     done=PrintHandleGadget(imsg);
  231.                     break;
  232.  
  233.                 }
  234.  
  235.             if (noreply) GF_ReplyIMsg(imsg);
  236.  
  237.              }
  238.   }
  239.  
  240.   /* close window */
  241.   GF_SetGUIAttr(printGUI, GUI_OpenGUI, FALSE, TAG_DONE);            
  242.   printWin = NULL;
  243.  
  244.   if (printEm == TRUE) 
  245.     PrintGo();
  246.       
  247.   AmiUnlock();
  248. }
  249.  
  250. /***************************************************
  251. * PrintHandleGadget....
  252. *
  253. *     double clicks change ord val.
  254. ****************************************************/
  255. BOOL PrintHandleGadget(struct IntuiMessage *imsg)
  256. {
  257. BOOL done = FALSE;
  258. struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
  259. UWORD code = imsg->Code;
  260. UWORD temp;
  261.  
  262.  switch (gad->GadgetID) {
  263.     case GID_PRAUTOVOID:
  264.         localPrint.autoVoid = code;
  265.         break;
  266.     
  267.     case GID_PRCHECKPAGE:
  268.         temp = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
  269.         if (temp == 0 || temp > checkForms.userForm.checks_page) {
  270.             DisplayBeep(printWin->WScreen);
  271.             DataAnnounce(printGUI, "Checks/page illegal.");
  272.             GF_ReplyIMsg(imsg);
  273.             DataSitNSpin(PR_PrintSpecs[GID_PRCHECKPAGE]->gs_Gadget,printWin);
  274.             return (done);
  275.         }
  276.         else localPrint.checksPage1 = temp;
  277.         break;
  278.     
  279.     case GID_PRCHECKSTART:
  280.         localPrint.checkNumber = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
  281.         break;
  282.  
  283.     case GID_PRPRINTMODE:
  284.         localPrint.printMode = code;
  285.         break;
  286.  
  287.     case GID_PRCANCEL:
  288.         done = TRUE;
  289.         break;
  290.  
  291.     case GID_PROK:
  292.         if (PrintGoodbye(imsg) == TRUE) {
  293.             memcpy(&checkPrint,&localPrint,sizeof(printControl));
  294.             done = TRUE;
  295.             printEm = TRUE;
  296.         }
  297.         else return(FALSE);
  298.         break;
  299.  }
  300.  
  301.  return (done);
  302. }
  303.  
  304. /***********************************************************
  305. * PrintGoodbye()
  306. *
  307. *    collect user input
  308. ************************************************************/
  309. BOOL PrintGoodbye(struct IntuiMessage *imsg)
  310. {
  311.  UWORD val;
  312.  
  313.  val =  (UWORD)((struct StringInfo*)(PR_PrintSpecs[GID_PRCHECKPAGE]->gs_Gadget)->SpecialInfo)->LongInt;
  314.  if (val == 0 || val > checkForms.userForm.checks_page) {
  315.     DisplayBeep(printWin->WScreen);
  316.     DataAnnounce(printGUI, "Checks/page illegal.");
  317.     GF_ReplyIMsg(imsg);
  318.     DataSitNSpin(PR_PrintSpecs[GID_PRCHECKPAGE]->gs_Gadget,printWin);
  319.     return (FALSE);
  320.  }
  321.  localPrint.checksPage1 = val;
  322.  
  323.  localPrint.checkNumber =  (UWORD)((struct StringInfo*)(PR_PrintSpecs[GID_PRCHECKSTART]->
  324.                 gs_Gadget)->SpecialInfo)->LongInt;
  325.  
  326.  return (TRUE);
  327. }
  328.  
  329. /***********************************************************
  330. * PrintInit()
  331. *
  332. *
  333. ************************************************************/
  334. void PrintInit(void)
  335. {
  336.  printEm = FALSE;
  337.  
  338.  memcpy(&localPrint,&checkPrint,sizeof(printControl));
  339.  localPrint.checksPage1 = checkForms.userForm.checks_page;
  340.  
  341.  /* fill in the details */
  342.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRAUTOVOID]->gs_Gadget,
  343.     GTCB_Checked,localPrint.autoVoid,
  344.     TAG_DONE);
  345.  
  346.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRCHECKPAGE]->gs_Gadget,
  347.     GTIN_Number, localPrint.checksPage1,
  348.     TAG_DONE); 
  349.  
  350.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRCHECKSTART]->gs_Gadget,
  351.     GTIN_Number, localPrint.checkNumber,
  352.     TAG_DONE);
  353.  
  354.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRPRINTMODE]->gs_Gadget,
  355.     GTCY_Active,localPrint.printMode,
  356.     TAG_DONE);
  357.  
  358.  /* disable if appropriate */
  359.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRAUTOVOID]->gs_Gadget,
  360.     GA_Disabled,!checkForms.userForm.sheet_feed,
  361.     TAG_DONE);
  362.  
  363.  GF_SetGadgetAttrs (printGUI, PR_PrintSpecs[GID_PRCHECKPAGE]->gs_Gadget,
  364.     GA_Disabled,!checkForms.userForm.sheet_feed,
  365.     TAG_DONE); 
  366. }
  367.  
  368. /***********************************************************
  369. * PrintItem()
  370. *
  371. *    Print a page of checks out ( now wants a filterNode )
  372. ************************************************************/
  373. BOOL PrintItem(FILE *out,filterNode *filt, formControl *form, BOOL test, BOOL page1, int *lastone)
  374. {
  375.  BOOL retval = TRUE;
  376.  int checks;
  377.  entryNode *entry, voidEntry;
  378.  BOOL printpage1 = page1;
  379.  needFeed = TRUE;
  380.  
  381.  /* empty list? */
  382.  if (filt == NULL)
  383.     return (TRUE);
  384.  
  385.  
  386.  if (test == FALSE)
  387.     amiChangedItems = TRUE;
  388.  
  389.  /* begin printing */
  390.  entry = filt->entry;
  391.  
  392.  for (checks = 0;checks < form->userForm.checks_page;checks++) {
  393.  
  394.     /* pre-check voucher? */
  395.     if (form->userForm.voucher_type == VT_ABOVEBELOW || form->userForm.voucher_type == VT_ABOVE) {
  396.         PrintBuildVoucher(entry,&form->userForm,test);
  397.         if (!PrintCheckImage(out,&form->userForm,FALSE, (checks == 0),&page1 ))
  398.             return (FALSE);
  399.     }
  400.  
  401.      /* build & print check image */
  402.     if (form->userForm.voucher_type == VT_LEFTRIGHT)
  403.         PrintBuildVoucher(entry,&form->userForm,test);
  404.  
  405.      PrintBuildImage(entry, &form->userForm,test);
  406.     if (!PrintCheckImage(out,&form->userForm,
  407.             (form->userForm.voucher_type == VT_LEFTRIGHT && checks == form->userForm.checks_page-1),
  408.             (form->userForm.voucher_type != VT_ABOVEBELOW && form->userForm.voucher_type != VT_ABOVE 
  409.                 && checks == 0),&page1)) 
  410.         return(FALSE);
  411.  
  412.     /* post-check voucher? */
  413.     if (form->userForm.voucher_type == VT_ABOVEBELOW || form->userForm.voucher_type == VT_BELOW) {
  414.         PrintBuildVoucher(entry,&form->userForm,test);
  415.         if (!PrintCheckImage(out,&form->userForm,TRUE,FALSE,&page1))
  416.             return(FALSE);
  417.     }
  418.  
  419.     /* double-voucher? */
  420.     else if (form->userForm.voucher_type == VT_TWOBELOW) {
  421.         PrintBuildVoucher(entry,&form->userForm,test);
  422.         if (!PrintCheckImage(out,&form->userForm,FALSE,FALSE,&page1))
  423.             return(FALSE);
  424.         if (!PrintCheckImage(out,&form->userForm,TRUE,FALSE,&page1)) 
  425.             return(FALSE);
  426.     }
  427.  
  428.     /* is there a next check? */
  429.     if (test == FALSE && printpage1 == TRUE && checks == checkPrint.checksPage1-1)    
  430.         break;
  431.     else if (checks == form->userForm.checks_page-1)
  432.         break;
  433.  
  434.     /* grab next node if not test */
  435.     if (test == FALSE) {
  436.  
  437.         /* mark up current one */
  438.         if (filt != NULL) {
  439.             *lastone++;
  440.  
  441.             /* are we done? */
  442.             filt->entry->flags |= PRINTED;
  443.             filt = PrintCheckFind(filt->entry->check+1);
  444.             if (filt != NULL) {
  445.                 if (filt->entry->flags & PRINTED) 
  446.                     filt = NULL;
  447.                 else    entry = filt->entry;
  448.             }
  449.         }
  450.         
  451.         /* test for next step */
  452.         if (filt == NULL) {
  453.             /* if last node, use autovoid? */
  454.             if (checkPrint.autoVoid == TRUE) {
  455.                 /* create autovoid node */
  456.                  PrintAutoVoid(&voidEntry);
  457.                 entry = &voidEntry;
  458.             }
  459.             else    break;
  460.         }
  461.     }
  462.  }
  463.  
  464.  /* spit form out */
  465.  if (form->userForm.sheet_feed) {
  466.      if (fprintf(out,"\f\n") != strlen("\f\n"))
  467.         return (FALSE);
  468.  }
  469.  
  470.  return (retval);
  471. }
  472.  
  473. /***********************************************************
  474. * PrintCheckAlloc()
  475. *
  476. *    Allocate the check field
  477. ************************************************************/
  478. char *PrintCheckAlloc(checkForm *fc)
  479. {
  480.  alloccolumns = fc->columns+1;
  481.  return ( (char *)malloc((fc->lines_check) * (fc->columns+1)));
  482. }
  483.  
  484. /***********************************************************
  485. * PrintCheckImage()
  486. *
  487. *    Print the actual image 
  488. ************************************************************/
  489. BOOL PrintCheckImage(FILE *out,checkForm *form, BOOL lastvoucher, BOOL first, BOOL *page1)
  490. {
  491.  int x,start;
  492.  int cols,lines = form->lines_check;
  493.  
  494.  PrintClipImage();
  495.  
  496.  if (form->sheet_feed == TRUE) {
  497.      if (first == TRUE) 
  498.         start = form->top_lines;
  499.      else    start = 0;
  500.  }
  501.  else {
  502.     if (*page1 == TRUE) {
  503.         start = form->top_lines;
  504.         *page1 = FALSE;
  505.     }
  506.     else    start = 0;
  507.  }
  508.  
  509.  for (x=start;x<lines;x++) {
  510.         
  511.    /* fix the length up */
  512.    cols = strlen(&CHECKGRID(x,0));
  513.    if (cols > form->columns)
  514.         cols = form->columns;
  515.    if (cols < MAXCHECKCOLS) {
  516.         CHECKGRID(x,cols)=0;
  517.    }
  518.  
  519.     if (lastvoucher && x == lines-1)
  520.         sprintf(tempstr,"%s",&CHECKGRID(x,0));
  521.     else    sprintf(tempstr,"%s\n",&CHECKGRID(x,0));
  522.    
  523.     if (fprintf(out,tempstr) != strlen(tempstr))
  524.         return (FALSE);
  525.  }
  526.  
  527.  if (lastvoucher && strlen(tempstr) > 1)
  528.     needFeed = FALSE;
  529.  
  530.  return (TRUE);
  531. }
  532.  
  533. /***********************************************************
  534. * PrintBuildVoucher()
  535. *
  536. *    Build a voucher
  537. ************************************************************/
  538. void PrintBuildVoucher(entryNode *entry, checkForm *form, BOOL test)
  539. {
  540.  char str[STRINGSIZE];
  541.  int x,y,z;
  542.  int len;
  543.  int vwidth = form->columns-1;
  544.  int vmargin = (form->columns < 5)?form->columns:5;
  545.  int vline = 5;
  546.  int off = 1;
  547.  
  548.  /* only do voucher if requested */
  549.  if (form->voucher_type == VT_NONE)
  550.     return;
  551.  
  552.  if (form->voucher_type == VT_LEFTRIGHT) {
  553.     vwidth = form->voucher_width;
  554.     vmargin = form->voucher_margin;
  555.  }
  556.  
  557.  /* build the page image */
  558.  for (y=0;y<form->lines_check;y++) {
  559.     /* initialize the check */
  560.     memset(&CHECKGRID(y,0),' ',form->columns);
  561.     CHECKGRID(y,form->columns)=0;
  562.  
  563.     /* fill test data */
  564.     if (test == TRUE) {
  565.         if (y == 0) {
  566.             for (x=0;x<form->columns;x++)
  567.                 CHECKGRID(y,x) = ('0'+ (x%10));
  568.         }
  569.         else if (y == form->lines_check-1) {
  570.             for (x=0;x<form->columns;x++)
  571.                 CHECKGRID(y,x) = ('0'+ (x%10));
  572.         }
  573.         
  574.         CHECKGRID(y,0) = ('0'+(y%10));
  575.     }
  576.  
  577.     for (x=0;x<form->columns;x++) {
  578.         /* amount */
  579.         if (y==(2*off)+vline && vmargin == x) {
  580.             DataBuildAmnt(TRUE,&entry->amount,str);
  581.             len = strlen(str);
  582.             if (len > vwidth) len = vwidth;
  583.             if (len > form->columns-x) len = form->columns-x;
  584.  
  585.             for (z=0;z<len;z++){
  586.                 CHECKGRID(y,x+z)=str[z];
  587.             }
  588.         }
  589.  
  590.         /* date */
  591.         if (y==(0*off)+vline && vmargin == x) {
  592.             DataBuildDate(&entry->date,str);
  593.             len = strlen(str);
  594.             if (len > vwidth) len = vwidth;
  595.             if (len > form->columns-x) len = form->columns-x;
  596.  
  597.             for (z=0;z<len;z++){
  598.                 CHECKGRID(y,x+z)=str[z];
  599.             }
  600.         }
  601.  
  602.         /* name */
  603.         if (y==(1*off)+vline && vmargin == x) {
  604.             len = strlen(entry->name);
  605.             if (len > vwidth) len = vwidth;
  606.             if (len > form->columns-x) len = form->columns-x;
  607.  
  608.             for (z=0;z<len;z++){
  609.                 CHECKGRID(y,x+z)=entry->name[z];
  610.             }
  611.         }
  612.  
  613.         /* memo */
  614.         if (y==(3*off)+vline && vmargin == x) {
  615.             len = strlen(entry->memo);
  616.             if (len > vwidth) len = vwidth;
  617.             if (len > form->columns-x) len = form->columns-x;
  618.  
  619.             for (z=0;z<len;z++){
  620.                 CHECKGRID(y,x+z)=entry->memo[z];
  621.             }        
  622.         }
  623.  
  624.         /* category */
  625.         if (y==(4*off)+vline && vmargin == x) {
  626.             len = strlen(entry->category);
  627.             if (len > vwidth) len = vwidth;
  628.             if (len > form->columns-x) len = form->columns-x;
  629.  
  630.             for (z=0;z<len;z++){
  631.                 CHECKGRID(y,x+z)=entry->category[z];
  632.             }        
  633.         }
  634.  
  635.         /* state */
  636.         if (y==(4*off)+1+vline && vmargin == x) {
  637.             strcpy(str,"****");
  638.             if (entry->flags & CLEARED) str[2]='C';
  639.             if (entry->flags & VOIDED)  str[0]='V';
  640.             if (entry->flags & TAXDEDUCT) str[1]='T';
  641.             if (entry->flags & RECONCILED) str[3]='R';
  642.  
  643.             len = strlen(str);
  644.             if (len > vwidth) len = vwidth;
  645.             if (len > form->columns-x) len = form->columns-x;
  646.  
  647.             for (z=0;z<len;z++){
  648.                 CHECKGRID(y,x+z)=str[z];
  649.             }        
  650.         }
  651.  
  652.         if (y<=(4*off)+1+vline && (test == TRUE && form->columns-x > len ) && y >= vline)
  653.             for (z=len;z+x<vwidth && z < form->columns-x;z++)
  654.                 CHECKGRID(y,x+z)='*';
  655.     }
  656.  }
  657.  
  658. }
  659.  
  660. /***********************************************************
  661. * PrintClipImage()
  662. *
  663. *    Clip excess spaces
  664. ************************************************************/
  665. void PrintClipImage(void)
  666. {
  667. #if 0
  668.  int x,y;
  669.  
  670.  for (y=0;y<MAXCHECKLINES;y++)
  671.     for (x=form->columns-1;x>=0;x--) 
  672.         if (CHECKGRID(y,x) != ' ') {
  673.             CHECKGRID(y,x+1)=0;
  674.             break;
  675.         }
  676. #endif
  677. }
  678.  
  679. /***********************************************************
  680. * PrintBuildImage()
  681. *
  682. *    Build the check image
  683. ************************************************************/
  684. void PrintBuildImage(entryNode *entry, checkForm *form,BOOL test)
  685. {
  686.  char str[STRINGSIZE];
  687.  int x,y,z,t;
  688.  int len;
  689.  
  690.  /* build the page image */
  691.  for (y=0;y<form->lines_check;y++) {
  692.     /* initialize the check */
  693.     if (form->voucher_type != VT_LEFTRIGHT) memset(&CHECKGRID(y,0),' ',form->columns);
  694.     CHECKGRID(y,form->columns)=0;
  695.  
  696.     /* fill test data */
  697.     if (test == TRUE && form->voucher_type != VT_LEFTRIGHT) {
  698.         if (y == 0) {
  699.             for (x=0;x<form->columns;x++)
  700.                 CHECKGRID(y,x) = ('0'+ (x%10));
  701.         }
  702.         else if (y == form->lines_check-1) {
  703.             for (x=0;x<form->columns;x++)
  704.                 CHECKGRID(y,x) = ('0'+ (x%10));
  705.         }
  706.         
  707.         CHECKGRID(y,0) = ('0'+(y%10));
  708.     }
  709.  
  710.     for (x=0;x<form->columns;x++) {
  711.  
  712.         /* amount */
  713.         if (form->amnt_line == y && form->amnt_margin == x) {
  714.             if (entry->flags & VOIDED || entry->amount == 0 )
  715.                 strcpy(str,"0.00");
  716.             else     DataBuildAmnt(TRUE,&entry->amount,str);
  717.             len = strlen(str);
  718.  
  719.             /* right justify */
  720.             memset(tempstr,' ',form->columns);
  721.             tempstr[form->columns]=0;
  722.             
  723.             if (len > form->amnt_width) len = form->amnt_width;
  724.             if (len > form->columns-x) len = form->columns-x;
  725.  
  726.             t=form->amnt_width<form->columns-x?form->amnt_width:form->columns-x;
  727.             if (len > 0) {    
  728.                 if (test == TRUE)
  729.                     memset(tempstr,'*',t);
  730.  
  731.                 for (z=0;z<len;z++)
  732.                     tempstr[t-z-1]=str[strlen(str)-z-1]; 
  733.  
  734.                 for (z=0;z<t;z++){
  735.                     CHECKGRID(y,x+z)=tempstr[z];
  736.                 }
  737.  
  738.             }
  739.         }
  740.  
  741.         /* date */
  742.         if (form->date_line == y && form->date_margin == x) {
  743.             DataBuildDate(&entry->date,str);
  744.             len = strlen(str);
  745.             if (len > form->date_width) len = form->date_width;
  746.             if (len > form->columns-x) len = form->columns-x;
  747.  
  748.             for (z=0;z<len;z++){
  749.                 CHECKGRID(y,x+z)=str[z];
  750.             }
  751.  
  752.             if (test == TRUE && form->columns-x > len)
  753.                 for (z=len;z<form->date_width && z < form->columns-x;z++)
  754.                     CHECKGRID(y,x+z)='*';
  755.  
  756.         }
  757.  
  758.         /* name */
  759.         if (form->pay_line == y && form->pay_margin == x) {
  760.             if (entry->flags & VOIDED)
  761.                 strcpy(str,"VOIDED CHECK");
  762.             else    strcpy(str,entry->name);
  763.  
  764.             len = strlen(str);
  765.             if (len > form->pay_width) len = form->pay_width;
  766.             if (len > form->columns-x) len = form->columns-x;
  767.  
  768.             for (z=0;z<len;z++){
  769.                 CHECKGRID(y,x+z)=str[z];
  770.             }
  771.  
  772.             if (test == TRUE && form->columns-x > len)
  773.                 for (z=len;z<form->pay_width && z < form->columns-x;z++)
  774.                     CHECKGRID(y,x+z)='*';
  775.  
  776.         }
  777.  
  778.         /* memo */
  779.         if (form->memo_line == y && form->memo_margin == x) {
  780.             if (entry->flags & VOIDED)
  781.                 strcpy(str,entry->name);    
  782.             else     strcpy(str,entry->memo);
  783.  
  784.             len = strlen(str);
  785.             if (len > form->memo_width) len = form->memo_width;
  786.             if (len > form->columns-x) len = form->columns-x;
  787.  
  788.             for (z=0;z<len;z++){
  789.                 CHECKGRID(y,x+z)=str[z];
  790.             }        
  791.  
  792.             if (test == TRUE && form->columns-x > len)
  793.                 for (z=len;z<form->memo_width && z < form->columns-x;z++)
  794.                     CHECKGRID(y,x+z)='*';
  795.         }
  796.  
  797.         /* amnt string */
  798.         if (form->str_line == y && form->str_margin == x) {
  799.             PrintBuildAmntStr(entry,tempstr);
  800.             len = strlen(tempstr);
  801.             if (len > form->str_width) len = form->str_width;
  802.             if (len > form->columns-x) len = form->columns-x;
  803.  
  804.             for (z=0;z<len;z++){
  805.                 CHECKGRID(y,x+z)=tempstr[z];
  806.             }        
  807.  
  808.             if (form->columns-x > len)
  809.                 for (z=len;z<form->str_width && z < form->columns-x;z++)
  810.                     CHECKGRID(y,x+z)='*';
  811.  
  812.         }
  813.  
  814.     }
  815.  }
  816.  
  817. }
  818.  
  819. /****************************************************************
  820. * PrintBuildAmntStr()
  821. *
  822. *    build the amount text
  823. *****************************************************************/
  824. void PrintBuildAmntStr(entryNode *entry, char *dest)
  825. {
  826.  ULONG places[4][2];
  827.  ULONG temp;
  828.  int ctr;
  829.  int tens;
  830.  ULONG dollar = entry->amount/100;
  831.  ULONG cent = entry->amount%100;
  832.  BOOL place = FALSE;
  833.  
  834.  if (entry->flags & VOIDED) {
  835.     dollar = 0;
  836.     cent = 0;
  837.  }
  838.  
  839.  temp = dollar;
  840.  
  841.  /* record the places */
  842.  for (ctr=0;ctr<4;ctr++) {
  843.     places[ctr][0] =  temp%1000;
  844.     places[ctr][1] =  places[ctr][0]%100;
  845.     places[ctr][0] -= places[ctr][1];
  846.     places[ctr][0] /= 100; /* move places over */
  847. #if 0
  848.     places[ctr][2] = places[ctr][1] % 10;
  849.     places[ctr][1] -= places[ctr][2];
  850.     places[ctr][1] /= 10; /* move places over */
  851. #endif
  852.  
  853.     temp /= 1000;
  854.  }
  855.  
  856.  if (temp > 0) {
  857.     sprintf(dest,"ERROR: AMOUNT TOO LARGE");
  858.     return;
  859.  }
  860.  
  861.  /* spit it out */
  862.  for (ctr=3;ctr>=0; ctr--) {
  863.     if (places[ctr][0] != 0) {
  864.         sprintf(dest,"%s %s ",amounts[places[ctr][0]],amounts[28]);
  865.         dest += strlen(dest);
  866.         place = TRUE;
  867.     }
  868.     if (places[ctr][1] != 0) {
  869.         if (places[ctr][1] > 19) {
  870.             tens = places[ctr][1] / 10;
  871.             sprintf(dest,"%s",amounts[20+tens-2]);
  872.             dest += strlen(dest);
  873.             if (places[ctr][1]%10)
  874.                 sprintf(dest,"-%s ",amounts[places[ctr][1]%10]);
  875.             else     sprintf(dest," ");
  876.             dest += strlen(dest);
  877.         }
  878.         else     {
  879.             sprintf(dest,"%s ",amounts[places[ctr][1]]);
  880.             dest += strlen(dest);
  881.         }
  882.         place = TRUE;
  883.  
  884.     }
  885.  
  886.     if (place == TRUE && ctr >= 1) {
  887.         sprintf(dest,"%s ",amounts[29+ctr-1]);
  888.         dest += strlen(dest);
  889.     }
  890.     place = FALSE;
  891.  }
  892.  
  893.  /* check again for zero */
  894.  if (dollar == 0) {
  895.     sprintf(dest,"zero ");
  896.      dest += strlen("zero ");
  897.  }
  898.  
  899.  /* stuff in cents */
  900.  if (cent > 0) 
  901.     sprintf(dest,"+ %d/100 ",entry->amount%100);
  902.  else    sprintf(dest,"+ zero/100 ");
  903. }
  904.  
  905. /********************************************************************
  906. * PrintAutoVoid()
  907. *
  908. *    Handle voiding checks
  909. *********************************************************************/
  910. void PrintAutoVoid(entryNode *entry)
  911. {
  912.  filterNode *filt = NULL;
  913.  
  914.  entry->flags = VOIDED | PRINTED;
  915.  entry->type = CHECKTYPE;
  916.  entry->amount = 0;
  917.  memcpy(&entry->date,&currDate,sizeof(dateType));
  918.  strcpy(entry->name,"AUTOVOIDED");
  919.  strcpy(entry->memo,"Check Printed");
  920.  strcpy(entry->category,"None");
  921.  
  922.  entry->check = amntState.currCheckNumber;
  923.  
  924.  /* bump up and insert! */
  925.  amntState.currCheckNumber++;
  926.  DataAddEntry(entry,&entries,&filt); 
  927.  
  928.  if (filt != NULL) {
  929.     RegAddEntry(filt);
  930.     AmiDisableSel(TRUE);
  931.  }
  932. }
  933.  
  934. /********************************************************************
  935. * PrintGo()
  936. *
  937. *    Print checks or mark as needed
  938. *********************************************************************/
  939. void PrintGo(void)
  940. {
  941.  filterNode *filt = NULL;
  942.  int curr = checkPrint.checkNumber;
  943.  int lastcheck=curr,firstcheck=curr;
  944.  FILE *out;
  945.  char msg[100];
  946.  BOOL fail=FALSE,first = TRUE;
  947.  
  948.  if (usrAccount.decimal != 2) {
  949.     AmiAnnounce("Printing requires two-decimal amounts.\nIf you need otherwise please contact me.");
  950.     return;
  951.  }
  952.  
  953.  /* find first non-printed check */
  954.  while ( (filt = PrintCheckFind(curr)) != NULL && filt->entry->flags & PRINTED) {
  955.         curr++;
  956.         continue;
  957.  }
  958.  
  959.  if (filt == NULL)
  960.     return;
  961.  
  962.  /* now open the check device */
  963.  if ( (out = fopen(checkForms.device,"w")) == NULL) {
  964.     AmiAnnounce("Device Failure.\nCannot open device.");
  965.     return;
  966.  }
  967.  
  968.  GF_LockGUI(printGUI);
  969.  
  970.  
  971.  /* allocate the check */
  972.  if (!(checkImage = PrintCheckAlloc(&checkForms.userForm))) {
  973.     AmiAnnounce("Could not allocate RAM for check printing");
  974.     return;
  975.  }
  976.  
  977.  
  978.  /* now, from here lets print! */
  979.  do {
  980.     if (filt->entry->flags & PRINTED)
  981.         break;
  982.  
  983.     /* print or mark? */
  984.     if (checkPrint.printMode == 0) {
  985.             
  986.             if (!PrintItem(out,filt,&checkForms,FALSE,first,&lastcheck)) {            
  987.                 fail=TRUE;
  988.                 break;
  989.             }
  990.             first = FALSE;
  991.  
  992.             /* bump forward xxx times */
  993.             curr += checkForms.userForm.checks_page-1;
  994.             lastcheck = curr;
  995.     }
  996.     else filt->entry->flags |= PRINTED;
  997.  
  998.     curr++;
  999.  
  1000.  } while ( (filt = PrintCheckFind(curr)) != NULL);
  1001.  
  1002.  /* free up check image */
  1003.  free (checkImage);
  1004.  
  1005.  GF_UnlockGUI(printGUI); 
  1006.  fclose(out);
  1007.  
  1008.  if (fail) {
  1009.     AmiAnnounce("Printer Failure.\nOperation cancelled.");
  1010.  
  1011.      if (firstcheck == lastcheck)
  1012.         sprintf(msg,"Printing Information:\nStarting Check: %d\nNo checks printed.",firstcheck);
  1013.  }
  1014.  else    sprintf(msg,"Printing Information:\nStarting Check: %d\nEnding Check: %d",firstcheck,lastcheck);
  1015.  
  1016.  if (strlen(msg))
  1017.      AmiAnnounce(msg);
  1018.  msg[0]=0;
  1019. }
  1020.  
  1021. /********************************************************************
  1022. * PrintCheckFind()
  1023. *
  1024. *    Find the next check to print
  1025. *********************************************************************/
  1026. filterNode *PrintCheckFind(int check)
  1027. {
  1028.  filterNode *filt = NULL;
  1029.  
  1030.  while ( (filt = (filterNode *)DataGetNext((struct List *)&filtered,(struct Node *)filt)) != NULL)
  1031.     if (filt->entry->type == CHECKTYPE && filt->entry->check == check) {
  1032. /*
  1033.         if (filt->entry->flags & PRINTED)
  1034.             return (NULL);
  1035. */
  1036.  
  1037.         return (filt);
  1038.     }
  1039.  
  1040.  return (NULL);
  1041. }
  1042.