home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a009 / 6.ddi / RL.LIF / RLFRONT.PRG < prev   
Encoding:
Text File  |  1991-04-14  |  37.7 KB  |  1,844 lines

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