[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]


/*********************************************************************

   Misc.PRG - Miscellaneous functions for the Demo program.

   Author: Dave Rooney
   Date  : Feb. 22, 1993

*********************************************************************/

#include "Demo.ch"
#include "Directry.CH"
#include "FileIO.CH"

#define READ_BLOCK      512


/*********************************************************************

   FUNCTION BrowseFile - Browse a file.

   This function is used to browse (that's read-only!!!) a file,
   based on the file specification passed.

   NOTE: Due to the limit of 4096 elements in any one dimension of
         an array, the browser is limited to 4096 lines in the file.


   Parameters: cFileSpec - The file spec. for the file list.

      Returns: Always returns .T.


   Author: Dave Rooney
   Date  : Feb. 22, 1993

*********************************************************************/

FUNCTION BrowseFile( cFileSpec )

LOCAL sOldScreen,    ; // Screen on entry
      cOldColor,     ; // Colour on entry
      nMouse,        ; // Mouse on entry
      nCursor,       ; // Cursor on entry
      cFileName,     ; // File name to be browsed
      cBuffer,       ; // Editing buffer
      nTotRows,      ; // Number of rows in the buffer
      cLine,         ; // Current line of the buffer
      aTitles,       ; // Column titles array
      aBufArray,     ; // Main buffer array
      i, j             // Loop counters

DEFAULT cFileSpec TO "*.*"

cOldColor := SETCOLOR()

//
// Get the file name to be browsed...
//
cFileName := ALLTRIM( GetFile( cFileSpec ) )

IF !EMPTY( cFileName )
   //
   // Load the browse array...
   //
   aBufArray := LoadBrowseArray( cFileName )
   aTitles   := { "", "", "" }

   STDBrowse( 2, 1, MAXROW() - 3, MAXCOL() - 2, { aTitles, aBufArray }, ;
               " Browsing: " + cFileName + " ",, ;
               "B/BG,W+/B,N/BG,W+/R", .T. )

   aBufArray := NIL
ENDIF

SETCOLOR( cOldColor )

RETURN .F.
//
// EOP: BrowseFile
//


/*************************************************************************

   LoadBrowseArray - This function builds the browse array for
                     the file name passed.


   Parameters: cFileName - The file for which to build the browse array

      Returns: aBufArray - Array for the STDBrowse.

**************************************************************************/

STATIC FUNCTION LoadBrowseArray ( cFileName )

LOCAL cScreen,       ; // Screen behind 'Wait' message
      cOldColor,     ; // Colour on entry
      cBuffer,       ; // Input buffer
      nTotRows,      ; // Total number of rows in the buffer
      aBufArray,     ; // Buffer array
      nHandle,       ; // File handle for the read
      i, j             // Loop counters

cOldColor := SETCOLOR()
cBuffer   := MEMOREAD( cFileName )
nTotRows  := MLCOUNT( cBuffer, 254 )
cBuffer   := ""

nTotRows := MIN( 4096, nTotRows )

//
// Open the file in Read only mode.
//
IF ( nHandle := FOPEN( cFileName, FO_READ )) > 0
   SETCOLOR( "GR+/BG" )

   cScreen := ShadowBox( 9, 28, 12, 52 )

   SETCOLOR( "R/BG" )

   @ 10,30 SAY "Loading file..."

   SETCOLOR( "B/BG" )

   @ 11,30 SAY REPLICATE( "#", 20 )

   aBufArray := ARRAY( nTotRows, 2 )

   FOR i := 1 TO nTotRows
      @ 11,30 SAY REPLICATE( "#", INT(( i / nTotRows ) * 20 ))

      //
      // Read a line from the file...
      //
      IF FReadLn( nHandle, @cBuffer ) == 0
         EXIT
      ENDIF

      //
      // Replace TAB's with spaces...
      //
      cBuffer := STRTRAN( cBuffer, _TAB, SPACE(3) )

      //
      // Load the array...
      //
      aBufArray[ i, 1 ] := PADR( LEFT( cBuffer, MAXCOL() - 7 ), MAXCOL() - 7 )
      aBufArray[ i, 2 ] := PADR( SUBSTR( cBuffer, MAXCOL() - 6, MAXCOL() - 7 ), MAXCOL() - 7 )
   NEXT

   //
   // Don't forget to close it!
   //
   FCLOSE( nHandle )

   KillBox( cScreen )
ELSE
   aBufArray := {}
ENDIF

RETURN aBufArray
//
// EOP: LoadBrowseArray
//


