home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a012 / 1.ddi / CHAP25.EXE / CHP2515.PRG < prev   
Encoding:
Text File  |  1991-06-12  |  5.3 KB  |  191 lines

  1. /*
  2.    Listing 25.15. Two simultaneous browse windows, one with
  3.                   a listing of database file names and the
  4.                   other with corresponding field structures.
  5.    Calls ArraySkip(), which is in Listing 25.11 (CHP2511.PRG)
  6.    Author: Craig Yellick
  7.    Excerpted from "Clipper 5: A Developer's Guide"
  8.    Copyright (c) 1991 M&T Books
  9.                       501 Galveston Drive
  10.                       Redwood City, CA 94063-4728
  11.                       (415) 366-3600
  12. */
  13.  
  14. //───── NOTE: must compile with the /N option!
  15.  
  16. function DBFdirect(fileSpec)
  17. /*
  18.    Call this function from DOS. It will display
  19.    two browse windows, one with database file name
  20.    information and one with the field structure of
  21.    the currently highlighted database.
  22.  
  23.    If you think this routine would form an excellent
  24.    base for a general purpose database utility and are
  25.    already dreaming up specifications and features...
  26.    you've been bitten by that Clipper 5.0 bug and we
  27.    wish you well! Turn off the lights when you leave
  28.    and try to get some sleep once and a while.
  29. */
  30. #include "inkey.ch"
  31. #include "directry.ch"
  32. #include "dbstruct.ch"
  33.  
  34. local dir_, stru_
  35. local dbf, dirPos
  36. local stru, struPos
  37. local i, bytes, col, key
  38.  
  39.   //  Default filespec if none specified.
  40.   if fileSpec = nil
  41.     fileSpec := "*.dbf"
  42.   elseif .not. ("." $ fileSpec)
  43.     fileSpec += ".dbf"
  44.   endif
  45.  
  46.   setcursor(0)
  47.   @ 0,0 clear
  48.   @ 1,0 say padc("Database Directory & Structure Viewer: " ;
  49.                  +fileSpec, 80)
  50.   @ 2,0 say "Loading..."
  51.  
  52.   //  Load directory entries.
  53.   dir_ := directory(fileSpec)
  54.   if len(dir_) = 0
  55.     @ 2,0
  56.     @ 2,0 say "No files found."
  57.     return nil
  58.   endif
  59.  
  60.   //  This array will hold database structures.
  61.   stru_ := {}
  62.  
  63.   //  For each database file in the directory...
  64.   for i := 1 to len(dir_)
  65.     @ 2,11 say i
  66.     use (dir_[i, DBS_NAME]) shared
  67.  
  68.     //  Add record and field counts to the directory array.
  69.     aadd(dir_[i], lastrec())
  70.     aadd(dir_[i], fcount())
  71.  
  72.     //  Add current database's structure to the array.
  73.     aadd(stru_, dbstruct())
  74.     use
  75.   next i
  76.  
  77.   //  Sum the file sizes.
  78.   bytes := 0
  79.   aeval(dir_, { |f_| bytes += f_[F_SIZE] } )
  80.  
  81.   //  Clear the "loading" message.
  82.   @ 2,0
  83.  
  84.   //  Draw the static portions of the screen.
  85.   @  4,1 say "Up/Down, PgUp/PgDn"
  86.   @  5,0 to 15,52
  87.   @ 16,1 say ltrim(transform(bytes, "999,999,999")) ;
  88.             +" bytes in " ;
  89.             +ltrim(str(len(dir_))) +" files."
  90.  
  91.   @ 4,54 say "Left/Right, Tab/ShiftTab"
  92.   @ 5,53 to 15,79
  93.  
  94.   //  Construct a browse object for the directory array.
  95.   //
  96.   dirPos := 1
  97.   dbf := TBrowseNew(6,1,14,51)
  98.   dbf:headSep := "--"
  99.   dbf:colSep  := "|"
  100.   dbf:goTopBlock    := { | | dirPos := 1 }
  101.   dbf:goBottomBlock := { | | dirPos := len(dir_) }
  102.   dbf:skipBlock     := { |n| ArraySkip(len(dir_), @dirPos, n) }
  103.  
  104.   //  Directory window columns.
  105.   dbf:addcolumn(TBColumnNew("File Name", ;
  106.       { || padr(dir_[dirPos, F_NAME], 12) } ))
  107.   dbf:addcolumn(TBColumnNew("Size",      ;
  108.       { || transform(dir_[dirPos, F_SIZE], "99,999,999 ") } ))
  109.   dbf:addcolumn(TBColumnNew("Date",      ;
  110.       { || dir_[dirPos, F_DATE] } ))
  111.   dbf:addcolumn(TBColumnNew("Records",   ;
  112.       { || transform(dir_[dirPos, 6], "999,999 ") } ))
  113.   dbf:addcolumn(TBColumnNew("Fields",    ;
  114.       { || transform(dir_[dirPos, 7], "999") } ))
  115.  
  116.   //  Construct a browse object for the structure array.
  117.   //
  118.   struPos := 1
  119.   stru := TBrowseNew(6,54,14,78)
  120.   stru:headSep := "--"
  121.   stru:colSep  := "|"
  122.   stru:goTopBlock    := { | | struPos := 1 }
  123.   stru:goBottomBlock := { | | struPos := len(stru_) }
  124.   stru:skipBlock     := ;
  125.        { |n| ArraySkip(len(stru_[dirPos]), @struPos, n) }
  126.  
  127.   //  Structure window columns.
  128.   stru:addcolumn(TBColumnNew("Field", ;
  129.        { || padr(stru_[dirPos, struPos, DBS_NAME], 10) } ))
  130.   stru:addcolumn(TBColumnNew("Type",  ;
  131.        { || padc(stru_[dirPos, struPos, DBS_TYPE],  4) } ))
  132.   stru:addcolumn(TBColumnNew("Width", ;
  133.        { || str(stru_[dirPos, struPos,  DBS_LEN],   5) } ))
  134.   stru:addcolumn(TBColumnNew("Dec",   ;
  135.        { || str(stru_[dirPos, struPos,  DBS_DEC],   3) } ))
  136.  
  137.   do while .t.
  138.  
  139.     //  If the directory window position was altered,
  140.     //  we must update the structure window to match it.
  141.     if .not. dbf:stable
  142.       stru:rowPos := 1
  143.       stru:goTop()
  144.       stru:refreshAll()
  145.     endif
  146.  
  147.     //  Stabilize both windows.
  148.     do while (.not. dbf:stabilize()) .and. (nextkey() = 0)
  149.     enddo
  150.     do while (.not. stru:stabilize()) .and. (nextkey() = 0)
  151.     enddo
  152.  
  153.     //  Update the structure summary lines.
  154.     @ 16,54
  155.     @ 17,54
  156.     bytes := 0
  157.     aeval(stru_[dirPos], { |s_| bytes += s_[DBS_LEN] } )
  158.     @ 16,54 say ltrim(str(bytes)) +" bytes per record,"
  159.     @ 17,54 say ltrim(str(len(stru_[dirPos]))) +" fields."
  160.  
  161.     key := inkey(0)
  162.  
  163.     //  Database window navigation keys
  164.     do case
  165.     case key = K_UP
  166.       dbf:up()
  167.     case key = K_DOWN
  168.       dbf:down()
  169.     case key = K_PGUP
  170.       dbf:pageUp()
  171.     case key = K_PGDN
  172.       dbf:pageDown()
  173.  
  174.     //  Structure window navigation keys.
  175.     case key = K_LEFT
  176.       stru:up()
  177.     case key = K_RIGHT
  178.       stru:down()
  179.     case key = K_TAB
  180.       stru:pageDown()
  181.     case key = K_SH_TAB
  182.       stru:pageUp()
  183.     case key = K_ESC
  184.       exit
  185.     endcase
  186.   enddo
  187.   setcursor(1)
  188. return nil
  189.  
  190. // end of file CHP2515.PRG
  191.