home *** CD-ROM | disk | FTP | other *** search
- *****************************************************************
- FUNCTION READTEXT
- *****************************************************************
-
- * Display a text file of any size in a window for reading
-
- * Copyright(c) 1991 -- James Occhiogrosso
-
- # include "inkey.ch"
- # include "box.ch"
- # define wind_rows (bottom - top) - 1 // window rows
- # define wind_cols (right - left) - 3 // window columns
-
- LOCAL counter := 0, old_cursor := SETCURSOR(0), old_screen := ''
- PRIVATE text_array := {}, col_offset := 1, keypress := 0
- PARAMETERS text_file, top, left, bottom, right, start_line
-
- * Initialize arguments not passed with defaults
-
- top = IF(top = NIL, 0, top)
- left = IF(left = NIL, 0, left)
- bottom = IF(bottom = NIL, MAXROW(), bottom)
- right = IF(right = NIL, MAXCOL(), right)
- start_line = IF(start_line = NIL, 1, start_line)
-
-
- * If file cannot be opened, return
- IF (handle := FOPEN(text_file)) > 0
-
- * Save old screen and box text area
- old_screen = SCRNSAVE(top, left, bottom, right)
- @ top, left, bottom, right BOX B_SINGLE + SPACE(1)
-
- * Save end of file value
- text_eof = FSEEK(handle, 0, 2)
-
- * Declare view array as number of window rows by 2 columns
- * Columns: 1 = file pointer, 2 = line text
- text_array := array(wind_rows,2)
-
- IF start_line > 1
- FOR counter = 1 TO (start_line)
- * Move file pointer to specified line
- FREADLINE(handle)
- NEXT
- ENDIF
-
- * Load array and display initial window of lines
- FILL_ARRAY()
- DISP_ARRAY()
-
- * Process keys pressed and redisplay the array
- PROCESS_KEY()
-
- * Restore old screen and close file
- SCRNREST(old_screen)
- FCLOSE(handle)
-
- ENDIF
-
-
- SETCURSOR(old_cursor)
- RETURN NIL
-
-
- *****************************************************************
- STATIC FUNCTION PROCESS_KEY
- *****************************************************************
-
- * Process keys for window movement
-
- LOCAL buffer := SPACE(512), line_end := line_num := pointer := 0
-
- DO WHILE keypress != K_ESC
-
- * If key is valid, process it
-
- IF keypress = K_UP .OR. keypress = K_DOWN .OR. ;
- keypress = K_HOME .OR. keypress = K_END .OR. ;
- keypress = K_PGUP .OR. keypress = K_PGDN .OR. ;
- keypress = K_LEFT .OR. keypress = K_RIGHT .OR. ;
- keypress = K_CTRL_LEFT .OR. keypress = K_CTRL_RIGHT ;
- .OR. keypress = K_ENTER
-
- * Move up 1 line or 1 screen
- IF keypress = K_UP .OR. keypress = K_PGUP
-
- IF text_array[1][1] != 0 // Top of file
-
- * Move file pointer to top array line
- pointer = FSEEK(handle, text_array[1][1], 0)
-
- * Back up file pointer (row or screen window)
- pointer = REWIND(handle, IF(keypress = K_UP, ;
- 1, wind_rows), pointer)
-
- * And reload array
- FILL_ARRAY()
- ENDIF
-
- * Move down 1 line or 1 screen
- ELSEIF keypress = K_DOWN .OR. keypress = K_PGDN
-
- * Test for end of file
- IF FSEEK(handle,0,1) != text_eof
-
- * If not EOF or BOF, reload array
- IF keypress = K_DOWN
- * Move pointer to second array element
- FSEEK(handle, text_array[2][1], 0)
- ENDIF
-
- FILL_ARRAY()
- ENDIF
-
- * Move to top of file
- ELSEIF keypress = K_HOME
- pointer = FSEEK(handle,0,0)
- FILL_ARRAY()
-
- * Move to bottom of file
- ELSEIF keypress = K_END
- pointer = FSEEK(handle,0,2)
- * Move pointer back one screen window
- pointer = REWIND(handle, wind_rows, pointer)
- FILL_ARRAY()
-
- * Scroll window 1 column right
- ELSEIF keypress = K_RIGHT
- col_offset := IF(col_offset < 512,++col_offset, 512)
-
- * Scroll window 1 column left
- ELSEIF keypress = K_LEFT
- col_offset := IF(col_offset > 1, --col_offset, 1)
-
- * Scroll window 8 columns right
- ELSEIF keypress = K_CTRL_RIGHT
- col_offset := IF(col_offset < 512,col_offset+8, 512)
-
- * Scroll window 8 columns left
- ELSEIF keypress = K_CTRL_LEFT
- col_offset := IF(col_offset > 8, col_offset-8, 1)
-
- * Reset window offset to first column
- ELSEIF keypress = K_ENTER
- col_offset := 1
-
- ENDIF
-
- * Redisplay array
- keypress = DISP_ARRAY()
-
- ELSE
- * Key is invalid, get another
- keypress = INKEY(0)
- ENDIF
- ENDDO
-
- RETURN NIL
-
-
- *****************************************************************
- STATIC FUNCTION FILL_ARRAY
- *****************************************************************
-
- * Load viewing array with pointer and text of each line
-
- LOCAL counter := 1
-
- FOR counter = 1 TO (wind_rows)
- text_array[counter][1] := FSEEK(handle, 0, 1)
- text_array[counter][2] := FREADLINE(handle)
- IF FSEEK(handle, 0, 1) >= text_eof ; EXIT ; ENDIF
- NEXT
-
- * If at EOF, fill balance of array with dummy values
- IF counter++ < wind_rows
- FOR counter = counter TO wind_rows
- text_array[counter][1] := text_eof
- text_array[counter][2] := ''
- NEXT
- ENDIF
-
- RETURN NIL
-
- *****************************************************************
- STATIC FUNCTION DISP_ARRAY
- *****************************************************************
-
- * Display array. Return immediately if a key is pressed
-
- LOCAL counter := 1, disp_string
-
- * Clear keyboard buffer and window area
-
- CLEAR TYPEAHEAD
- @ top+1, left+2 CLEAR TO bottom-1, right-2
-
- * Display window lines until done or a key is pressed
- DO WHILE (keypress := INKEY()) = 0 .AND. counter <= wind_rows
- * Display string and increment line counter
- @ (top + counter), left + 2 SAY ;
- SUBSTR(text_array[counter][2], col_offset, wind_cols)
- counter++
-
- ENDDO
-
- RETURN keypress
-
-
- *****************************************************************
- STATIC FUNCTION REWIND (handle, num_lines, pointer)
- *****************************************************************
-
- * Move file pointer back specified number of lines
-
- LOCAL buffer := SPACE(512), first_line := .F., line_end := 0
-
- DO WHILE num_lines > 0
-
- * Clear buffer
- buffer := SPACE(512)
-
- IF pointer >= 514
- * Move pointer back 514 bytes
- FSEEK(handle, -514, 1)
-
- * Fill buffer without carriage return/line feed (CR/LF)
- FREAD(handle, @buffer, 512)
-
- ELSE
- * Move pointer to BOF and read remaining text
- FSEEK(handle, -pointer, 1)
- FREAD(handle, @buffer, pointer-2)
-
- * Set first line flag if no CR/LF in buffer
- buffer = TRIM(buffer)
- first_line := IF(AT(CHR(13)+CHR(10), buffer) > 0,.F.,.T.)
- ENDIF
-
- * Look for previous CR/LF
- DO WHILE (line_end := RAT(CHR(13)+CHR(10), buffer)) > 0 ;
- .AND. num_lines > 0
-
- * Move pointer to end of previous line
- pointer = FSEEK(handle, -(LEN(buffer)-(line_end-1)), 1)
-
- * Strip line from buffer and decrement number remaining
- buffer = SUBSTR(buffer, 1, line_end - 1)
- num_lines--
- ENDDO
-
- IF ! first_line
- * Move pointer to beginning of next line (skip CR/LF)
- pointer = FSEEK(handle, 2, 1)
- ELSE
- * Reset pointer to BOF and exit
- FSEEK(handle, 0, 0)
- EXIT
- ENDIF
-
-
- ENDDO
-
- RETURN pointer
-
-