/*************************************************************************

   GetFile - This function displays a list of files matching the file
             specification passed, and reads the user's selection.

   Parameters: cFileSpec - The file spec. for which to display the list.

      Returns: cFileName - The file selected by the user.

**************************************************************************/

FUNCTION GetFile ( cFileSpec )

LOCAL cFileName,  ; // File name to be returned
      aHotKeys,   ; // Array of hot keys for the browse
      aDir,       ; // Array storing directory information
      aFiles,     ; // Array storing file names for the browse
      nFile,      ; // Index in aFiles of the file selected
      i             // Loop counter

cFileName := ""
aDir      := DIRECTORY( cFileSpec )
aFiles    := ARRAY( LEN( aDir ))
nFile     := 0
aHotKeys  := { { K_ENTER, {|o| nFile := _SelectFile(o), .F. } }, ;
               { M_DOUBLE_CLICK, {|o| nFile := _SelectFile(o), .F. } } }

//
// Sort the files by file name.
//
ASORT( aDir,,, { | x,y | x[ F_NAME ] < y[ F_NAME ] } )

FOR i := 1 TO LEN( aDir )
   aFiles[i] := PADR( aDir[ i, 1 ], 20 )
NEXT

IF !EMPTY( aFiles )
   STDBrowse( 5, 10, 15, 35, { cFileSpec, aFiles }, " File List ", ;
               aHotKeys, "GR+/B,BG+/B,W+/B,W+/R", .T. )

   //
   // If a selection was made, set the
   // file name to that selection.
   //
   IF nFile > 0
      cFileName := ALLTRIM( aFiles[ nFile ] )
   ENDIF
ENDIF

RETURN cFileName
//
// EOP: GetFile
//


/*************************************************************************

   _SelectFile - This function is used to perform the selection from
                 the STDBrowse file list.

   Parameters: oBrowse - The STDBrowse TBrowse object.

      Returns: nFile - The index in the files array of the selection.

**************************************************************************/

STATIC FUNCTION _SelectFile ( oBrowse )

LOCAL nFile    // Index in the files array of the selection

//
// Read the current position in the array...
//
nFile := oBrowse:cargo[ B_NCURRENT ]

//
// Force the browse to be terminated...
//
oBrowse:cargo[ B_LMORE ] := .F.

RETURN nFile
//
// EOP: _SelectFile
//


/*******************************************************************

   _BuildPrinter - This function builds the Printer lookup table
                   if it doesn't already exist.

   Parameters: None.

      Returns: NIL

*******************************************************************/

FUNCTION _BuildPrinter

LOCAL lRetCode,      ; // .T. if file created successfully
      aPrinters,     ; // Array storing printer names
      aStruct,       ; // File structure for Printer.DBF
      i                // Loop counter

lRetCode := .F.

aPrinters := { ;
   { "Epson LQ-1050",      "LPT2", .F. }, ;
   { "HP LaserJet II",     "LPT1", .F. }, ;
   { "HP LaserJet III",    "LPT1", .F. }, ;
   { "HP LaserJet IIIsi",  "LPT1", .F. }, ;
   { "QMS 410 - EMS",      "LPT2", .T. }  }

aStruct := {   { "PRNNAME",   "C", 30, 0 }, ;
               { "PORT",      "C",  4, 0 }, ;
               { "POSTSCRIPT","L",  1, 0 }  }

DBCREATE( "Printer", aStruct )

IF FILE( "Printer.DBF" )
   lRetCode := .T.

   DBNetUse( .T., "DBFNTX", "Printer", "Printer", .F. )

   FOR i := 1 TO LEN( aPrinters )
      DBAPPEND()
      REPLACE FIELD->PrnName     WITH aPrinters[ i, 1 ]
      REPLACE FIELD->Port        WITH aPrinters[ i, 2 ]
      REPLACE FIELD->PostScript  WITH aPrinters[ i, 3 ]
      DBUNLOCK()
   NEXT

   DBCOMMIT()

   INDEX ON UPPER( FIELD->PrnName ) TO Printer

   DBNetClose( "Printer" )
ENDIF

RETURN lRetCode
//
// EOP: _BuildPrinter
//


************************
**  FUNCTION FReadLn  **
*****************************************************************************
//
//  This function reads a single CR/LF-terminated line from the file
//  being viewed.  The number of bytes read is determined by READ_BLOCK.
//
//  Parameters: fh  - The file handle of the report file.
//              buf - The output buffer (passed by reference).
//
//     Returns: The number of lines actually read.
//
//  Author: Dave Baker
//  Date  : July, 1992
//

FUNCTION FReadLn ( fh, buf )

