home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / clipper / cuaclip.zip / MISC.PRG < prev    next >
Text File  |  1993-06-01  |  11KB  |  473 lines

  1. /*********************************************************************
  2.  
  3.     Misc.PRG - Miscellaneous functions for the Demo program.
  4.  
  5.     Author: Dave Rooney
  6.     Date  : Feb. 22, 1993
  7.  
  8. *********************************************************************/
  9.  
  10. #include "Demo.ch"
  11. #include "Directry.CH"
  12. #include "FileIO.CH"
  13.  
  14. #define READ_BLOCK      512
  15.  
  16.  
  17. /*********************************************************************
  18.  
  19.     FUNCTION BrowseFile - Browse a file.
  20.  
  21.     This function is used to browse (that's read-only!!!) a file,
  22.     based on the file specification passed.
  23.  
  24.     NOTE: Due to the limit of 4096 elements in any one dimension of
  25.             an array, the browser is limited to 4096 lines in the file.
  26.  
  27.  
  28.     Parameters: cFileSpec - The file spec. for the file list.
  29.  
  30.         Returns: Always returns .T.
  31.  
  32.  
  33.     Author: Dave Rooney
  34.     Date  : Feb. 22, 1993
  35.  
  36. *********************************************************************/
  37.  
  38. FUNCTION BrowseFile( cFileSpec )
  39.  
  40. LOCAL sOldScreen,    ; // Screen on entry
  41.         cOldColor,     ; // Colour on entry
  42.         nMouse,        ; // Mouse on entry
  43.         nCursor,       ; // Cursor on entry
  44.         cFileName,     ; // File name to be browsed
  45.         cBuffer,       ; // Editing buffer
  46.         nTotRows,      ; // Number of rows in the buffer
  47.         cLine,         ; // Current line of the buffer
  48.         aTitles,       ; // Column titles array
  49.         aBufArray,     ; // Main buffer array
  50.         i, j             // Loop counters
  51.  
  52. DEFAULT cFileSpec TO "*.*"
  53.  
  54. cOldColor := SETCOLOR()
  55.  
  56. //
  57. // Get the file name to be browsed...
  58. //
  59. cFileName := ALLTRIM( GetFile( cFileSpec ) )
  60.  
  61. IF !EMPTY( cFileName )
  62.     //
  63.     // Load the browse array...
  64.     //
  65.     aBufArray := LoadBrowseArray( cFileName )
  66.     aTitles   := { "", "", "" }
  67.  
  68.     STDBrowse( 2, 1, MAXROW() - 3, MAXCOL() - 2, { aTitles, aBufArray }, ;
  69.                     " Browsing: " + cFileName + " ",, ;
  70.                     "B/BG,W+/B,N/BG,W+/R", .T. )
  71.  
  72.     aBufArray := NIL
  73. ENDIF
  74.  
  75. SETCOLOR( cOldColor )
  76.  
  77. RETURN .F.
  78. //
  79. // EOP: BrowseFile
  80. //
  81.  
  82.  
  83. /*************************************************************************
  84.  
  85.     LoadBrowseArray - This function builds the browse array for
  86.                             the file name passed.
  87.  
  88.  
  89.     Parameters: cFileName - The file for which to build the browse array
  90.  
  91.         Returns: aBufArray - Array for the STDBrowse.
  92.  
  93. **************************************************************************/
  94.  
  95. STATIC FUNCTION LoadBrowseArray ( cFileName )
  96.  
  97. LOCAL cScreen,       ; // Screen behind 'Wait' message
  98.         cOldColor,     ; // Colour on entry
  99.         cBuffer,       ; // Input buffer
  100.         nTotRows,      ; // Total number of rows in the buffer
  101.         aBufArray,     ; // Buffer array
  102.         nHandle,       ; // File handle for the read
  103.         i, j             // Loop counters
  104.  
  105. cOldColor := SETCOLOR()
  106. cBuffer   := MEMOREAD( cFileName )
  107. nTotRows  := MLCOUNT( cBuffer, 254 )
  108. cBuffer   := ""
  109.  
  110. nTotRows := MIN( 4096, nTotRows )
  111.  
  112. //
  113. // Open the file in Read only mode.
  114. //
  115. IF ( nHandle := FOPEN( cFileName, FO_READ )) > 0
  116.     SETCOLOR( "GR+/BG" )
  117.  
  118.     cScreen := ShadowBox( 9, 28, 12, 52 )
  119.  
  120.     SETCOLOR( "R/BG" )
  121.  
  122.     @ 10,30 SAY "Loading file..."
  123.  
  124.     SETCOLOR( "B/BG" )
  125.  
  126.     @ 11,30 SAY REPLICATE( "░", 20 )
  127.  
  128.     aBufArray := ARRAY( nTotRows, 2 )
  129.  
  130.     FOR i := 1 TO nTotRows
  131.         @ 11,30 SAY REPLICATE( "█", INT(( i / nTotRows ) * 20 ))
  132.  
  133.         //
  134.         // Read a line from the file...
  135.         //
  136.         IF FReadLn( nHandle, @cBuffer ) == 0
  137.             EXIT
  138.         ENDIF
  139.  
  140.         //
  141.         // Replace TAB's with spaces...
  142.         //
  143.         cBuffer := STRTRAN( cBuffer, _TAB, SPACE(3) )
  144.  
  145.         //
  146.         // Load the array...
  147.         //
  148.         aBufArray[ i, 1 ] := PADR( LEFT( cBuffer, MAXCOL() - 7 ), MAXCOL() - 7 )
  149.         aBufArray[ i, 2 ] := PADR( SUBSTR( cBuffer, MAXCOL() - 6, MAXCOL() - 7 ), MAXCOL() - 7 )
  150.     NEXT
  151.  
  152.     //
  153.     // Don't forget to close it!
  154.     //
  155.     FCLOSE( nHandle )
  156.  
  157.     KillBox( cScreen )
  158. ELSE
  159.     aBufArray := {}
  160. ENDIF
  161.  
  162. RETURN aBufArray
  163. //
  164. // EOP: LoadBrowseArray
  165. //
  166.  
  167.  
  168. /*************************************************************************
  169.  
  170.     GetFile - This function displays a list of files matching the file
  171.                  specification passed, and reads the user's selection.
  172.  
  173.     Parameters: cFileSpec - The file spec. for which to display the list.
  174.  
  175.         Returns: cFileName - The file selected by the user.
  176.  
  177. **************************************************************************/
  178.  
  179. FUNCTION GetFile ( cFileSpec )
  180.  
  181. LOCAL cFileName,  ; // File name to be returned
  182.         aHotKeys,   ; // Array of hot keys for the browse
  183.         aDir,       ; // Array storing directory information
  184.         aFiles,     ; // Array storing file names for the browse
  185.         nFile,      ; // Index in aFiles of the file selected
  186.         i             // Loop counter
  187.  
  188. cFileName := ""
  189. aDir      := DIRECTORY( cFileSpec )
  190. aFiles    := ARRAY( LEN( aDir ))
  191. nFile     := 0
  192. aHotKeys  := { { K_ENTER, {|o| nFile := _SelectFile(o), .F. } }, ;
  193.                     { M_DOUBLE_CLICK, {|o| nFile := _SelectFile(o), .F. } } }
  194.  
  195. //
  196. // Sort the files by file name.
  197. //
  198. ASORT( aDir,,, { | x,y | x[ F_NAME ] < y[ F_NAME ] } )
  199.  
  200. FOR i := 1 TO LEN( aDir )
  201.     aFiles[i] := PADR( aDir[ i, 1 ], 20 )
  202. NEXT
  203.  
  204. IF !EMPTY( aFiles )
  205.     STDBrowse( 5, 10, 15, 35, { cFileSpec, aFiles }, " File List ", ;
  206.                     aHotKeys, "GR+/B,BG+/B,W+/B,W+/R", .T. )
  207.  
  208.     //
  209.     // If a selection was made, set the
  210.     // file name to that selection.
  211.     //
  212.     IF nFile > 0
  213.         cFileName := ALLTRIM( aFiles[ nFile ] )
  214.     ENDIF
  215. ENDIF
  216.  
  217. RETURN cFileName
  218. //
  219. // EOP: GetFile
  220. //
  221.  
  222.  
  223. /*************************************************************************
  224.  
  225.     _SelectFile - This function is used to perform the selection from
  226.                       the STDBrowse file list.
  227.  
  228.     Parameters: oBrowse - The STDBrowse TBrowse object.
  229.  
  230.         Returns: nFile - The index in the files array of the selection.
  231.  
  232. **************************************************************************/
  233.  
  234. STATIC FUNCTION _SelectFile ( oBrowse )
  235.  
  236. LOCAL nFile    // Index in the files array of the selection
  237.  
  238. //
  239. // Read the current position in the array...
  240. //
  241. nFile := oBrowse:cargo[ B_NCURRENT ]
  242.  
  243. //
  244. // Force the browse to be terminated...
  245. //
  246. oBrowse:cargo[ B_LMORE ] := .F.
  247.  
  248. RETURN nFile
  249. //
  250. // EOP: _SelectFile
  251. //
  252.  
  253.  
  254. /*******************************************************************
  255.  
  256.     _BuildPrinter - This function builds the Printer lookup table
  257.                          if it doesn't already exist.
  258.  
  259.     Parameters: None.
  260.  
  261.         Returns: NIL
  262.  
  263. *******************************************************************/
  264.  
  265. FUNCTION _BuildPrinter
  266.  
  267. LOCAL lRetCode,      ; // .T. if file created successfully
  268.         aPrinters,     ; // Array storing printer names
  269.         aStruct,       ; // File structure for Printer.DBF
  270.         i                // Loop counter
  271.  
  272. lRetCode := .F.
  273.  
  274. aPrinters := { ;
  275.     { "Epson LQ-1050",      "LPT2", .F. }, ;
  276.     { "HP LaserJet II",     "LPT1", .F. }, ;
  277.     { "HP LaserJet III",    "LPT1", .F. }, ;
  278.     { "HP LaserJet IIIsi",  "LPT1", .F. }, ;
  279.     { "QMS 410 - EMS",      "LPT2", .T. }  }
  280.  
  281. aStruct := {   { "PRNNAME",   "C", 30, 0 }, ;
  282.                     { "PORT",      "C",  4, 0 }, ;
  283.                     { "POSTSCRIPT","L",  1, 0 }  }
  284.  
  285. DBCREATE( "Printer", aStruct )
  286.  
  287. IF FILE( "Printer.DBF" )
  288.     lRetCode := .T.
  289.  
  290.     DBNetUse( .T., "DBFNTX", "Printer", "Printer", .F. )
  291.  
  292.     FOR i := 1 TO LEN( aPrinters )
  293.         DBAPPEND()
  294.         REPLACE FIELD->PrnName     WITH aPrinters[ i, 1 ]
  295.         REPLACE FIELD->Port        WITH aPrinters[ i, 2 ]
  296.         REPLACE FIELD->PostScript  WITH aPrinters[ i, 3 ]
  297.         DBUNLOCK()
  298.     NEXT
  299.  
  300.     DBCOMMIT()
  301.  
  302.     INDEX ON UPPER( FIELD->PrnName ) TO Printer
  303.  
  304.     DBNetClose( "Printer" )
  305. ENDIF
  306.  
  307. RETURN lRetCode
  308. //
  309. // EOP: _BuildPrinter
  310. //
  311.  
  312.  
  313. ************************
  314. **  FUNCTION FReadLn  **
  315. *****************************************************************************
  316. //
  317. //  This function reads a single CR/LF-terminated line from the file
  318. //  being viewed.  The number of bytes read is determined by READ_BLOCK.
  319. //
  320. //  Parameters: fh  - The file handle of the report file.
  321. //              buf - The output buffer (passed by reference).
  322. //
  323. //     Returns: The number of lines actually read.
  324. //
  325. //  Author: Dave Baker
  326. //  Date  : July, 1992
  327. //
  328.  
  329. FUNCTION FReadLn ( fh, buf )
  330.  
  331. LOCAL num_lines, num_chars, tmp_buf
  332. LOCAL skip_lf, eol, eof, start_pos
  333.  
  334. eol := 0
  335. eof := 0
  336. num_lines := 0
  337.  
  338. start_pos := FSEEK( fh, 0, 1 )
  339. tmp_buf := SPACE( READ_BLOCK )
  340.  
  341. num_chars := FREAD( fh, @tmp_buf, READ_BLOCK )
  342. IF (num_chars > 0)
  343.     eol := AT( CHR(13), tmp_buf )
  344.  
  345.     IF (eol > 0)
  346.         skip_lf := IF( SUBSTR( tmp_buf, eol + 1, 1) == CHR(10), 1, 0)
  347.  
  348.         FSEEK( fh, -num_chars + eol + skip_lf, 1 )
  349.         buf := SUBSTR( tmp_buf, 1, eol - 1)
  350.     ELSE
  351.         eof := AT( CHR(K_CTRL_Z), tmp_buf)
  352.  
  353.         IF (eof > 0)
  354.             FSEEK( fh, -num_chars + eof, 1 )
  355.             buf := SUBSTR( tmp_buf, 1, eof - 1)
  356.         ELSE
  357.             // If no chars left (effectively EOF).
  358.  
  359.             IF ((start_pos + num_chars) >= FSEEK( fh, 0, 1 ))
  360.                 buf := SUBSTR( tmp_buf, 1, num_chars)
  361.             ENDIF
  362.         ENDIF
  363.     ENDIF
  364.     num_lines := 1
  365. ENDIF
  366.  
  367. RETURN num_lines
  368. //
  369. // EOP: FReadLn
  370. //
  371.  
  372.  
  373. **************************
  374. **  FUNCTION FUnReadLn  **
  375. *****************************************************************************
  376. //
  377. //  This function resets the file pointer to the beginning of the
  378. //  previous line (it unreads the line!).
  379. //
  380. //  Parameters: fh        - The file handle of the report file.
  381. //              num_lines - The number of lines to 'unread'.
  382. //              buf       - Text buffer for the read.
  383. //
  384. //     Returns: line_cnt - The number of lines actually unread.
  385. //
  386. //  Author: Dave Baker
  387. //  Date  : July, 1992
  388. //
  389.  
  390. FUNCTION FUnReadLn ( fh, num_lines, buf )
  391.  
  392. LOCAL i, tmp_buf, read_buf, line_cnt
  393. LOCAL eol, bof, skip_back, skip_lf, start_pos, next_pos, block_size
  394.  
  395. eol := 0
  396. bof := .F.
  397. line_cnt := 0
  398. tmp_buf := ""
  399.  
  400. IF (num_lines == 0)
  401.     RETURN line_cnt
  402. ENDIF
  403.  
  404. buf := IF( buf == NIL, "", buf )
  405.  
  406. start_pos := FSEEK( fh, 0, 1 )
  407. block_size := MIN( start_pos, READ_BLOCK )
  408. next_pos := FSEEK( fh, -block_size, 1 )
  409.  
  410. IF (start_pos == 0)
  411.     bof := .T.
  412. ELSE
  413.     read_buf := SPACE( block_size)
  414.     FREAD( fh, @read_buf, block_size )
  415. ENDIF
  416.  
  417. DO WHILE (!bof .AND. (line_cnt < num_lines))
  418.     tmp_buf := read_buf + tmp_buf
  419.  
  420.     DO WHILE (line_cnt < num_lines)
  421.         * Is last char a LF, IF not assume CR.
  422.         * Use this to skip to last char of previous line.
  423.         skip_back := IF( SUBSTR( tmp_buf, LEN( tmp_buf), 1) == CHR( 10), 2, 1)
  424.  
  425.         eol := RAT( CHR(13), SUBSTR( tmp_buf, 1, LEN( tmp_buf) - skip_back))
  426.  
  427.         IF (eol > 0)
  428.             skip_lf := IF( SUBSTR( tmp_buf, eol + 1, 1) == CHR( 10), 1, 0)
  429.  
  430.             buf := SUBSTR( tmp_buf, eol + skip_lf + 1,;
  431.                 LEN( tmp_buf) - eol - skip_lf - skip_back)
  432.  
  433.             tmp_buf := SUBSTR( tmp_buf, 1, eol + skip_lf)
  434.  
  435.             ++line_cnt
  436.         ELSE
  437.             * Either the line is incomplete or we are at bof
  438.             buf := SUBSTR( tmp_buf, 1, LEN( tmp_buf) - skip_back)
  439.  
  440.             EXIT
  441.         ENDIF
  442.     ENDDO
  443.  
  444.     * If more lines to unread.
  445.     IF (line_cnt < num_lines)
  446.         start_pos := FSEEK( fh, next_pos, 0 )
  447.         block_size := MIN( start_pos, READ_BLOCK )
  448.         next_pos := FSEEK( fh, -block_size, 1 )
  449.  
  450.         IF (start_pos == 0)
  451.             line_cnt := line_cnt + 1
  452.             bof := .T.
  453.         ELSE
  454.             read_buf := SPACE( block_size )
  455.             FREAD( fh, @read_buf, block_size )
  456.         ENDIF
  457.     ENDIF
  458. ENDDO
  459.  
  460. * Always leave with file pointer at beginning of line or bof.
  461. IF (bof)
  462.     FSEEK( fh, 0, 0 )
  463. ELSE
  464.     FSEEK( fh, next_pos + LEN( tmp_buf), 0 )
  465. ENDIF
  466.  
  467. RETURN line_cnt
  468. //
  469. // EOP: FUnReadLn
  470. //
  471.  
  472.  
  473.