home *** CD-ROM | disk | FTP | other *** search
- /*
- Program: POPPHONE.PRG
- System: GRUMPFISH LIBRARY
- Author: Greg Lief
- Copyright (c) 1988-90, Greg Lief
- Clipper 5.01 Version
- Compile instructions: clipper popphone /n/w/a
- Procs & Fncts: PHONEMAINT()
- : PRINTPHONE()
- : PH_HEAD()
- : DIALER()
- : MODEMSETUP()
- : PHONEBOOK()
- : FRONTPAGE()
- : PRINTERROR()
-
- Calls: ERR_MSG() (function in ERRMSG.PRG)
- : YES_NO2() (function in YESNO2.PRG)
- : HELPACT() (function in HELPBROW.PRG)
- : PRINTOK() (function in PRINTOK.PRG)
- : SHADOWBOX() (function in SHADOWB.PRG)
- : WAITON() (function in WAITON.PRG)
- : WAITOFF() (function in WAITON.PRG)
-
- Uses: PHONE.DBF
-
- Indexes: PHONE.NTX
- */
-
- //───── begin preprocessor directives
-
- #include "grump.ch"
- #include "inkey.ch"
- #include "error.ch"
- #define PBXFLAG gfphone[1]
- #define HANGUP gfphone[2]
- #define MODEMINIT gfphone[3]
- #define TONEDIAL gfphone[4]
- #define COMMPORT gfphone[5]
- #define AREACODE gfphone[6]
- #define MODEMDELAY gfphone[7]
- #define CONFIGFILE "gfphone.cfg"
- #define TOPROW 5
-
- /*
- if I left the following as a bona fide function, that would mean that
- the local variables SEARCHING and SEARCHSTR would have to be made
- external static, and that disturbed me, so here we are...
- */
- #translate endsearch() => searching := .f. ; ;
- searchstr := '' ; ;
- devpos(TOPROW, (maxcol() + 1) / 2 - 11) ; ;
- devout(replicate(chr(205), 22))
-
- //───── end preprocessor directives
-
- //───── begin global declarations
-
- static gfphone := { .F., 'ATH', 'ATZ', 'T', '1', ' ', 1.0 }
- static redialnum // last number dialed (for redialing)
- static headings_ := { { "First Name", "!XXXXXXXXXXXXXX"} , ;
- { "Last Name", "!XXXXXXXXXXXXXX"} , ;
- { "Phone Number", "###-###-####"} , ;
- { "Ext", "####" } , ;
- { "Company", "!XXXXXXXXXXXXXXXXXXX"} , ;
- { "Address", "!XXXXXXXXXXXXXXXXXXXXXXXX" } , ;
- { "City", "!XXXXXXXXXXXXXX" } , ;
- { "St", "@!" } , ;
- { "Zip" , "@!" } , ;
- { "LD", "Y" } }
-
- //───── end global declarations
-
- function popphone(gfproc, line, var)
- local hotkey := 0, mfile, searchstr := [], xx, key, marker, ;
- maincolor := ColorSet(C_PHONEBOOK_WINDOW1, .T.), searching := .f., ;
- olddelete := set(_SET_DELETED, .T.), browse, column, ;
- wk_area := select(), oldscore := set(_SET_SCOREBOARD, .f.)
-
- memvar phonedir // global PUBLIC that may have been set in calling program
-
- GFSaveEnv(.t., 0) // shut off cursor
- GFSaveGets()
-
- //───── if the file GFPHONE.CFG exists, read in previously saved modem settings
- if file(CONFIGFILE)
- if loadarray(xx, CONFIGFILE)
- gfphone := xx
- endif
- endif
-
- //───── determine whether this was called via hot-key; if so, disable it
- if (gfproc != NIL)
- setkey(hotkey := lastkey(), NIL)
- endif
-
- //───── open phone.dbf... first determine path, then confirm existence of file
- mfile := if(type('phonedir') = 'U', '', phonedir + '\') + 'phone'
- if ! file(mfile + '.dbf')
- waiton('Initializing phone database... please wait')
- dbcreate(mfile + ".dbf", { {"FNAME", "C", 15, 0} , ;
- {"LNAME", "C", 15, 0} , ;
- {"PHONE_NO","C", 12, 0} , ;
- {"EXT", "C", 4, 0} , ;
- {"COMPANY", "C", 20, 0} , ;
- {"ADDRESS", "C", 25, 0} , ;
- {"CITY", "C", 15, 0} , ;
- {"STATE", "C", 2, 0} , ;
- {"ZIP", "C", 10, 0} , ;
- {"LONGDIST","L", 1, 0} } )
- waitoff()
- endif
- if ! file(mfile + '.ntx')
- use (mfile) new exclusive
- index on upper(phone->lname + phone->fname) to (mfile)
- use
- endif
- use (mfile) new index (mfile)
-
- //───── create new browse object
- browse := TBrowseDB( 6, 3, 19, 75)
- browse:headSep := "═"
- browse:colorSpec := maincolor + ',' + "+W/N"
- for xx = 1 to 9
- column := TBColumnNew( headings_[xx, 1], fieldblock( field(xx) ) )
- browse:addColumn(column)
- next
- browse:freeze := 2 // freeze first two columns (fname and lname)
- scroll(22, 00, 24, 79, 0)
- @ 23,08 ssay 'phonebook'
- @ 23,26 ssay 'list'
- @ 23,39 ssay 'dial phone'
- @ 23,58 ssay 'redial'
- @ 23,73 ssay 'setup'
- @ 24,03 ssay "Add"
- @ 24,14 ssay "Edit"
- @ 24,26 ssay "Delete"
- @ 24,40 ssay "Search"
- @ 24,55 ssay "to move"
- @ 24,72 ssay "to exit"
- setcolor('i')
- @ 23,02 ssay 'Alt-B'
- @ 23,20 ssay 'Alt-L'
- @ 23,33 ssay 'Alt-P'
- @ 23,52 ssay 'Alt-R'
- @ 23,67 ssay 'Alt-S'
- @ 24,01 ssay "A"
- @ 24,12 ssay "E"
- @ 24,24 ssay "D"
- @ 24,38 ssay "S"
- @ 24,52 ssay CHR(24)+CHR(25)
- @ 24,68 ssay "Esc"
- shadowbox(0, 31, 2, 45, 6)
- @ 01,32 ssay 'phone numbers'
- setcolor(maincolor)
- shadowbox(05, 02, 20, 76, 1)
- do while .t.
-
- //───── wait for the display to stabilize, which will
- //───── loop once for each row in the browse window.
- //───── allow a keypress to bust out of this loop
- dispbegin()
- do while ! browse:stabilize() .and. (key := inkey()) = 0
- enddo
- dispend()
-
- if browse:stable
- key := ginkey(0, "KEY")
- endif
-
- //───── deal with the keypress
- do case
-
- case key == K_UP
- endsearch()
- browse:up()
-
- case key == K_LEFT
- browse:left()
-
- case key == K_RIGHT
- browse:right()
-
- case key == K_DOWN
- endsearch()
- browse:down()
-
- case key == K_CTRL_PGUP
- endsearch()
- browse:goTop()
-
- case key == K_CTRL_PGDN
- endsearch()
- browse:goBottom()
-
- case key == K_CTRL_LEFT
- browse:panLeft()
-
- case key == K_CTRL_RIGHT
- browse:panRight()
-
- case key == K_PGUP .or. key == K_HOME
- endsearch()
- browse:pageUp()
-
- case key == K_PGDN .or. key == K_END
- endsearch()
- browse:pageDown()
-
- case key == K_ENTER .and. searching // end search mode
- endsearch()
-
- case key == K_ESC
- exit
-
- case searching .and. isalpha(chr(key)) // letter key - search 'em, Dan-O
- marker := recno()
- seek searchstr + upper(chr(key))
- if eof()
- go marker
- else
- searchstr += upper(chr(key))
- @ TOPROW, (maxcol() + 1) / 2 - 10 ssay padc(searchstr, 20)
- browse:refreshAll()
- endif
-
- case key == 65 .or. key == 97 // Add Record
- endsearch()
- PhoneMaint("A")
- browse:refreshAll()
-
- case key == 69 .or. key == 101 // Edit Record
- endsearch()
- PhoneMaint("E")
- browse:refreshCurrent()
-
- case key == 68 .or. key == 100 // Delete
- endsearch()
- if yes_no('This record will be deleted from the file',;
- 'Do you want to do this')
- if rlock()
- delete
- skip -1
- else
- err_msg(NETERR_MSG)
- endif
- endif
- browse:refreshAll()
-
- case key == 83 .OR. key == 115 // search
- searching := .t.
- @ TOPROW, (maxcol() + 1) / 2 - 11 ssay "[" + space(20) + "]"
-
- case key == K_BS .and. searching // truncate the search string
- if len(searchstr) > 0
- searchstr := substr(searchstr, 1, len(searchstr) - 1)
- seek searchstr
- if len(searchstr) > 0
- @ TOPROW, (maxcol() + 1) / 2 - 10 ssay padc(searchstr, 20)
- else
- endsearch()
- endif
- browse:refreshAll()
- endif
-
- case key == K_ALT_L // print list
- endsearch()
- printphone(mfile)
-
- case key == K_ALT_B // phone book
- endsearch()
- phonebook()
-
- case key == K_ALT_P // dial phone #
- endsearch()
- Dialer(phone->phone_no)
-
- case key == K_ALT_R // redial
- endsearch()
- if redialnum == NIL
- Err_Msg('No redial number has been established yet')
- else
- Dialer(redialnum)
- endif
-
- case key == K_ALT_S // modem setup
- ModemSetup()
-
- endcase
- enddo
- use
- select(wk_area)
- //───── restore hot-key
- if hotkey != 0
- setkey( hotkey, {|p, l, v| popphone(p, l, v)} )
- endif
- GFRestEnv()
- GFRestGets()
- set(_SET_SCOREBOARD, oldscore) // go ahead and keep score if you must
- set(_SET_DELETED, olddelete)
- return NIL
-
- * end function PopPhone()
- *--------------------------------------------------------------------*
-
-
- /*
- phone_maint(): add/edit records in phone.dbf
- */
- static function phonemaint(mode)
- local num_flds := fcount(), ahold := {}, marker := recno(), app_ok, xx
- memvar getlist
- gfsaveenv( .t., 2)
- scroll(maxrow() - 2, 00, maxrow(), maxcol(), 0)
- @ 23, 25 ssay 'save edits'
- @ 23, 43 ssay 'exit without saving'
- @ 23, 18 ssay 'Ctrl-W' color 'I'
- @ 23, 39 ssay 'Esc' color 'I'
- ColorSet(C_PHONEBOOK_WINDOW2)
- ShadowBox(6, 18, 17, 61, 2)
- //───── use the phantom record to grab initial values if adding
- if mode == 'A'
- go 0
- endif
-
- //───── dump field contents to an array
- for xx := 1 to num_flds
- aadd(ahold, fieldget(xx))
- @ 6 + xx, 20 ssay headings_[xx, 1]
- @ 6 + xx, 33 get ahold[xx] picture headings_[xx, 2]
- next
- setcursor(2)
- read
- setcursor(0)
- if lastkey() != K_ESC
- if mode == 'A' // adding record
- append blank
- app_ok := ! neterr()
- else
- app_ok := rlock()
- endif
- if app_ok
- //───── now dump array contents to the fields of the blank record
- for xx := 1 to num_flds
- fieldput(xx, ahold[xx])
- next
- else
- err_msg(NETERR_MSG)
- endif
- elseif mode == 'A'
- go marker
- endif
- gfrestenv()
- return NIL
-
- * end static function PhoneMaint()
- *--------------------------------------------------------------------*
-
-
- /*
- printphone(): print phone list
- */
- static function PrintPhone(mindex)
- local page := 1, buffer, morder := 1
- memvar getlist
- ColorSet(C_MESSAGE)
- buffer := shadowbox(19, 10, 22, 69, 2, 'List options')
- @ 20,12 ssay 'Sort list by (1) last name, (2) company, (3) phone no'
- @ 21,22 ssay '(press ESC to exit without printing)'
- @ 20,67 get morder picture '#'
- setcursor(1)
- read
- setcursor(0)
- byebyebox(buffer)
- if lastkey() != K_ESC
- if morder == 2
- index on upper(phone->company) to phonetmp
- elseif morder == 3
- index on phone->phone_no to phonetmp
- endif
- go top
- waiton()
- if printok()
- Ph_Head(@page)
- do while ! eof()
- if prow() > 59
- Ph_Head(@page)
- endif
- @ prow()+2,1 say phone->company
- @ prow(),24 say trim(phone->fname) + ' ' + phone->lname
- @ prow(),58 say phone->phone_no
- @ prow(),74 say phone->ext
- @ prow()+1,1 say phone->address
- @ prow(),31 say trim(phone->city) + ' ' + phone->state + ' ' + ;
- phone->zip
- skip
- enddo
- eject
- endif
- waitoff()
- set device to screen
- set index to (mindex)
- ferase('phonetmp.ntx')
- endif
- return NIL
-
- * end static function PrintPhone()
- *--------------------------------------------------------------------*
-
-
- /*
- ph_head(): heading for phone list report
- */
- static function Ph_Head(page)
- memvar phonehead // global that may have been set in calling program
- @ 0,1 say dtoc(date())
- CENTER(0, if(type('phonehead') = 'U', 'Phone List', phonehead))
- @ 0,71 say 'page ' + ltrim(str(page++))
- @ prow()+2,1 say 'Company Name'
- @ prow(),24 say 'Contact Name'
- @ prow(),58 say 'Phone Number'
- @ prow(),74 say 'Ext.'
- @ prow()+1,1 say 'Address'
- @ prow(),31 say 'City State Zip'
- @ prow()+1,1 say replicate('-',79)
- return NIL
-
- * end static function Ph_Head()
- *--------------------------------------------------------------------*
-
-
- /*
- Dialer(): self-explanatory
- */
- static function Dialer(numtodial)
- local numbr, xx, yy, oldcolor, buffer, mareacode, oldprint, oldcons, ;
- newhandler, oldhandler
- /*
- establish new error handler for this module that will
- trap any printer errors - these may be common because
- of invalid COMM port settings
- */
- newhandler := { | e | printerror(e, oldhandler) }
- oldhandler := errorblock(newhandler)
- redialnum := numtodial // save this number for redialing
- mareacode := substr(numtodial, 1, 3)
- //───── see if this area code matches the local area code
- if mareacode == AREACODE
- numtodial := if(phone->longdist, '1-', '') + substr(numtodial, 5)
- endif
- numtodial := ltrim(trim(numtodial))
-
- //───── clean up the phone number
- if len(numtodial) == 12
- numtodial := '1-' + numtodial
- elseif substr(numtodial, 1, 1) == '-'
- numtodial := substr(numtodial, 2)
- endif
- yy := len(numtodial)
- numbr := strtran(numtodial, '-', '')
-
- //───── add the requisite half second pause if using a pbx system
- numbr := if(PBXFLAG, "9 ~ ", "") + numbr
- oldprint := set(_SET_PRINTFILE, 'com' + COMMPORT)
- oldcolor := ColorSet(C_MESSAGE)
- buffer := shadowbox(19, 12, 22, 67, 2)
- @ 21,14 ssay "Wait for ring, then pick up phone and press spacebar"
- SCRNCENTER(20, "dialing " + numtodial, '+' + setcolor())
- begin sequence // any break would come from PrintError() -- see below
- set print on
- oldcons := set(_SET_CONSOLE, .F.)
- QQOut('+++' + chr(13))
- inkey(MODEMDELAY)
- QQOut(trim(MODEMINIT) + chr(13))
- inkey(MODEMDELAY)
- QQOut('ATD' + TONEDIAL + numbr + chr(13))
- inkey(0)
- QQOut(trim(HANGUP) + chr(13))
- end sequence
- set print off
- ByeByeBox(buffer)
- setcolor(oldcolor)
- set(_SET_CONSOLE, oldcons)
- set(_SET_PRINTFILE, oldprint)
- errorblock(oldhandler) /* reset previous error handler */
- return NIL
-
- * end static function Dialer()
- *--------------------------------------------------------------------*
-
-
- /*
- ModemSetup(): establish/edit modem parameters
- */
- static function ModemSetup
- local oldscrn, oldcolor := ColorSet(C_PHONEBOOK_WINDOW2)
- memvar getlist
- oldscrn := shadowbox(08, 18, 16, 62, 2, 'Communications Parameters')
- HANGUP := padr(HANGUP, 20)
- MODEMINIT := padr(MODEMINIT, 20)
- @ 09, 20 ssay 'PBX (y/n)'
- @ 10, 20 ssay 'Modem set-up string'
- @ 11, 20 ssay 'Modem hang-up string'
- @ 12, 20 ssay '[T]one / [P]ulse'
- @ 13, 20 ssay 'COM port'
- @ 14, 20 ssay 'Local area code'
- @ 15, 20 ssay 'Timing delay'
- @ 09, 41 get PBXFLAG picture "Y"
- @ 10, 41 get MODEMINIT
- @ 11, 41 get HANGUP
- @ 12, 41 get TONEDIAL picture '!' valid TONEDIAL $ 'PT'
- @ 13, 41 get COMMPORT valid COMMPORT $ '12345'
- @ 14, 41 get AREACODE picture '###'
- @ 15, 41 get MODEMDELAY picture '#.#'
- setcursor(1)
- read
- setcursor(0)
- HANGUP := trim(HANGUP)
- MODEMINIT := trim(MODEMINIT)
- ByeByeBox(oldscrn)
- setcolor(oldcolor)
- //───── if user did not escape out, ask for confirmation and write GFPHONE.CFG
- if lastkey() != K_ESC
- if yes_no2("Save these modem settings?", 12, " Save ", " Don't Save ")
- if if(! file(CONFIGFILE), .T., yes_no2("Overwrite configuration file?", ;
- 12, " Overwrite ", " Cancel "))
- gsavearray(gfphone, CONFIGFILE)
- endif
- endif
- endif
- return NIL
-
- * end static function ModemSetup()
- *--------------------------------------------------------------------*
-
-
- /*
- phonebook(): prints pocket-sized phone directory
- */
- static function phonebook(cname)
- local xx, yy, mletter, newletter, mname, mcompany, maddress, mcity, ;
- curr_line := 1, pages := 1, maxrec, mpage, temparray := {}, ;
- curr_elem, mlines, lines, melem, laserjet
-
- default cname to ''
- laserjet := yes_no2("What type of printer are you using?", 12, ;
- " HP Laserjet ", " IBM Graphics ")
- if lastkey() != K_ESC
- waiton("Creating Phone Directory")
- go top
- mletter := chr(32)
- do while ! eof()
- newletter := .f. && flag set true if alpha category changes
- //───── determine person and company names to use for this entry
- if len(trim(phone->lname)) > 0
- mname := ltrim(trim(phone->lname)) + ;
- if(len(trim(phone->lname)) > 0, ', ' + ;
- ltrim(trim(phone->fname)), [])
- mcompany := space(4) + ltrim(trim(phone->company))
- else
- mname := ltrim(trim(phone->company))
- mcompany := []
- endif
- mname += space(32 - len(mname)) + ;
- if(val(phone->phone_no) = 0, "No Number", phone->phone_no)
- maddress := space(5) + ltrim(trim(phone->address))
- mcity := space(5) + ltrim(trim(phone->city)) + " " + ;
- ltrim(trim(phone->state)) + " " + ;
- ltrim(trim(phone->zip))
- lines := 1
- //───── did alphabetical category change?
- if mletter != substr(phone->lname, 1, 1)
- mletter := substr(phone->lname, 1, 1)
- lines++
- newletter := .t.
- endif
- //───── determine how many lines this entry will need, so that we
- //───── can thus determine whether or not they will fit on this page
- lines += if(len(mcompany) > 1, 1, 0) + ;
- if(len(maddress) > 1, 1, 0) + ;
- if(len(mcity) > 3, 1, 0)
- //───── this entry will go on next page - add blank lines to complete page
- if lines + curr_line > 22
- pages++
- for xx = curr_line to 22
- aadd(temparray, '')
- next
- curr_line := 1
- endif
- //───── if we started a new alpha category, must put the heading in now
- if newletter
- curr_line++
- aadd(temparray, space(20) + '- ' + mletter + ' -')
- endif
- curr_line++
- aadd(temparray, mname)
- if len(mcompany) > 1
- curr_line++
- aadd(temparray, mcompany)
- endif
- if len(maddress) > 1
- curr_line++
- aadd(temparray, maddress)
- endif
- if len(mcity) > 3
- curr_line++
- aadd(temparray, mcity)
- endif
- select phone
- skip
- enddo
- //───── add enough blank records in temp file to make last page full length
- if curr_line < 22
- //───── also, it will be a hell of a lot easier if we have an
- //───── even number of pages, so we'll check on that right now
- mlines := (23 - curr_line) + if(pages%2 != 0, 22, 0)
- //───── increment number of pages if we previously had an odd number
- if pages % 2 != 0
- pages++
- endif
- for xx = 1 to mlines
- aadd(temparray, '')
- next
- endif
-
- //───── now begins the arduous task of printing the book
- if printok()
- devout(if(laserjet, chr(27) + "&k2S", chr(15)))
- maxrec := len(temparray) / 2
- mpage := 0
- frontpage(cname)
- curr_elem := 1
- do while curr_elem < maxrec
- mpage++
- for xx = 1 to 27
- @ prow()+1, 0 say "."
- if xx == 1 .or. xx == 27
- for yy = 1 to 46
- @prow(), pcol()+1 say "."
- next
- else
- if xx == 26
- @ prow(), 12 say mpage picture '###'
- @ prow(), 68 say pages + 1 - mpage picture '###'
- else
- if xx > 2 .and. xx < 25
- @ prow(), 2 say temparray[curr_elem]
- endif
- if (xx > 8 .and. xx < 12) .or. (xx > 16 .and. xx < 20)
- @ prow(), 47 say "|"
- endif
- if xx > 2 .and. xx < 25
- if (melem := len(temparray) - ;
- (22 * (int(curr_elem / 22) + 1)) + ;
- (curr_elem % 22) ) != 0
- @ prow(), 49 say temparray[melem]
- endif
- curr_elem++
- endif
- endif
- endif
- @ prow(), 94 say "."
- next
- //───── since we are putting two pages per sheet,
- //───── only eject every other time
- if mpage % 2 != 0
- eject
- endif
- enddo
- devout(if(laserjet, chr(27) + "&k0S", chr(18)))
- eject
- set device to screen
- endif
- waitoff()
- endif
- return NIL
-
- * end static function PhoneBook()
- *--------------------------------------------------------------------*
-
-
- /*
- FrontPage(): print phone page of phone directory
- */
- static function frontpage(cname)
- local mdate, xx, yy
- for xx = 1 to 27
- @ prow()+1, 0 say "."
- do case
- case xx == 1 .or. xx == 27
- for yy = 1 to 46
- @prow(), pcol()+1 say "."
- next
- //───── draw lines for staples in middle of page
- case (xx > 8 .and. xx < 12) .or. (xx > 16 .and. xx < 20)
- @ prow(), 47 say "|"
- endcase
- do case
- case xx == 11
- @ prow(), 61 say "Telephone Directory"
- case xx == 13
- @ prow(), 69 say "for"
- case xx == 15
- @ prow(), 48 + int((48 - len(cname)) / 2) say cname
- case xx == 17
- mdate := cmonth(date()) + ' ' + ltrim(str(day(date()))) + ', ' + ;
- ltrim(str(year(date())))
- @ prow(), 48 + int((48 - len(mdate)) / 2) say mdate
- endcase
- @ prow(), 94 say "."
- next
- return []
-
- * end static function FrontPage()
- *--------------------------------------------------------------------*
-
-
- /*
- PrintError(): custom printer error handler for dialing
- */
- static function printerror(e, oldhandler)
- if e:gencode() == EG_PRINT
- err_msg("Unable to dial... please check your COMM port setting")
- set print off
- break
- return .t.
- endif
- return eval(oldhandler, e)
-
- * end static function PrintError()
- *--------------------------------------------------------------------*
-
- * eof popphone.prg
-