LOCAL num_lines, num_chars, tmp_buf
LOCAL skip_lf, eol, eof, start_pos

eol := 0
eof := 0
num_lines := 0

start_pos := FSEEK( fh, 0, 1 )
tmp_buf := SPACE( READ_BLOCK )

num_chars := FREAD( fh, @tmp_buf, READ_BLOCK )
IF (num_chars > 0)
   eol := AT( CHR(13), tmp_buf )

   IF (eol > 0)
      skip_lf := IF( SUBSTR( tmp_buf, eol + 1, 1) == CHR(10), 1, 0)

      FSEEK( fh, -num_chars + eol + skip_lf, 1 )
      buf := SUBSTR( tmp_buf, 1, eol - 1)
   ELSE
      eof := AT( CHR(K_CTRL_Z), tmp_buf)

      IF (eof > 0)
         FSEEK( fh, -num_chars + eof, 1 )
         buf := SUBSTR( tmp_buf, 1, eof - 1)
      ELSE
         // If no chars left (effectively EOF).

         IF ((start_pos + num_chars) >= FSEEK( fh, 0, 1 ))
            buf := SUBSTR( tmp_buf, 1, num_chars)
         ENDIF
      ENDIF
   ENDIF
   num_lines := 1
ENDIF

RETURN num_lines
//
// EOP: FReadLn
//


**************************
**  FUNCTION FUnReadLn  **
*****************************************************************************
//
//  This function resets the file pointer to the beginning of the
//  previous line (it unreads the line!).
//
//  Parameters: fh        - The file handle of the report file.
//              num_lines - The number of lines to 'unread'.
//              buf       - Text buffer for the read.
//
//     Returns: line_cnt - The number of lines actually unread.
//
//  Author: Dave Baker
//  Date  : July, 1992
//

FUNCTION FUnReadLn ( fh, num_lines, buf )

LOCAL i, tmp_buf, read_buf, line_cnt
LOCAL eol, bof, skip_back, skip_lf, start_pos, next_pos, block_size

eol := 0
bof := .F.
line_cnt := 0
tmp_buf := ""

IF (num_lines == 0)
   RETURN line_cnt
ENDIF

buf := IF( buf == NIL, "", buf )

start_pos := FSEEK( fh, 0, 1 )
block_size := MIN( start_pos, READ_BLOCK )
next_pos := FSEEK( fh, -block_size, 1 )

IF (start_pos == 0)
   bof := .T.
ELSE
   read_buf := SPACE( block_size)
   FREAD( fh, @read_buf, block_size )
ENDIF

DO WHILE (!bof .AND. (line_cnt < num_lines))
   tmp_buf := read_buf + tmp_buf

   DO WHILE (line_cnt < num_lines)
      * Is last char a LF, IF not assume CR.
      * Use this to skip to last char of previous line.
      skip_back := IF( SUBSTR( tmp_buf, LEN( tmp_buf), 1) == CHR( 10), 2, 1)

      eol := RAT( CHR(13), SUBSTR( tmp_buf, 1, LEN( tmp_buf) - skip_back))

      IF (eol > 0)
         skip_lf := IF( SUBSTR( tmp_buf, eol + 1, 1) == CHR( 10), 1, 0)

         buf := SUBSTR( tmp_buf, eol + skip_lf + 1,;
            LEN( tmp_buf) - eol - skip_lf - skip_back)

         tmp_buf := SUBSTR( tmp_buf, 1, eol + skip_lf)

         ++line_cnt
      ELSE
         * Either the line is incomplete or we are at bof
         buf := SUBSTR( tmp_buf, 1, LEN( tmp_buf) - skip_back)

         EXIT
      ENDIF
   ENDDO

   * If more lines to unread.
   IF (line_cnt < num_lines)
      start_pos := FSEEK( fh, next_pos, 0 )
      block_size := MIN( start_pos, READ_BLOCK )
      next_pos := FSEEK( fh, -block_size, 1 )

      IF (start_pos == 0)
         line_cnt := line_cnt + 1
         bof := .T.
      ELSE
         read_buf := SPACE( block_size )
         FREAD( fh, @read_buf, block_size )
      ENDIF
   ENDIF
ENDDO

* Always leave with file pointer at beginning of line or bof.
IF (bof)
   FSEEK( fh, 0, 0 )
ELSE
   FSEEK( fh, next_pos + LEN( tmp_buf), 0 )
ENDIF

RETURN line_cnt
//
// EOP: FUnReadLn
//

This page created by ng2html v1.05, the Norton guide to HTML conversion utility. Written by Dave Pearson