home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / repease / rep_sec.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  16KB  |  438 lines

  1. /*==============================================================================
  2.    REP_SEC.C
  3.    Report Ease: Section related functions.
  4.  
  5.    ReportEase Plus
  6.    Sub Systems, Inc.
  7.    ReportEase Plus, Copyright (c) 1993, Sub Systems, Inc. All Rights Reserved.
  8.    159 Main Street, #8C, Stoneham,  MA 02180 
  9.    (617) 438-8901.
  10.  
  11.    Software License Agreement  (1993)              
  12.    ----------------------------------
  13.    This license agreement allows the purchaser the right to modify the 
  14.    source code to incorporate in their application.
  15.    The target application must not be distributed as a standalone report writer
  16.    or a mail merge product.
  17.    Sub Systems, Inc. reserves the right to prosecute anybody found to be 
  18.    making illegal copies of the executable software or compiling the source
  19.    code for the purpose of selling there after.
  20.  
  21. ===============================================================================*/
  22. #include "windows.h"
  23.  
  24. #if defined (_WIN32)
  25.    #if !defined(WIN32)
  26.      #define WIN32
  27.    #endif
  28. #endif
  29. #if !defined(WIN32) 
  30.   #include "print.h"
  31. #endif
  32.  
  33. #include "stdio.h"
  34. #include "stdlib.h"
  35. #include "ctype.h"
  36. #include "fcntl.h"
  37. #include "io.h"
  38. #include "sys\types.h"
  39. #include "sys\stat.h"
  40. #include "string.h"
  41. #include "setjmp.h"
  42.  
  43. #include "rep.h"
  44.  
  45. #define  PREFIX extern
  46. #include "rep1.h"
  47.  
  48.  
  49. /******************************************************************************
  50.     NewSection:
  51.     Insert a new section in the report.
  52. ******************************************************************************/
  53. NewSection()
  54. {
  55.     LPSTR SecName[MAX_SECTIONS];
  56.     int   count=0,i,select,SecIdx[MAX_SECTIONS],SecHdr,NewSection,
  57.           CurItem,PrevSec,PrevItem;
  58.     int    FieldIndex;
  59.     struct StrField GroupField;
  60.  
  61.     if (TotalItems>=MAX_ITEMS) {  // check for item table space
  62.        MessageBox(hFrWnd,"Item Table Full!",NULL,MB_OK);
  63.        return TRUE;
  64.     }
  65.  
  66.     // deselect currently selected item
  67.     if (SelItem>=0) DeselectItem();// deselect the current item
  68.  
  69.     // build an array of sections to choose from 
  70.     for (i=0;i<MAX_SECTIONS;i++) {
  71.         if (!section[i].InUse) {
  72.             // Select the header sections
  73.             if (i>SEC_HDR_LVL1 && i<=SEC_HDR_LVL9) {
  74.                if (section[i-1].InUse) {    // select only if lower section selected 
  75.                    SecIdx[count]=i;         // selected index 
  76.                    SecName[count]=(LPSTR)SectionName[i];
  77.                    count++;
  78.                }
  79.                continue;
  80.             }
  81.             // Select the detail sections
  82.             if (i>SEC_DETAIL1 && i<=SEC_DETAIL9) {
  83.                if (section[i-1].InUse && section[i-1].columns==1) { // select only if previous detail selected and uses one column only
  84.                    SecIdx[count]=i;         // selected index 
  85.                    SecName[count]=(LPSTR)SectionName[i];
  86.                    count++;
  87.                }
  88.                continue;
  89.             }
  90.             // Select the footer sections
  91.             if (i>=SEC_FTR_LVL9 && i<=SEC_FTR_LVL1) {
  92.                SecHdr=SEC_HDR_LVL1+8-(i-SEC_FTR_LVL9);
  93.                if (section[SecHdr].InUse) { // select only if the section header selected 
  94.                    SecIdx[count]=i;         // selected index 
  95.                    SecName[count]=SectionName[i];
  96.                    count++;
  97.                }
  98.                continue;
  99.             }
  100.             SecIdx[count]=i;                // selected index 
  101.             SecName[count]=SectionName[i];
  102.             count++;
  103.         }
  104.     }
  105.  
  106.     SecName[count]=NULL;
  107.  
  108.     if ((select=CallDialogBox("NewSecParam",NewSecParam,(DWORD)(LPSTR)SecName))<0) return FALSE;
  109.  
  110.     NewSection=SecIdx[select];        // section number to insert 
  111.  
  112.     //*** get the sorting field for a group break sections ***
  113.     if (NewSection>=SEC_HDR_LVL1 && NewSection<=SEC_HDR_LVL9) {   // select a group sort field 
  114.         
  115.         // ACCEPT GROUP FIELD
  116.         InitField(&GroupField);       // initialize the field variables 
  117.         GroupField.section=NewSection;
  118.         
  119.         if (!(FormArg.UserSelection)(hFrWnd,&GroupField,NewSection-SEC_HDR_LVL1+1)) return FALSE;  // call a user routine to select a data field  
  120.         
  121.         //****************** Find room for the Sort field *********
  122.         if (END_OF_EXP==(FieldIndex=FindFieldSlot())) {
  123.            MessageBox(hFrWnd,"Ran out of field table!",NULL,MB_OK);
  124.            return FALSE;
  125.         }
  126.  
  127.         // copy the field into the current array position 
  128.         field[FieldIndex]=GroupField;
  129.         BreakField[TotalBreakFields].SortField=FieldIndex;
  130.  
  131.         //****************** Find room for the Comparision field *********
  132.         if (END_OF_EXP==(FieldIndex=FindFieldSlot())) {
  133.            MessageBox(hFrWnd,"Ran out of field table!",NULL,MB_OK);
  134.            return FALSE;
  135.         }
  136.  
  137.         // copy the field into the current array position 
  138.         field[FieldIndex]=GroupField;
  139.         BreakField[TotalBreakFields].CompField=FieldIndex;
  140.  
  141.         // update the break field structure 
  142.         BreakField[TotalBreakFields].section=NewSection;
  143.         TotalBreakFields++;
  144.     }
  145.  
  146.     // find the item number before which to insert this section 
  147.     for (i=0;i<TotalItems;i++) if (item[i].section>NewSection) break;
  148.     if (i<TotalItems) {
  149.        CurItem=i;
  150.        MoveItemArray(CurItem,1,'B');  // scoll down other items;
  151.     }
  152.     else {
  153.        CurItem=TotalItems;
  154.        TotalItems++;
  155.     }
  156.  
  157.     // create the section item
  158.     InitItem(&item[CurItem]);
  159.     item[CurItem].type=SECTION;
  160.     item[CurItem].section=NewSection;
  161.     item[CurItem].x=(int)(FormHdr.LeftMargin*UNITS_PER_INCH);
  162.     if (CurItem==0) item[CurItem].y=0;
  163.     else {                                 // locate the previous section to get the current Y
  164.        PrevSec=item[CurItem-1].section;
  165.        PrevItem=section[PrevSec].ScrItem;  // item number for the previous section
  166.        item[CurItem].y=item[PrevItem].y+item[PrevItem].height;
  167.     }           
  168.     item[CurItem].width=FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin));
  169.     item[CurItem].height=DEF_SEC_HEIGHT;
  170.     
  171.     // set the current section array element
  172.     section[NewSection].InUse=TRUE;        // define the page header
  173.     section[NewSection].ScrItem=CurItem;   // reference to the item
  174.     section[NewSection].SelExp[0]=END_OF_EXP;
  175.     section[NewSection].flags=0;
  176.  
  177.     // adjust the Y position of the remaining items
  178.     for (i=CurItem+1;i<TotalItems;i++) {
  179.        item[i].y+=item[CurItem].height;
  180.     }
  181.     FrHeight+=item[CurItem].height;        // adjust the form height
  182.  
  183.     SelItem=CurItem;                       // select the current section
  184.     FrWinOrgY=item[CurItem].y-(FrWinHeight-item[CurItem].height)/2;  // show new section at the center
  185.     FrPaint();
  186.     FrModified=TRUE;
  187.  
  188.     return TRUE;
  189. }
  190.  
  191. /******************************************************************************
  192.     EditSection:
  193.     Edit Section Parameters.
  194. ******************************************************************************/
  195. EditSection()
  196. {
  197.     if (SelItem<0) return TRUE;
  198.  
  199.     DlgIndex=item[SelItem].section;     // pass the section number to the dialog box 
  200.  
  201.     if (CallDialogBox("EditSecParam",EditSecParam,0L)) {
  202.        // recalculate the section width
  203.        if (DlgIndex==SEC_DETAIL1) item[SelItem].width=(FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin)))/section[DlgIndex].columns;
  204.        FrPaint();
  205.     }
  206.     return TRUE;
  207. }
  208.  
  209. /******************************************************************************
  210.     DeleteSection:
  211.     Delete the current section from the report.
  212. ******************************************************************************/
  213. DeleteSection()
  214. {
  215.     int CurSec,CurItem,height,i,count,HdrBreakNo,FtrBreakNo;
  216.              
  217.     CurSec=item[SelItem].section;   // section to delete
  218.  
  219.     // Last section check
  220.     count=0;
  221.     for (i=0;i<MAX_SECTIONS;i++) if (i!=CurSec && section[i].InUse) count++;
  222.     if (count==0) {
  223.        MessageBox(hFrWnd,"Can not delete the last section!",NULL,MB_OK);
  224.        return FALSE;
  225.     }
  226.  
  227.     // Detail section check
  228.     if (CurSec>=SEC_DETAIL1 && CurSec<SEC_DETAIL9 && section[CurSec+1].InUse) {
  229.        MessageBox(hFrWnd,"Must Delete all Higher Detail Sections First!",NULL,MB_OK);
  230.        return FALSE;
  231.     }
  232.  
  233.     // Validate for group header fields 
  234.     if (CurSec>=SEC_HDR_LVL1 && CurSec<=SEC_HDR_LVL9) {
  235.        HdrBreakNo=CurSec-SEC_HDR_LVL1;
  236.        FtrBreakNo=SEC_FTR_LVL1-HdrBreakNo;
  237.        if (section[FtrBreakNo].InUse) {
  238.           MessageBox(hFrWnd,"Must Delete the Group Footer Before Deleting the Group Header Section!",NULL,MB_OK);
  239.           return FALSE;
  240.        }
  241.        if (BreakField[TotalBreakFields-1].section!=CurSec) {
  242.           MessageBox(hFrWnd,"Must Delete all Higher Group Sections Before Deleting This Section",NULL,MB_OK);
  243.           return FALSE;
  244.        }
  245.     }
  246.  
  247.     // Delete confirmation
  248.     wsprintf(msg,"Delete Current Section: %s? ",(LPSTR)SectionName[CurSec]);
  249.     if (IDNO==MessageBox(hFrWnd,msg,"Confirmation",MB_YESNO)) return FALSE;
  250.  
  251.     // Delete all items within the section
  252.     PaintEnabled=FALSE;             // suspend painting until the whole operation is over
  253.     while (TRUE) {
  254.        for (i=0;i<TotalItems;i++) {
  255.          if (item[i].type!=SECTION && item[i].type!=GROUP && item[i].section==CurSec) break;
  256.        }
  257.        if (i==TotalItems) break;    // items deleted
  258.        SelItem=i;
  259.        DeleteItem();                // delete this item;
  260.     }
  261.  
  262.     // Delete the section item
  263.     for (i=0;i<TotalItems;i++) if (item[i].type==SECTION && item[i].section==CurSec) break;
  264.     if (i==TotalItems) AbortFr("Section Not Found!(DeleteSection)",ERR_OTHER);
  265.     CurItem=i;
  266.     height=item[CurItem].height;          // save the section height
  267.     FrEraseFocusRect(hFrDC,&CursRect); 
  268.     MoveItemArray(CurItem,1,'D');         // delete and scroll the item array
  269.  
  270.     // scroll up the remaining items;
  271.     for (i=CurItem;i<TotalItems;i++) {
  272.        item[i].y-=height;
  273.        if (item[i].y<0) item[i].y=0;
  274.     }
  275.     FrHeight-=height;                    // reduce the form height
  276.  
  277.     // relocate the group item to the first section
  278.     for (i=0;i<TotalItems;i++) if (item[i].type==GROUP) break;
  279.     if (i==TotalItems) AbortFr("Group Item Not Found!(DeleteSection)",ERR_OTHER);
  280.     if (item[i].section==CurSec) { // relocate to the top of the form
  281.        MoveEachItem(i,item[0].x-item[i].x,item[0].y-item[i].y+FormHdr.SecBannerHeight);
  282.     }
  283.  
  284.     //*** delete the group sort and comparision fields **
  285.     if (CurSec>=SEC_HDR_LVL1 && CurSec<=SEC_HDR_LVL9) {
  286.         DeleteField(BreakField[TotalBreakFields-1].SortField);
  287.         DeleteField(BreakField[TotalBreakFields-1].CompField);
  288.         TotalBreakFields--;
  289.     }
  290.  
  291.     //***** Release the selection expression symbols ****
  292.     ReleaseSymbols(section[CurSec].SelExp);
  293.     section[CurSec].SelExp[0]=END_OF_EXP;
  294.  
  295.     section[CurSec].InUse=FALSE;
  296.  
  297.     SelItem=-1;                    // Deselect all items
  298.  
  299.     PaintEnabled=TRUE;             // refresh the screen
  300.     FrPaint();
  301.     
  302.     return TRUE;
  303. }
  304.  
  305. /******************************************************************************
  306.     EditSectionFilter:
  307.     Edit section selection criteria.
  308. ******************************************************************************/
  309. EditSectionFilter()
  310. {
  311.     int CurSec,i;
  312.     int NewExp[NAME_WIDTH+2];
  313.  
  314.     CurSec=item[SelItem].section;
  315.  
  316.     if (ModifyExp(section[CurSec].SelExp,NewExp,"Section Selection Criteria",EXP_PARM)!=-1) {
  317.        i=0;
  318.        while(NewExp[i]!=END_OF_EXP) {
  319.           section[CurSec].SelExp[i]=NewExp[i];
  320.           i++;
  321.        }
  322.        section[CurSec].SelExp[i]=NewExp[i];
  323.     }
  324.  
  325.     return TRUE;
  326. }
  327.  
  328. /******************************************************************************
  329.     EditSectionSort:
  330.     Edit section sort field.  Section sort fields are application for
  331.     sort header sections only.
  332. ******************************************************************************/
  333. EditSectionSort()
  334. {
  335.     int i,CurSec,SortFieldIndex,BreakFieldIndex;
  336.     BOOL IdenticalFields;
  337.  
  338.     CurSec=item[SelItem].section;
  339.  
  340.     if (CurSec<SEC_HDR_LVL1 || CurSec>SEC_HDR_LVL9) return FALSE;
  341.     
  342.     for (i=0;i<TotalBreakFields;i++) if (BreakField[i].section==CurSec) {
  343.        SortFieldIndex=BreakField[i].SortField;
  344.        BreakFieldIndex=BreakField[i].CompField;
  345.        break;
  346.     }
  347.     if (i==TotalBreakFields) {
  348.        AbortFr("Invalid Section, File Corruption Detected!",10);
  349.     }
  350.  
  351.     DlgIndex=SortFieldIndex;        // pass the section sort field number using the global variable 
  352.     
  353.     //***** check if sort and break field are identical *****
  354.     IdenticalFields=FALSE;
  355.     if (lstrcmp(field[SortFieldIndex].name,field[BreakFieldIndex].name)==0) IdenticalFields=TRUE;
  356.  
  357.     if (CallDialogBox("SecSortParam",SecSortParam,(DWORD)CurSec)) {
  358.        if (IdenticalFields) {       // change the break field as well 
  359.           lstrcpy(field[BreakFieldIndex].name,field[SortFieldIndex].name);
  360.           field[BreakFieldIndex].type=field[SortFieldIndex].type;
  361.           field[BreakFieldIndex].width=field[SortFieldIndex].width;
  362.           field[BreakFieldIndex].DecPlaces=field[SortFieldIndex].DecPlaces;
  363.           field[BreakFieldIndex].FileId=field[SortFieldIndex].FileId;
  364.           field[BreakFieldIndex].FieldId=field[SortFieldIndex].FieldId;
  365.        }
  366.     }
  367.  
  368.     return TRUE;
  369. }
  370.  
  371. /******************************************************************************
  372.     EditSectionBreak:
  373.     Edit section break field.  A section break occurs when the corresponding
  374.     section break field value changes.
  375. ******************************************************************************/
  376. EditSectionBreak()
  377. {
  378.     int i,CurSec,BreakFieldIndex,SortFieldIndex,SecLevel,ExpType,ResultType;
  379.     int NewExp[NAME_WIDTH+2];
  380.  
  381.     CurSec=item[SelItem].section;
  382.  
  383.     if (CurSec<SEC_HDR_LVL1 || CurSec>SEC_HDR_LVL9) return FALSE;
  384.     
  385.     for (i=0;i<TotalBreakFields;i++) if (BreakField[i].section==CurSec) {
  386.        BreakFieldIndex=BreakField[i].CompField;
  387.        SortFieldIndex=BreakField[i].SortField;
  388.        SecLevel=i+1;
  389.        break;
  390.     }
  391.     if (i==TotalBreakFields) {
  392.        AbortFr("Invalid Section, File Corruption Detected!",10);
  393.     }
  394.     
  395.     DlgTempField=field[BreakFieldIndex];    // make a working copy of the field 
  396.     
  397.     while (TRUE) {
  398.        if (DlgTempField.source==SRC_CALC) {
  399.            if (CurSec>=SEC_FTR_LVL9) ExpType=EXP_FOOTER;
  400.            else                      ExpType=EXP_OTHER;
  401.            
  402.            if ((ResultType=ModifyExp(DlgTempField.CalcExp,NewExp,DlgTempField.name,ExpType))<0) {
  403.               DlgTempField=field[SortFieldIndex];
  404.               continue;
  405.            }
  406.  
  407.            i=0;
  408.            while(NewExp[i]!=END_OF_EXP) {
  409.               DlgTempField.CalcExp[i]=NewExp[i];
  410.               i++;
  411.            }
  412.            DlgTempField.CalcExp[i]=NewExp[i];
  413.            DlgTempField.type=ResultType;
  414.            
  415.            if (i==0) {                      // a calculatio field not specified 
  416.               DlgTempField=field[SortFieldIndex];
  417.               continue;
  418.            }
  419.            else break;                      // a valid calculation field provided 
  420.        }
  421.        else {
  422.           DlgIndex=BreakFieldIndex;        // pass the section break field number using the global variable 
  423.           if (!CallDialogBox("SecBreakParam",SecBreakParam,(DWORD)CurSec)) return TRUE;
  424.           if (DlgTempField.name[0]==0) {   // create a calculation field 
  425.              DlgTempField.source=SRC_CALC;
  426.              DlgTempField.type=TYPE_NUM;
  427.              wsprintf(DlgTempField.name,"COMP_EXP%d",SecLevel);
  428.              DlgTempField.CalcExp[0]=END_OF_EXP;
  429.           }
  430.           else break;                      // a valid data field provided 
  431.        }
  432.     }
  433.     
  434.     field[BreakFieldIndex]=DlgTempField;
  435.     
  436.     return TRUE;
  437. }
  438.