home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a067 / 1.img / GRUMP501.EXE / POPPHONE.PRG < prev    next >
Encoding:
Text File  |  1991-06-07  |  22.0 KB  |  734 lines

  1. /*
  2.     Program: POPPHONE.PRG
  3.     System: GRUMPFISH LIBRARY
  4.     Author: Greg Lief
  5.     Copyright (c) 1988-90, Greg Lief
  6.     Clipper 5.01 Version
  7.     Compile instructions: clipper popphone /n/w/a
  8.     Procs & Fncts: PHONEMAINT()
  9.                  : PRINTPHONE()
  10.                  : PH_HEAD()
  11.                  : DIALER()
  12.                  : MODEMSETUP()
  13.                  : PHONEBOOK()
  14.                  : FRONTPAGE()
  15.                  : PRINTERROR()
  16.  
  17.             Calls: ERR_MSG()     (function in ERRMSG.PRG)
  18.                  : YES_NO2()     (function in YESNO2.PRG)
  19.                  : HELPACT()     (function in HELPBROW.PRG)
  20.                  : PRINTOK()     (function in PRINTOK.PRG)
  21.                  : SHADOWBOX()   (function in SHADOWB.PRG)
  22.                  : WAITON()      (function in WAITON.PRG)
  23.                  : WAITOFF()     (function in WAITON.PRG)
  24.  
  25.              Uses: PHONE.DBF
  26.  
  27.           Indexes: PHONE.NTX
  28. */
  29.  
  30. //───── begin preprocessor directives
  31.  
  32. #include "grump.ch"
  33. #include "inkey.ch"
  34. #include "error.ch"
  35. #define PBXFLAG      gfphone[1]
  36. #define HANGUP       gfphone[2]
  37. #define MODEMINIT    gfphone[3]
  38. #define TONEDIAL     gfphone[4]
  39. #define COMMPORT     gfphone[5]
  40. #define AREACODE     gfphone[6]
  41. #define MODEMDELAY   gfphone[7]
  42. #define CONFIGFILE   "gfphone.cfg"
  43. #define TOPROW       5
  44.  
  45. /*
  46.    if I left the following as a bona fide function, that would mean that
  47.    the local variables SEARCHING and SEARCHSTR would have to be made
  48.    external static, and that disturbed me, so here we are...
  49. */
  50. #translate endsearch() => searching := .f. ; ;
  51.                           searchstr := ''  ; ;
  52.                           devpos(TOPROW, (maxcol() + 1) / 2 - 11) ; ;
  53.                           devout(replicate(chr(205), 22))
  54.  
  55. //───── end preprocessor directives
  56.  
  57. //───── begin global declarations
  58.  
  59. static gfphone := { .F., 'ATH', 'ATZ', 'T', '1', '   ', 1.0 }
  60. static redialnum                         // last number dialed (for redialing)
  61. static headings_ := { { "First Name", "!XXXXXXXXXXXXXX"} , ;
  62.                       { "Last Name",  "!XXXXXXXXXXXXXX"} , ;
  63.                       { "Phone Number", "###-###-####"}  , ;
  64.                       { "Ext", "####" }                  , ;
  65.                       { "Company", "!XXXXXXXXXXXXXXXXXXX"} , ;
  66.                       { "Address", "!XXXXXXXXXXXXXXXXXXXXXXXX" } , ;
  67.                       { "City", "!XXXXXXXXXXXXXX" }      , ;
  68.                       { "St",  "@!" }                    , ;
  69.                       { "Zip" , "@!" }                   , ;
  70.                       { "LD", "Y" } }
  71.  
  72. //───── end global declarations
  73.  
  74. function popphone(gfproc, line, var)
  75. local hotkey := 0, mfile, searchstr := [], xx, key, marker, ;
  76.       maincolor := ColorSet(C_PHONEBOOK_WINDOW1, .T.), searching := .f., ;
  77.       olddelete := set(_SET_DELETED, .T.), browse, column, ;
  78.       wk_area := select(), oldscore := set(_SET_SCOREBOARD, .f.)
  79.  
  80. memvar phonedir      // global PUBLIC that may have been set in calling program
  81.  
  82. GFSaveEnv(.t., 0)    // shut off cursor
  83. GFSaveGets()
  84.  
  85. //───── if the file GFPHONE.CFG exists, read in previously saved modem settings
  86. if file(CONFIGFILE)
  87.    if loadarray(xx, CONFIGFILE)
  88.       gfphone := xx
  89.    endif
  90. endif
  91.  
  92. //───── determine whether this was called via hot-key; if so, disable it
  93. if (gfproc != NIL)
  94.    setkey(hotkey := lastkey(), NIL)
  95. endif
  96.  
  97. //───── open phone.dbf... first determine path, then confirm existence of file
  98. mfile := if(type('phonedir') = 'U', '', phonedir + '\') + 'phone'
  99. if ! file(mfile + '.dbf')
  100.    waiton('Initializing phone database... please wait')
  101.    dbcreate(mfile + ".dbf", { {"FNAME",   "C", 15, 0} , ;
  102.                               {"LNAME",   "C", 15, 0} , ;
  103.                               {"PHONE_NO","C", 12, 0} , ;
  104.                               {"EXT",     "C",  4, 0} , ;
  105.                               {"COMPANY", "C", 20, 0} , ;
  106.                               {"ADDRESS", "C", 25, 0} , ;
  107.                               {"CITY",    "C", 15, 0} , ;
  108.                               {"STATE",   "C",  2, 0} , ;
  109.                               {"ZIP",     "C", 10, 0} , ;
  110.                               {"LONGDIST","L",  1, 0} } )
  111.    waitoff()
  112. endif
  113. if ! file(mfile + '.ntx')
  114.    use (mfile) new exclusive
  115.    index on upper(phone->lname + phone->fname) to (mfile)
  116.    use
  117. endif
  118. use (mfile) new index (mfile)
  119.  
  120. //───── create new browse object
  121. browse := TBrowseDB( 6, 3, 19, 75)
  122. browse:headSep := "═"
  123. browse:colorSpec := maincolor + ',' + "+W/N"
  124. for xx = 1 to 9
  125.    column := TBColumnNew( headings_[xx, 1], fieldblock( field(xx) ) )
  126.    browse:addColumn(column)
  127. next
  128. browse:freeze := 2   // freeze first two columns (fname and lname)
  129. scroll(22, 00, 24, 79, 0)
  130. @ 23,08 ssay 'phonebook'
  131. @ 23,26 ssay 'list'
  132. @ 23,39 ssay 'dial phone'
  133. @ 23,58 ssay 'redial'
  134. @ 23,73 ssay 'setup'
  135. @ 24,03 ssay "Add"
  136. @ 24,14 ssay "Edit"
  137. @ 24,26 ssay "Delete"
  138. @ 24,40 ssay "Search"
  139. @ 24,55 ssay "to move"
  140. @ 24,72 ssay "to exit"
  141. setcolor('i')
  142. @ 23,02 ssay 'Alt-B'
  143. @ 23,20 ssay 'Alt-L'
  144. @ 23,33 ssay 'Alt-P'
  145. @ 23,52 ssay 'Alt-R'
  146. @ 23,67 ssay 'Alt-S'
  147. @ 24,01 ssay "A"
  148. @ 24,12 ssay "E"
  149. @ 24,24 ssay "D"
  150. @ 24,38 ssay "S"
  151. @ 24,52 ssay CHR(24)+CHR(25)
  152. @ 24,68 ssay "Esc"
  153. shadowbox(0, 31, 2, 45, 6)
  154. @ 01,32 ssay 'phone numbers'
  155. setcolor(maincolor)
  156. shadowbox(05, 02, 20, 76, 1)
  157. do while .t.
  158.  
  159.    //───── wait for the display to stabilize, which will
  160.    //───── loop once for each row in the browse window.
  161.    //───── allow a keypress to bust out of this loop
  162.    dispbegin()
  163.    do while ! browse:stabilize() .and. (key := inkey()) = 0
  164.    enddo
  165.    dispend()
  166.  
  167.    if browse:stable
  168.       key := ginkey(0, "KEY")
  169.    endif
  170.  
  171.    //───── deal with the keypress
  172.    do case
  173.  
  174.       case key == K_UP
  175.          endsearch()
  176.          browse:up()
  177.  
  178.       case key == K_LEFT
  179.          browse:left()
  180.  
  181.       case key == K_RIGHT
  182.          browse:right()
  183.  
  184.       case key == K_DOWN
  185.          endsearch()
  186.          browse:down()
  187.  
  188.       case key == K_CTRL_PGUP
  189.          endsearch()
  190.          browse:goTop()
  191.  
  192.       case key == K_CTRL_PGDN
  193.          endsearch()
  194.          browse:goBottom()
  195.  
  196.       case key == K_CTRL_LEFT
  197.          browse:panLeft()
  198.  
  199.       case key == K_CTRL_RIGHT
  200.          browse:panRight()
  201.  
  202.       case key == K_PGUP .or. key == K_HOME
  203.          endsearch()
  204.          browse:pageUp()
  205.  
  206.       case key == K_PGDN .or. key == K_END
  207.          endsearch()
  208.          browse:pageDown()
  209.  
  210.       case key == K_ENTER .and. searching       // end search mode
  211.          endsearch()
  212.  
  213.       case key == K_ESC
  214.          exit
  215.  
  216.       case searching .and. isalpha(chr(key))   // letter key - search 'em, Dan-O
  217.          marker := recno()
  218.          seek searchstr + upper(chr(key))
  219.          if eof()
  220.             go marker
  221.          else
  222.             searchstr += upper(chr(key))
  223.             @ TOPROW, (maxcol() + 1) / 2 - 10 ssay padc(searchstr, 20)
  224.             browse:refreshAll()
  225.          endif
  226.  
  227.       case key == 65 .or. key == 97             // Add Record
  228.          endsearch()
  229.          PhoneMaint("A")
  230.          browse:refreshAll()
  231.  
  232.       case key == 69 .or. key == 101            // Edit Record
  233.          endsearch()
  234.          PhoneMaint("E")
  235.          browse:refreshCurrent()
  236.  
  237.       case key == 68 .or. key == 100            // Delete
  238.          endsearch()
  239.          if yes_no('This record will be deleted from the file',;
  240.                    'Do you want to do this')
  241.             if rlock()
  242.                delete
  243.                skip -1
  244.             else
  245.                err_msg(NETERR_MSG)
  246.             endif
  247.          endif
  248.          browse:refreshAll()
  249.  
  250.       case key == 83 .OR. key == 115        // search
  251.          searching := .t.
  252.          @ TOPROW, (maxcol() + 1) / 2 - 11 ssay "[" + space(20) + "]"
  253.  
  254.       case key == K_BS .and. searching     // truncate the search string
  255.          if len(searchstr) > 0
  256.             searchstr := substr(searchstr, 1, len(searchstr) - 1)
  257.             seek searchstr
  258.             if len(searchstr) > 0
  259.                @ TOPROW, (maxcol() + 1) / 2 - 10 ssay padc(searchstr, 20)
  260.             else
  261.                endsearch()
  262.             endif
  263.             browse:refreshAll()
  264.          endif
  265.  
  266.       case key == K_ALT_L               // print list
  267.          endsearch()
  268.          printphone(mfile)
  269.  
  270.       case key == K_ALT_B               // phone book
  271.          endsearch()
  272.          phonebook()
  273.  
  274.       case key == K_ALT_P               // dial phone #
  275.          endsearch()
  276.          Dialer(phone->phone_no)
  277.  
  278.       case key == K_ALT_R               // redial
  279.          endsearch()
  280.          if redialnum == NIL
  281.             Err_Msg('No redial number has been established yet')
  282.          else
  283.             Dialer(redialnum)
  284.          endif
  285.  
  286.       case key == K_ALT_S               // modem setup
  287.          ModemSetup()
  288.  
  289.    endcase
  290. enddo
  291. use
  292. select(wk_area)
  293. //───── restore hot-key
  294. if hotkey != 0
  295.    setkey( hotkey, {|p, l, v| popphone(p, l, v)} )
  296. endif
  297. GFRestEnv()
  298. GFRestGets()
  299. set(_SET_SCOREBOARD, oldscore)  // go ahead and keep score if you must
  300. set(_SET_DELETED, olddelete)
  301. return NIL
  302.  
  303. * end function PopPhone()
  304. *--------------------------------------------------------------------*
  305.  
  306.  
  307. /*
  308.   phone_maint(): add/edit records in phone.dbf
  309. */
  310. static function phonemaint(mode)
  311. local num_flds := fcount(), ahold := {}, marker := recno(), app_ok, xx
  312. memvar getlist
  313. gfsaveenv( .t., 2)
  314. scroll(maxrow() - 2, 00, maxrow(), maxcol(), 0)
  315. @ 23, 25 ssay 'save edits'
  316. @ 23, 43 ssay 'exit without saving'
  317. @ 23, 18 ssay 'Ctrl-W' color 'I'
  318. @ 23, 39 ssay 'Esc' color 'I'
  319. ColorSet(C_PHONEBOOK_WINDOW2)
  320. ShadowBox(6, 18, 17, 61, 2)
  321. //───── use the phantom record to grab initial values if adding
  322. if mode == 'A'
  323.    go 0
  324. endif
  325.  
  326. //───── dump field contents to an array
  327. for xx := 1 to num_flds
  328.    aadd(ahold, fieldget(xx))
  329.    @ 6 + xx, 20 ssay headings_[xx, 1]
  330.    @ 6 + xx, 33 get ahold[xx] picture headings_[xx, 2]
  331. next
  332. setcursor(2)
  333. read
  334. setcursor(0)
  335. if lastkey() != K_ESC
  336.    if mode == 'A'      // adding record
  337.       append blank
  338.       app_ok := ! neterr()
  339.    else
  340.       app_ok := rlock()
  341.    endif
  342.    if app_ok
  343.       //───── now dump array contents to the fields of the blank record
  344.       for xx := 1 to num_flds
  345.          fieldput(xx, ahold[xx])
  346.       next
  347.    else
  348.       err_msg(NETERR_MSG)
  349.    endif
  350. elseif mode == 'A'
  351.    go marker
  352. endif
  353. gfrestenv()
  354. return NIL
  355.  
  356. * end static function PhoneMaint()
  357. *--------------------------------------------------------------------*
  358.  
  359.  
  360. /*
  361.    printphone(): print phone list
  362. */
  363. static function PrintPhone(mindex)
  364. local page := 1, buffer, morder := 1
  365. memvar getlist
  366. ColorSet(C_MESSAGE)
  367. buffer := shadowbox(19, 10, 22, 69, 2, 'List options')
  368. @ 20,12 ssay 'Sort list by (1) last name, (2) company, (3) phone no'
  369. @ 21,22 ssay '(press ESC to exit without printing)'
  370. @ 20,67 get morder picture '#'
  371. setcursor(1)
  372. read
  373. setcursor(0)
  374. byebyebox(buffer)
  375. if lastkey() != K_ESC
  376.    if morder == 2
  377.       index on upper(phone->company) to phonetmp
  378.    elseif morder == 3
  379.       index on phone->phone_no to phonetmp
  380.    endif
  381.    go top
  382.    waiton()
  383.    if printok()
  384.       Ph_Head(@page)
  385.       do while ! eof()
  386.          if prow() > 59
  387.             Ph_Head(@page)
  388.          endif
  389.          @ prow()+2,1 say phone->company
  390.          @ prow(),24  say trim(phone->fname) + ' ' + phone->lname
  391.          @ prow(),58  say phone->phone_no
  392.          @ prow(),74  say phone->ext
  393.          @ prow()+1,1 say phone->address
  394.          @ prow(),31  say trim(phone->city) + ' ' + phone->state + '  ' + ;
  395.                           phone->zip
  396.          skip
  397.       enddo
  398.       eject
  399.    endif
  400.    waitoff()
  401.    set device to screen
  402.    set index to (mindex)
  403.    ferase('phonetmp.ntx')
  404. endif
  405. return NIL
  406.  
  407. * end static function PrintPhone()
  408. *--------------------------------------------------------------------*
  409.  
  410.  
  411. /*
  412.   ph_head(): heading for phone list report
  413. */
  414. static function Ph_Head(page)
  415. memvar phonehead   // global that may have been set in calling program
  416. @ 0,1 say dtoc(date())
  417. CENTER(0, if(type('phonehead') = 'U', 'Phone List', phonehead))
  418. @ 0,71 say 'page ' + ltrim(str(page++))
  419. @ prow()+2,1 say 'Company Name'
  420. @ prow(),24  say 'Contact Name'
  421. @ prow(),58  say 'Phone Number'
  422. @ prow(),74  say 'Ext.'
  423. @ prow()+1,1 say 'Address'
  424. @ prow(),31  say 'City  State  Zip'
  425. @ prow()+1,1 say replicate('-',79)
  426. return NIL
  427.  
  428. * end static function Ph_Head()
  429. *--------------------------------------------------------------------*
  430.  
  431.  
  432. /*
  433.   Dialer(): self-explanatory
  434. */
  435. static function Dialer(numtodial)
  436. local numbr, xx, yy, oldcolor, buffer, mareacode, oldprint, oldcons, ;
  437.       newhandler, oldhandler
  438. /*
  439.    establish new error handler for this module that will
  440.    trap any printer errors - these may be common because
  441.    of invalid COMM port settings
  442. */
  443. newhandler := { | e | printerror(e, oldhandler) }
  444. oldhandler := errorblock(newhandler)
  445. redialnum := numtodial   // save this number for redialing
  446. mareacode := substr(numtodial, 1, 3)
  447. //───── see if this area code matches the local area code
  448. if mareacode == AREACODE
  449.    numtodial := if(phone->longdist, '1-', '') + substr(numtodial, 5)
  450. endif
  451. numtodial := ltrim(trim(numtodial))
  452.  
  453. //───── clean up the phone number
  454. if len(numtodial) == 12
  455.    numtodial := '1-' + numtodial
  456. elseif substr(numtodial, 1, 1) == '-'
  457.    numtodial := substr(numtodial, 2)
  458. endif
  459. yy := len(numtodial)
  460. numbr := strtran(numtodial, '-', '')
  461.  
  462. //───── add the requisite half second pause if using a pbx system
  463. numbr := if(PBXFLAG, "9 ~ ", "") + numbr
  464. oldprint := set(_SET_PRINTFILE, 'com' + COMMPORT)
  465. oldcolor := ColorSet(C_MESSAGE)
  466. buffer := shadowbox(19, 12, 22, 67, 2)
  467. @ 21,14 ssay "Wait for ring, then pick up phone and press spacebar"
  468. SCRNCENTER(20, "dialing " + numtodial, '+' + setcolor())
  469. begin sequence  // any break would come from PrintError() -- see below
  470.    set print on
  471.    oldcons := set(_SET_CONSOLE, .F.)
  472.    QQOut('+++' + chr(13))
  473.    inkey(MODEMDELAY)
  474.    QQOut(trim(MODEMINIT) + chr(13))
  475.    inkey(MODEMDELAY)
  476.    QQOut('ATD' + TONEDIAL + numbr + chr(13))
  477.    inkey(0)
  478.    QQOut(trim(HANGUP) + chr(13))
  479. end sequence
  480. set print off
  481. ByeByeBox(buffer)
  482. setcolor(oldcolor)
  483. set(_SET_CONSOLE, oldcons)
  484. set(_SET_PRINTFILE, oldprint)
  485. errorblock(oldhandler)            /* reset previous error handler */
  486. return NIL
  487.  
  488. * end static function Dialer()
  489. *--------------------------------------------------------------------*
  490.  
  491.  
  492. /*
  493.    ModemSetup(): establish/edit modem parameters
  494. */
  495. static function ModemSetup
  496. local oldscrn, oldcolor := ColorSet(C_PHONEBOOK_WINDOW2)
  497. memvar getlist
  498. oldscrn := shadowbox(08, 18, 16, 62, 2, 'Communications Parameters')
  499. HANGUP    := padr(HANGUP, 20)
  500. MODEMINIT := padr(MODEMINIT, 20)
  501. @ 09, 20 ssay 'PBX (y/n)'
  502. @ 10, 20 ssay 'Modem set-up string'
  503. @ 11, 20 ssay 'Modem hang-up string'
  504. @ 12, 20 ssay '[T]one / [P]ulse'
  505. @ 13, 20 ssay 'COM port'
  506. @ 14, 20 ssay 'Local area code'
  507. @ 15, 20 ssay 'Timing delay'
  508. @ 09, 41 get PBXFLAG picture "Y"
  509. @ 10, 41 get MODEMINIT
  510. @ 11, 41 get HANGUP
  511. @ 12, 41 get TONEDIAL picture '!' valid TONEDIAL $ 'PT'
  512. @ 13, 41 get COMMPORT valid COMMPORT $ '12345'
  513. @ 14, 41 get AREACODE picture '###'
  514. @ 15, 41 get MODEMDELAY picture '#.#'
  515. setcursor(1)
  516. read
  517. setcursor(0)
  518. HANGUP    := trim(HANGUP)
  519. MODEMINIT := trim(MODEMINIT)
  520. ByeByeBox(oldscrn)
  521. setcolor(oldcolor)
  522. //───── if user did not escape out, ask for confirmation and write GFPHONE.CFG
  523. if lastkey() != K_ESC
  524.    if yes_no2("Save these modem settings?", 12, " Save ", " Don't Save ")
  525.       if if(! file(CONFIGFILE), .T., yes_no2("Overwrite configuration file?", ;
  526.                                      12, " Overwrite ", " Cancel "))
  527.          gsavearray(gfphone, CONFIGFILE)
  528.       endif
  529.    endif
  530. endif
  531. return NIL
  532.  
  533. * end static function ModemSetup()
  534. *--------------------------------------------------------------------*
  535.  
  536.  
  537. /*
  538.    phonebook(): prints pocket-sized phone directory
  539. */
  540. static function phonebook(cname)
  541. local xx, yy, mletter, newletter, mname, mcompany, maddress, mcity, ;
  542.       curr_line := 1, pages := 1, maxrec, mpage, temparray := {}, ;
  543.       curr_elem, mlines, lines, melem, laserjet
  544.  
  545. default cname to ''
  546. laserjet := yes_no2("What type of printer are you using?", 12, ;
  547.                     " HP Laserjet ", " IBM Graphics ")
  548. if lastkey() != K_ESC
  549.    waiton("Creating Phone Directory")
  550.    go top
  551.    mletter := chr(32)
  552.    do while ! eof()
  553.       newletter := .f.   && flag set true if alpha category changes
  554.       //───── determine person and company names to use for this entry
  555.       if len(trim(phone->lname)) > 0
  556.          mname := ltrim(trim(phone->lname)) + ;
  557.                   if(len(trim(phone->lname)) > 0, ', ' + ;
  558.                   ltrim(trim(phone->fname)), [])
  559.          mcompany := space(4) + ltrim(trim(phone->company))
  560.       else
  561.          mname := ltrim(trim(phone->company))
  562.          mcompany := []
  563.       endif
  564.       mname += space(32 - len(mname)) + ;
  565.               if(val(phone->phone_no) = 0, "No Number", phone->phone_no)
  566.       maddress := space(5) + ltrim(trim(phone->address))
  567.       mcity := space(5) + ltrim(trim(phone->city)) + " " + ;
  568.                ltrim(trim(phone->state)) + " " + ;
  569.                ltrim(trim(phone->zip))
  570.       lines := 1
  571.       //───── did alphabetical category change?
  572.       if mletter != substr(phone->lname, 1, 1)
  573.          mletter := substr(phone->lname, 1, 1)
  574.          lines++
  575.          newletter := .t.
  576.       endif
  577.       //───── determine how many lines this entry will need, so that we
  578.       //───── can thus determine whether or not they will fit on this page
  579.       lines += if(len(mcompany) > 1, 1, 0) + ;
  580.                if(len(maddress) > 1, 1, 0) + ;
  581.                if(len(mcity) > 3, 1, 0)
  582.       //───── this entry will go on next page - add blank lines to complete page
  583.       if lines + curr_line > 22
  584.          pages++
  585.          for xx = curr_line to 22
  586.             aadd(temparray, '')
  587.          next
  588.          curr_line := 1
  589.       endif
  590.       //───── if we started a new alpha category, must put the heading in now
  591.       if newletter
  592.          curr_line++
  593.          aadd(temparray, space(20) + '- ' + mletter + ' -')
  594.       endif
  595.       curr_line++
  596.       aadd(temparray, mname)
  597.       if len(mcompany) > 1
  598.          curr_line++
  599.          aadd(temparray, mcompany)
  600.       endif
  601.       if len(maddress) > 1
  602.          curr_line++
  603.          aadd(temparray, maddress)
  604.       endif
  605.       if len(mcity) > 3
  606.          curr_line++
  607.          aadd(temparray, mcity)
  608.       endif
  609.       select phone
  610.       skip
  611.    enddo
  612.    //───── add enough blank records in temp file to make last page full length
  613.    if curr_line < 22
  614.       //───── also, it will be a hell of a lot easier if we have an
  615.       //───── even number of pages, so we'll check on that right now
  616.       mlines := (23 - curr_line) + if(pages%2 != 0, 22, 0)
  617.       //───── increment number of pages if we previously had an odd number
  618.       if pages % 2 != 0
  619.          pages++
  620.       endif
  621.       for xx = 1 to mlines
  622.          aadd(temparray, '')
  623.       next
  624.    endif
  625.  
  626.    //───── now begins the arduous task of printing the book
  627.    if printok()
  628.       devout(if(laserjet, chr(27) + "&k2S", chr(15)))
  629.       maxrec := len(temparray) / 2
  630.       mpage := 0
  631.       frontpage(cname)
  632.       curr_elem := 1
  633.       do while curr_elem < maxrec
  634.          mpage++
  635.          for xx = 1 to 27
  636.             @ prow()+1, 0 say "."
  637.             if xx == 1 .or. xx == 27
  638.                for yy = 1 to 46
  639.                   @prow(), pcol()+1 say "."
  640.                next
  641.             else
  642.                if xx == 26
  643.                   @ prow(), 12 say mpage picture '###'
  644.                   @ prow(), 68 say pages + 1 - mpage picture '###'
  645.                else
  646.                   if xx > 2 .and. xx < 25
  647.                      @ prow(), 2 say temparray[curr_elem]
  648.                   endif
  649.                   if (xx > 8 .and. xx < 12) .or. (xx > 16 .and. xx < 20)
  650.                      @ prow(), 47 say "|"
  651.                   endif
  652.                   if xx > 2 .and. xx < 25
  653.                      if (melem := len(temparray) - ;
  654.                                   (22 * (int(curr_elem / 22) + 1)) + ;
  655.                                   (curr_elem % 22) ) != 0
  656.                         @ prow(), 49 say temparray[melem]
  657.                      endif
  658.                      curr_elem++
  659.                   endif
  660.                endif
  661.             endif
  662.             @ prow(), 94 say "."
  663.          next
  664.          //───── since we are putting two pages per sheet,
  665.          //───── only eject every other time
  666.          if mpage % 2 != 0
  667.             eject
  668.          endif
  669.       enddo
  670.       devout(if(laserjet, chr(27) + "&k0S", chr(18)))
  671.       eject
  672.       set device to screen
  673.    endif
  674.    waitoff()
  675. endif
  676. return NIL
  677.  
  678. * end static function PhoneBook()
  679. *--------------------------------------------------------------------*
  680.  
  681.  
  682. /*
  683.    FrontPage(): print phone page of phone directory
  684. */
  685. static function frontpage(cname)
  686. local mdate, xx, yy
  687. for xx = 1 to 27
  688.    @ prow()+1, 0 say "."
  689.    do case
  690.       case xx == 1 .or. xx == 27
  691.          for yy = 1 to 46
  692.             @prow(), pcol()+1 say "."
  693.          next
  694.       //───── draw lines for staples in middle of page
  695.       case (xx > 8 .and. xx < 12) .or. (xx > 16 .and. xx < 20)
  696.          @ prow(), 47 say "|"
  697.    endcase
  698.    do case
  699.       case xx == 11
  700.          @ prow(), 61 say "Telephone Directory"
  701.       case xx == 13
  702.          @ prow(), 69 say "for"
  703.       case xx == 15
  704.          @ prow(), 48 + int((48 - len(cname)) / 2) say cname
  705.       case xx == 17
  706.          mdate := cmonth(date()) + ' ' + ltrim(str(day(date()))) + ', ' + ;
  707.                   ltrim(str(year(date())))
  708.          @ prow(), 48 + int((48 - len(mdate)) / 2) say mdate
  709.    endcase
  710.    @ prow(), 94 say "."
  711. next
  712. return []
  713.  
  714. * end static function FrontPage()
  715. *--------------------------------------------------------------------*
  716.  
  717.  
  718. /*
  719.    PrintError(): custom printer error handler for dialing
  720. */
  721. static function printerror(e, oldhandler)
  722. if e:gencode() == EG_PRINT
  723.    err_msg("Unable to dial... please check your COMM port setting")
  724.    set print off
  725.    break
  726.    return .t.
  727. endif
  728. return eval(oldhandler, e)
  729.  
  730. * end static function PrintError()
  731. *--------------------------------------------------------------------*
  732.  
  733. * eof popphone.prg
  734.