home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Database / CLIPR502.DOS / SOURCE / RL / RLFRONT.PRG < prev   
Encoding:
Text File  |  1993-02-15  |  37.9 KB  |  1,906 lines

  1. /***
  2. *  
  3. *   Rlfront.prg
  4. *
  5. *   Front end for REPORT and LABEL FORM design program
  6. *  
  7. *   Copyright (c) 1987-1993, Computer Associates International, Inc.
  8. *   All rights reserved.
  9. *  
  10. *   Note: Compile with /m
  11. */
  12.  
  13. // File-wide definitions
  14. #include "inkey.ch"
  15. #include "setcurs.ch"
  16.  
  17. // Event types
  18. #define E_CANCEL        1        // Cancel, continue
  19. #define E_NO            2        // Exit, no save
  20. #define E_OK            3        // Exit, save
  21.  
  22.  
  23. /***
  24. *
  25. *  Main()
  26. *
  27. */
  28. PROCEDURE Main()
  29.    LOCAL cStartScr
  30.  
  31.    PUBLIC file_error, exit_status, my_update, no_save_flag, form_state
  32.  
  33.    file_error = 0                // File ok
  34.  
  35.    SET SCOREBOARD OFF            // Row 0 is being used
  36.    SET WRAP ON
  37.    SAVE SCREEN TO cStartScr      // Save beginning screen
  38.  
  39.    RlMain()                      // Edit reports and label definitions
  40.  
  41.    RESTORE SCREEN FROM cStartScr
  42.    RETURN
  43.  
  44.  
  45.  
  46. /***
  47. *
  48. *  SayMsg( cMessage ) --> NIL
  49. *
  50. *  Display a message to the message line
  51. *
  52. */
  53. FUNCTION SayMsg( cMsg )
  54.     LOCAL cLastColor := SETCOLOR("n/gr")
  55.     @ 2,0 SAY cMsg 
  56.     SETCOLOR( cLastColor )    
  57.     RETURN NIL
  58.  
  59.  
  60.  
  61. /***
  62. *
  63. *     SignOn() --> NIL
  64. *
  65. *     Display the sign-on message and wait for a key
  66. *
  67. */
  68. FUNCTION SignOn( aMenu )
  69.     LOCAL cLastColor, lLastCursor
  70.  
  71.     cLastColor = SETCOLOR("N/BG")
  72.     @ 0, 0 SAY aMenu[ 1 ] 
  73.     SETCOLOR( cLastColor )
  74.     lLastCursor := SETCURSOR( SC_NONE )
  75.  
  76.     @ 0, 10 SAY aMenu[ 2 ]
  77.     @ 0, 19 SAY aMenu[ 3 ]
  78.    @ 1, 0  TO 1, MAXCOL()
  79.    SayMsg( "RL - Copyright (c) 1986-1993, Computer Associates International, Inc., " +;
  80.             "All Rights Reserved" )
  81.  
  82.     CLEAR TYPEAHEAD
  83.     nKey = INKEY(0)
  84.     @ 2, 0
  85.     KEYBOARD CHR( nKey )
  86.  
  87.     SETPOS( 0, 0 )
  88.     SETCURSOR( lLastCursor )
  89.  
  90.     RETURN NIL
  91.  
  92.  
  93.  
  94. /***
  95. *
  96. *  RlMain()
  97. *
  98. *  main procedure
  99. *
  100. *     event types are:
  101. *          1 = cancel, (continue)
  102. *          2 = No,     (exit-no save)
  103. *          3 = Ok,     (exit-w/ save)
  104. */
  105. PROCEDURE RlMain
  106.     LOCAL aMainMenu
  107.  
  108.     PRIVATE rl_opt1, rl_opt2, rl_quit
  109.     PRIVATE rl_choice, execute, filename, open_name, file_box, event_type
  110.  
  111.     // item functions must be listed in ascending order...that
  112.     // is, higher numbered items must be located at a higher
  113.     // row number, a higher column number, or both.
  114.     DECLARE file_box[5]
  115.  
  116.     // item functions used in this program
  117.     file_box[1] = "enter_title(sysparam)"
  118.     file_box[2] = "rl_getfil(sysparam)"
  119.     file_box[3] = "ok_button(sysparam)"
  120.     file_box[4] = "cancel_button(sysparam)"
  121.     file_box[5] = "filelist(sysparam)"
  122.  
  123.     okee_dokee = "do_it()"
  124.     execute = .T.
  125.     aMainMenu := { " Report ", " Label ", " Quit " }
  126.  
  127.     SET COLOR TO BG+/B,N/BG,,,N/W
  128.   CLEAR
  129.   SignOn( aMainMenu )
  130.  
  131.     DO WHILE execute
  132.         CLEAR
  133.  
  134.         event_type   = E_CANCEL            // loop
  135.         filename     = SPACE(64)
  136.  
  137.         // Set flags
  138.         my_update    = .F.
  139.         no_save_flag = .F.
  140.  
  141.         // Display main menu
  142.         @ 0, 0  PROMPT aMainMenu[ 1 ]
  143.         @ 0, 10 PROMPT aMainMenu[ 2 ]
  144.         @ 0, 19 PROMPT aMainMenu[ 3 ]
  145.       @ 1, 0  TO 1, MAXCOL()
  146.  
  147.         MENU TO rl_choice
  148.         SET CURSOR OFF
  149.  
  150.         DO CASE
  151.         CASE rl_choice == 3 .OR. rl_choice == 0
  152.  
  153.             // Exit
  154.             execute = .F.
  155.  
  156.         CASE rl_choice == 1
  157.  
  158.             // Select REPORT FORM
  159.             DECLARE files[adir("*.FRM") + 1]
  160.             afill(files,"")
  161.             adir("*.FRM", files)
  162.       altd()
  163.  
  164.             IF multibox(7, 17, 7, 5, file_box) = 0        // <esc> or cancel?
  165.                 LOOP
  166.             ENDIF
  167.  
  168.         // add an extension if none was found (.frm)
  169.             open_name = EXT_ADD(filename, "R")  
  170.  
  171.         CASE rl_choice == 2
  172.  
  173.             // Select LABEL FORM
  174.             DECLARE files[adir("*.LBL") + 1]
  175.             afill(files,"")
  176.             adir("*.LBL", files)
  177.  
  178.             IF multibox(7, 17, 7, 5, file_box) = 0        // <esc> or cancel?
  179.                 LOOP
  180.             ENDIF
  181.  
  182.         // Add an extension if none was found (.lbl)
  183.             open_name = EXT_ADD(filename, "L")  
  184.  
  185.         ENDCASE
  186.  
  187.       IF EMPTY( filename )
  188.          execute = .F.
  189.       ENDIF
  190.  
  191.     IF execute
  192.  
  193.       * report choice was selected from menu bar
  194.         IF rl_choice == 1
  195.  
  196.             SET COLOR TO BG*+/B
  197.             @ 2,0 SAY "Loading..."
  198.             SET COLOR TO BG+/B,N/BG,,,N/W
  199.  
  200.             IF !FRM_LOAD(open_name, "FRM_FILE.DBF", "FRM_FILE.MEM")
  201.                 FRM_ERROR(open_name, file_error)
  202.                 EXIT
  203.             ENDIF
  204.  
  205.             * proceed to editing the report
  206.             DO WHILE (event_type == 1)
  207.  
  208.             * initital state of report screen (fields screen)
  209.                form_state = 3
  210.  
  211.             * the edit routine
  212.                IF FRM_EDIT(open_name, "FRM_FILE.DBF", "FRM_FILE.MEM")
  213.  
  214.                 * get the event_type from selection box upon exit
  215.                    event_type = SYSTEM_EXIT()
  216.  
  217.                     IF event_type == 2        // 'No' button was selected
  218.                         event_type = 0
  219.                     ENDIF
  220.  
  221.                     IF event_type == 3        // 'Ok' button was selected
  222.                            IF !FRM_SAVE(open_name, "FRM_FILE.DBF", "FRM_FILE.MEM")
  223.                                FRM_ERROR(open_name, file_error)
  224.  
  225.                          * exit while loop, some error was found
  226.                                event_type = 0
  227.                         ENDIF
  228.                     ENDIF
  229.  
  230.                 ELSE
  231.  
  232.                * no update (my_update) when editing, go home
  233.                     event_type = 0    
  234.  
  235.                 ENDIF
  236.  
  237.             ENDDO
  238.  
  239.             * delete work files, always
  240.             DELETE FILE frm_file.dbf
  241.             DELETE FILE frm_file.mem
  242.  
  243.         ENDIF    // rl_choice = 1
  244.  
  245.       * label choice was selected from menu bar
  246.         IF rl_choice == 2    
  247.  
  248.             SET COLOR TO BG*+/B
  249.             @ 2,10 SAY "Loading..."
  250.             SET COLOR TO BG+/B
  251.             IF !LBL_LOAD(open_name, "LBL_FILE.DBF", "LBL_FILE.MEM")
  252.                 LBL_ERROR(open_name, file_error)
  253.                 EXIT
  254.             ENDIF
  255.  
  256.             *  edit the label file
  257.             DO WHILE (event_type == 1)
  258.  
  259.                 IF LBL_EDIT(open_name, "LBL_FILE.DBF", "LBL_FILE.MEM")
  260.  
  261.                     event_type = SYSTEM_EXIT()
  262.  
  263.                     IF event_type == 2        // 'No' button
  264.                         event_type = 0
  265.                     ENDIF
  266.  
  267.                     IF event_type == 3
  268.                         IF !LBL_SAVE(open_name, "LBL_FILE.DBF", "LBL_FILE.MEM")
  269.                             LBL_ERROR(open_name, file_error)
  270.                             event_type = 0
  271.                         ENDIF
  272.                     ENDIF
  273.  
  274.                 ELSE
  275.  
  276.                * no update (my_update) when editing, go home
  277.                     event_type = 0
  278.  
  279.                 ENDIF
  280.  
  281.             ENDDO
  282.  
  283.             * delete work files
  284.             DELETE FILE lbl_file.dbf
  285.             DELETE FILE lbl_file.mem
  286.  
  287.         ENDIF
  288.  
  289.     ENDIF
  290.  
  291. ENDDO
  292.  
  293. SET CURSOR ON
  294. // end of RlMain (procedure)
  295.  
  296.  
  297.  
  298. ***
  299. * lbl_clear (function)
  300. *
  301. * clear gets for label system
  302. ***
  303. PROCEDURE lbl_clear
  304. PARAMETERS dummy1, dummy2, dummy3
  305. CLEAR GETS
  306. RETURN
  307.  
  308.  
  309.  
  310. ***
  311. * lbl_edit (function)
  312. *
  313. * edit a label file
  314. ***
  315. FUNCTION LBL_EDIT
  316. PARAMETERS label_file, label_dbf, label_mem
  317.  
  318. PRIVATE field_list, paint_only
  319.  
  320. exit_status = .F.
  321.  
  322. // get default .MEM file info
  323. RESTORE FROM &label_mem ADDITIVE
  324.  
  325. // .DBF file info
  326. SELECT 0
  327. USE &label_dbf ALIAS label_dbf
  328.  
  329. DECLARE field_list[FCOUNT()]
  330.  
  331. FOR n = 1 TO FCOUNT()
  332.     field_list[n] = FIELDNAME(n)
  333. NEXT
  334.  
  335. // draw the screen once
  336. LBL_SCR(label_file)
  337.  
  338. // cursor back on (multibox sets it off)
  339. SET CURSOR ON
  340.  
  341. paint_only = .T.
  342. DO WHILE !exit_status
  343.  
  344.     * set 'break-out' key, toggle switch
  345.     SET KEY -1 TO lbl_clear    // (F2)
  346.  
  347.     * set label format key
  348.     SET KEY -2 TO lab_setup
  349.  
  350.     * set F10 key to the exit procedure
  351.     SET KEY -9 TO set_exit_flag
  352.  
  353.     @ 05,16 GET lbl_width  PICTURE "999"
  354.     @ 06,16 GET lbl_height PICTURE "999" VALID LINE_CHK(lbl_height)
  355.     @ 07,16 GET lbl_across PICTURE "999"
  356.  
  357.     @ 05,52 GET lbl_margin PICTURE "999"
  358.     @ 06,52 GET lbl_lines  PICTURE "999"
  359.     @ 07,52 GET lbl_spaces PICTURE "999"
  360.  
  361.     @ 09,16 GET lbl_remark
  362.  
  363.     IF !paint_only
  364.         READ
  365.     ENDIF
  366.  
  367.     my_update = my_update .OR. UPDATED()
  368.  
  369.     IF exit_status
  370.          EXIT
  371.   ENDIF
  372.  
  373.     * send the escape key to exit from dbedit the first time    
  374.     IF paint_only
  375.         CLEAR GETS
  376.         KEYBOARD CHR(27)
  377.         paint_only = .F.
  378.     ENDIF
  379.  
  380.     * view/edit field expressions
  381.     SET KEY -9 TO
  382.   SET KEY 1  TO Home_key
  383.   SET KEY 6  TO End_key
  384.   SET KEY -1 TO
  385.  
  386.     SET CURSOR OFF
  387.     @ 12,0 SAY "Line " + LTRIM(STR(RECNO())) + " ═"
  388.     DBEDIT(11, 7, 23, 79, field_list, "LBL_ED")
  389.     SET CURSOR ON
  390.  
  391.     SET KEY -9 TO set_exit_flag
  392.   SET KEY 1  TO 
  393.   SET KEY 6  TO 
  394.  
  395. ENDDO
  396.  
  397. CLOSE DATABASES
  398.  
  399. IF my_update .AND. !no_save_flag
  400.     * save off to .mem file, if it was updated and 'No' was not selected
  401.    SAVE ALL LIKE lbl_* TO &label_mem
  402. ENDIF
  403.  
  404. // disable SET KEY's
  405. SET KEY -1 TO
  406. SET KEY -2 TO
  407. SET KEY -9 TO
  408.  
  409. RETURN (my_update)
  410. // end of lbl_edit (function)
  411.  
  412.  
  413.  
  414. PROCEDURE Home_key
  415. KEYBOARD CHR(31)
  416. RETURN
  417.  
  418.  
  419.  
  420. PROCEDURE End_key
  421. KEYBOARD CHR(30)
  422. RETURN     
  423.  
  424.  
  425.  
  426. ***
  427. *    lab_setup (procedure)
  428. *
  429. *    handle the various formats that dBASE supports
  430. ***
  431. PROCEDURE lab_setup
  432. PARAMETERS procName, dummy2, dummy3
  433.  
  434. PRIVATE double, more, type, type1, type2, type3, type4, type5
  435.  
  436. double = "╔═╗║╝═╚║"
  437.  
  438. SAVE SCREEN
  439.  
  440. @ 08,18,20,57 BOX ""    // space around window
  441.  
  442. // make window
  443. @ 10,20,18,55 BOX double
  444.  
  445. // disable options
  446. SET KEY -1 TO
  447. SET KEY -2 TO
  448. SET KEY 1  TO 
  449. SET KEY 6  TO 
  450.  
  451. // no F10 here, ESC returns
  452. SET KEY -9 TO
  453.  
  454. // various label types
  455. type1 = "     3 1/2 x 15/16 by 1       "
  456. type2 = "     3 1/2 x 15/16 by 2       "
  457. type3 = "     3 1/2 x 15/16 by 3       "
  458. type4 = "       4 x 17/16 by 1         "
  459. type5 = "3 2/10 x 11/12 by 3 (Cheshire)"
  460.  
  461. more = .T.
  462. DO WHILE more
  463.  
  464.     * selections
  465.     @ 12,23 PROMPT type1
  466.     @ 13,23 PROMPT type2
  467.     @ 14,23 PROMPT type3
  468.     @ 15,23 PROMPT type4
  469.     @ 16,23 PROMPT type5
  470.  
  471.     MENU TO lab_choice
  472.  
  473.     * set up the strings, based on choice
  474.     DO CASE
  475.         CASE lab_choice = 0
  476.             more = .F.
  477.         CASE lab_choice = 1
  478.             type = LTRIM(TRIM(type1)) + SPACE(60-18)
  479.             more = stuff_label(35,5,0,1,0,1,type)
  480.             UpdateHeight(5)
  481.         CASE lab_choice = 2
  482.             type = LTRIM(TRIM(type2)) + SPACE(60-18)
  483.             more = stuff_label(35,5,0,1,2,2,type)
  484.             UpdateHeight(5)
  485.         CASE lab_choice = 3
  486.             type = LTRIM(TRIM(type3)) + SPACE(60-18)
  487.             more = stuff_label(35,5,0,1,2,3,type)
  488.             UpdateHeight(5)
  489.         CASE lab_choice = 4
  490.             type = LTRIM(TRIM(type4)) + SPACE(60-14)
  491.             more = stuff_label(40,8,0,1,0,1,type)
  492.             UpdateHeight(8)
  493.         CASE lab_choice = 5
  494.             type = type5 + SPACE(60-30)
  495.             more = stuff_label(32,5,0,1,2,3,type)
  496.             UpdateHeight(5)
  497.     ENDCASE
  498.  
  499. ENDDO
  500.  
  501. SET KEY 1  TO Home_key
  502. SET KEY 6  TO End_key
  503.  
  504. CLEAR GETS
  505.  
  506. // break out of dbedit()
  507. KEYBOARD CHR(27)
  508.  
  509. RESTORE SCREEN
  510. RETURN
  511. // end of lab_setup (procedure)
  512.  
  513.  
  514.  
  515. ***
  516. *    stuff_label (function)
  517. *
  518. *    stuff label variables with values from lbl_setup, return .F.
  519. ***
  520. FUNCTION stuff_label
  521. PARAMETERS one,two,three,four,five,six,seven
  522.  
  523. lbl_width  = one
  524. lbl_height = two
  525. lbl_margin = three
  526. lbl_lines  = four
  527. lbl_spaces = five
  528. lbl_across = six
  529. lbl_remark = seven
  530.  
  531. // generates an update
  532. my_update = .T.
  533.  
  534. RETURN (.F.)
  535. // end of stuff_label (function)
  536.  
  537.  
  538.  
  539. ***
  540. *    lbl_ed (function)
  541. *
  542. *    user defined function to be called from DBEDIT, used in LBL_EDIT
  543. ***
  544. FUNCTION LBL_ED
  545. PARAMETERS mode, i
  546.  
  547. PRIVATE cur_field
  548.  
  549. // get the name of the current field into a regular variable
  550. cur_field = field_list[i]
  551.  
  552. DO CASE
  553. CASE mode = 0
  554.     * idle mode...
  555.     @ 12,0 SAY "Line " + LTRIM(STR(RECNO())) + " ═"
  556.     RETURN(1)
  557.  
  558. CASE mode = 1
  559.     KEYBOARD CHR(30)
  560.     RETURN 1
  561.  
  562. CASE mode = 2
  563.   KEYBOARD CHR(31)
  564.   RETURN 1
  565.  
  566. CASE mode < 4
  567.   * case action can be implemented for each mode
  568.   RETURN (1)
  569.  
  570. CASE LASTKEY() = -1                                      // F2
  571.     SET CURSOR ON
  572.     RETURN (0)
  573.  
  574. CASE LASTKEY() = 7
  575.   * Del..delete current line.
  576.   rec_num = RECNO()
  577.   DELETE
  578.   PACK
  579.   APPEND BLANK
  580.  
  581.   GO REC_NUM
  582.   my_update = .t.
  583.  
  584.   RETURN 2
  585.  
  586. CASE LASTKEY() = 27
  587.     RETURN (0)
  588.  
  589. CASE LASTKEY() = 13 .OR. LASTKEY() > 32 .AND. LASTKEY() < 128
  590.     * force key into GET field
  591.     IF LASTKEY() != 13
  592.         KEYBOARD CHR(LASTKEY())
  593.   ENDIF
  594.  
  595.     * enter key..edit the current field
  596.     * ..current row and col are correct
  597.     @ ROW(), COL() GET &cur_field
  598.  
  599.     * set curson on and edit the expressions
  600.     SET CURSOR ON
  601.     SET KEY -9 TO set_exit_flag
  602.     SET KEY 1 TO
  603.     SET KEY 6 TO
  604.  
  605.     READEXIT(.T.)
  606.     READ
  607.     READEXIT(.F.)
  608.  
  609.     SET KEY -9 TO
  610.     SET KEY 1 TO home_key
  611.     SET KEY 6 TO end_key
  612.  
  613.     SET CURSOR OFF
  614.  
  615.     * set the update flag
  616.     my_update = my_update .OR. UPDATED()
  617.     IF LASTKEY() = 13
  618.         KEYBOARD CHR(24)
  619.     ENDIF
  620.  
  621.     * don't quit
  622.      RETURN(1)
  623.  
  624. CASE LASTKEY() = -9
  625.     exit_status = .T.
  626.     RETURN 0
  627.  
  628. OTHERWISE
  629.     * don't quit
  630.     RETURN 1
  631.  
  632. ENDCASE
  633. // end of lbl_ed (function)
  634.  
  635.  
  636.  
  637. ***
  638. * lbl_scr (function)
  639. *
  640. * paint the label screen using SAY's
  641. ***
  642. FUNCTION LBL_SCR
  643. PARAMETERS label_file
  644.  
  645. CLEAR
  646.  
  647. @ 0,00 SAY "F1"
  648. @ 0,09 SAY "F2"
  649. @ 0,20 SAY "F3"
  650. @ 0,70 SAY "F10"
  651.  
  652. @ 1,00 SAY "Help"
  653. @ 1,09 SAY "Toggle"
  654. @ 1,20 SAY "Formats"
  655. @ 1,70 SAY "Exit"
  656.  
  657. @ 2,0 SAY REPLICATE(CHR(196),80)
  658.  
  659. // display the filename all the way to the right
  660. @ 03,80-LEN("File " + label_file) SAY "File " + label_file
  661.  
  662. // display headers
  663. @ 04,01 SAY "Dimensions"
  664. @ 04,30 SAY "Formatting"
  665.  
  666. @ 05,06 SAY "Width   "
  667. @ 06,06 SAY "Height  "
  668. @ 07,06 SAY "Across  "
  669. @ 05,36 SAY "Margin  "
  670. @ 06,36 SAY "Lines   "
  671. @ 07,36 SAY "Spaces  "
  672. @ 09,06 SAY "Remarks "
  673.  
  674. RETURN ("")
  675. // end of lbl_scr (function)
  676.  
  677.  
  678.  
  679. ***
  680. * line_chk (function)
  681. *
  682. * Check the line_height variable.  Report error if not in range. Modify 
  683. * database to accomodate new values, if any. Return Boolean valid_flag.
  684. ***
  685. FUNCTION LINE_CHK
  686. PARAMETERS height, file
  687.  
  688. PRIVATE lines, range_error, valid_flag, i
  689.  
  690. range_error = "(Valid range is between 1 and 16.)"
  691. valid_flag  = .T.
  692.  
  693. SET CURSOR OFF
  694.  
  695. IF height > 16 .OR. height <= 0
  696.         @ 24, CENTER(range_error,80) SAY range_error
  697.         valid_flag = .F.
  698.  
  699. ELSEIF height != LASTREC()
  700.  
  701.         UpdateHeight(height)
  702.       @ 24,0    // ok to clear line
  703. END
  704.  
  705. SET CURSOR ON
  706.  
  707. RETURN (valid_flag)
  708. // end of line_chk (function)
  709.  
  710.  
  711.  
  712. ***
  713. *
  714. *     UpdateHeight(height, lines)
  715. *         Delete added lines or expand to fill if lines are less than height.
  716. *        Uses inherited privates vars.
  717. *
  718. *        8/13/89 CEW
  719. *
  720. PROCEDURE UpdateHeight
  721.  
  722.         PARAMETERS height
  723.  
  724.       * delete lineitems
  725.       DELETE ALL FOR RECNO() > height
  726.       PACK
  727.  
  728.         * add lineitems
  729.         lines = RECCOUNT()
  730.       IF height > lines
  731.           DO WHILE lines < height
  732.               APPEND BLANK
  733.               SKIP
  734.               lines = lines + 1
  735.           ENDDO
  736.           GO TOP    // reset
  737.       ENDIF
  738.  
  739. RETURN
  740.  
  741.  
  742.  
  743. ***
  744. *  set_exit_flag (procedure)
  745. *
  746. *  sets the global exit_status flag to .T. upon exit (F10).
  747. ***
  748. PROCEDURE set_exit_flag
  749. CLEAR GETS
  750. exit_status = .T.
  751. RETURN
  752. // end of set_exit_flag (procedure)
  753.  
  754.  
  755.  
  756. ***
  757. * system_exit (function)
  758. *
  759. * save changes to file ...?   Ok     - Save and exit
  760. *                                    No     - Exit
  761. *                                     Cancel - loop (continue)
  762. ****
  763. FUNCTION system_exit
  764. PARAMETERS dummy1, dummy2, dummy3
  765.  
  766. PRIVATE exit_box, continue
  767.  
  768. continue = 3    // save and exit
  769.  
  770. DECLARE exit_box[4]
  771.  
  772. exit_box[1] = "save_title(sysparam)"
  773. exit_box[2] = "ok_button(sysparam)"
  774. exit_box[3] = "no_button(sysparam)"
  775. exit_box[4] = "can_button(sysparam)"
  776.  
  777. SET CURSOR OFF
  778. IF multibox(7, 17, 7, 2, exit_box) = 0        // save changes? (Y,N,C)
  779.  
  780.     continue = 1         // cancel
  781.  
  782.     IF no_save_flag        // set inside multibox routine
  783.         continue = 2
  784.     ENDIF
  785.  
  786. ENDIF
  787. SET CURSOR ON
  788.  
  789. RETURN (continue)
  790. // end of system_exit (function)
  791.  
  792.  
  793.  
  794. ****
  795. * frm_edit (function)
  796. *
  797. * this routine calls 6 procedures, using SET KEY <n> TO ...
  798. *
  799. * F-key:                      (procedure name):
  800. * F2 = pageheading screen     (form_layout)
  801. * F3 = group/subgroup screen  (form_groups)
  802. * F4 = default fields screen  (form_fields)
  803. * F5 = delete                 (form_delete)
  804. * F6 = insert                 (form_insert)
  805. * F7 = goto field             (form_goto)
  806. *
  807. ****
  808. FUNCTION FRM_EDIT
  809. PARAMETERS form_file, form_dbf, form_mem
  810.  
  811. PRIVATE phdr_lines, chdr_lines, i, lkey, phdr_flag, insert_flag
  812.  
  813. // get default .MEM file info
  814. RESTORE FROM &form_mem ADDITIVE
  815.  
  816. // .DBF file info
  817. SELECT 0
  818. USE &form_dbf ALIAS form_dbf
  819.  
  820. // set up work arrays
  821. DECLARE phdr_lines[4]
  822. DECLARE chdr_lines[24*4]    // 24 fields, 4 lines each
  823.  
  824. // inititalize pagetitle array
  825. afill(phdr_lines,SPACE(60))
  826.  
  827. // translate semicolons into lines and stuff array
  828. fstart_pos = 1
  829. phdr_lines[1] = XLATE(frm_pagehdr, ";", 60)
  830. phdr_lines[2] = XLATE(frm_pagehdr, ";", 60)
  831. phdr_lines[3] = XLATE(frm_pagehdr, ";", 60)
  832. phdr_lines[4] = XLATE(frm_pagehdr, ";", 60)
  833.  
  834. // initalize contents header array
  835. afill(chdr_lines, SPACE(65), 1, 24*4)
  836.  
  837. // set the array index
  838. ar_index = 1
  839.  
  840. // get the strings from datafile
  841. GO TOP
  842. FOR i = 1 TO RECCOUNT()
  843.  
  844.    * set field start position    
  845.     fstart_pos = 1
  846.  
  847.     * set up fields contents headers
  848.     chdr_lines[ar_index]   = XLATE(form_dbf->header, ";", 65)
  849.     chdr_lines[ar_index+1] = XLATE(form_dbf->header, ";", 65)
  850.     chdr_lines[ar_index+2] = XLATE(form_dbf->header, ";", 65)
  851.     chdr_lines[ar_index+3] = XLATE(form_dbf->header, ";", 65)
  852.  
  853.    * next one
  854.     SKIP
  855.  
  856.     * increment array subscript (in groups of four)
  857.     ar_index = ar_index + 4
  858.  
  859. NEXT
  860.     
  861. // pad the group/subgroup area, if necessary
  862. frm_grpexpr  = frm_grpexpr + SPACE(200 - LEN(frm_grpexpr))
  863. frm_grphdr   = frm_grphdr  + SPACE( 50 - LEN(frm_grphdr ))
  864. frm_subexpr  = frm_subexpr + SPACE(200 - LEN(frm_subexpr))
  865. frm_subhdr   = frm_subhdr  + SPACE( 50 - LEN(frm_subhdr ))
  866.  
  867. // modifying old file
  868. GO TOP
  869. IF frm_colcount != 0    
  870.  
  871.     m_contents = form_dbf->contents
  872.     m_width    = form_dbf->width
  873.     m_decimals = form_dbf->decimals
  874.     m_totals   = form_dbf->totals
  875.  
  876. ***** 03/29/88
  877. * originally:
  878. *    total_fields   = frm_colcount
  879. * fix:
  880.     TOTAL_FIELDS = int(FRM_COLCOUNT)
  881.  
  882.  
  883. ELSE    // modifying new file, frm_colcount == 0
  884.  
  885.     m_contents = SPACE(254)
  886.     m_width    = 10
  887.     m_decimals = 0
  888.     m_totals   = "N"
  889.     total_fields   = 1
  890.  
  891. ENDIF
  892.     
  893. // get the data again if 'Cancel' on filebox
  894. IF my_update
  895.  
  896.     m_contents = form_dbf->contents
  897.     m_width    = form_dbf->width
  898.     m_decimals = form_dbf->decimals
  899.     m_totals   = form_dbf->totals
  900.  
  901. ENDIF
  902.  
  903. insert_flag = .F.    // no inserted fields yet
  904. exit_status = .F.     // exit not set yet
  905.  
  906. // exit on F10
  907. SET KEY -9 TO set_exit_flag
  908.  
  909. key = form_state        // the fields screen
  910.  
  911. // index is always 1 on entry
  912. ar_index = 1
  913.  
  914. // control loop for frm_edit
  915. DO WHILE !exit_status
  916.  
  917.    * set page function keys    
  918.     SET KEY -1 TO clear_gets   // F2
  919.     SET KEY -2 TO clear_gets   // F3         
  920.     SET KEY -3 TO clear_gets   // F4
  921.  
  922.     DO CASE
  923.         CASE M->form_state == 1
  924.             DO form_layout
  925.         CASE M->form_state == 2
  926.             DO form_groups
  927.         CASE M->form_state == 3
  928.             DO form_fields
  929.         CASE M->form_state == 4
  930.             DO form_delete
  931.             form_state = 3
  932.             * DON'T get new key 
  933.             LOOP
  934.         CASE M->form_state == 5
  935.             DO form_insert
  936.             form_state = 3
  937.             * DON'T get new key 
  938.             LOOP
  939.         CASE M->form_state == 6
  940.             DO form_goto
  941.             form_state = 3
  942.             * DON'T get new key 
  943.             LOOP
  944.     ENDCASE
  945.  
  946.     * get the key
  947.     key = LASTKEY()
  948.  
  949.     DO CASE
  950.  
  951.       * if key was F10
  952.         CASE M->key == -9
  953.             DO set_exit_flag
  954.  
  955.         CASE M->key == 27 .OR. M->key == 18 .OR. M->key == 3
  956.             * define your own special 'read-exit' keys here, if needed
  957.         
  958.         ***** 03/29/88
  959.         * fix:
  960.         case m->KEY > 27 .and. m->KEY < 255
  961.  
  962.         OTHERWISE    // the function keys
  963.             form_state = VAL(SUBSTR(LTRIM(STR(M->key)),2))    // get the new state
  964.  
  965.     ENDCASE
  966.  
  967. ENDDO
  968. // check for empty pagetitle
  969. phdr_flag = .F.
  970. FOR i = 1 TO 4
  971.     IF !EMPTY(phdr_lines[i])
  972.         phdr_flag = .T.
  973.     ENDIF
  974. NEXT
  975.  
  976. // get the pageheader if not empty
  977. IF phdr_flag
  978.  
  979. ***** 03/29/88
  980. * originally:
  981. *    frm_pagehdr = TRIM(phdr_lines[1]) + ";" + TRIM(phdr_lines[2])+";" + ;
  982. *              TRIM(phdr_lines[3]) + ";" + phdr_lines[4]
  983. * fix:
  984. frm_pagehdr = IF(!EMPTY(phdr_lines[1]), TRIM(phdr_lines[1]) + ";", SPACE(60)) +;
  985.               IF(!EMPTY(phdr_lines[2]), TRIM(phdr_lines[2]) + ";", SPACE(60)) +;
  986.               IF(!EMPTY(phdr_lines[3]), TRIM(phdr_lines[3]) + ";", SPACE(60)) +;
  987.               IF(!EMPTY(phdr_lines[4]), TRIM(phdr_lines[4]) + ";", SPACE(60))
  988.  
  989. ELSE
  990.     frm_pagehdr = ""
  991. ENDIF
  992.  
  993. // strip of spaces in the group/subgroup areas
  994. frm_grpexpr  = TRIM(frm_grpexpr)
  995. frm_grphdr   = TRIM(frm_grphdr)
  996. frm_subexpr  = TRIM(frm_subexpr)
  997. frm_subhdr   = TRIM(frm_subhdr)
  998.  
  999. // save if updated and 'No' was not selected
  1000. IF my_update .AND. !no_save_flag
  1001.  
  1002.     *  set number of fields
  1003.     frm_colcount = MAX(total_fields, frm_colcount)
  1004.  
  1005.    SAVE ALL LIKE frm_* TO &form_mem
  1006.     
  1007.     * put the semicolon's back on, the simple way
  1008.     i = 1
  1009.     GO TOP
  1010.     DO WHILE .NOT. EOF()
  1011.         REPLACE form_dbf->header WITH ;
  1012.         TRIM(chdr_lines[i]) + ";" + TRIM(chdr_lines[i+1]) + ";" + ;
  1013.         TRIM(chdr_lines[i+2]) + ";" + TRIM(chdr_lines[i+3])
  1014.         SKIP
  1015.         i = i + 4
  1016.     ENDDO
  1017.  
  1018. ENDIF
  1019.  
  1020. CLOSE DATABASES
  1021.  
  1022. // disable SET KEYs ...
  1023. FOR i = 1 TO 6
  1024.     SET KEY -i TO
  1025. NEXT
  1026. SET KEY -9 TO 
  1027.  
  1028. RETURN (my_update)
  1029. // end of frm_edit (function)
  1030.  
  1031.  
  1032.  
  1033. ****
  1034. * form_fields (procedure)
  1035. *
  1036. * called from frm_edit, processes editing requests
  1037. ****
  1038. PROCEDURE form_fields
  1039.  
  1040. PRIVATE stay_msg, no_more_fields, rec_saved
  1041.  
  1042. SET CURSOR ON
  1043.  
  1044. // set up function keys
  1045. SET KEY -4 TO clear_gets    // delete (F5)
  1046. SET KEY -5 TO clear_gets    // insert (F6)
  1047. SET KEY -6 TO clear_gets    // goto # (F7)
  1048.  
  1049. SET KEY -3 TO    // disable this option (F4)
  1050.  
  1051. // draw screen
  1052. FRM_SCR(3)
  1053.  
  1054. // possible error messages
  1055. stay_msg       = "(Must type in inserted field, or delete, before moving)."
  1056. no_more_fields = "(You have reached end of file)."
  1057.  
  1058. break_out = .F.        // flag to break out of WHILE loop
  1059.  
  1060. DO WHILE !exit_status
  1061.  
  1062.    * just in case
  1063.    @ 4,71 SAY IF (!BOF(), "Field " + LTRIM(STR(RECNO())) + " ", "<bof>  ")
  1064.    @ 4,71 SAY IF (!EOF(), "Field " + LTRIM(STR(RECNO())) + " ", "<eof>  ")
  1065.  
  1066.    @ 5,71 SAY "Total " + LTRIM(STR(total_fields)) + " "
  1067.  
  1068.    @ 07,09 GET m_contents PICTURE "@S65"
  1069.  
  1070.    @ 11,09 GET chdr_lines[ar_index]
  1071.    @ 12,09 GET chdr_lines[ar_index+1]
  1072.    @ 13,09 GET chdr_lines[ar_index+2]
  1073.    @ 14,09 GET chdr_lines[ar_index+3]
  1074.  
  1075.    @ 19,10 GET m_width    PICTURE "99"
  1076.    @ 20,10 GET m_decimals PICTURE "99"
  1077.    @ 21,10 GET m_totals   PICTURE "!"
  1078.  
  1079.    READ
  1080.  
  1081.    lkey = LASTKEY()
  1082.  
  1083.    IF break_out        // set in clear_gets procedure
  1084.         EXIT
  1085.    ENDIF
  1086.  
  1087.    * was it updated?
  1088.    my_update = my_update .OR. UPDATED()
  1089.  
  1090.     * F10?
  1091.     IF exit_status
  1092.  
  1093.      IF .NOT. UPDATED() .AND. RECNO() < 24
  1094.              IF total_fields > 0
  1095.                  total_fields = total_fields - 1
  1096.                 ENDIF
  1097.        ELSE
  1098.           IF my_update
  1099.                 REPLACE form_dbf->contents WITH m_contents
  1100.                  REPLACE form_dbf->totals   WITH m_totals
  1101.                    REPLACE form_dbf->width    WITH m_width
  1102.                 REPLACE form_dbf->decimals WITH m_decimals
  1103.            ENDIF
  1104.         ENDIF
  1105.  
  1106.    ENDIF
  1107.  
  1108.    DO CASE
  1109.       CASE lkey == 13 .OR. lkey == 3    // CR or PgDn
  1110.     
  1111.             * put the information in the file when going forward        
  1112.             REPLACE form_dbf->contents WITH m_contents
  1113.             REPLACE form_dbf->totals   WITH m_totals
  1114.             REPLACE form_dbf->width    WITH m_width
  1115.             REPLACE form_dbf->decimals WITH m_decimals
  1116.  
  1117.             IF insert_flag .AND. !my_update
  1118.                 @ 24,CENTER(stay_msg,80) SAY stay_msg
  1119.                 INKEY(5)
  1120.                 @ 24,0
  1121.                 LOOP
  1122.             ELSE
  1123.                 * reset insert flag    
  1124.                 insert_flag = .F.
  1125.             ENDIF
  1126.  
  1127.             * add a new one
  1128.             IF (UPDATED() .AND. RECNO() == LASTREC()) .OR. (RECNO() == LASTREC() .AND. !EMPTY(m_contents))
  1129.  
  1130.                 * save for restore, if illegal APPEND
  1131.                 rec_saved = RECNO()
  1132.  
  1133.                 APPEND BLANK
  1134.  
  1135.                 * no more than 24 fields allowed
  1136.                 IF RECNO() > 24
  1137.  
  1138.                     @ 24,CENTER(no_more_fields,80) SAY no_more_fields
  1139.                     INKEY(2)
  1140.                     DELETE
  1141.                     PACK
  1142.  
  1143.                     @ 24,0
  1144.                     * restore
  1145.                     GO rec_saved
  1146.  
  1147.                     LOOP
  1148.                 ENDIF
  1149.  
  1150.                 * increment array subscript
  1151.                IF ar_index <= 92
  1152.                     ar_index = ar_index + 4
  1153.                 ENDIF
  1154.  
  1155.                 * add the total field count
  1156.                 total_fields = total_fields + 1
  1157.  
  1158.                 * init new field
  1159.               m_contents = SPACE(254)
  1160.                   m_width    = 10
  1161.               m_decimals =  0
  1162.                   m_totals   = "N"
  1163.  
  1164.             ELSE
  1165.  
  1166.               SKIP
  1167.                IF ar_index <= 92
  1168.                   ar_index = ar_index + 4
  1169.                ENDIF
  1170.  
  1171.                 IF EOF()
  1172.  
  1173.                   * no more ...
  1174.                     @ 24,CENTER(no_more_fields,80) SAY no_more_fields
  1175.                     INKEY(3)
  1176.                     @ 24,0
  1177.  
  1178.                    SKIP -1
  1179.  
  1180.                   IF RECNO() < 24
  1181.                       IF ar_index > 1
  1182.                            ar_index = ar_index - 4
  1183.                        ENDIF
  1184.                   ENDIF
  1185.  
  1186.               ENDIF
  1187.     
  1188.                 m_contents = form_dbf->contents
  1189.                  m_width    = form_dbf->width
  1190.               m_decimals = form_dbf->decimals
  1191.                 m_totals   = form_dbf->totals
  1192.     
  1193.             ENDIF
  1194.                                 
  1195.       CASE lkey == 18     // PgUp
  1196.  
  1197.          * put the information in the file when going backward
  1198.            REPLACE form_dbf->contents WITH m_contents
  1199.            REPLACE form_dbf->totals   WITH m_totals
  1200.            REPLACE form_dbf->width    WITH m_width
  1201.            REPLACE form_dbf->decimals WITH m_decimals
  1202.  
  1203.         IF insert_flag .AND. !my_update
  1204.             @ 24,CENTER(stay_msg,80) SAY stay_msg
  1205.             INKEY(3)
  1206.             @ 24,0
  1207.             LOOP
  1208.         ELSE
  1209.             * reset insert flag    
  1210.             insert_flag = .F.
  1211.         ENDIF
  1212.  
  1213.            IF !BOF()
  1214.  
  1215.                SKIP -1
  1216.  
  1217.                IF ar_index > 1
  1218.                    ar_index = ar_index - 4
  1219.                ENDIF
  1220.  
  1221.               m_contents = form_dbf->contents
  1222.               m_width    = form_dbf->width
  1223.                m_decimals = form_dbf->decimals
  1224.               m_totals   = form_dbf->totals
  1225.  
  1226.            ENDIF
  1227.  
  1228.    ENDCASE
  1229.  
  1230. ENDDO
  1231.  
  1232. my_update = my_update .OR. UPDATED()
  1233.  
  1234. RETURN
  1235. // end of form_fields (procedure)
  1236.  
  1237.  
  1238.  
  1239. ***
  1240. * form_insert (procedure)
  1241. *
  1242. * insert a column (field) in the report file
  1243. *
  1244. * insert a field only when:
  1245. *   a) field is not the first one, first time
  1246. *   b) field is not the last one
  1247. *   c) total field count is not larger than maximum, 24
  1248. *
  1249. * Purpose:
  1250. *  shifts fields up by one, inserts a new one
  1251. * Note: Field that is left blank creates an error in expression area.
  1252. *       Delete 'unused' field to avoid this.
  1253. *
  1254. ***
  1255. PROCEDURE form_insert
  1256. PARAMETERS dummy1, dummy2, dummy3
  1257.  
  1258. PRIVATE saved_record, insert_error, temp
  1259.  
  1260. insert_error = "(Cannot insert field. Insert (F6) invalid here, or maximum is reached)."
  1261.  
  1262. IF RECNO() != 1 .AND. RECNO() != LASTREC() .AND. RECCOUNT() < 24 .AND. !EMPTY(form_dbf->contents)
  1263.  
  1264.     * save position before insert call
  1265.     saved_record = RECNO()
  1266.  
  1267.     * new field, return Boolean to insert_flag for processing in form_fields
  1268.    insert_flag = insert_blank(RECNO())
  1269.     
  1270.     * restore record#
  1271.     GO saved_record
  1272.  
  1273.     * add an item in array, starting at ar_index pos
  1274.     FOR temp = ar_index TO ar_index + 3
  1275.         ains(chdr_lines, ar_index)
  1276.         chdr_lines[ar_index] = SPACE(65)        // no (U) here!
  1277.     NEXT
  1278.  
  1279.    * increment field count variables
  1280.     total_fields = total_fields + 1
  1281.     frm_colcount = frm_colcount + 1
  1282.  
  1283.     * initialize new field
  1284.     m_contents = SPACE(254)
  1285.     REPLACE form_dbf->contents WITH SPACE(254)
  1286.     REPLACE form_dbf->header   WITH SPACE(260)
  1287.     REPLACE form_dbf->width    WITH 10
  1288.     REPLACE form_dbf->totals   WITH "N"
  1289.     REPLACE form_dbf->decimals WITH 0
  1290.  
  1291.     * no update flag for insert
  1292.     my_update = .F.
  1293.  
  1294. ELSE
  1295.  
  1296.     @ 24,CENTER(insert_error,80) SAY insert_error
  1297.     INKEY(4)
  1298. ENDIF
  1299.  
  1300. RETURN
  1301. // end of form_insert (procedure)
  1302.  
  1303.  
  1304.  
  1305. ***
  1306. *  insert_blank (function)
  1307. *
  1308. *  insert a blank record in dbf at position 'pos'
  1309. *
  1310. ***
  1311. FUNCTION insert_blank
  1312. PARAMETERS pos
  1313.  
  1314. PRIVATE inserted
  1315.  
  1316. // yes, we are inserting, set flag
  1317. inserted = .T.
  1318.  
  1319. // set position for insert
  1320. @ 3,0 SAY "Insert at field " + LTRIM(STR(pos)) + " ..."
  1321.  
  1322. // position
  1323. GO pos
  1324.  
  1325. // make temp file, copy the rest of file
  1326. COPY NEXT LASTREC() TO temp
  1327.  
  1328. // mark them, delete
  1329. DELETE ALL FOR RECNO() >= pos
  1330.  
  1331. // add a new one
  1332. APPEND BLANK
  1333.  
  1334. // get the tail list
  1335. APPEND FROM temp
  1336.  
  1337. // remove deleted items
  1338. PACK
  1339.  
  1340. // delete temporary work file, insertion done!
  1341. DELETE FILE temp.DBF
  1342.  
  1343. RETURN (inserted)
  1344. // end of insert_blank (function)
  1345.  
  1346.  
  1347.  
  1348. ***
  1349. * form_delete (procedure)
  1350. *
  1351. * purpose:
  1352. *    delete a column (field) in the report file
  1353. *
  1354. * delete a field when the field is already blank
  1355. * so user has the option to abort process.
  1356. *
  1357. * note: a deletion sets the my_update flag so the file may
  1358. *       be saved to disk.
  1359. ***
  1360. PROCEDURE form_delete
  1361. PARAMETERS dummy1, dummy2, dummy3
  1362.  
  1363. PRIVATE temp, saved_record, content_error
  1364.  
  1365. content_error = "(Field must be blank to do that.  Use Ctrl-Y to delete)."
  1366.  
  1367. // field contents is empty, OK to delete
  1368. IF EMPTY(m_contents)
  1369.  
  1370.     * remove items in array, starting at ar_index pos
  1371.     FOR temp = ar_index TO ar_index + 3
  1372.         adel(chdr_lines, ar_index)
  1373.         chdr_lines[LEN(chdr_lines)] = SPACE(65)        // no (U) here!
  1374.     NEXT
  1375.  
  1376.     * save this record before delete
  1377.     saved_record = RECNO()
  1378.  
  1379.     DELETE
  1380.     PACK
  1381.  
  1382.     * reset insert flag, in case of 'insert-notyping-delete' process
  1383.     insert_flag = .F.
  1384.  
  1385.     IF !EOF()
  1386.  
  1387.         IF saved_record = total_fields
  1388.               GO saved_record - 1
  1389.             IF ar_index > 1
  1390.                 ar_index = ar_index - 4
  1391.             ENDIF
  1392.         ELSE
  1393.               GO saved_record
  1394.         ENDIF
  1395.  
  1396.     ELSE
  1397.  
  1398.         APPEND BLANK
  1399.  
  1400.         REPLACE form_dbf->contents WITH SPACE(254)
  1401.     REPLACE form_dbf->header   WITH SPACE(260)
  1402.         REPLACE form_dbf->width    WITH 10
  1403.         REPLACE form_dbf->totals   WITH "N"
  1404.         REPLACE form_dbf->decimals WITH  0
  1405.  
  1406.     ENDIF
  1407.  
  1408.     IF total_fields > 1
  1409.         total_fields = total_fields - 1
  1410.         frm_colcount = frm_colcount - 1
  1411.     ENDIF
  1412.  
  1413.     * get the new data
  1414.     m_contents = form_dbf->contents
  1415.     m_width    = form_dbf->width
  1416.     m_decimals = form_dbf->decimals
  1417.     m_totals   = form_dbf->totals
  1418.  
  1419.     my_update = .T.        // generates an update...
  1420.  
  1421. ELSE    // field content is not empty, error
  1422.  
  1423.     * honk 
  1424.     ?? CHR(7)
  1425.  
  1426.     * display the error msg
  1427.     @ 24,CENTER(content_error,80) SAY content_error
  1428.     INKEY(4)
  1429. ENDIF
  1430.  
  1431. RETURN
  1432. // end of form_delete (procedure)
  1433.  
  1434.  
  1435.  
  1436. ***
  1437. *    form_goto (procedure)
  1438. *
  1439. *    goto specified field (F7)
  1440. ***
  1441. PROCEDURE form_goto
  1442.  
  1443. PRIVATE goto_str, goto_field, goto_error, goto_ok, recno_saved
  1444.  
  1445. * for this procedure only
  1446. SET CONFIRM ON
  1447.  
  1448. goto_str   = "Go to field number "
  1449. goto_error = "(Field not in valid range.  Range is 1 to 24)."
  1450. goto_field = RECNO()
  1451.  
  1452. goto_ok = .F.
  1453. DO WHILE !goto_ok
  1454.  
  1455.     @ 24,0
  1456.     @ 24,20 SAY goto_str
  1457.     @ 24,39 GET goto_field PICTURE "99"
  1458.     READ
  1459.  
  1460.    * abort if <esc> key was hit
  1461.    IF LASTKEY() == 27
  1462.       RETURN   
  1463.    ENDIF
  1464.  
  1465.    * save, to restore if error (eof)
  1466.    recno_saved = RECNO()
  1467.  
  1468.    * first check
  1469.    GO goto_field
  1470.  
  1471.    * entry ok?
  1472.    IF goto_field <= 0 .OR. goto_field >= 25 .OR. EOF()
  1473.         @ 24,CENTER(goto_error,80) SAY goto_error
  1474.         INKEY(4)
  1475.       IF EOF()
  1476.          GO recno_saved
  1477.       ENDIF
  1478.     ELSE
  1479.         goto_ok = .T.
  1480.     ENDIF
  1481.  
  1482. ENDDO
  1483.  
  1484. // new field position
  1485. GO goto_field
  1486.  
  1487. // set ar_index to new position
  1488. ar_index = (goto_field * 4) - 3
  1489.  
  1490. // the data of the new position
  1491. m_contents = form_dbf->contents
  1492. m_width    = form_dbf->width
  1493. m_decimals = form_dbf->decimals
  1494. m_totals   = form_dbf->totals
  1495.  
  1496. // set back to default
  1497. SET CONFIRM OFF
  1498.  
  1499. RETURN
  1500. // end of form_goto (procedure)
  1501.  
  1502.  
  1503.  
  1504. ***
  1505. *    clear_gets (procedure)
  1506. *
  1507. *    exit read
  1508. ***
  1509. PROCEDURE clear_gets
  1510. PARAMETERS dummy1,dummy2,dummy3
  1511.  
  1512. IF form_state = 3    // break out of loop when in fields procedure only
  1513.     break_out = .T.
  1514. ENDIF
  1515. CLEAR GETS
  1516. RETURN
  1517. // end of clear_gets (procedure)
  1518.  
  1519.  
  1520.  
  1521. ***
  1522. * form_layout (procedure)
  1523. *
  1524. * display the pageheading and items related to report layout
  1525. ***
  1526. PROCEDURE form_layout
  1527.  
  1528. FRM_SCR(1)
  1529.  
  1530. SET CURSOR ON
  1531.  
  1532. SET KEY -4 TO     // no delete option
  1533. SET KEY -5 TO  // no insert option
  1534. SET KEY -6 TO    // no goto option here
  1535. SET KEY -1 TO    // disable this option
  1536.  
  1537. @ 06,12 GET phdr_lines[1]
  1538. @ 07,12 GET phdr_lines[2]
  1539. @ 08,12 GET phdr_lines[3]
  1540. @ 09,12 GET phdr_lines[4]
  1541.     
  1542. @ 12,42 GET frm_pagewidth PICTURE "999"
  1543. @ 13,42 GET frm_leftmarg  PICTURE "999"
  1544. @ 14,42 GET frm_rightmarg PICTURE "999"
  1545. @ 15,42 GET frm_linespage PICTURE "999"
  1546. @ 16,42 GET frm_dblspaced PICTURE "!"
  1547.             
  1548. @ 20,49 GET frm_pebp      PICTURE "!"
  1549. @ 21,49 GET frm_peap      PICTURE "!"
  1550. @ 22,49 GET frm_plainpage PICTURE "!"
  1551.             
  1552. READ
  1553.  
  1554. IF UPDATED()
  1555.     my_update = .T.
  1556. ENDIF
  1557.  
  1558. RETURN
  1559. // end of form_layout (procedure)
  1560.  
  1561.  
  1562.  
  1563. ***
  1564. * form_groups (procedure)
  1565. *
  1566. * display the group and subgroup headers, plus summary and eject options
  1567. ***
  1568. PROCEDURE form_groups
  1569.  
  1570. FRM_SCR(2)
  1571.  
  1572. SET CURSOR ON
  1573.  
  1574. SET KEY -4 TO     // no delete option here
  1575. SET KEY -5 TO  // no insert option here
  1576. SET KEY -6 TO    // no goto option here
  1577.  
  1578. SET KEY -2 TO    // disable this option
  1579.  
  1580. @ 06,25 GET frm_grpexpr PICTURE "@S50"
  1581. @ 07,25 GET frm_grphdr
  1582.  
  1583. @ 11,23 GET frm_summary PICTURE "!"
  1584. @ 12,23 GET frm_pe PICTURE "!"
  1585.  
  1586. @ 18,25 GET frm_subexpr PICTURE "@S50"
  1587. @ 19,25 GET frm_subhdr
  1588.  
  1589. READ    
  1590.     
  1591. IF UPDATED()
  1592.     my_update = .T.
  1593. ENDIF
  1594.  
  1595. RETURN
  1596. // end of form_groups (procedure)
  1597.  
  1598.  
  1599.  
  1600. ***
  1601. * frm_scr (function)
  1602. *
  1603. * draw the report screens, indicated by parameter 'screen'
  1604. ***
  1605. FUNCTION FRM_SCR
  1606. PARAMETERS screen
  1607.  
  1608. PRIVATE pagehead, field_def, group, sub_group, m_exit, m_nogo
  1609. PRIVATE m_f1, m_f2, m_f3, m_f4, m_f5, m_f6, m_f10, m_layout, m_groups, m_fields
  1610. PRIVATE m_insert, m_delete, m_help
  1611.  
  1612. pagehead  = "═══ Page Header ═══"
  1613. field_def = "═══ Column Definitions ═══"
  1614. group     = "═══ Group Specifications ═══"
  1615. sub_group = "═══ Sub-Group Specifications ═══"
  1616.  
  1617. m_f1  = "F1"
  1618. m_f2  = "F2"
  1619. m_f3  = "F3"
  1620. m_f4  = "F4"
  1621. m_f5  = "F5"
  1622. m_f6  = "F6"
  1623. m_f7  = "F7"
  1624. m_f10 = "F10"
  1625.  
  1626. m_help   = "Help  "
  1627. m_layout = "Report"         // "Layout"
  1628. m_groups = "Groups"
  1629. m_fields = "Columns"        //    "Fields"
  1630. m_delete = "Delete"
  1631. m_insert = "Insert"
  1632. m_goto   = "Go To "
  1633. m_exit   = "Exit  "
  1634. m_nogo   = "...    "
  1635.  
  1636. CLEAR
  1637.  
  1638. // Display menu line.
  1639. @ 00,01 SAY m_f1
  1640. @ 00,11 SAY m_f2
  1641. @ 00,21 SAY m_f3
  1642. @ 00,31 SAY m_f4
  1643. @ 00,41 SAY m_f5
  1644. @ 00,51 SAY m_f6
  1645. @ 00,61 SAY m_f7
  1646. @ 00,70 SAY m_f10
  1647.  
  1648. @ 01,01 SAY m_help
  1649. @ 01,11 SAY m_layout
  1650. @ 01,21 SAY m_groups
  1651. @ 01,31 SAY m_fields
  1652. @ 01,41 SAY m_delete
  1653. @ 01,51 SAY m_insert
  1654. @ 01,61 SAY m_goto
  1655. @ 01,70 SAY m_exit
  1656.  
  1657. @ 02,00 SAY REPLICATE(CHR(196),80)
  1658.  
  1659. DO CASE
  1660.  
  1661.     CASE screen == 1
  1662.         * Page definition screen.
  1663.  
  1664.         @ 01,11 SAY m_nogo   // this option 'disabled'
  1665.         @ 01,41 SAY m_nogo     // delete 'disabled'
  1666.         @ 01,51 SAY m_nogo   // insert 'disabled'
  1667.         @ 01,61 SAY m_nogo     // go to  'disabled'
  1668.  
  1669.         @ 03,80-LEN("File " + form_file) SAY "File " + form_file
  1670.  
  1671.         @ 04,30 SAY pagehead
  1672.  
  1673.         @ 11,27 SAY "Formatting "
  1674.     
  1675.         @ 12,27 SAY "Page Width"
  1676.         @ 13,27 SAY "Left Margin"
  1677.         @ 14,27 SAY "Right Margin"
  1678.         @ 15,27 SAY "Lines Per Page"
  1679.         @ 16,27 SAY "Double Spaced?"
  1680.     
  1681.         @ 19,24 SAY "Printer Directives"
  1682.  
  1683.         @ 20,24 SAY "Page Eject Before Print"
  1684.         @ 21,24 SAY "Page Eject After Print"
  1685.         @ 22,24 SAY "Plain Page"
  1686.  
  1687.     CASE screen == 2
  1688.         * Group definition screen.
  1689.  
  1690.         @ 01,21 SAY m_nogo   // this option 'disabled'
  1691.         @ 01,41 SAY m_nogo    // delete 'disabled'
  1692.         @ 01,51 SAY m_nogo   // insert 'disabled'
  1693.         @ 01,61 SAY m_nogo    // go to  'disabled'
  1694.  
  1695.         @ 03,80-LEN("File " + form_file) SAY "File " + form_file
  1696.  
  1697.         @ 04,CENTER(group,80) SAY group
  1698.  
  1699.         @ 06,0 SAY "Group On Expression"
  1700.         @ 07,0 SAY "Group Heading" 
  1701.  
  1702.         @ 11,0 SAY "Summary Report Only"
  1703.         @ 12,0 SAY "Page Eject After Group"
  1704.  
  1705.         @ 16,CENTER(sub_group, 80) SAY sub_group
  1706.  
  1707.         @ 18,0 SAY "Sub-Group On Expression"
  1708.         @ 19,0 SAY "Sub-Group Heading"
  1709.  
  1710.     CASE screen == 3
  1711.  
  1712.         * Column definition screen.
  1713.         @ 03,80-LEN("File " + form_file) SAY "File " + form_file
  1714.         @ 01,31 SAY m_nogo
  1715.  
  1716.         @ 05,CENTER(field_def, 80) SAY field_def
  1717.  
  1718.         @ 07,00 SAY "Contents"
  1719.         @ 10,00 SAY "Heading"
  1720.  
  1721.         @ 11,06 SAY "1"
  1722.         @ 12,06 SAY "2"
  1723.         @ 13,06 SAY "3"
  1724.      @ 14,06 SAY "4"
  1725.         @ 18,00 SAY "Formatting"
  1726.  
  1727.         @ 19,00 SAY "Width"
  1728.         @ 20,00 SAY "Decimals"
  1729.         @ 21,00 SAY "Totals"
  1730.  
  1731. ENDCASE
  1732.  
  1733. RETURN ("")
  1734. // end of frm_scr (function)
  1735.  
  1736.  
  1737.  
  1738. ***
  1739. * frm_error (function)
  1740. *
  1741. * display the report file errors
  1742. ****
  1743. FUNCTION FRM_ERROR
  1744. PARAMETERS fname, dos_error
  1745.  
  1746. PRIVATE err_str, dos_code
  1747.  
  1748. dos_code = LTRIM(STR(dos_error))
  1749.  
  1750. DO CASE
  1751.  
  1752.     CASE dos_error == -3        // eof while reading
  1753.          err_str = "Code " + dos_code + " " + "eof while reading report " + fname
  1754.  
  1755.     CASE dos_error == -2        // disk full
  1756.          err_str = "Code " + dos_code + " " + "disk full saving report " + fname
  1757.  
  1758.     CASE dos_error == -1        // not a report file
  1759.          err_str = "Code " + dos_code + " " + "not a report file " + fname
  1760.  
  1761.     CASE dos_error == 2        // Open error, file not found
  1762.          err_str = "Code " + dos_code + " " + "error opening report " + fname
  1763.  
  1764.     CASE dos_error == 6        // Close error, invalid handle
  1765.         err_str = "Code " + dos_code + " " + "error closing report " + fname
  1766.  
  1767.    CASE dos_error == 25   // Seek error, FSEEK
  1768.         err_str = "Code " + dos_code + " " + "error seeking report " + fname
  1769.  
  1770.     CASE dos_error == 29        // Write error, write fault
  1771.         err_str = "Code " + dos_code + " " + "error writing report " + fname
  1772.  
  1773.     CASE dos_error == 30        // Read error, read fault
  1774.         err_str = "Code " + dos_code + " " + "error reading report " + fname
  1775.  
  1776.   OTHERWISE
  1777.         err_str = "Code " + dos_code + " " + "see DOS extended error codes"
  1778.  
  1779. ENDCASE
  1780.  
  1781. @ 24,CENTER(err_str,80) SAY err_str
  1782. INKEY(4)
  1783. @ 24,0
  1784.  
  1785. RETURN ("")
  1786. // end of frm_error (function)
  1787.  
  1788.  
  1789.  
  1790. ***
  1791. * lbl_error (function)
  1792. *
  1793. * display the label file errors
  1794. ***
  1795. FUNCTION LBL_ERROR
  1796. PARAMETERS fname, dos_error
  1797.  
  1798. PRIVATE err_str, dos_code
  1799.  
  1800. dos_code = LTRIM(STR(dos_error))
  1801.  
  1802. DO CASE
  1803.  
  1804.     CASE dos_error == -3        // eof while reading
  1805.          err_str = "Code " + dos_code + " " + "eof while reading label " + fname
  1806.  
  1807.     CASE dos_error == -2        // disk full
  1808.          err_str = "Code " + dos_code + " " + "disk full saving label " + fname
  1809.  
  1810.     CASE dos_error == -1        // not a label file
  1811.          err_str = "Code " + dos_code + " " + "not a label file " + fname
  1812.  
  1813.     CASE dos_error == 2        // Open error, file not found
  1814.          err_str = "Code " + dos_code + " " + "error opening label " + fname
  1815.  
  1816.     CASE dos_error == 6        // Close error, invalid handle
  1817.         err_str = "Code " + dos_code + " " + "error closing label " + fname
  1818.  
  1819.    CASE dos_error == 25   // Seek error, FSEEK
  1820.         err_str = "Code " + dos_code + " " + "error seeking label " + fname
  1821.  
  1822.     CASE dos_error == 29        // Write error, write fault
  1823.         err_str = "Code " + dos_code + " " + "error writing label " + fname
  1824.  
  1825.     CASE dos_error == 30        // Read error, read fault
  1826.         err_str = "Code " + dos_code + " " + "error reading label " + fname
  1827.  
  1828.   OTHERWISE
  1829.         err_str = "Code " + dos_code + " " + "see DOS extended error codes"
  1830.  
  1831. ENDCASE
  1832.  
  1833. @ 24,CENTER(err_str,80) SAY err_str
  1834. INKEY(4)
  1835. @ 24,0
  1836.  
  1837. RETURN ("")
  1838. // end of lbl_error (function)
  1839.  
  1840.  
  1841.  
  1842. ***
  1843. * center (function)
  1844. *
  1845. * center a string
  1846. ***
  1847. FUNCTION CENTER
  1848. PARAMETER string,length
  1849. RETURN INT((length-LEN(string))/2)
  1850.  
  1851. //**
  1852. // ext_add (function)
  1853. //
  1854. // append an .FRM/.LBL extension if one was not found
  1855. //**
  1856. FUNCTION EXT_ADD
  1857. PARAMETERS fname, type
  1858.  
  1859. PRIVATE open
  1860.  
  1861. IF AT(".", fname) == 0
  1862.     IF type == "L"
  1863.         open = TRIM(fname) + ".LBL"
  1864.     ENDIF
  1865.     IF type == "R"
  1866.         open = TRIM(fname) + ".FRM"
  1867.     ENDIF
  1868. ELSE
  1869.     open = TRIM(fname)
  1870. ENDIF
  1871.  
  1872. RETURN (open)
  1873. // end of ext_add (function)
  1874.  
  1875.  
  1876.  
  1877. ***
  1878. * Xlate()
  1879. *    Translate the semicolons
  1880. ***
  1881. FUNCTION XLATE
  1882. PARAMETERS source, char, len
  1883.  
  1884. PRIVATE xlated_str
  1885.  
  1886. fend_pos = AT(char, SUBSTR(source, fstart_pos, len))
  1887.  
  1888. IF fend_pos = 0
  1889.     xlated_str = SUBSTR(source, fstart_pos, len)
  1890.     fstart_pos = fstart_pos + LEN(xlated_str)
  1891. ELSE
  1892.     xlated_str = SUBSTR(source, fstart_pos, fend_pos - 1)
  1893.     fstart_pos = fstart_pos + LEN(xlated_str) + 1
  1894. ENDIF
  1895.  
  1896. // pad string with spaces when needed
  1897. IF LEN(xlated_str) != len
  1898.     xlated_str = xlated_str + SPACE(len - LEN(xlated_str))
  1899. ENDIF
  1900.  
  1901. RETURN (xlated_str)
  1902.