home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Database / CLIPR503.W96 / BROWSYS.PR_ / BROWSYS.PR
Text File  |  1995-06-20  |  22KB  |  736 lines

  1. /*****************************************************************************
  2. *
  3. *  Browsys.prg
  4. *
  5. *  Standard Clipper 5.3 tBrowse Subsystem
  6. *
  7. *  Copyright (c) 1991-1995, Computer Associates International, Inc.
  8. *  All rights reserved.
  9. *
  10. *  NOTE: compile with /m /n /w
  11. *
  12. */
  13.  
  14.  
  15. #INCLUDE "button.ch"
  16. #INCLUDE "browsys.ch"
  17. #INCLUDE "inkey.ch"
  18. #INCLUDE "Set.ch"
  19. #INCLUDE "SetCurs.ch"
  20. #INCLUDE "tbrowse.ch"
  21. #INCLUDE "llibg.ch"
  22.  
  23. #DEFINE NVALTYPE_CHAR      67
  24. #DEFINE NVALTYPE_DATE      68
  25. #DEFINE NVALTYPE_LOGICAL   76
  26. #DEFINE NVALTYPE_NUMERIC   78
  27. #DEFINE NVALTYPE_BLOCK     66
  28. #DEFINE NVALTYPE_ARRAY     65
  29. #DEFINE NVALTYPE_NIL       85
  30.  
  31.  
  32. /*****************************************************************************
  33. *  tbCreate( <uOwner>, <nTop>, <nLeft>, <nBottom>, <nRight>
  34. *              [, <cColorInfo>] ) -> aTBinfo
  35. *  create and initialize a browse window.
  36. *
  37. *****************************************************************************/
  38. FUNCTION tbCreate( uOwner, nTop, nLeft, nBottom, nRight, cColorInfo, cBorder, lAppend, lUpdate )
  39.    LOCAL oBrowse, aTBinfo
  40.  
  41.       oBrowse := tBrowseNew( nTop, nLeft, nBottom, nRight )
  42.       oBrowse:AutoLite      := .F.
  43.       oBrowse:HeadSep       := "─"
  44.       oBrowse:ColSep        := "│"
  45.       oBrowse:SkipBlock     := { | x | tbSkip( aTBInfo, x ) }
  46.  
  47.       IF ( ValType( uOwner ) == "A" )
  48.          oBrowse:GoTopBlock    := { || aTBinfo[ TBR_POSITION ] := 1 }
  49.          oBrowse:GoBottomBlock := { || aTBinfo[ TBR_POSITION ] := Len( aTBinfo[ TBR_REFERENCE ] ) }
  50.  
  51.       ELSE
  52.          oBrowse:GoTopBlock    := { || tbGoTop( aTBInfo ) }
  53.          oBrowse:GoBottomBlock := { || tbGoBot( aTBInfo ) }
  54.  
  55.       ENDIF
  56.  
  57.       IF ( ValType( cColorInfo ) == "C" )
  58.          oBrowse:ColorSpec := cColorInfo
  59.       ENDIF
  60.  
  61.       IF ( ValType( cBorder ) == "C" )
  62.          oBrowse:Border := cBorder
  63.       ENDIF
  64.  
  65.       IF ( ValType( lAppend ) == "L" )
  66.          oBrowse:SetStyle( TBR_APPEND, lAppend )
  67.  
  68.       ELSE
  69.          lAppend := .F.
  70.  
  71.       ENDIF
  72.  
  73.       IF ( ValType( lUpdate ) == "L" )
  74.          oBrowse:SetStyle( TBR_MODIFY, lUpdate )
  75.  
  76.       ELSE
  77.          lUpdate := .F.
  78.  
  79.       ENDIF
  80.  
  81.       IF ( lUpdate )
  82.          oBrowse:SetKey( 0, { | oB, nK | tbEditCell( oB, nK ) } )
  83.       ENDIF
  84.  
  85.       aTBinfo := ARRAY( TBR_ELEMENTS )
  86.  
  87.       aTBinfo[ TBR_BROWSE      ] := oBrowse
  88.       aTBinfo[ TBR_SAVESCREEN  ] := ""
  89.       aTBinfo[ TBR_REFERENCE   ] := uOwner
  90.       aTBinfo[ TBR_COLINFO     ] := {}
  91.       aTBinfo[ TBR_FILTERBLOCK ] := { || .T. }
  92.  
  93.       IF ( ( SET( _SET_VIDEOMODE ) == LLG_VIDEO_TXT ) .OR.;
  94.            ( SET( _SET_VIDEOMODE ) == NIL ) )
  95.  
  96.          aTBinfo[ TBR_SAVESCREEN ] := CHR( oBrowse:nTop    )     + ;
  97.                                       CHR( oBrowse:nLeft   )     + ;
  98.                                       CHR( oBrowse:nBottom )     + ;
  99.                                       CHR( oBrowse:nRight  )     + ;
  100.                                       SAVESCREEN( oBrowse:nTop   , ;
  101.                                                   oBrowse:nLeft  , ;
  102.                                                   oBrowse:nBottom, ;
  103.                                                   oBrowse:nRight )
  104.       ELSE     // Graphic mode
  105.  
  106.          aTBinfo[ TBR_SAVESCREEN ] := SaveScreen( oBrowse:nTop,    ;
  107.                                                   oBrowse:nLeft,   ;
  108.                                                   oBrowse:nBottom, ;
  109.                                                   oBrowse:nRight )
  110.          AADD( aTBinfo[ TBR_SAVESCREEN ], oBrowse:nTop )
  111.          AADD( aTBinfo[ TBR_SAVESCREEN ], oBrowse:nLeft )
  112.          AADD( aTBinfo[ TBR_SAVESCREEN ], oBrowse:nBottom )
  113.          AADD( aTBinfo[ TBR_SAVESCREEN ], oBrowse:nRight )
  114.  
  115.       ENDIF
  116.  
  117.   RETURN ( aTBinfo )
  118.  
  119.  
  120. /*****************************************************************************
  121. *  tbClose( <aTBinfo> ) -> aTBinfo
  122. *  close a browse window.
  123. *
  124. *****************************************************************************/
  125. FUNCTION tbClose( aTBinfo )
  126.  
  127.    LOCAL nLen, n1, n2, n3, n4
  128.  
  129.       IF ( ( SET( _SET_VIDEOMODE ) == LLG_VIDEO_TXT ) .OR.;
  130.            ( SET( _SET_VIDEOMODE ) == NIL ) )
  131.  
  132.           RESTSCREEN( ASC( SUBSTR( aTBinfo[ TBR_SAVESCREEN ], 1, 1 ) ), ;
  133.                       ASC( SUBSTR( aTBinfo[ TBR_SAVESCREEN ], 2, 1 ) ), ;
  134.                       ASC( SUBSTR( aTBinfo[ TBR_SAVESCREEN ], 3, 1 ) ), ;
  135.                       ASC( SUBSTR( aTBinfo[ TBR_SAVESCREEN ], 4, 1 ) ), ;
  136.                            SUBSTR( aTBinfo[ TBR_SAVESCREEN ], 5    ) )
  137.  
  138.       ELSE      // Graphic mode
  139.  
  140.           nLen := LEN( aTBinfo[ TBR_SAVESCREEN ] )
  141.           n1 := aTBinfo[ TBR_SAVESCREEN ][ nLen - 3 ]
  142.           n2 := aTBinfo[ TBR_SAVESCREEN ][ nLen - 2 ]
  143.           n3 := aTBinfo[ TBR_SAVESCREEN ][ nLen - 1 ]
  144.           n4 := aTBinfo[ TBR_SAVESCREEN ][ nLen ]
  145.  
  146.           RESTSCREEN( n1, n2, n3, n4, aTBinfo[ TBR_SAVESCREEN ] )
  147.  
  148.       ENDIF
  149.  
  150.    RETURN ( NIL )
  151.  
  152.  
  153. /*****************************************************************************
  154. *  tbDisplay( <aTBinfo>, <lMode> ) -> aTBinfo
  155. *  display a browse window.
  156. *
  157. *****************************************************************************/
  158. FUNCTION tbDisplay( aTBinfo, lMode )
  159.  
  160.  
  161.       IF ( ! ValType( lMode ) == "L" )
  162.          lMode := .F.
  163.       ENDIF
  164.  
  165.       IF ( lMode )
  166.          aTBinfo[ TBR_BROWSE ]:Invalidate()
  167.  
  168.       ELSE
  169.          aTBinfo[ TBR_BROWSE ]:RefreshAll()
  170.  
  171.       ENDIF
  172.  
  173.       aTBinfo[ TBR_BROWSE ]:ForceStable()
  174.  
  175.    RETURN ( aTBInfo )
  176.  
  177.  
  178. /*****************************************************************************
  179. *  tbAddCol( <aTBinfo>, <aColInfo> ) -> aTBinfo
  180. *  add a column to a browse.
  181. *
  182. *****************************************************************************/
  183. FUNCTION tbAddCol( aTBinfo, aColInfo )
  184.    RETURN ( MakeColumn( aTBinfo, aColInfo, NIL ) )
  185.  
  186.  
  187. /*****************************************************************************
  188. *  tbInsCol( <aTBinfo>, <aColInfo>, <nPosition> ) -> aTBinfo
  189. *  insert a column into a browse.
  190. *
  191. *****************************************************************************/
  192. FUNCTION tbInsCol( aTBinfo, aColInfo, nPosition )
  193.    RETURN ( MakeColumn( aTBinfo, aColInfo, nPosition ) )
  194.  
  195.  
  196. /*****************************************************************************
  197. *  MakeColumn( <aTBinfo>, <aColInfo>, <nPosition> ) -> aTBinfo
  198. *  create a new tBrowse column.
  199. *
  200. *****************************************************************************/
  201. static FUNCTION MakeColumn( aTBinfo, aColInfo, nPosition )
  202.    LOCAL oColumn
  203.  
  204. /*--- determine if the column is being appended or inserted. */
  205.       IF ( ! VALTYPE( nPosition ) == "N" )
  206.          nPosition := LEN( aTBinfo[ TBR_COLINFO ] ) + 1
  207.  
  208.       ELSEIF ( nPosition < 1 )
  209.          RETURN ( aTBinfo )
  210.  
  211.       ELSEIF ( nPosition > LEN( aTBinfo[ TBR_COLINFO ] ) )
  212.          RETURN ( aTBinfo )
  213.  
  214.       ENDIF
  215.  
  216.       AADD( aTBinfo[ TBR_COLINFO ], aColInfo[ TBC_OWNERCOL ] )
  217.  
  218.       IF ( ValType( aTBinfo[ TBR_REFERENCE ] ) == "A" )
  219.  
  220.          oColumn := tbColumnNew( aColInfo[ TBC_HEADING ], ;
  221.                     { | x | IIF( x == NIL,                                              ;
  222.                     aTBinfo[ TBR_REFERENCE, aTBinfo[ TBR_POSITION ] ],       ;
  223.                     aTBinfo[ TBR_REFERENCE, aTBinfo[ TBR_POSITION ] ] := x ) } )
  224.       ELSE
  225.          oColumn := tbColumnNew( aColInfo[ TBC_HEADING ], ;
  226.          FieldWblock( aColInfo[ TBC_OWNERCOL ], Select( aTBinfo[ TBR_REFERENCE ] ) ) )
  227.  
  228.       ENDIF
  229.  
  230.       aColInfo := aSize( aColInfo, TBC_ELEMENTS )
  231.  
  232.       oColumn:ColorBlock   := aColInfo[ TBC_COLORBLOCK ]
  233.       oColumn:ColSep       := aColInfo[ TBC_COLSEP     ]
  234.       oColumn:DefColor     := aColInfo[ TBC_DEFCOLOR   ]
  235.       oColumn:Footing      := aColInfo[ TBC_FOOTING    ]
  236.       oColumn:FootSep      := aColInfo[ TBC_FOOTSEP    ]
  237.       oColumn:Heading      := aColInfo[ TBC_HEADING    ]
  238.       oColumn:HeadSep      := aColInfo[ TBC_HEADSEP    ]
  239.       oColumn:Width        := aColInfo[ TBC_WIDTH      ]
  240.       oColumn:Picture      := aColInfo[ TBC_PICTURE    ]
  241.       oColumn:PreBlock     := aColInfo[ TBC_PREBLOCK   ]
  242.       oColumn:PostBlock    := aColInfo[ TBC_POSTBLOCK  ]
  243.  
  244.       IF ( ValType( aColInfo[ TBC_CANWRITE ] ) == "L" )
  245.          oColumn:SetStyle( TBC_READWRITE, aColInfo[ TBC_CANWRITE ] )
  246.       ENDIF
  247.  
  248.       aTBinfo[ TBR_BROWSE ]:AddColumn( oColumn )
  249.  
  250.  
  251.    RETURN ( aTBinfo )
  252.  
  253.  
  254. /*****************************************************************************
  255. *  tbDelCol( <aTBinfo>, <nPosition> ) -> aTBinfo
  256. *  delete a column from a browse.
  257. *
  258. *****************************************************************************/
  259. FUNCTION tbDelCol( aTBinfo, nPosition )
  260.    local aColInfo
  261.  
  262.       IF ( nPosition <= aTBinfo[ TBR_BROWSE ]:ColCount )
  263.          aTBinfo[ TBR_BROWSE ]:DelColumn( nPosition )
  264.          aColInfo := aTBInfo[ TBR_COLINFO ]
  265.          aDel( aColInfo, nPosition )
  266.          aSize( aColInfo, Len( aColInfo ) - 1 )
  267.       ENDIF
  268.  
  269.    RETURN ( aTBinfo )
  270.  
  271.  
  272. /*****************************************************************************
  273. *  tbSblock( <aTBinfo>, <bBlock> ) -> bBlock
  274. *  get/set the seek block.
  275. *
  276. *****************************************************************************/
  277. FUNCTION tbSblock( aTBinfo, bBlock )
  278.    LOCAL bReturn
  279.  
  280.       bReturn := aTBinfo[ TBR_SEEKBLOCK ]
  281.  
  282.       IF ( ValType( bBlock ) == "B" )
  283.          aTBinfo[ TBR_SEEKBLOCK ] := bBlock
  284.       ENDIF
  285.  
  286.    RETURN ( bReturn )
  287.  
  288.  
  289. /*****************************************************************************
  290. *  tbFblock( <aTBinfo>, <bBlock> ) -> bBlock
  291. *  get/set the filter block.
  292. *
  293. *****************************************************************************/
  294. FUNCTION tbFblock( aTBinfo, bBlock )
  295.    LOCAL bReturn
  296.  
  297.       bReturn := aTBinfo[ TBR_FILTERBLOCK ]
  298.  
  299.       IF ( ValType( bBlock ) == "B" )
  300.          aTBinfo[ TBR_FILTERBLOCK ] := bBlock
  301.       ENDIF
  302.  
  303.    RETURN ( bReturn )
  304.  
  305.  
  306. /*****************************************************************************
  307. *  tbBblock( <aTBinfo>, <bBlock> ) -> bBlock
  308. *  get/set the gobottom block.
  309. *
  310. *****************************************************************************/
  311. FUNCTION tbBblock( aTBinfo, bBlock )
  312.    LOCAL nPosition, bReturn
  313.  
  314.       bReturn := aTBinfo[ TBR_BBLOCK ]
  315.  
  316.       IF ( ValType( bBlock ) == "B" )
  317.          aTBinfo[ TBR_BBLOCK ] := bBlock
  318.       ENDIF
  319.  
  320.    RETURN ( bReturn )
  321.  
  322.  
  323. /*****************************************************************************
  324. *  tbGoTop( <aTBinfo> ) -> aTBinfo
  325. *  go to the top of a browse.
  326. *
  327. *****************************************************************************/
  328. FUNCTION tbGoTop( aTBinfo )
  329.    LOCAL bSeek
  330.       bSeek   := aTBinfo[ TBR_SEEKBLOCK ]
  331.       IF ( bSeek == NIL )
  332.          ( aTBinfo[ TBR_REFERENCE ] )->( dbGoTop() )
  333.       ELSE
  334.          Eval( bSeek, aTBinfo )
  335.       ENDIF
  336.  
  337.    RETURN ( aTBinfo )
  338.  
  339.  
  340. /*****************************************************************************
  341. *  tbGoBot( <aTBinfo> ) -> aTBinfo
  342. *  go to the bottom of a browse.
  343. *
  344. *****************************************************************************/
  345. FUNCTION tbGoBot( aTBinfo )
  346.    LOCAL bBot, bSeek, bFilter, cAlias
  347.       bBot   := aTBinfo[ TBR_BBLOCK ]
  348.       IF ( bBot == NIL )
  349.         bSeek   := aTBinfo[ TBR_SEEKBLOCK ]
  350.         IF (bSeek != NIL )
  351.           Eval( bSeek, aTBinfo )
  352.           cAlias  := aTBinfo[ TBR_REFERENCE ]
  353.           bFilter   := aTBinfo[ TBR_FILTERBLOCK ]
  354.                 IF ( ! ( cAlias )->( eof() ) )
  355.                 WHILE ( .T. )
  356.                    ( cAlias ) -> ( dbSkip( 1 ) )
  357.                     IF ( ( ( cAlias )->( eof() ) ) .OR. ;
  358.                       ( ! Eval( bFilter, aTBinfo ) ) )
  359.                           ( cAlias )->( dbSkip( -1 ) )
  360.                     EXIT
  361.                     ENDIF
  362.                 ENDDO
  363.           ENDIF
  364.         ELSE
  365.           ( aTBinfo[ TBR_REFERENCE ] )->( dbGoBottom() )
  366.         ENDIF
  367.       ELSE
  368.          Eval( bBot, aTBinfo )
  369.       ENDIF
  370.  
  371.    RETURN ( aTBinfo )
  372.  
  373.  
  374. /*****************************************************************************
  375. *  tbSkip( <aTBinfo>, <nRows> ) -> nRowsMoved
  376. *  skip one or more rows in a browse.
  377. *
  378. *****************************************************************************/
  379. FUNCTION tbSkip( aTBinfo, nAmount )
  380.    LOCAL nPos, nLength, nReturn, nDirection, cAlias, bFilter, lIsAppend
  381.  
  382.       bFilter   := aTBinfo[ TBR_FILTERBLOCK ]
  383.       lIsAppend := aTBinfo[ TBR_BROWSE ]:SetStyle( TBR_APPENDING )
  384.  
  385.       IF ( ValType( aTBinfo[ TBR_REFERENCE ] ) == "A" )
  386.          nPos := aTBInfo[ TBR_POSITION ] + nAmount
  387.  
  388.          IF ( nPos < 1 )
  389.             nAmount += ( ABS( nPos ) + 1 )
  390.             nPos := 1
  391.  
  392.          ELSEIF ( nPos > ( nLength := LEN( ( aTBInfo[ TBR_REFERENCE ] ) ) ) )
  393.             nAmount -= ( nLength - nPos )
  394.             nPos := nLength
  395.  
  396.          ENDIF
  397.  
  398.          aTBInfo[ TBR_POSITION ] := nPos
  399.  
  400.       ELSE
  401.           nReturn := 0
  402.          cAlias  := aTBinfo[ TBR_REFERENCE ]
  403.  
  404.           IF ( LastRec() != 0 )
  405.               IF ( nAmount == 0 )
  406.                  ( cAlias )->( dbSkip( 0 ) )
  407.  
  408.               ELSEIF ( ( nAmount > 0 ) .AND. ( ! ( cAlias )->( Eof() ) ) )
  409.                  WHILE ( nReturn < nAmount )
  410.                     ( cAlias )->( dbSkip( 1 ) )
  411.  
  412.                      IF ( ( ( cAlias )->( eof() ) ) .OR. ;
  413.                        ( ! Eval( bFilter, aTBinfo ) ) )
  414.  
  415.                      IF ( lIsAppend )
  416.                               IF ( ! ( cAlias )->( eof() ) )
  417.                                  ( cAlias )->( dbGoBottom() )
  418.                                  ( cAlias )->( dbSkip( 1 ) )
  419.                         ENDIF
  420.                         nReturn ++
  421.  
  422.                      ELSE
  423.                            ( cAlias )->( dbSkip( -1 ) )
  424.  
  425.                      ENDIF
  426.  
  427.                          EXIT
  428.                      ENDIF
  429.  
  430.                      nReturn ++
  431.                  ENDDO
  432.  
  433.               ELSEIF ( nAmount < 0 )
  434.                IF ( ( cAlias )->( Eof() ) )
  435.                   Eval( aTBinfo[ TBR_BROWSE ]:GoBottomBlock )
  436.                   nReturn --
  437.                ENDIF
  438.                  WHILE ( nReturn > nAmount )
  439.                     ( cAlias )->( dbSkip( -1 ) )
  440.                      IF ( ( cAlias )->( bof() ) )
  441.                          EXIT
  442.  
  443.                      ELSEIF ( ! Eval( bFilter, aTBinfo ) )
  444.                         ( cAlias )->( dbSkip( 1 ) )
  445.                          EXIT
  446.  
  447.                      ENDIF
  448.  
  449.                      nReturn --
  450.                  ENDDO
  451.               ENDIF
  452.           ENDIF
  453.  
  454.          aTBInfo[ TBR_POSITION ] := ( cAlias )->( RECNO() )
  455.       ENDIF
  456.  
  457.    RETURN ( nReturn )
  458.  
  459.  
  460. /*****************************************************************************
  461. *  tbModal( <oBrowse> ) -> nKey
  462. *  give input focus to a browse.
  463. *
  464. *****************************************************************************/
  465. FUNCTION tbModal( oBrowse )
  466.    LOCAL nKey, nSaveCursor, lAutoLite
  467.  
  468.       nSaveCursor      := SetCursor( SC_NONE )
  469.       lAutoLite        := oBrowse:AutoLite
  470.       oBrowse:AutoLite := .T.
  471.  
  472.       WHILE ( .T. )
  473.          WHILE ( ( ( nKey := Inkey() ) == 0 ) .AND. ( ! oBrowse:Stabilize() ) )
  474.          ENDDO
  475.  
  476.          IF ( nKey == 0 )
  477.             /* nKey is 0, so the browse must be stable. */
  478.             IF ( ( oBrowse:hitBottom ) .AND. ;
  479.                  ( oBrowse:SetStyle( TBR_APPEND ) ) .AND. ;
  480.                  ( ! oBrowse:SetStyle( TBR_APPENDING ) ) )
  481.                oBrowse:SetStyle( TBR_APPENDING, .T. )
  482.                nKey := K_DOWN
  483.  
  484.             ELSE
  485.                nKey := Inkey( 0 )
  486.  
  487.             ENDIF
  488.          ENDIF
  489.  
  490.          IF ( ( nKey == K_CTRL_PGDN ) .OR. ( nKey == K_CTRL_PGUP ) )
  491.             oBrowse:SetStyle( TBR_APPENDING, .F. )
  492.  
  493.          ELSEIF ( ( nKey == K_UP ) .OR. ( nKey == K_PGUP ) )
  494.             IF ( oBrowse:SetStyle( TBR_APPENDING ) )
  495.                oBrowse:SetStyle( TBR_APPENDING, .F. )
  496.                oBrowse:refreshAll()
  497.             ENDIF
  498.  
  499.          ELSEIF ( ( nKey == K_LBUTTONDOWN ) .AND. ;
  500.                   ( oBrowse:mRowPos != oBrowse:RowPos ) .AND. ;
  501.                   ( oBrowse:HitTest( mRow(), mCol() ) == HTCELL ) )
  502.             IF ( oBrowse:SetStyle( TBR_APPENDING ) )
  503.                oBrowse:SetStyle( TBR_APPENDING, .F. )
  504.                oBrowse:refreshAll()
  505.             ENDIF
  506.          ENDIF
  507.  
  508.          IF ( oBrowse:ApplyKey( nKey ) == TBR_EXIT )
  509.             EXIT
  510.          ENDIF
  511.       ENDDO
  512.  
  513.       oBrowse:AutoLite := lAutoLite
  514.       oBrowse:deHilite()
  515.  
  516.       SetCursor( nSaveCursor )
  517.  
  518.    RETURN ( nKey )
  519.  
  520.  
  521. /*****************************************************************************
  522. *  tbEditCell( <oBrowse>, <nKey> ) -> uNewValue
  523. *  modify the current cell.
  524. *
  525. *****************************************************************************/
  526. FUNCTION tbEditCell( oBrowse, nKey )
  527.    LOCAL bSaveInsert, GetList, lAppend, nLength, nSaveCursor, oColumn, ;
  528.          uNewKey, uSavKey
  529.       IF ( ! oBrowse:SetStyle( TBR_MODIFY ) )
  530.          RETURN ( TBR_EXCEPTION )
  531.       ENDIF
  532.  
  533.       oColumn  := oBrowse:GetColumn( oBrowse:ColPos )
  534.  
  535.       IF ( ! oColumn:SetStyle( TBC_READWRITE ) )
  536.          RETURN ( TBR_EXCEPTION )
  537.       ENDIF
  538.  
  539.       IF ( nKey == K_ENTER )
  540.       ELSEIF ( nKey < 32 )
  541.          RETURN ( TBR_EXCEPTION )
  542.  
  543.       ELSEIF ( nKey > 255 )
  544.          RETURN ( TBR_EXCEPTION )
  545.  
  546.       ENDIF
  547.  
  548.       IF ( Eof() )
  549.          lAppend := .T.
  550.  
  551.       ELSE
  552.          lAppend := oBrowse:SetStyle( TBR_APPENDING )
  553.  
  554.       ENDIF
  555.  
  556.       oBrowse:ForceStable()
  557.  
  558.       IF ( lAppend )
  559.          dbAppend()
  560.       ENDIF
  561.  
  562.       uSavKey := iif( Empty( IndexKey() ), NIL, &( IndexKey() ) )
  563.       nLength := oBrowse:colWidth( oBrowse:colPos )
  564.  
  565.       KeyBoard( Chr( nKey ) )
  566.  
  567.       /* Create a corresponding GET. */
  568.       GetList := { getnew( row(), col(),        ;
  569.                            oColumn:block,       ;
  570.                            oColumn:heading,     ;
  571.                            oColumn:picture,     ;
  572.                            oBrowse:colorSpec ) }
  573.  
  574.       GetList[ 1 ]:PreBlock  := oColumn:PreBlock
  575.       GetList[ 1 ]:PostBlock := oColumn:PostBlock
  576.  
  577.       bSaveInsert  := setkey( K_INS, { || InsToggle() } )
  578.       nSaveCursor := SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) )
  579.  
  580.       ReadModal( GetList )
  581.  
  582.       setcursor( nSaveCursor )
  583.       setkey( K_INS, bSaveInsert )
  584.  
  585.       oBrowse:SetStyle( TBR_APPENDING, .F. )
  586.  
  587.       // Get the record's key value (or NIL) after the GET
  588.       uNewKey := if( empty( indexkey() ), NIL, &( indexkey() ) )
  589.  
  590.       oBrowse:Invalidate()
  591.       oBrowse:RefreshAll():ForceStable()
  592.  
  593.       IF ( ! ( uNewKey == uSavKey ) .or. ( lAppend .and. uNewKey != NIL ) )
  594.          /* perform a complete refresh. */
  595.          oBrowse:refreshAll():forceStable()
  596.  
  597.       ENDIF
  598.  
  599.       /* Check the exit key from the read. */
  600.       nKey := LastKey()
  601.       IF ( ( nKey == K_UP   ) .OR. ;
  602.            ( nKey == K_DOWN ) .OR. ;
  603.            ( nKey == K_PGUP ) .OR. ;
  604.            ( nKey == K_PGDN )      )
  605.  
  606.          /* Yea, yea. What's a guy to do? */
  607.          keyboard( chr( nKey ) )
  608.       ENDIF
  609.  
  610.    RETURN ( TBR_CONTINUE )
  611.  
  612.  
  613. *****************************************************************************/
  614. *   InsToggle()
  615. *
  616. *   Toggle the global insert mode and the cursor shape.
  617. *
  618. *****************************************************************************/
  619. STATIC FUNCTIOn InsToggle()
  620.  
  621.       IF ( ReadInsert() )
  622.          ReadInsert( .F. )
  623.          SetCursor( SC_NORMAL )
  624.  
  625.       ELSE
  626.          ReadInsert( .T. )
  627.          SetCursor( SC_INSERT )
  628.  
  629.       ENDIF
  630.  
  631.    RETURN ( NIL )
  632.  
  633.  
  634. /*****************************************************************************
  635. *  tbMouse ( <oBrowse>, <nRow>, <nColumn> ) -> oBrowse
  636. *  perform mouse related activities on a tBrowse object.
  637. *
  638. *****************************************************************************/
  639. FUNCTION tbMouse( oBrowse, nRow, nCol )
  640.    LOCAL nCount
  641.  
  642.       IF ( oBrowse:HitTest( nRow, nCol ) == HTCELL )
  643.  
  644.          nCount := oBrowse:mRowPos - oBrowse:RowPos
  645.          WHILE ( nCount < 0 )
  646.             nCount ++
  647.             oBrowse:Up()
  648.          ENDDO
  649.  
  650.          WHILE ( nCount > 0 )
  651.             nCount --
  652.             oBrowse:Down()
  653.          ENDDO
  654.  
  655.          nCount := oBrowse:mColPos - oBrowse:ColPos
  656.          WHILE ( nCount < 0 )
  657.             nCount ++
  658.             oBrowse:Left()
  659.          ENDDO
  660.  
  661.          WHILE ( nCount > 0 )
  662.             nCount --
  663.             oBrowse:Right()
  664.          ENDDO
  665.  
  666.          RETURN ( TBR_CONTINUE )
  667.       ENDIF
  668.  
  669.    RETURN ( TBR_EXCEPTION )
  670.  
  671.  
  672. /*****************************************************************************
  673. *  FieldNBlock( <cAlias>, <cField> ) -> bGetSet
  674. *  create a network aware get/set block.
  675. *
  676. *****************************************************************************/
  677. FUNCTION FieldNBlock( cAlias, cField )
  678.    LOCAL nField
  679.  
  680.       IF ( Select( cAlias ) == 0 )
  681.          RETURN ( NIL )
  682.  
  683.       ELSEIF ( ( cAlias )->( ( nField := FieldPos( cField ) ) ) == 0 )
  684.          RETURN ( NIL )
  685.  
  686.       ENDIF
  687.  
  688.    RETURN ( { | x | IIF( x == NIL, ( cAlias )->( FieldGet( nField ) ), ;
  689.                                    FieldNPut( cAlias, cField, x ) ) } )
  690.  
  691.  
  692. /*****************************************************************************
  693. *  FieldNPut( <cAlias>, <cField>, <uData> ) -> lSuccess
  694. *  create a network aware fieldput() function.
  695. *
  696. *****************************************************************************/
  697. FUNCTION FieldNPut( cAlias, cField, uData )
  698.    LOCAL nField, nSeconds
  699.  
  700.       IF ( Select( cAlias ) == 0 )
  701.          RETURN ( .F. )
  702.  
  703.       ELSEIF ( ( cAlias )->( ( nField := FieldPos( cField ) ) ) == 0 )
  704.          RETURN ( .F. )
  705.  
  706.       ENDIF
  707.  
  708.       nSeconds := Seconds()
  709.  
  710.       WHILE ( ! ( cAlias )->( dbRlock() ) )
  711.          IF ( Seconds() < nSeconds )
  712.          ELSEIF ( Alert( "ERROR: Unable to Save Information", ;
  713.                          { "Retry", "Cancel" } ) != 1 )
  714.             RETURN ( .F. )
  715.  
  716.          ELSE
  717.             nSeconds := Seconds() + 20
  718.  
  719.          ENDIF
  720.  
  721.          Inkey( .2 )
  722.       ENDDO
  723.  
  724.       ( cAlias )->( FieldPut( nField, uData ) )
  725.       ( cAlias )->( dbrUnlock( ( cAlias )->( Recno() ) ) )
  726.  
  727.  
  728.    RETURN ( .T. )
  729.  
  730.  
  731. /*****************************************************************************
  732. *  eof: browsys.prg
  733. *****************************************************************************/
  734.  
  735. 
  736.