home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a009 / 6.ddi / DBU.LIF / DBUEDIT.PRG < prev    next >
Encoding:
Text File  |  1991-04-14  |  19.9 KB  |  1,044 lines

  1. /***********
  2. *    Program....:  DBU
  3. *    Filename...:  DBUEDIT.PRG
  4. *    Author.....:  Dennis L. Dias
  5. *    Date.......:  06/18/86, 06/18/90, 03/26/91
  6. *    Purpose....:  Data File Editing Module
  7. *
  8. *    Copyright (c) 1986-1991 Nantucket Corp., All Rights Reserved.
  9. */
  10.  
  11. #include "inkey.ch"
  12. #include "memoedit.ch"
  13.  
  14.  
  15. /***
  16. *    browse
  17. *
  18. *    browse one file or the entire View
  19. */
  20. proc browse
  21.  
  22. local i,j,nHelpSave,cNtx,cFieldArray,cFieldName,nWa,cMemo,oB,nRec,;
  23.     cBrowseBuf,nPrimeArea,nHsepRow,cEditField,bAlias,cAlias,nCType,;
  24.     cHead,lMore,lCanAppend,cMemoBuff,aMoveExp,cPrimeDbf,;
  25.     nColorSave,lAppend,lGotKey,lKillAppend,bColBlock
  26. memvar keystroke,help_code,func_sel,cur_area,cur_dbf,field_list,frame,;
  27.     curs_on,cur_ntx,ntx1,dbf,local_func,box_open,;
  28.     color1,color7,color8,color9
  29.  
  30.     /* turn off cursor */
  31.     nCType := SetCursor(0)
  32.     curs_on := .f.
  33.  
  34.     /* save prev help code */
  35.     nHelpSave := help_code
  36.  
  37.     /* save, clear, and frame the window */
  38.     cBrowseBuf := SaveScreen(8, 0, 23, 79)
  39.  
  40.     /* array to save move_ptr expressions */
  41.     aMoveExp := Array(4)
  42.     AFill(aMoveExp, "")
  43.  
  44.     /* heading separator row if only one database */
  45.     nHsepRow := 11
  46.  
  47.     /* determine what to browse */
  48.     if ( func_sel == 1 )
  49.         /* browse one file */
  50.         nPrimeArea := cur_area
  51.         cFieldArray := "field_n" + Substr("123456", cur_area, 1)
  52.         cNtx := "ntx" + Substr("123456", cur_area, 1)
  53.         cur_ntx := &cNtx[1]
  54.         cPrimeDbf := Substr(cur_dbf, Rat("\", cur_dbf) + 1)
  55.         lCanAppend := .T.
  56.     else
  57.         /* browse the entire view */
  58.         nPrimeArea := 1
  59.         cFieldArray := "field_list"
  60.         cur_ntx := ntx1[1]
  61.         cPrimeDbf := Substr(dbf[1], Rat("\", dbf[1]) + 1)
  62.         lCanAppend := .F.
  63.  
  64.         if ( "->" $ field_list[afull(field_list)] )
  65.             nHsepRow := 12
  66.         end
  67.     end
  68.  
  69.     /* block to extract alias from alias->field */
  70.     bAlias := &("{|i| if('->' $" + cFieldArray + "[i], Substr(" +;
  71.                 cFieldArray + "[i], 1, At('->'," + cFieldArray +;
  72.                 "[i]) - 1), '')}")
  73.  
  74.     Select(nPrimeArea)
  75.     if ( Eof() )
  76.         /* end of file not allowed */
  77.         go top
  78.     end
  79.  
  80.     /* misc */
  81.     lAppend := .F.
  82.     nRec := 0
  83.  
  84.     /* create TBrowse object */
  85.     nColorSave := SetColor(color7)
  86.     oB := TBrowseDB(10, 1, 23, 78)
  87.  
  88.     oB:headSep := "═╤═"
  89.     oB:colSep  := " │ "
  90.     oB:footSep := "═╧═"
  91.     oB:skipBlock := {|x| Skipped(x, lAppend)}
  92.  
  93.     /* put columns into browse */
  94.     j := Len(&cFieldArray)
  95.     for i := 1 TO j
  96.         if ( Empty(&cFieldArray[i]) )
  97.             EXIT
  98.         end
  99.  
  100.         /* determine workarea/alias stuff */
  101.         cEditField := &cFieldArray[i]
  102.         if ( "->" $ cEditField )
  103.             cAlias := Substr(cEditField, 1, At("->", cEditField) + 1)
  104.             cFieldName := Substr(cEditField, At("->", cEditField) + 2)
  105.             cHead := cAlias + ";" + cFieldName
  106.             nWa := Select(cAlias)
  107.         else
  108.             cAlias := ""
  109.             cFieldName := cHead := cEditField
  110.             nWa := Select()
  111.         end
  112.  
  113.         /* memos are handled differently */
  114.         if ( ValType(&cEditField) == "M" )
  115.             bColBlock := &("{|| '  <Memo>  '}")
  116.         else
  117.             bColBlock := FieldWBlock(cFieldName, nWa)
  118.         end
  119.  
  120.         /* add one column */
  121.         oB:addColumn(TBColumnNew(cHead, bColBlock))
  122.     next
  123.  
  124.     /* initialize parts of screen not handled by TBrowse */
  125.     stat_msg("")
  126.     scroll(8, 0, 23, 79, 0)
  127.     @ 8, 0, 23, 79 BOX frame
  128.     @ nHsepRow, 0 SAY "╞"
  129.     @ nHsepRow, 79 SAY "╡"
  130.  
  131.     /* init rest of locals */
  132.     cAlias := ""
  133.     lKillAppend := .f.
  134.     if ( (LastRec() == 0) .and. lCanAppend )
  135.         /* empty file..force append mode */
  136.         keystroke := K_DOWN
  137.         lGotKey := .t.
  138.     else
  139.         lGotKey := .f.
  140.     end
  141.  
  142.     lMore := .t.
  143.     while (lMore)
  144.         if ( !lGotKey )
  145.             /* keystroke will interrupt stabilize */
  146.             while ( !oB:stabilize() )
  147.                 if ( (keystroke := Inkey()) != 0 )
  148.                     lGotKey := .t.
  149.                     exit
  150.                 end
  151.             end
  152.         end
  153.  
  154.         if ( !lGotKey )
  155.             if ( oB:hitBottom .and. lCanAppend )
  156.                 /* turn on or continue append mode */
  157.                 if ( !lAppend .or. Recno() != LastRec() + 1 )
  158.                     if ( lAppend )
  159.                         /* continue append mode */
  160.                         oB:refreshCurrent()
  161.                         while ( !oB:stabilize() ) ; end
  162.                         go bottom
  163.                     else
  164.                         /* first append */
  165.                         lAppend := .t.
  166.                         SetCursor(1)
  167.                         curs_on := .t.
  168.                     end
  169.  
  170.                     /* move down and stabilize to set rowPos */
  171.                     oB:down()
  172.                     while ( !oB:stabilize() ) ; end
  173.                     oB:colorRect({oB:rowPos,1,oB:rowPos,oB:colCount},{2,2})
  174.                 end
  175.             end
  176.  
  177.             /* display status */
  178.             cAlias := Eval(bAlias, oB:colPos)
  179.             statline(oB, lAppend, cAlias)
  180.  
  181.             /* stabilize again for correct cursor pos */
  182.             while ( !oB:stabilize() ) ; end
  183.  
  184.             /* idle */
  185.             keystroke := Inkey(0)
  186.         else
  187.             /* reset for next loop */
  188.             lGotKey := .f.
  189.         end
  190.  
  191.         do case
  192.         case keystroke == K_DOWN
  193.             if ( lAppend )
  194.                 oB:hitBottom := .t.
  195.             else
  196.                 oB:down()
  197.             end
  198.  
  199.         case keystroke == K_UP
  200.             if ( lAppend )
  201.                 lKillAppend := .t.
  202.             else
  203.                 oB:up()
  204.             end
  205.  
  206.         case keystroke == K_PGDN
  207.             if ( lAppend )
  208.                 oB:hitBottom := .t.
  209.             else
  210.                 oB:pageDown()
  211.             end
  212.  
  213.         case keystroke == K_PGUP
  214.             if ( lAppend )
  215.                 lKillAppend := .t.
  216.             else
  217.                 oB:pageUp()
  218.             end
  219.  
  220.         case keystroke == K_CTRL_PGUP
  221.             if ( lAppend )
  222.                 lKillAppend := .t.
  223.             else
  224.                 oB:goTop()
  225.             end
  226.  
  227.         case keystroke == K_CTRL_PGDN
  228.             if ( lAppend )
  229.                 lKillAppend := .t.
  230.             else
  231.                 oB:goBottom()
  232.             end
  233.  
  234.         case keystroke == K_RIGHT
  235.             oB:right()
  236.  
  237.         case keystroke == K_LEFT
  238.             oB:left()
  239.  
  240.         case keystroke == K_HOME
  241.             oB:home()
  242.  
  243.         case keystroke == K_END
  244.             oB:end()
  245.  
  246.         case keystroke == K_CTRL_LEFT
  247.             oB:panLeft()
  248.  
  249.         case keystroke == K_CTRL_RIGHT
  250.             oB:panRight()
  251.  
  252.         case keystroke == K_CTRL_HOME
  253.             oB:panHome()
  254.  
  255.         case keystroke == K_CTRL_END
  256.             oB:panEnd()
  257.  
  258.         case keystroke == K_DEL
  259.             /* toggle deleted() flag */
  260.             while ( !oB:stabilize() ) ; end
  261.             cAlias := Eval(bAlias, oB:colPos)
  262.             if ( !Empty(cAlias) )
  263.                 Select(cAlias)
  264.             end
  265.  
  266.             if ( Recno() != Lastrec() + 1 )
  267.                 if Deleted()
  268.                     recall
  269.                 else
  270.                     delete
  271.                 end
  272.             end
  273.  
  274.             Select(nPrimeArea)
  275.  
  276.         case keystroke == K_INS
  277.             /*toggle insert mode */
  278.             tog_insert()
  279.  
  280.         case keystroke == K_RETURN
  281.             /* edit the current field */
  282.             while ( !oB:stabilize() ) ; end
  283.             cAlias := Eval(bAlias, oB:colPos)
  284.  
  285.             if ( !Empty(cAlias) )
  286.                 Select(cAlias)
  287.             end
  288.  
  289.              if ( !lAppend .and. (Recno() == LastRec() + 1) )
  290.                 Select(nPrimeArea)
  291.                 loop    /* NOTE */
  292.             end
  293.  
  294.             Select(nPrimeArea)
  295.  
  296.             /* make sure the display is correct */
  297.             oB:hitTop := .f.
  298.             Statline(oB, lAppend, cAlias)
  299.             while ( !oB:stabilize() ) ; end
  300.  
  301.             cEditField := &cFieldArray[oB:colPos]
  302.  
  303.             /* turn the cursor on */
  304.             SetCursor(1)
  305.             curs_on := .t.
  306.  
  307.             if ( Type(cEditField) == "M" )
  308.                 /* edit memo field */
  309.                 help_code := 19
  310.                 box_open := .t.
  311.  
  312.                 /* save, clear, and frame window for memoedit */
  313.                 cMemoBuff := SaveScreen(10, 10, 22, 69)
  314.  
  315.                 SetColor(color8)
  316.                 Scroll(10, 10, 22, 69, 0)
  317.                 @ 10, 10, 22, 69 BOX frame
  318.  
  319.                 /* use fieldspec for title */
  320.                 SetColor(color9)
  321.                 @ 10,((76 - Len(cEditField)) / 2) SAY "  " + cEditField + "  "
  322.  
  323.                 /* edit the memo field */
  324.                 SetColor(color8)
  325.                 cMemo := MemoEdit(&cEditField, 11, 11, 21, 68,.T.,"xmemo")
  326.  
  327.                 if Lastkey() == K_CTRL_END
  328.                     /* ^W..new memo confirmed */
  329.  
  330.                     if ( lAppend .and. Eof() )
  331.                         /* first data in new record */
  332.                         append blank
  333.                     end
  334.  
  335.                     /* put it there */
  336.                     replace &cEditField WITH cMemo
  337.                     oB:refreshCurrent()
  338.  
  339.                     /* move to next field */
  340.                     keystroke := K_RIGHT
  341.                     lGotKey := .t.
  342.                 else
  343.                     keystroke := 0
  344.                 end
  345.  
  346.                 /* restore the window */
  347.                 RestScreen(10, 10, 22, 69, cMemoBuff)
  348.                 box_open := .F.
  349.             else
  350.                 /* regular data entry */
  351.                 SetColor(color1)
  352.                 keystroke := DoGet(oB, lAppend, cAlias)
  353.                 lGotKey := ( keystroke != 0 )
  354.             end
  355.  
  356.             /* turn off the cursor unless append mode */
  357.             if ( !lAppend )
  358.                 SetCursor(0)
  359.                 curs_on := .f.
  360.             end
  361.  
  362.             help_code := nHelpSave
  363.             SetColor(color7)
  364.  
  365.         otherwise
  366.             if ( isdata(keystroke) )
  367.                 /* forward data keystroke to GET system */
  368.                 keyboard Chr(K_RETURN) + Chr(keystroke)
  369.             else
  370.                 /* check for menu request */
  371.                 sysmenu()
  372.  
  373.                 do case
  374.                 case q_check()
  375.                     /* exit */
  376.                     lMore := .f.
  377.  
  378.                 case local_func == 1
  379.                     /* help requested */
  380.                     DO syshelp
  381.  
  382.                 case local_func == 7
  383.                     /* move option selected..only the primary can be moved */
  384.                     nRec := Recno()
  385.                     move_ptr(aMoveExp, cPrimeDbf)
  386.  
  387.                     if ( nRec != Recno() )
  388.                         if ( lAppend )
  389.                             /* no more append mode */
  390.                             lKillAppend := .t.
  391.                         else
  392.                             FreshOrder(oB)
  393.                         end
  394.                     end
  395.                 end
  396.             end
  397.         end
  398.  
  399.         if ( lKillAppend )
  400.             /* turn off append mode */
  401.             lKillAppend := .f.
  402.             lAppend := .f.
  403.  
  404.             /* refresh respecting any change in index order */
  405.             FreshOrder(oB)
  406.             SetCursor(0)
  407.             curs_on := .f.
  408.         end
  409.     end
  410.  
  411.     /* restore the screen */
  412.     RestScreen(8, 0, 23, 79, cBrowseBuf)
  413.     SetColor(nColorSave)
  414.     SetCursor(nCType)
  415.     curs_on := (nCType != 0)
  416.     stat_msg("")
  417.  
  418. return
  419.  
  420.  
  421. /***
  422. *    xmemo()
  423. *
  424. *    memoedit user function
  425. */
  426. func xmemo(mmode, line, col)
  427. local nRet
  428. memvar keystroke,local_func
  429.  
  430.     nRet := 0
  431.  
  432.     if mmode <> ME_IDLE
  433.         /* check for menu request */
  434.         keystroke := Lastkey()
  435.         sysmenu()
  436.  
  437.         do case
  438.         case local_func == 1
  439.             /* help requested */
  440.             do syshelp
  441.  
  442.         case keystroke == K_INS
  443.             /* insert key pressed */
  444.             tog_insert()
  445.             nRet := ME_IGNORE
  446.  
  447.         case keystroke == K_ESC
  448.             /* escape key pressed */
  449.             if mmode == ME_UNKEYX
  450.                 /* memo has been altered */
  451.                 if rsvp("Ok To Lose Changes? (Y/N)") <> "Y"
  452.                     /* no exit if not confirmed (32 == ignore) */
  453.                     nRet := ME_IGNORE
  454.                 end
  455.             end
  456.         end
  457.     end
  458.  
  459. return (nRet)
  460.  
  461.  
  462. /***
  463. *    tog_insert()
  464. *
  465. *    ditto
  466. */
  467. static func tog_insert
  468. local nCType
  469.  
  470.     Readinsert(!Readinsert())
  471.     nCType := SetCursor(0)
  472.     show_insert()
  473.     SetCursor(nCType)
  474.  
  475. return (0)
  476.  
  477.  
  478. /***
  479. *    show_insert()
  480. *
  481. *    display current insert mode
  482. */
  483. static func show_insert
  484. local nColorSave
  485.  
  486.     nColorSave := SetColor(color7)
  487.     @ 9,4 say if(ReadInsert(), "<Insert>", "        ")
  488.     SetColor(nColorSave)
  489.  
  490. return (0)
  491.  
  492.  
  493. /***
  494. *    statline()
  495. *
  496. *    update the status line in the browse window
  497. */
  498. static func statline(oB, lAppend, cAlias)
  499. local cColorSave, cCurrAlias, lNoFilter, nWaSave, nCType
  500.  
  501.     /* preserve current state */
  502.     nCType := SetCursor(0)
  503.  
  504.     nWaSave := Select()
  505.     if ( !Empty(cAlias) )
  506.         Select(cAlias)
  507.     end
  508.  
  509.     cColorSave := SetColor(color7)
  510.  
  511.     /* show current mode */
  512.     show_insert()
  513.  
  514.     /* show filter status */
  515.     lNoFilter := Empty(&("kf" + Substr("123456", Select(), 1)))
  516.     @ 9,16 say if(lNoFilter, "        ", "<Filter>")
  517.  
  518.     /* display record pointer information */
  519.     @ 9,41 say if(Empty(cAlias), space(10), Lpad(cAlias + "->", 10));
  520.                + "Record "
  521.  
  522.     if ( EmptyFile() .and. .not. lAppend )
  523.         /* file is empty */
  524.         @ 9,58 say "<none>               "
  525.     elseif ( Eof() )
  526.         /* no record number if eof */
  527.         @ 9,28 say "         "
  528.         @ 9,58 say "                " + if(lAppend, "<new>", "<eof>")
  529.     else
  530.         /* normal record..display recno()/lastrec() and deleted() */
  531.         @ 9,28 say if(Deleted(), "<Deleted>", "         ")
  532.         @ 9,58 say Pad(Ltrim(Str(Recno())) + "/" + Ltrim(Str(Lastrec())),15)+;
  533.                    If(oB:hitTop, " <bof>", if(oB:hitBottom, " <eof>", "      "))
  534.     end
  535.  
  536.     /* restore state */
  537.     SetColor(cColorSave)
  538.     Select(nWaSave)
  539.     SetCursor(nCType)
  540.  
  541. return (0)
  542.  
  543.  
  544. /***
  545. *    move_ptr()
  546. *
  547. *    seek, goto, locate, skip
  548. *
  549. *    the following array is defined and initialized in browse:
  550. *        aMoveExp[1] == the last SEEK expression
  551. *        aMoveExp[2] == the last GOTO value
  552. *        aMoveExp[3] == the last LOCATE expressions
  553. *        aMoveExp[4] == the last SKIP value
  554. */
  555. static func move_ptr(aMoveExp, cPrimeDbf)
  556.  
  557. local nHelpSave,aBox
  558. memvar okee_dokee, k_trim, movp_sel, titl_str, exp_label
  559. memvar help_code,local_sel,ntx_expr
  560. private okee_dokee, k_trim, movp_sel, titl_str, exp_label, ntx_expr
  561.  
  562.     nHelpSave := help_code
  563.  
  564.     /* save function select number */
  565.     movp_sel := local_sel
  566.  
  567.     /* initialize expression to previous value, if any */
  568.     k_trim := aMoveExp[movp_sel]
  569.  
  570.     /* set up for multibox */
  571.     aBox := Array(4)
  572.  
  573.     aBox[1] := "movp_title(sysparam)"
  574.     aBox[2] := "movp_exp(sysparam)"
  575.     aBox[3] := "ok_button(sysparam)"
  576.     aBox[4] := "can_button(sysparam)"
  577.  
  578.     do case
  579.     case movp_sel == 1
  580.         /* seek */
  581.         okee_dokee := "do_seek()"
  582.         titl_str := "Seek in file " + cPrimeDbf + "..."
  583.         exp_label := "Expression"
  584.         ntx_expr := Indexkey(0)
  585.         help_code := 13
  586.  
  587.     case movp_sel == 2
  588.         /* goto */
  589.         okee_dokee := "do_goto()"
  590.         titl_str := "Move pointer in file " + cPrimeDbf + " to..."
  591.         exp_label := "Record#"
  592.         help_code := 14
  593.  
  594.     case movp_sel == 3
  595.         /* locate */
  596.         okee_dokee := "do_locate()"
  597.         titl_str := "Locate in file " + cPrimeDbf + "..."
  598.         exp_label := "Expression"
  599.         help_code := 10
  600.  
  601.     case movp_sel == 4
  602.         /* skip */
  603.         okee_dokee := "do_skip()"
  604.         titl_str := "Skip records in file " + cPrimeDbf + "..."
  605.         exp_label := "Number"
  606.         help_code := 20
  607.     end
  608.  
  609.     /* do it */
  610.     set key K_INS to tog_insert
  611.     multibox(14, 17, 5, 2, aBox)
  612.     set key K_INS to
  613.  
  614.     /* save expression for next time */
  615.     aMoveExp[movp_sel] := k_trim
  616.  
  617.     help_code := nHelpSave
  618.  
  619. return (0)
  620.  
  621.  
  622. /***
  623. *    movp_title()
  624. *
  625. *    display title for move pointer functions
  626. */
  627. func movp_title(sysparam)
  628. memvar titl_str
  629. return (box_title(sysparam, titl_str))
  630.  
  631.  
  632. /***
  633. *    movp_exp()
  634. *
  635. *    get parameter for move pointer
  636. */
  637. func movp_exp(sysparam)
  638. memvar exp_label
  639. return (get_k_trim(sysparam, exp_label))
  640.  
  641.  
  642. /***
  643. *    do_seek()
  644. *
  645. *    seek to expression
  646. */
  647. func do_seek
  648.  
  649. local lDone, nRec, cSeekType
  650. memvar k_trim,ntx_expr
  651.  
  652.     lDone := .F.
  653.  
  654.     if Empty(k_trim)
  655.         error_msg("Expression not entered")
  656.     else
  657.         stat_msg("Searching...")
  658.  
  659.         /* save record number in case no find */
  660.         nRec := Recno()
  661.  
  662.         /* determine type for seek */
  663.         cSeekType := Type(ntx_expr)
  664.  
  665.         /* try it */
  666.         do case
  667.         case cSeekType == "C"
  668.             /* character search */
  669.             seek k_trim
  670.  
  671.         case cSeekType == "N"
  672.             /* numeric search */
  673.             seek Val(k_trim)
  674.  
  675.         case cSeekType == "D"
  676.             /* date search */
  677.             seek Ctod(k_trim)
  678.         end
  679.  
  680.         if Found()
  681.             /* operation complete */
  682.             stat_msg("Found")
  683.             lDone := .T.
  684.         else
  685.             /* consider this an error..start over */
  686.             error_msg("Not found")
  687.             goto nRec
  688.         end
  689.     end
  690.  
  691. return (lDone)
  692.  
  693.  
  694. /***
  695. *    do_goto()
  696. *
  697. *    go to record number
  698. */
  699. func do_goto
  700.  
  701. local lDone, nWhich
  702. memvar k_trim
  703.  
  704.     lDone := .F.
  705.     nWhich := Val(k_trim)        && convert to number
  706.  
  707.     do case
  708.     case Empty(k_trim)
  709.         error_msg("Record number not entered")
  710.  
  711.     case .not. Substr(Ltrim(k_trim), 1, 1) $ "-+1234567890"
  712.         error_msg("Record number not numeric")
  713.  
  714.     case nWhich <= 0 .or. nWhich > Lastrec()
  715.         error_msg("Record out of range")
  716.  
  717.     otherwise
  718.         /* operation complete */
  719.         goto nWhich
  720.         lDone := .T.
  721.  
  722.     end
  723.  
  724. return (lDone)
  725.  
  726.  
  727. /***
  728. *    do_locate()
  729. *
  730. *    locate expression
  731. */
  732. func do_locate
  733.  
  734. local lDone, nRec
  735. memvar k_trim
  736.  
  737.     lDone := .F.
  738.  
  739.     do case
  740.     case Empty(k_trim)
  741.         error_msg("Expression not entered")
  742.  
  743.     case Type(k_trim) <> "L"
  744.         error_msg("Expression Type must be Logical")
  745.  
  746.     otherwise
  747.         /* save record number in case no find */
  748.         nRec := Recno()
  749.         stat_msg("Searching...")
  750.  
  751.         if &k_trim
  752.             /* current record meets the condition */
  753.             skip
  754.         end
  755.  
  756.         /* search forward to end of file */
  757.         locate for &k_trim while .T.
  758.  
  759.         if Found()
  760.             /* operation complete */
  761.             stat_msg("Found")
  762.             lDone := .T.
  763.  
  764.         else
  765.             /* consider this an error..start over */
  766.             error_msg("Not found")
  767.             goto nRec
  768.         end
  769.     end
  770.  
  771. return (lDone)
  772.  
  773.  
  774. /***
  775. *    do_skip()
  776. *
  777. *    skip number of records
  778. */
  779. func do_skip
  780.  
  781. local lDone, nSkip
  782. memvar k_trim
  783.  
  784.     lDone := .F.
  785.     nSkip := Val(k_trim)        && convert to number
  786.  
  787.     do case
  788.     case Empty(k_trim)
  789.         error_msg("Skip value not entered")
  790.  
  791.     case .not. Substr(Ltrim(k_trim), 1, 1) $ "-+1234567890"
  792.         error_msg("Skip value not numeric")
  793.  
  794.     case nSkip == 0
  795.         error_msg("Skip value zero")
  796.  
  797.     otherwise
  798.         /* no out of range or over-skip error */
  799.         lDone := .T.
  800.  
  801.         skip nSkip
  802.  
  803.         if Eof()
  804.             /* over-skip..clear eof flag */
  805.             go bottom
  806.         end
  807.  
  808.         if Bof()
  809.             /* over-skip..clear bof flag */
  810.             go top
  811.         end
  812.     end
  813.  
  814. return (lDone)
  815.  
  816.  
  817. /***
  818. *    EmptyFile()
  819. */
  820.  
  821. static func EmptyFile()
  822.  
  823.     if (LastRec() == 0 )
  824.         return (.t.)
  825.     end
  826.  
  827.     if ( (Eof() .or. Recno() == LastRec() + 1) .and. Bof() ) 
  828.         return (.t.)
  829.     end
  830.  
  831. return (.f.)
  832.  
  833.  
  834. /***
  835. *    DoGet()
  836. *
  837. *    Edit the current field
  838. */
  839.  
  840. static func DoGet(oB, lAppend, cAlias)
  841.  
  842. local lExitSave, oCol, oGet, nKey, cExpr, xEval
  843. local lFresh, mGetVar, nWaSave
  844.  
  845.     /* save state */
  846.     lExitSave := Set(_SET_EXIT, .t.)
  847.     nWaSave := Select()
  848.     if ( !Empty(cAlias) )
  849.         Select(cAlias)
  850.     end
  851.  
  852.     /* set insert key to toggle insert mode and cursor */
  853.     set key K_INS to tog_insert
  854.     xkey_clear()
  855.  
  856.     /* get the controlling index key */
  857.     cExpr := IndexKey(0)
  858.     if ( !Empty(cExpr) )
  859.         /* expand key expression for later comparison */
  860.         xEval := &cExpr
  861.     end
  862.  
  863.     /* get column object from browse */
  864.     oCol := oB:getColumn(oB:colPos)
  865.  
  866.     /* use temp for safety */
  867.     mGetVar := Eval(oCol:block)
  868.  
  869.     /* create a corresponding GET with ambiguous set/get block */
  870.     oGet := GetNew(Row(), Col(),                                    ;
  871.                    {|x| if(PCount() == 0, mGetVar, mGetVar := x)},    ;
  872.                    "mGetVar")
  873.  
  874.     /* refresh flag */
  875.     lFresh := .f.
  876.  
  877.     /* read it */
  878.     if ( ReadModal( {oGet} ) )
  879.         /* new data has been entered */
  880.         if ( lAppend .and. Recno() == LastRec() + 1 )
  881.             /* new record confirmed */
  882.             append blank
  883.         end
  884.  
  885.         /* replace with new data */
  886.         Eval(oCol:block, mGetVar)
  887.  
  888.         /* test for change in index order */
  889.         if ( !Empty(cExpr) .and. !lAppend )
  890.             if ( xEval != &cExpr )
  891.                 /* change in index key eval */
  892.                 lFresh := .t.
  893.             end
  894.         end
  895.     end
  896.  
  897.     Select(nWaSave)
  898.     if ( lFresh )
  899.         /* record in new indexed order */
  900.         FreshOrder(oB)
  901.  
  902.         /* no other action */
  903.         nKey := 0
  904.     else
  905.         /* refresh the current row only */
  906.         oB:refreshCurrent()
  907.  
  908.         /* certain keys move cursor after edit if no refresh */
  909.         nKey := ExitKey(lAppend)
  910.     end
  911.  
  912.     if ( lAppend )
  913.         /* maintain special row color */
  914.         oB:colorRect({oB:rowPos,1,oB:rowPos,oB:colCount}, {2,2})
  915.     end
  916.  
  917.     /* restore state */
  918.     Set(_SET_EXIT, lExitSave)
  919.     set key K_INS to
  920.     xkey_norm()
  921.  
  922. return (nKey)
  923.  
  924.  
  925. /***
  926. *    ExitKey()
  927. *
  928. *    Determine the follow-up action after editing a field
  929. */
  930.  
  931. static func ExitKey(lAppend)
  932.  
  933. memvar keystroke
  934.  
  935.     keystroke := LastKey()
  936.     if ( keystroke == K_PGDN )
  937.         /* move down if not append mode */
  938.         if ( lAppend )
  939.             keystroke := 0
  940.         else
  941.             keystroke := K_DOWN
  942.         end
  943.  
  944.     elseif ( keystroke == K_PGUP )
  945.         /* move up if not append mode */
  946.         if ( lAppend )
  947.             keystroke := 0
  948.         else
  949.             keystroke := K_UP
  950.         end
  951.  
  952.     elseif ( keystroke == K_RETURN .or. isdata(keystroke) )
  953.         /* return key or type out..move right */
  954.         keystroke := K_RIGHT
  955.  
  956.     elseif (keystroke != K_UP .and. keystroke != K_DOWN .and. menu_key() == 0)
  957.         /* no other action */
  958.         keystroke := 0
  959.     end
  960.  
  961. return (keystroke)
  962.  
  963.  
  964. /***
  965. *    FreshOrder()
  966. *
  967. *    Refresh respecting any change in index order
  968. */
  969.  
  970. static func FreshOrder(oB)
  971.  
  972. local nRec
  973.  
  974.     nRec := Recno()
  975.     oB:refreshAll()
  976.  
  977.     /* stabilize to see if TBrowse moves the record pointer */
  978.     while ( !oB:stabilize() ) ; end
  979.  
  980.     if ( nRec != LastRec() + 1 )
  981.         /* record pointer may move if bof is on screen */
  982.         while ( Recno() != nRec )
  983.             /* falls through unless record is closer to bof than before */
  984.             oB:up()
  985.             while ( !oB:stabilize() ) ; end
  986.         end
  987.     end
  988.  
  989. return (NIL)
  990.  
  991.  
  992. /***
  993. *    Skipped(n)
  994. *
  995. *    Skip thru database and return the
  996. *    actual number of records skipped
  997. */
  998.  
  999. static func Skipped(nRequest, lAppend)
  1000.  
  1001. local nCount
  1002.  
  1003.     nCount := 0
  1004.     if ( LastRec() != 0 )
  1005.         if ( nRequest == 0 )
  1006.             skip 0
  1007.  
  1008.         elseif ( nRequest > 0 .and. Recno() != LastRec() + 1 )
  1009.             /* forward */
  1010.             while ( nCount < nRequest )
  1011.                 skip 1
  1012.                 if ( Eof() )
  1013.                     if ( lAppend )
  1014.                         /* eof record allowed if append mode */
  1015.                         nCount++
  1016.                     else
  1017.                         /* back to last actual record */
  1018.                         skip -1
  1019.                     end
  1020.  
  1021.                     exit
  1022.                 end
  1023.  
  1024.                 nCount++
  1025.             end
  1026.  
  1027.         elseif ( nRequest < 0 )
  1028.             /* backward */
  1029.             while ( nCount > nRequest )
  1030.                 skip -1
  1031.                 if ( Bof() )
  1032.                     exit
  1033.                 end
  1034.  
  1035.                 nCount--
  1036.             end
  1037.         end
  1038.     end
  1039.  
  1040. return (nCount)
  1041.  
  1042.  
  1043. /* eof dbuedit.prg */
  1044.