************************************************** *-- Class: txtsearchgrid *-- ParentClass: textbox DEFINE CLASS TXTSEARCHGRID AS TXTGRID BORDERSTYLE = 0 HEIGHT = 18 MARGIN = 0 SELECTONENTRY = .F. SPECIALEFFECT = 1 *-- Holds the name of the index tag on the current column if it exists CTAG = "" *-- Value in seconds at which to reset the search string (analogous to _DBLCLICK) NTIMEOUT = 5 *-- Search String as it is keyed in by user CSEARCHSTRING = "" *-- DATETIME() value saved last time a key was pressed...used to determne if we should time out and reset the search string TLASTPRESS = (DATETIME()) NAME = "txtsearchgrid" *-- Sets the cTagProperty for faster evaluation during incremental searching PROCEDURE SETTAG WITH THIS.PARENT *** If the column is bound, see if there is a tag in the grid's RecordSource *** that has the same name as the field the column is bound to IF ! EMPTY( .CONTROLSOURCE ) IF THIS.ISTAG( JUSTEXT( .CONTROLSOURCE ), .PARENT.RECORDSOURCE ) THIS.CTAG = JUSTEXT( .CONTROLSOURCE ) ENDIF ENDIF ENDWITH ENDPROC *-- Searches the grid's recordSource to find a match for what has been typed in PROCEDURE SEARCH LOCAL LNSELECT, LNCURREC, LCALIAS *** Save Current work area LNSELECT = SELECT() *** Get the grid's RecordSource LCALIAS = THIS.PARENT.PARENT.RECORDSOURCE THISFORM.LOCKSCREEN = .T. *** Search for the closes match to the Search string WITH THIS *** Save the current record LNCURREC = RECNO( LCALIAS ) IF ! EMPTY( .CTAG ) *** Use an index tag if one exists IF SEEK( UPPER( .CSEARCHSTRING ), LCALIAS, .CTAG ) *** Do nothing...we found a record ELSE *** Restore the record pointer GO LNCURREC IN ( LCALIAS ) ENDIF ELSE *** No Tag...have to use LOCATE SELECT ( LCALIAS ) LOCATE FOR UPPER( EVAL( JUSTEXT( .PARENT.CONTROLSOURCE ) ) ) = ; UPPER( .CSEARCHSTRING ) IF ! FOUND() GO LNCURREC ENDIF SELECT ( LNSELECT ) ENDIF ENDWITH THISFORM.LOCKSCREEN = .F. THIS.PARENT.PARENT.SETFOCUS() ENDPROC *-- Handles the keystroke and does the searching PROCEDURE HANDLEKEY LPARAMETERS TNKEYCODE *** First check to see if we have a key that we can handle *** A 'printable' character, backspace or <DEL> are good candidates IF BETWEEN( TNKEYCODE, 32, 128 ) OR TNKEYCODE = 7 WITH THIS *** First check to see if we have timed out *** and reset the search string if we have IF DATETIME() - .TLASTPRESS > .NTIMEOUT .CSEARCHSTRING = '' ENDIF *** So now handle the key DO CASE CASE TNKEYCODE = 7 *** If the delete key was pressed, reset the search string *** and exit stage left .CSEARCHSTRING = '' RETURN .T. CASE TNKEYCODE = 127 *** Backspace: Remove the last character from the Search string IF LEN( .CSEARCHSTRING ) > 1 .CSEARCHSTRING = LEFT( .CSEARCHSTRING, LEN( .CSEARCHSTRING ) - 1 ) ELSE .CSEARCHSTRING = '' RETURN .T. ENDIF OTHERWISE *** A garden variety printable character *** add it to the search string .CSEARCHSTRING = .CSEARCHSTRING + CHR( TNKEYCODE ) ENDCASE *** Search for the closest match in the grid's record source .SEARCH() *** Update value for keyPress interval timer .TLASTPRESS = DATETIME() ENDWITH ELSE *** Not a key we can handle *** Let VFP handle it by default THIS.CSEARCHSTRING = '' RETURN .F. ENDIF ENDPROC *-- Returns truw if the passed tag is a tag in the passed alias PROCEDURE ISTAG LPARAMETERS TCTAGNAME, TCTABLE LOCAL ARRAY LATAGS[1] LOCAL LLRETVAL *** Did we get a tag name? IF TYPE( 'tcTagName' ) # 'C' *** Error - must pass a Tag Name ERROR '9000: Must Pass a Tag Name when calling ISTAG()' RETURN .F. ENDIF *** How about a table alias? IF TYPE( 'tcTable' ) = 'C' AND ! EMPTY( TCTABLE ) *** Get all open indexes for the specified table ATAGINFO( LATAGS, "", TCTABLE ) ELSE *** Get all open indexes for the current table ATAGINFO( LATAGS, "" ) ENDIF *** Do a Case Insensitive, Exact=ON, Scan of the first column of array *** Return Whether the Tag is Found or not RETURN ( ASCAN( LATAGS, TCTAGNAME, -1, -1, 1, 7 ) > 0 ) ENDPROC PROCEDURE CLICK *!* *** Make sure the cell stays selected *!* *** even when the user clicks in it with the mouse *!* This.SelStart = 0 *!* This.SelLength = LEN( ALLTRIM( This.Value ) ) ENDPROC PROCEDURE KEYPRESS LPARAMETERS NKEYCODE, NSHIFTALTCTRL *** Pass the key stroke on to be handled IF THIS.HANDLEKEY( NKEYCODE ) NODEFAULT ENDIF ENDPROC PROCEDURE INIT IF DODEFAULT() THIS.SETTAG() ENDIF ENDPROC PROCEDURE GOTFOCUS THIS.TLASTPRESS = DATETIME() ENDPROC ENDDEFINE