home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Du Jour
/
SoftwareDuJour.iso
/
BUSINESS
/
DBASE
/
PAGES2.ARC
/
PAGES.SRC
< prev
next >
Wrap
Text File
|
1986-11-25
|
10KB
|
338 lines
* pages.src
* pages procedures file
* Andrew Schulman, 12 Humboldt St., Cambridge MA 02140
* 11/16/86
* revised 11/18/86: replaced pack with list while .not. deleted()
* revised 11/19/86: added check for .not. deleted() before clearing screen
* revised 11/21/86: no recursion: pages & caller share variable thisfile
* revised 11/21/86: any len(line) ok: list off trim(substr(line,1,length))
* but added test for field name line
* revised 11/24/86: added parameter SWITCH_OK: let calling program
* determine if OK to go to another file
procedure PAGES
parameters FILENAME, MYTOP, DEPTH, START, SHOWPAGE, SHOWRULE, SWITCH_OK
**************************** error checking *************************
if DEPTH + START > 22 .or. START > 22 .or. SHOWPAGE > START .or. ;
SHOWRULE > START
@3,0 say "PAGES won't fit on screen or SHOWPAGE/SHOWRULE won't show"
@4,0 say "Correct example: do PAGES with 'pages.src', 1, 19, 3, 1, 2"
return
endif
if .not. file(FILENAME)
@START,0 say "PAGES can't find " + FILENAME
return
endif
****************************** definitions ************************
* below are scan codes for PC keys: note that these shouldn't be variables,
* which is what they are here, but shouldn't be dropped in code as "magic
* numbers" either. dBase needs something like #define in C. There IS a
* keyword "define" in DB++ preprocessor I'm writing. Also user-defined
* functions and procedures INSIDE same file as non-procedures. Readers are
* invited to send me their "wish lists." Right now I'm writing the pre-
* processor in dBase so that dBase programmers can modify it. Parsing in
* dBase relies heavily on functions substr() and at() and works fine but is
* slow! Might just write it in C. Anyway...
up = 5
down = 24
pgUp = 18
pgDn = 3
homekey = 1
endkey = 6
****************************** set up ******************************
store space(10) to whichpage, phrase, otherfile
msgline = START + DEPTH + 1
@START,0 clear to msgline-2,79
@START,0 say "Working...."
do BLINKY
set heading off
load curson
load cursoff
call cursoff
* DEMO.PRG checked to make sure these existed; your calling program should too
use line
if field(1) <> "LINE"
@START,0 say "Please use LINE.DBF that comes with PAGES"
do BYE_BYE with ""
return
endif
length = iif(len(line) < 78, len(line), 78)
set safety off
zap
set safety on
append from &FILENAME sdf
go bottom
del_num = 0
do while len(trim(line)) < 1 .and. recno() > 1
delete
del_num = del_num + 1
skip -1
enddo
* don't pack
* wish I could use APPEND FROM &FILENAME FOR LEN(TRIM(LINE)) > 0 SDF,
* because of interesting way FOR condition works during APPEND,
* but that would kill blank lines in middle of file; not just at tail-end
tot = reccount() - del_num
if tot < 1
do WAIT_MSG with "File is empty"
do BYE_BYE with ""
return
endif
page = 1
size = tot + 1 - MYTOP
p = size / DEPTH
q = int(p)
pages = iif(p - q = 0, q, q + 1)
end = iif(size < DEPTH, 1, size - DEPTH + START)
didsearch = .F.
foundit = 0
overlap = 0 && this can be changed to anything < DEPTH
if SHOWRULE > 0
@SHOWRULE,0 to SHOWRULE,78 double
endif
@msgline-1,0 to msgline-1,78 double
prompt = iif(pages = 1, "", "Prev, Next, Begin, End, Search, Repeat, #, ") + ;
iif(SWITCH_OK, "File, ", "") + "or Quit? "
FILENAME = ""
thisfile = ""
* FILENAME is pages2's copy of PUBLIC thisfile, declared in calling program
* demo2.prg and passed to pages2 as parameter. Looks like we have to
* change BOTH because passed as parameter???
* extract from LIST MEMORY:
* THISFILE pub (hidden) C ""
* FILENAME priv @ THISFILE
* THISFILE priv C ""
***************************** main loop ***********************************
goto MYTOP
do while .not. eof()
thispage = "Page " + str(page,2) + " of " + str(pages,2)
do SHOW_REV with thispage, SHOWPAGE, 66
if recno() <> MYTOP
skip overlap + 1
endif
if .not. deleted()
@START,0 clear to msgline-2,79
@START-1,79 && see Liskin, Adv dBase III, p.286, for why
list off trim(substr(line,1,length)) next DEPTH while .not. deleted()
endif
** all the work is done here
** nonprocedural list is 20% faster than procedural do-while loop
** and there is another 20% improvement when you trim line
** if you wanted to show line numbers, you could:
** list trim(substr(line,1,70)) next DEPTH while .not. deleted()
if foundit > 0
saverec = min(recno(), tot - 1)
goto foundit
set color to N/W+
@START,1 say trim(line) && why trouble if first few lines?
set color to
goto saverec
foundit = 0
endif
do MSG with prompt
ink = 0
do while ink = 0
ink = inkey()
enddo
which = upper(chr(ink))
num = val(which)
beforerec = recno()
if pages = 1
do case
case which = 'F' .and. SWITCH_OK
do NEW_FILE
if len(trim(thisfile)) > 0
return
endif
case which = 'Q'
do BYE_BYE with ""
return
otherwise
do WAIT_MSG with "Only one page"
do GO_HOME
endcase
else
do case
case which = 'B' .or. ink = homekey
do GO_HOME
case which = 'E' .or. ink = endkey
do GO_END
case which = 'P' .or. ink = up .or. ink = pgUp
do GO_PREV
case which = 'N' .or. ink = down .or. ink = pgDn
do GO_NEXT
case num > 0 && it's a page number
do GO_PAGE with num
case which = '#' && if can't get to page with 1 digit
do ACCEPTVAR with "Go to page #", whichpage
mypage = val(whichpage)
do GO_PAGE with mypage
case which $ "SR"
do SEARCH
case which = 'F' .and. SWITCH_OK
do NEW_FILE
if len(trim(thisfile)) > 0
return
endif
case which = 'Q'
do BYE_BYE with ""
return
otherwise
do GO_NEXT
endcase
endif
enddo
return
*************************** procedures ******************************
procedure ACCEPTVAR
parameters msg, var
@msgline,0
@msgline,len(msg)
do BLINKY
@msgline-1,79
accept msg to temp
var = temp
* var has to be declared PUBLIC
return
procedure BLINKY && our own blinking cursor: don't call curson
set color to w*
?? '_'
set color to
return
procedure BYE_BYE
parameter sendmessag
close databases
call curson
FILENAME = sendmessag && send message back to caller
thisfile = sendmessag
@msgline,0
return
procedure GO_END
goto end
page = pages
return
procedure GO_HOME
goto MYTOP
page = 1
return
procedure GO_NEXT
goto iif(eof(), recno() - DEPTH + 1, recno())
page = iif(page < pages - 1, page + 1, pages)
return
procedure GO_PAGE
parameter pg
pg = iif(pg <= 1, 1, int(pg))
goto iif(pg >= pages, end, ((pg - 1) * DEPTH) + MYTOP - iif(pg = 1, 0, 1))
page = iif(pg >= pages, pages, pg)
return
procedure GO_PREV
prev = iif(recno() > (DEPTH*2+1), recno()-(DEPTH*2), MYTOP)
goto prev
page = iif(page > 1, page - 1, 1)
return
procedure MSG
parameter msg
@msgline,0 clear
@msgline,0 say msg
do BLINKY
return
procedure NEW_FILE
saverec = iif(recno() - DEPTH > 1, recno() - DEPTH, 1)
do ACCEPTVAR with "New filename to switch to? ", otherfile
if file(otherfile)
do MSG with "Switching file..."
do BYE_BYE with otherfile
return
* depends on calling program PUBLIC variable thisfile
* this way, pages sends message to calling program rather
* than recursively calling itself as in previous version of PAGES
else
do WAIT_MSG with "No such file"
goto saverec
endif
return
procedure SEARCH
if which = 'S'
do ACCEPTVAR with "Search for ", phrase
endif
if which = 'S' .or. (which = 'R' .and. didsearch)
do MSG with "Searching for " + phrase + "..."
endif
saverec = iif(recno() - DEPTH > 1, recno() - DEPTH, 1)
if .not. eof()
goto saverec + 1
endif
if which = 'S'
locate for at(phrase, line) > 0
didsearch = .T.
else if which = 'R'
if didsearch
continue
else
do WAIT_MSG with "Must do SEARCH before REPEAT"
endif
endif
**** replaced do-while loop with locate/continue
if .not. found()
if didsearch
do WAIT_MSG with "Not found"
endif
goto saverec
else
foundit = recno()
skip -1 && back up so they can see it
page = int(((recno() - MYTOP) / DEPTH) + 1)
endif
return
procedure SHOW_REV
parameters msg, row, col
@row,col
@row,col get msg
clear gets
return
procedure WAIT_MSG
parameter msg
@msgline,len(msg)+32
do BLINKY
@msgline-1,79
wait msg + " ... Press any key to continue "
@msgline,0
return
** missing: need procedure INVAL_SCR to see if screen really needs to
** be redrawn. Right now, redraws each time through main loop, even if
** nothing has changed.
** if you're examining source code from within PAGES, please remember to
** return to file called PAGES.DAT