home *** CD-ROM | disk | FTP | other *** search
- /*
- Program: BrowDemo.Prg
- Date : 03/12/91
- Dialect: Clipper 5.0
- Author : Kathleen B. Uchman
- For Aquarium readers
-
- Compile: Clipper browdemo /m /n
-
- */
-
- #include "inkey.ch"
- memvar getlist
-
- function main()
- local filestru_, stufdata_, i, j
-
- set deleted on
-
- /* first, let's make some databases to browse */
- filestru_ := { {"vendid ","C",06,0},;
- {"name ","C",20,0},;
- {"address","C",20,0},;
- {"city ","C",20,0},;
- {"state ","C",02,0},;
- {"zip ","C",05,0},;
- {"ytdpur ","N",09,2},;
- {"ytdpay ","N",09,2} ;
- }
- dbcreate("vendors",filestru_)
-
- filestru_ := { {"vendid ","C",06,0},;
- {"invoice ","C",06,0},;
- {"ponumber","C",06,0},;
- {"purdate ","D",08,0},;
- {"amount ","N",09,2},;
- {"paid ","L",01,0} ;
- }
- dbcreate("invoices",filestru_)
-
- /* open the files, and throw in some default data */
- use vendors new
- index on vendors->vendid to vendors
- stufdata_ := { ;
- {"000010","Ajax Supplies","P.O. Box 235","Concord","CA","94598"},;
- {"000015","Wally's Pizza","1300 Clay Rd.",;
- "Concord","CA","94521",1571.22,1255.98},;
- {"100123","Aardvaark City","Bancroft & Main","Rodeo","CA","94310"} ;
- }
- for i := 1 to len(stufdata_)
- append blank
- for j := 1 to len(stufdata_[i])
- fieldput(j,stufdata_[i,j])
- next
- commit
- next
- /* We'll set up a couple of invoices for vendor 000015 */
- use invoices new
- index on invoices->vendid+invoices->invoice to invoices
- stufdata_ := { ;
- {"000015","102143","W00239",ctod("01/10/91"),315.24,.f.},;
- {"000015","102144","W00100",ctod("02/14/91"),1255.98,.t.};
- }
- for i := 1 to len(stufdata_)
- append blank
- for j := 1 to len(stufdata_[i])
- fieldput(j,stufdata_[i,j])
- next
- commit
- next
- /* Now let's browse these suckers! */
- Vendors()
- return nil
- * eof Main()
- * ==================================================== *
-
- function Vendors()
- /* Called by : Function Main()
- Purpose : Sets up call to Browser for Vendors.dbf
- Parameters : None
- Returns : Nil
- */
- /* array fields_ contains the items to be browsed */
- local fields_ := { "vendors->vendid" ,;
- "vendors->name" ,;
- "vendors->address",;
- "vendors->city" ,;
- "vendors->state" ,;
- "vendors->zip" }
-
- /* array heads_ contains the column headers for the browser */
- local heads_ := { "ID Key" ,;
- "Vendor Name" ,;
- "Address" ,;
- "City" ,;
- "State" ,;
- "Zip" }
-
- /* character var viewhead is the header to appear above the
- omnipresent data appearing in the viewbox.
-
- code block viewbox identifies the data to appear in the box
- below the browse window
- */
- local viewhead := "YTD Purchases"+space(13)+"YTD Payments"+;
- space(3)+"(F10=View Invoices)"
- local viewbox := { | | "$ "+trans(vendors->ytdpur,"###,###.##")+ ;
- space(14)+"$"+trans(vendors->ytdpay,"###,###.##") }
-
- cls
- select vendors
- Browser(02,5,08,74,fields_,heads_,"VendAction",viewhead,viewbox)
- return nil
- * eof Vendors()
- * ==================================================== *
-
- function VendAction(key)
- /* Called by : Function Browser() (directed by Vendors() )
- Purpose : Hotkey handler for viewing vendor data. Will
- set up the call to Browser() viewing Invoices.dbf.
- Parameter : key <expN> - last key hit by user in Browser()
- Returns : retval <expL> - determines whether to
- invoke brow:refreshAll()
- */
- local retval := .f. ,;
- fields_, heads_, keyfld, keydata
- if key == K_F10
- /* these are the fields to appear in the browse window */
- fields_ := { "invoices->invoice",;
- "invoices->ponumber",;
- "invoices->purdate",;
- "invoices->amount",;
- "iif(invoices->paid,'Paid ','Pending')" ;
- }
- /* these are the column headers for the browse window */
- heads_ := { "Invoice" ,;
- "PO No." ,;
- "Purchased",;
- "Amount" ,;
- "Status" ;
- }
-
- /* keyfld is the primary indexkey() value, and keydata is the
- value we want to match in this next browse.
- */
- keyfld := "vendid"
- keydata := vendors->vendid
-
- /* notice that we don't want to display a viewbox with this browse,
- so we just bypass those params in the Browser() call.
- */
-
- select invoices
- Browser(15,10,23,64,fields_,heads_,"InvAction",,,keyfld,keydata)
- select vendors
- endif
- return retval
- * eof VendAction(key)
- * ==================================================== *
-
- function InvAction(key)
- /* Called by : Function Browser() (directed by VendAction() )
- Purpose : Hotkey handler for viewing Invoices.dbf
- Parameter : key <expN> - last key pressed in Browser()
- Returns : retval <expL> - directs brow:refreshAll()
- */
- local retval := .f. ,;
- addone := (key == K_INS), ;
- buffer, markrec := recno()
-
- local mvendid, minvoice, mponumber, ;
- mpurdate, mamount, mpaid, oldamount := 0.00
-
- /* this is a random invoice number generator so you can add
- unique invoices to this demo database
- */
- static invoicectr := 100145
-
- if key == K_INS .or. ;
- key == K_ENTER
-
- if addone
- go lastrec() +1
- mvendid := vendors->vendid
- minvoice := str(++invoicectr,6)
- mponumber := invoices->ponumber
- mpurdate := date()
- mamount := invoices->amount
- mpaid := .f.
- go markrec
- else
- mvendid := invoices->vendid
- minvoice := invoices->invoice
- mponumber := invoices->ponumber
- mpurdate := invoices->purdate
- mamount := invoices->amount
- oldamount := invoices->amount
- mpaid := invoices->paid
- endif
-
- buffer := savescreen(18,10,20,64)
- @ 18,10,20,64 box '╔═╗║╝═╚║ '
- do while .t.
- @ 19,14 say minvoice
- @ 19,22 get mponumber picture "!#####"
- @ 19,32 get mpurdate
- @ 19,43 get mamount picture "######.##"
- @ 19,54 say iif(mpaid,"Paid ","Pending")
- read
- if lastkey() == K_ESC
- exit
- endif
- if addone
- append blank
- endif
- replace invoices->vendid with mvendid ,;
- invoices->invoice with minvoice ,;
- invoices->ponumber with mponumber,;
- invoices->purdate with mpurdate ,;
- invoices->amount with mamount ,;
- invoices->paid with mpaid
-
- commit
- select vendors
- if addone
- /* as long as we're putting the ytdpur field in
- the vendors.dbf viewbox, we should keep the
- values current.
- */
- vendors->ytdpur += mamount
- else
- vendors->ytdpur += (mamount - oldamount)
- endif
- commit
- select invoices
-
- retval := .t.
- exit
- enddo while .t.
- restscreen(18,10,20,64,buffer)
-
- elseif key == K_DEL
- delete
- commit
- /* just keeping the information current in the
- vendors.dbf -- keep your eye on the viewbox when
- you leave the invoices.dbf browse!
- */
- select vendors
- vendors->ytdpur -= invoices->amount
- if invoices->paid
- vendors->ytdpay -= invoices->amount
- endif
- commit
- select invoices
- skip -1
- retval := .t.
- endif
- return retval
- * eof InvAction(key)
- * ==================================================== *
-
- function Browser(t,l,b,r,fields_, heads_, keyfunc, ;
- viewhead, viewbox, keyfld, keydata)
- /* Called by : Functions Vendors() and VendAction()
- Purpose : Bare-bones browser for sake of this demo!
- Parameters : t,l,b,r <expN> - browse window params
- fields_ <expA> - fields to browse
- heads_ <expA> - column headers
- keyfunc <expC> - name of hotkey handler func
- viewhead <expC> - header for viewbox
- viewbox <expB> - code block of data for box
- keyfld <expC> - key field(s) in indexkey()
- keydata <expC> - data to be matched for a range
- Returns : Nil
- */
- /* Local vars: "brow, col" <expO> are the browse and column objects.
- "key" <expN> is the user's keypress while browsing.
- "nokey" <expL> is the result of "seek keydata",
- where no match is found().
- */
- local brow, col, key := 0, i, nokey, ;
- buffer := savescreen(0,0,24,79)
-
- @ t,l,b,r box '╔═╗║╝═╚║ '
- /* if a box of always-viewable data is to appear with this browse,
- draw a box for it and paint in the header.
- */
- if viewhead != NIL
- @ b+2,l,b+5,r box '╔═╗║╝═╚║ '
- @ b+3,l+1 say viewhead
- endif
-
- /* set up the browse object */
- brow := TBrowseDB(t+1,l+1,b-1,r-1)
- brow:headSep = '═╤═'
- brow:colSep = ' │ '
-
- /* if a range of data is to be specified (e.g., "do while
- invoices->vendid = vendors->vendid"), we have to establish
- the appropriate definitions for the browse movement blocks.
- */
- if keydata != NIL
- brow:goTopBlock := { | | GoTopBott(keydata,.t.) }
- brow:goBottomBlock := { | | GoTopBott(keydata,.f.) }
- brow:skipBlock := { | move | Skipper(move, keyfld, keydata) }
- endif
-
- /* now fill up the browse object with the columns defined by
- parameters "heads_" and "fields_" )
- */
- for i := 1 to len(fields_)
- col := TBColumnNew(heads_[i], &("{ | | "+fields_[i]+"}") )
- brow:AddColumn(col)
- next
-
- /* here's where we determine if any data is available to meet the
- browse criteria.
- */
- if keydata != NIL
- seek keydata
- nokey := !found()
- else
- go top
- nokey := ( eof() )
- endif
-
- do while .t.
-
- do while ! brow:stabilize() .and. ( key := inkey() ) == 0
- enddo
-
- /* if a box of data is to be kept current below the browse window,
- this is where we do it.
- */
- if viewbox != NIL
- @ b+4, l+1 say eval(viewbox)
- endif
-
- if brow:stable
- /* if no data in the browse matches the "seek keydata" criteria,
- or if this is an empty database, we want to roll right into
- insert mode and let the user start adding data.
- */
- if nokey
- key := K_INS
- else
- key = inkey(0)
- endif
- endif
-
- do case
- /* keeping it simple -- I didn't give you enough data to
- need more movement keys than these guys!
- */
- case key = K_UP
- brow:up()
- case key = K_DOWN
- brow:down()
- case key = K_LEFT
- brow:left()
- case key = K_RIGHT
- brow:right()
- case key = K_HOME
- brow:goTop()
- case key = K_END
- brow:goBottom()
- case key = K_ESC
- exit
- otherwise
- /* If the user hit anything other than the keys in the case
- statement above, we'll let the keyfunc decide whether to
- act upon it. This way, the same browser can be used for
- lots of different situations without having to modify the
- basic function.
- */
- if keyfunc != NIL
- /* The keyfunc must return a logical value. Basically, if the
- keypress resulted in activity that will change the content
- of the browse (edit, insert, delete), we want to refresh
- the screen on the next brow:stabilize(). But we don't
- want to engage in a lot of gratuitous browser refreshing!
- */
- if eval(&( "{ | | " + (keyfunc) + "("+str(key,3)+") }" ) ,key)
- brow:refreshAll()
- endif
- endif
- endcase
- /* if nokey was .t. when the loop started, or if the last key hit
- was the delete key, we want to reevaluate the nokey situation,
- and if it's *still* nokey, let's bail out of this browser.
- */
- if nokey .or. key == K_DEL
- if keydata != NIL
- seek keydata
- nokey := !found()
- else
- go top
- nokey := eof()
- endif
- if nokey
- exit
- endif
- endif
- enddo while .t.
-
- restscreen(0,0,24,79,buffer)
- return nil
- * eof Browser()
- * ==================================================== *
-
- function GoTopBott(keydata,top)
- /* Called by : Function Browser()
- Purpose : Responds to brow:goTopBlock and brow:goBottBlock
- Parameters : keydata <expC> - indexkey() seek criteria
- top <expL> - Is this brow:goTopBlock calling?
- Returns : Nil
- */
- local oldsoftseek := set(_SET_SOFTSEEK,.t.) ,;
- trimmed, increment, seekdata
-
- if top
- seek keydata
- else
- trimmed := trim(keydata)
- increment := chr(asc(subs(trimmed,len(trimmed)-1,1)) +1)
- seekdata := subs(trimmed,1,len(trimmed)-1) + increment
- seek seekdata
- skip -1
- endif
- set(_SET_SOFTSEEK,oldsoftseek)
- return nil
- * eof GoTopBott()
- * ==================================================== *
-
- function Skipper(move,keyfld,keydata)
- /* Called by : Function Browser()
- Purpose : Responds to brow:skipBlock
- Parameters : move <expN> - move how many?
- keyfld <expC> - index key field
- keydata <expC> - seek criteria to match keyfld
- Returns : howmany <expN> - how many records actually moved?
- */
- local howmany := 0
- if move > 0 .and. ;
- recno() != lastrec() +1
-
- do while howmany < move
- skip +1
- if !Moveabout(keyfld,keydata,.t.)
- exit
- endif
- ++howmany
- enddo
- elseif move < 0
- do while howmany > move
- skip -1
- if !Moveabout(keyfld,keydata,.f.)
- exit
- endif
- --howmany
- enddo
- endif
- return howmany
- * eof Skipper()
- * ==================================================== *
-
- function Moveabout(keyfld,keydata,skipahead)
- /* Called by : Function Skipper()
- Purpose : Determines whether the new record position meets
- the criteria determined by keyfld and keydata
- Parameters : keyfld <expC> - first key field in indexkey()
- keydata<expC> - value to match in the keyfld
- skipahead <expL> - are we going up (.t.),
- or down (.f.)?
- */
- local fieldvalue, retval := .t.
- /* fieldvalue is the contents of the keyfld for the record we're
- currently looking at. To be compared to the keydata.
- */
- fieldvalue := eval(fieldblock(keyfld))
- if upper(fieldvalue) != upper(keydata) ;
- .or. bof() .or. eof()
- if Skipahead // we were moving DOWN, have to back up one.
- skip -1
- else
- if !bof() // if we skipped into bof(), don't skip forward!
- skip +1
- endif
- endif
- retval := .f.
- endif
- return retval
- * eof MoveAbout()
- * ==================================================== *
-
- * eop browdemo.prg
- * ------------------------------------------------------------------------ *
-