home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR22 / JORF21_2.ZIP / CONTACT.J < prev    next >
Text File  |  1993-07-05  |  25KB  |  801 lines

  1. Class:Contact
  2.   Index:FullName
  3.   Index:Company
  4.   Index:WorkPhone
  5.   Index:LastName
  6.   Index:ZipCode
  7.   Addr1
  8.   Addr2
  9.   Addr3
  10.   HomePhone
  11.   FaxPhone
  12.   StartDate
  13.   LastUpDate
  14.   MailCode
  15.   CustCode
  16.   Location
  17.   Dear
  18.   PhoneNote
  19.   Comment
  20.   Type          | Customer, Vendor
  21.   Notes         | Memo Notes
  22.   Sales         | Sales to date
  23.  
  24. Contact:Start()
  25.   | JORF Contact Management Data Base
  26.   New (Contact:Contact)
  27.  
  28.   | Other source files
  29.   Jorf:File("TextEdit.J",Here)            | Text Editor
  30.   Jorf:File("Filter.J",Here)              | Filters
  31.   Jorf:File("ConHelp.J",Here)             | Help
  32.   Jorf:File("ConFlds.J",Here)            | Fields
  33.  
  34.   | Initialization . . .
  35.   Mem:Ptr->ContactFile   = "CONTACT.JCM"  | Default Contact File
  36.   Mem:Ptr->ContactFName  = "CONTACT"      | Name to display
  37.   Mem:Ptr->ContactFilter = Null           | All Records
  38.   Mem:Ptr->FilterDescr   = "All Records"  | All Records
  39.   Mem:Ptr->TopLevel      = Here           | Top Level
  40.   Mem:Ptr->PageNo        = 0              | Starting Page No
  41.  
  42.   | System Parameters.
  43.   Event:Add ("Contact","Key",Here)              | Set Contact handler
  44.   Contact:KeySearch(Contact,"FullName",False)   | Go to top of file
  45.  
  46.   | Contact Manager Main Window
  47.   |  The purpose of this window is to provide basic information on
  48.   |  the contact, as well as show a browser of nearby contacts.  When
  49.   |  you add, change or view, you can see additional information for
  50.   |  this contact.  The Additional screens are unlimited.
  51.   |
  52.   |  The Main Window also acts as the Main Menu.  All functions are
  53.   |  menu options from this screen.  When the operator hits escape
  54.   |  (or Alt-X) we are done with the program.
  55.   Win:Add ("Josephine's Contact Manager", 2, 2, 22, 78, Here)
  56.     Before:"Contact:Page(1)"
  57.     Menu:"&File"
  58.       Menu:"&Open           F4", Action:"Contact:OpenFile()", Hotkey:"F4_Key"
  59.       Menu:"&Filter         F7", Action:"Contact:Filter()",   Hotkey:"F7_Key"
  60.       Menu:"F&ield Editor     ", Action:"Contact:SetFields()"
  61.       Menu:"&Text Editor    F9", Action:"Textedit:Start()" HotKey:"F9_Key"
  62.       Menu:"&Rebuild        ",   Action:"Contact:Rebuild()"
  63.       Menu:
  64.       Menu:"&Dos Shell      F5", Action:"Jorf:System(Null,'C')", Hotkey:"F5_Key"
  65.       Menu:"Ca&lculator     F8", Action:"Calc:Start()",  Hotkey:"F8_Key"
  66.       Menu:
  67.       Menu:"&Set Mailcode   ",   Action:"Contact:SetMailCode(Contact)"
  68.       Menu:"&Clear Mailcode ",   Action:"Contact:ClearMailCode(Contact)"
  69.       Menu:
  70.       Menu:"&About            "  Action:"Contact:About"
  71.       Menu:"Cou&nt Records    ", Action:"Contact:Count"
  72.       Menu:"&Help           F1", Action:"Contact:Help" Hotkey:"F1_Key"
  73.       Menu:
  74.       Menu:"E&xit        Alt-X", Action:"Kbd:Put('Esc_Key')"
  75.     Menu:"&Edit"
  76.       Menu:"&Add     Alt-A",  Action:"Contact:Add(Contact)"    HotKey:"Alt_A_Key"
  77.       Menu:"&Change  Alt-C",  Action:"Contact:Change(Contact)" HotKey:"Alt_C_Key"
  78.       Menu:"&Delete  Alt-D",  Action:"Contact:Delete(Contact)" HotKey:"Alt_D_Key"
  79.       Menu:"&Hundreds     ",  Action:"Contact:Hundreds(Contact)"
  80.     Menu:"&Search",
  81.       Menu:"&Name       ",  Action:"Contact:KeySearch (Contact, 'FullName' ,True)
  82.       Menu:"&Company    ",  Action:"Contact:KeySearch (Contact, 'Company'  ,True)
  83.       Menu:"&Last Name  ",  Action:"Contact:KeySearch (Contact, 'LastName' ,True)
  84.       Menu:"&Phone      ",  Action:"Contact:KeySearch (Contact, 'WorkPhone',True)
  85.       Menu:"&Zip        ",  Action:"Contact:KeySearch (Contact, 'ZipCode'  ,True)
  86.     Menu:"&Reports"
  87.       Menu:"&Contact Data",       Action:"Contact:PrintData"
  88.       Menu:"&List of Contacts",   Action:"Contact:List"
  89.       Menu:"&Merge Letter",       Action:"Contact:MergeLetter"
  90.       Menu:"L&abels",
  91.         Menu:"&Avery 5162 - Laser Labels", Action:"Contact:Avery5162(Contact,'All')"
  92.         Menu:"&Continuous - 1x3½ Inch   ", Action:"Contact:ContinLabels(Contact,'All')"
  93.       Menu:"&One Label",
  94.         Menu:"&Avery 5162 - Laser Labels", Action:"Contact:Avery5162(Contact,'One')"
  95.         Menu:"&Continuous - 1x3½ Inch   ", Action:"Contact:ContinLabels(Contact,'One')"
  96.     InpBefore:"Contact:Lock(Contact)"
  97.     Input:"File:"   Row:22 Col:1  Wid:8  Field:"Mem:Ptr->ContactFName" Before:"False"
  98.     Input:"Index:"  Row:22 Col:18 Wid:10 Field:"Mem:Ptr->IndexName"    Before:"False"
  99.     Input:"Filter:" Row:22 Col:40 Wid:30 Field:"Mem:Ptr->FilterDescr"  Before:"False"
  100.     Group:"&Browse List", Row:1 Col:41, Len:6, Wid:36
  101.     List:""
  102.       Field:"Contact"
  103.       Next:"Contact:NextRecord(Contact,'Next')"
  104.       Prev:"Contact:NextRecord(Contact,'Prev')"
  105.       Show:"Contact:Show(Contact)"
  106.       Before:"Contact:Write()"
  107.       Display:"(Mem:Ptr->Locked==Null)"
  108.       Action:"Contact:Change(Contact)"
  109.     Group:"C&ontact", Row:1, Col:1, Wid:38, Len:6
  110.     Input:"Contact", Wid:30, Field:"Contact->FullName"
  111.       After:"Contact:SplitName(Contact)"
  112.     Input:"Company", Wid:30, Field:"Contact->Company"
  113.     Input:"Address", Wid:30, Field:"Contact->Addr1"
  114.     Input:"       ", Wid:30, Field:"Contact->Addr2"
  115.     Input:"       ", Wid:30, Field:"Contact->Addr3"
  116.       After:"Contact:ZipCode(Contact)"
  117.     Radio:"USA"  Row:7 Col:2
  118.       Action:"Contact->Location='USA'"
  119.       UnAction:"Contact->Location=Null"
  120.       Check:"Contact->Location=='USA'"
  121.     Radio:"Canada/Mexico" Row:7 Col:11
  122.       Action:"Contact->Location='CanMex'"
  123.       UnAction:"Contact->Location=Null"
  124.       Check:"Contact->Location=='CanMex'"
  125.     Radio:"Foreign" Row:7 Col:30
  126.       Action:"Contact->Location='Foreign'"
  127.       UnAction:"Contact->Location=Null"
  128.       Check:"Contact->Location=='Foreign'"
  129.     Marker:"Box"
  130.     Marker:"Fields"
  131.       | Fields will go here
  132.     Marker:"EndFields"
  133.   If (Kbd:Got='Esc_Key')
  134.     Return (Null)
  135.   Return (Contact)
  136.  
  137. Contact:About
  138.   Msg:Add ("The JORF Contact Manager", "Ok")
  139.     The JORF Contact Manager
  140.     Version 1.3,  March 20, 1993
  141.  
  142.     Copyright (C) 1993 by Wayland Bruns
  143.     All Rights Reserved
  144.  
  145.     The JORF Contact Manager is written as
  146.     a demonstration of what you can do with
  147.     the JORF Language.  The contact manager
  148.     is a "flat file" data base with multiple
  149.     keys, multiple files, filters, mail-
  150.     merge capability, reports and labels.
  151.  
  152.     The source code for this entire system
  153.     is less than 1000 lines, and you can
  154.     easily change it to suit your own
  155.     contact management needs.
  156.   Return (Ok)
  157.  
  158. Contact:Add(*Contact)
  159.   New (Contact:NewContact)
  160.   Contact:SetFile()
  161.   NewContact->FullName="New Record"
  162.   Jorf:Write(NewContact)
  163.   Contact=NewContact
  164.   Win:Dsp
  165.   Kbd:Put("Alt_O_Key")
  166.   Return(Ok)
  167.  
  168. Contact:Alt_F5_Key
  169.   Win:Msg('Flushing')
  170.   Jorf:Flush
  171.   Win:Msg()
  172.   Return (Ok)
  173.  
  174. Contact:Alt_Page_Down_Key
  175.   If (ConFlds:IsPage(Mem:Ptr->PageNo+1))
  176.     Contact:Page(Mem:Ptr->PageNo+1)
  177.   Else
  178.     Contact:Page(1)
  179.   Return (Ok)
  180.  
  181. Contact:Alt_Page_Up_Key
  182.   New (PageNo)
  183.   If (Mem:Ptr->PageNo>1)
  184.     Contact:Page(1)
  185.   Else
  186.     Contact:Page(ConFlds:LastPage())
  187.   Return (Ok)
  188.  
  189. Contact:Alt_X_Key
  190.   Return (Contact:Exit)
  191.  
  192. Contact:Avery5162(Contact,Flag)
  193.   New (Dest,Count,StartPos,OrigContact)
  194.   Dest=Jorf:Printer()
  195.   If (Dest)
  196.  
  197.     Event:Add
  198.     StartPos=1
  199.     Mem:Ptr->InsMode='OverStrike'
  200.     Win:Add ("Starting Position")
  201.       Type:"Message"
  202.       String:"This format prints on the right row of the"
  203.       String:"Avery 5162 label.  To conserve paper, you"
  204.       String:"may enter the label to start with.  The top"
  205.       String:"label is #1, and the bottom is #7."
  206.       String:""
  207.       Input:"Label to start        ", Wid:5, Field:"StartPos"
  208.       String:""
  209.       String:"When each sheet is printed, turn it around"
  210.       String:"to print on the other side."
  211.     Win:Del
  212.     Mem:Ptr->InsMode='Insert"
  213.     If (Kbd:Got = 'Esc_Key')
  214.       Return (Ok)
  215.  
  216.     Contact:SetFile()
  217.     OrigContact = Contact
  218.     | Report format for Continuous labels, 6 lines per label
  219.     |
  220.     Rep:Add ("Avery Labels", 9, 5, 49, 45, Here)
  221.       Next:"Contact:NextLabel(Contact,Flag,Count)"
  222.         Before:"Contact:Avery5162check(Contact,OrigContact,StartPos,Count)"
  223.       Item:"" NewRow:2
  224.       Item:"" NewRow:1 Col:26 Wid:12
  225.       Item:"Contact->FullName"    NewRow:1 Col:1  Wid:40
  226.       Item:"Contact->Company"     NewRow:1 Col:1  Wid:40
  227.         Before:"Contact->Company!=Null"
  228.       Item:"Contact->Addr1"       NewRow:1 Col:1  Wid:40
  229.       Item:"Contact->Addr2"       NewRow:1 Col:1  Wid:40
  230.       Item:"Contact->Addr3"       NewRow:1 Col:1  Wid:40
  231.       Item:"" NewRow:1
  232.         Before:"Contact->Company==Null"
  233.     File:Print("JREPORT.LST",Dest)
  234.   Return(Null)
  235.  
  236. Contact:Avery5162check(*Contact,OrigContact,*StartPos,*Count)
  237.   If (StartPos > 1)
  238.     --StartPos
  239.     Count = 0
  240.     Contact    = Null
  241.     Return (False)
  242.   If (Count < 1)
  243.     Contact    = OrigContact
  244.   Return (True)
  245.  
  246. Contact:Change(Contact)
  247.   | Just get them started on the Contact information
  248.   Kbd:Put("Alt_O_Key")
  249.   Return(Ok)
  250.  
  251. Contact:ClearMailCode
  252.   New (Res,Contact)
  253.  
  254.   Contact:SetFile()
  255.   Res=Msg:Add ('Clear Mail Code','Cancel')
  256.     This process will clear the Mail Code field
  257.     that is used to filter for labels and merge
  258.     letters.
  259.   If (Res)
  260.     Win:Add
  261.       Type:"Message"
  262.       Clearing contact records
  263.     While (Ok)
  264.       Contact=Contact:NextRecord(Contact,'Next'))
  265.       If (Contact==Null)
  266.         Break
  267.       If (Contact->MailCode)
  268.         If (Jorf:Lock(Contact)==False)
  269.           While (Jorf:Lock(Contact)==False)
  270.             Win:Msg("Waiting for locked record to clear")
  271.           Win:Del
  272.         Contact->MailCode=Null
  273.         Jorf:Write(Contact)
  274.     Win:Dsp
  275.   Return(Ok)
  276.  
  277. Contact:ContinLabels(Contact,Flag)
  278.   New (Dest,Count,i)
  279.   Dest=Jorf:Printer()
  280.   If (Dest)
  281.  
  282.     Contact:SetFile()
  283.     | Report format for Continuous labels, 6 lines per label, 1 line between
  284.     |
  285.     Rep:Add ("Continuous Labels")
  286.       Next:"Contact:Nextlabel(Contact,Flag,Count)"
  287.       Item:"" NewRow:1 Col:26 Wid:12
  288.       Item:"Contact->FullName"    NewRow:1 Col:1  Wid:40
  289.       Item:"Contact->Company"     NewRow:1 Col:1  Wid:40
  290.         Before:"Contact->Company!=Null"
  291.       Item:"Contact->Addr1"       NewRow:1 Col:1  Wid:40
  292.       Item:"Contact->Addr2"       NewRow:1 Col:1  Wid:40
  293.       Item:"Contact->Addr3"       NewRow:1 Col:1  Wid:40
  294.       Item:"" NewRow:1
  295.         Before:"Contact->Company==Null"
  296.  
  297.     | I like to append one blank label to advance the printer so I can
  298.     |  tear off the label just printed.
  299.     For (i=1 Thru 5)
  300.       File:Append("JREPORT.LST")
  301.  
  302.     File:Print("JREPORT.LST",Dest,TRUE)
  303.   Return(Ok)
  304.  
  305. Contact:Count
  306.   New (NewContact,Counter)
  307.   Contact:SetFile()
  308.   Win:Add ("Counting Records",0,0,5,30)
  309.     Type:"Message"
  310.   Move:To(2,2)
  311.   Str:Put("Record")
  312.   Move:To(3,2)
  313.   Str:Put("Name")
  314.   While (Ok)
  315.     NewContact = Struct:Next('Contact','FullName',NewContact)
  316.     If (NewContact = Null)
  317.       Break
  318.     ++Counter
  319.     Move:To(2,12)
  320.     Str:Put(Counter)
  321.     Move:To(3,12)
  322.     Str:Put(Str:Pad(NewContact->FullName,18))
  323.     If (Kbd:Hit)
  324.       If (Kbd:Get=="Esc_Key")
  325.         Break
  326.   Win:Pause
  327.   Return (Ok)
  328.  
  329. Contact:Dear (Contact)
  330.   If (Contact->Dear==Null)
  331.     Contact->Dear = (Word:At(Contact->FullName,1))
  332.   Return(Ok)
  333.  
  334. Contact:Delete(*Contact)                | Delete Contact Record
  335.   New (Result,NextContact)
  336.  
  337.   | Pop up a nice screen to ask if they are sure
  338.   Result=Msg:Add('Contact Delete','No')
  339.     Delete this record
  340.  
  341.     Name:     {Contact->FullName}
  342.     Company:  {Contact->Company}
  343.  
  344.   | If they said "Yes", then Result will equal ok (1)
  345.   If (Result==Ok)
  346.     Contact:SetFile()
  347.     NextContact = Struct:Next('Contact',Mem:Ptr->IndexName,Contact)
  348.     Jorf:Del(Contact)
  349.     Contact=NextContact
  350.     Win:Dsp
  351.   Return (Ok)
  352.  
  353. Contact:Dial(Number)
  354.   New (Port)
  355.   Port='COM2'
  356.   Win:Add ("Dialing")
  357.     Type:"Message"
  358.     Dialing {Number}
  359.  
  360.   Str:Print("ATDT"+Number+To:Char(13),Port)    | Dial
  361.   Win:Pause(500)
  362.  
  363.   Msg:Add("Dial")
  364.     Please pick up your phone and
  365.     press Enter to connect the call.
  366.  
  367.   Str:Print("ATH1"+Number+To:Char(13),Port)    | Switch to Voice mode
  368.   Return(Ok)
  369.  
  370. Contact:Enter_Key
  371.   | Change enter key - to tab key.
  372.   | Test if we are in an input then InpLen is set to the
  373.   |  number of input lines.
  374.   If (Str:In(Win:Ptr->InpField,"Phone"))
  375.     Contact:Dial(Win:Ptr->CurLine)
  376.     Return (Ok)
  377.   If (Win:Ptr->InpLen == 1)
  378.     Return ("Tab_Key")
  379.   Return (Null)
  380.  
  381. Contact:Left_Mouse_DClick
  382.   If (Str:In(Win:Ptr->InpField,"Phone"))
  383.     Contact:Dial(Win:Ptr->CurLine)
  384.     Return (Ok)
  385.   Return (Null)
  386.  
  387. Contact:Esc_Key
  388.   | Even block the escape key - which would otherwise cause
  389.   | the screen (and program) to go bye.
  390.   Return (Contact:Exit)
  391.  
  392. Contact:Exit
  393.   New (Res)
  394.   Contact:Write()
  395.   Res=Msg:Add(Null,"Cancel")
  396.     This will end your session with
  397.     Josephine's Contact Manager
  398.   If (Res)
  399.     Jorf:Exit
  400.   Return (Ok)
  401.  
  402. Contact:Filter
  403.   New (NewFilter)
  404.   NewFilter=Filter:Start()
  405.   If (Kbd:Got!='Esc_Key')
  406.     Mem:Ptr->ContactFilter = Filter:Method()
  407.     Mem:Ptr->FilterName    = Filter:Name()
  408.     Mem:Ptr->FilterDescr   = Filter:Descr()
  409.   Win:Dsp
  410.  
  411.   | Test current contact - if it doesn't count, null it out
  412.   If (Mem:Ptr->ContactFilter != Null)
  413.     If (Jorf:Do(Mem:Ptr->ContactFilter)==False)
  414.       Contact=Null
  415.   Return(Null)
  416.  
  417. Contact:GetLetter
  418.   New (PrintList,PrintChoice,Letter)
  419.  
  420.   PrintList = Arr:Sort(Arr:Dir('*.LTR'))
  421.   If (Arr:Len(PrintList) < 1)
  422.     Msg:Add
  423.       There are no .LTR files
  424.       on the current directory.
  425.   Else
  426.     Win:Add("Select Letter")
  427.       Type:"Message"
  428.       Group:"&Merge Letters", Row:1 Col:1 Len:6 Wid:22
  429.       Array:"" Field:"PrintList" Choice:"PrintChoice"
  430.  
  431.       Button:"  &Go  " Row:1 Col:32
  432.         Action:"Letter=PrintList[PrintChoice]"
  433.       Button:" &Cancel " Row:4 Col:32 Action:"Return ('Esc_Key')"
  434.   Return(Letter)
  435.  
  436. Contact:Help
  437.   If File:Exist("ConHelp.Jrf" 0)
  438.     Jorf:File ("ConHelp.Jrf",Here)
  439.     ConHelp:Start
  440.   Else
  441.     Msg:Add
  442.       The CONHELP.JRF file is not &
  443.       on the current directory
  444.   Return Ok
  445.  
  446. Contact:Hundreds(Contact)
  447.   New (Count,Counter,Contact:NewContact,NewName)
  448.   Win:Add("Adding Hundreds")
  449.     Type:"Message"
  450.     String:"Some people want to know how JORF acts when it has"
  451.     String:"a lot of records in a data base.  I created this"
  452.     String:"option to to add hundreds of records so you can"
  453.     String:"test program performance on a large data base."
  454.     String:""
  455.     String:"Adding Hundreds of records takes about 300K per"
  456.     String:"hundred.  Please be sure you have enough disk"
  457.     String:"space.  Press ESCAPE now to avoid adding hundreds."
  458.     String:""
  459.     Input:"Number of Records to add" Field:"Count" Wid:10
  460.     String:""
  461.     String:"Press ESCAPE now to avoid adding hundreds"
  462.   If (Count < 1)
  463.     Return (Ok)
  464.   Win:Add("Adding Hundreds",0,0,6,30)
  465.     Type:"Message"
  466.   Move:To(2,2)
  467.   Str:Put("Record")
  468.   Move:To(3,2)
  469.   Str:Put("Name")
  470.   Move:To(5,2)
  471.   Str:Put("Press ESC to exit")
  472.   Contact=Null
  473.   Contact:SetFile()
  474.   While (Count > 0)
  475.     ++Counter
  476.  
  477.     | Get a "Living" record for prototype
  478.     Contact = Struct:Next('Contact',Mem:Ptr->IndexName,Contact)
  479.     If (Contact==Null)
  480.       Contact = Struct:Next('Contact',Mem:Ptr->IndexName,Null)
  481.  
  482.     NewContact=Jorf:Dup(Contact)
  483.  
  484.     | Make up a random name, set fields
  485.     NewName=          To:Char(Num:Rand(65,90)) + To:Char(Num:Rand(97,122))
  486.     NewName=NewName + To:Char(Num:Rand(97,122)) + To:Char(Num:Rand(97,122))
  487.     NewName=NewName + ' '+To:Char(Num:Rand(65,90)) + '. '
  488.     NewName=NewName + To:Char(Num:Rand(65,90)) + To:Char(Num:Rand(97,122))
  489.     NewName=NewName + To:Char(Num:Rand(97,122)) + To:Char(Num:Rand(97,122))
  490.     NewName=NewName + To:Char(Num:Rand(97,122))
  491.  
  492.     NewContact->FullName = NewName
  493.     NewContact->LastName = Word:At(NewName,Word:Len(NewName))
  494.     NewContact->Dear     = Word:At(NewName,1)
  495.     Jorf:Write(NewContact)
  496.     Move:To(2,12)
  497.     Str:Put(Counter)
  498.     Move:To(3,12)
  499.     Str:Put(Str:Pad(NewContact->FullName,18))
  500.     If (Kbd:Hit)
  501.       If (Kbd:Get=="Esc_Key")
  502.         Break
  503.     --Count
  504.   Contact = Struct:Next('Contact',Mem:Ptr->IndexName,Null)
  505.   Win:Dsp
  506.   Return Ok
  507.  
  508. Contact:KeySearch (*Contact, Field, GetInp)
  509.   New (Value,Prompt,Display)
  510.  
  511.   Contact:SetFile()         | Set Current File
  512.   Event:Add                     | Block "Contact" Events so Alt-A won't work
  513.   Switch (Field)
  514.     Case ("FullName")
  515.       Prompt="Name"
  516.     Case ("Company")
  517.       Prompt="Company"
  518.     Case ("WorkPhone")
  519.       Prompt="Phone"
  520.     Case ("LastName")
  521.       Prompt="Last Name"
  522.     Case ("ZipCode")
  523.       Prompt="Zip Code"
  524.     Else
  525.       Msg:Add
  526.         Unknown Field {Field}
  527.       Return (Ok)
  528.  
  529.   If (GetInp)
  530.     Win:Add ("Key Search", 10, 25, 0, 0, Here)
  531.       Type:"Message"
  532.       Input:"Search for {Prompt}", Wid:30, Field:"Value"
  533.   If (Kbd:Got <> "Esc_Key")
  534.     Mem:Ptr->IndexName=Field
  535.     Contact=Struct:Find('Contact',Mem:Ptr->IndexName,Value)
  536.     If (Contact=Null And Value)
  537.       Msg:Add
  538.         Cannot find {Prompt} {Value}
  539.       Contact=Struct:Find('Contact',Mem:Ptr->IndexName,Null)
  540.     Win:Dsp
  541.   Return (Contact)
  542.  
  543. Contact:LastName (Contact)
  544.   If (Contact->LastName==Null)
  545.     Contact->LastName= (Word:At(Contact->FullName,Word:Len(Contact->FullName)))
  546.   Return(Ok)
  547.  
  548. Contact:List()
  549.   New (Dest,Date,Page,Contact,Count)
  550.   Dest=Jorf:Printer()
  551.   If (Dest)
  552.     Contact:SetFile()
  553.     Date = Date:Str(Date:Get,"s d, yyyy")
  554.     Rep:Add ("Contact Listing", 5, 5, 60, 75, Here)
  555.       Header:"'Contact Listing Report'"    NewRow:1 Col:30
  556.       Header:"'Page '+Page"        NewRow:1 Col:1
  557.         Before:"Contact:NextPage(Page)"
  558.       Header:"'Date '+Date"                Col:54
  559.       Header:"Str:AtSet(Null,1,'-',70)"     NewRow:1 Col:1
  560.       Next:"Contact:NextLabel(Contact,'All',Count)"
  561.       Item:"Contact->FullName"      NewRow:2 Col:1  Len:28
  562.       Item:"Contact->Company "               Col:30 Len:32
  563.       Item:"Contact->WorkPhone"              Col:62 Len:28
  564.       Item:"Contact->Addr1+', '+Contact->Addr2+' '+Contact->Addr3"
  565.         NewRow:1 Col:5  Len:70
  566.     File:Print("Jreport.lst",Dest)
  567.   Return (Ok)
  568.  
  569. Contact:Lock(Contact)
  570.   If (Mem:Ptr->Locked==Contact)
  571.     Win:Msg("You have locked this Record")
  572.     Return (Ok)
  573.   Contact:Write()
  574.   If (Jorf:Lock(Contact))
  575.     Mem:Ptr->Locked=Contact
  576.     Win:Msg("You have locked this Record")
  577.     Return (Ok)
  578.   If (Contact <> Mem:Ptr->Unlocked)         | If first time
  579.     Msg:Add("Record is Locked")             |  show message
  580.       Either someone else has this
  581.       record locked now, or it has
  582.       been locked before but never
  583.       unlocked.
  584.  
  585.       If no one else is in the data
  586.       base, you can unlock this
  587.       record by rebuilding the file.
  588.     Mem:Ptr->Unlocked = Contact             | Make a record that message is shown
  589.   Return(Null)
  590.  
  591. Contact:MergeLetter
  592.   New (Dest,Letter,CurrContact,Count)
  593.   Time:Get(Mem:Ptr)
  594.  
  595.   Letter=File:Load(Contact:GetLetter)
  596.   If (Letter!=Null)
  597.     Dest=Jorf:Printer()
  598.     If (Dest)
  599.       CurrContact=Contact
  600.       Contact=Null
  601.       Rep:Add ("Merge Letter", 5, 5, 60, 75,Here)
  602.         Next:"Contact:NextLabel(Contact,'All',Count)"
  603.         Text:"Letter" Row:1
  604.       File:Print("JREPORT.LST",Dest)
  605.       Contact=CurrContact
  606.   Return (Ok)
  607.  
  608. Contact:NextLabel(*Contact,Flag,*Count)
  609.   Count = Count + 1
  610.   If (Flag=='All')
  611.     If (Count == 1)
  612.       Contact = Null
  613.     Contact = Contact:NextRecord(Contact,'Next')
  614.   Else
  615.     If (Count > 1)
  616.       Contact=Null
  617.   Return (Contact)
  618.  
  619. Contact:NextPage(*Page)
  620.   ++Page
  621.   Return (Ok)
  622.  
  623. Contact:NextRecord(*Contact,Flag)
  624.   | Gets the next (or previous) record depending on Flag
  625.   | Flag is "Next" or "Prev" Easy!
  626.   |
  627.   Contact:Write()
  628.   Contact:SetFile()
  629.   While (Ok)
  630.     If (Flag=='Prev')
  631.       Contact=Struct:Prev('Contact',Mem:Ptr->IndexName,Contact)
  632.     Else
  633.       Contact=Struct:Next('Contact',Mem:Ptr->IndexName,Contact)
  634.     If (Contact==Null)
  635.       Break
  636.     If (Mem:Ptr->ContactFilter = Null)
  637.       Break
  638.     If (Jorf:Do(Mem:Ptr->ContactFilter))
  639.       Break
  640.   Return(Contact)
  641.  
  642. Contact:OpenFile()
  643.   New (NewFile,Pos)
  644.   NewFile=Dirlist:GetFile("*.JCM")
  645.   If (NewFile)
  646.     If (Str:In(Newfile,".")==0)
  647.       NewFile = NewFile + ".JCM"
  648.     Mem:Ptr->ContactFile=NewFile
  649.     Pos = Str:In(NewFile,"\")
  650.     While (Pos)
  651.       NewFile = Str:At(Newfile,Pos+1)
  652.       Pos =Str:In(NewFile,"\")
  653.     Pos = Str:In(NewFile,".")
  654.     If (Pos)
  655.       NewFile = Str:At(Newfile,1,Pos-1)
  656.     Mem:Ptr->ContactFName=To:Ucs(NewFile)
  657.     Contact=Contact:NextRecord(Null,'Next')
  658.     Win:Dsp
  659.   Return (Ok)
  660.  
  661. Contact:Page(PageNo)
  662.   New (WinText)
  663.  
  664.   If (PageNo == Mem:Ptr->PageNo)
  665.     Return (Ok)
  666.  
  667.   WinText=ConFlds:GetPage(PageNo)
  668.   If (WinText==Null)
  669.     PageNo = 1
  670.     WinText=ConFlds:GetPage(PageNo)
  671.   If (WinText)
  672.     Win:Chg("Box",9,1,11,76,WinText)
  673.     Mem:Ptr->PageNo=PageNo
  674.   Return (Ok)
  675.  
  676. Contact:PrintData
  677.   New (Dest,Contact)
  678.   Time:Get(Mem:Ptr)
  679.   Mem:Ptr->Page=1
  680.  
  681.   If (File:Exist("Contact.Rpt")==False)
  682.     Msg:Add
  683.       Print format "Contact.Rpt" is
  684.       not in the current directory.
  685.     Return (Ok)
  686.   Dest=Jorf:Printer()
  687.   Contact=Contact
  688.   If (Dest)
  689.     Rep:Add ("Contact Information", 5, 5, 60, 75,Here)
  690.       Header:"'Contact Information Report'"     NewRow:1 Col:30
  691.       Header:"'Date '+Mem:Ptr->SDate"         Col:50
  692.       Header:"Str:AtSet(Null,1,'-',80)" NewRow:1 Col:1
  693.       Text:"File:Load('Contact.Rpt')"
  694.       Next:"Null"
  695.     File:Print("Jreport.lst",Dest)
  696.   Return (Ok)
  697.  
  698. Contact:Rebuild()
  699.   | A rebuild writes the entire data file to an ascii file,
  700.   | then erases the original, reads the ascii and reindexes.
  701.   | The resulting process cleans any problem with the file and
  702.   | indexes.
  703.   |
  704.   | Set file
  705.   Contact:SetFile()
  706.  
  707.   | Then do the rebuild . . .
  708.   Jorf:Rebuild
  709.   Return (Ok)
  710.  
  711. Contact:SetFields()
  712.   New (PageNo)
  713.   ConFlds:Start()
  714.   PageNo=Mem:Ptr->PageNo
  715.   Mem:Ptr->PageNo=0
  716.   Contact:Page(PageNo)
  717.   Return (Null)
  718.  
  719. Contact:SetFile()
  720.   | This method is used to set the current file.  The current file
  721.   | name is in Mem:Ptr->ContactFile
  722.   Jorf:File (Mem:Ptr->ContactFile, Mem:Ptr->TopLevel) | Set file to use
  723.   Return
  724.  
  725. Contact:SetMailCode(Contact)
  726.   New (Res)
  727.  
  728.   Event:Add
  729.   If (Jorf:Lock(Contact)==False) | Lock Record
  730.     Msg:Add
  731.       Cannot set mail code,
  732.       record is locked.
  733.   Else
  734.     Win:Add ('Set Mail Code')
  735.       Type:"Message"
  736.       Input:"Set code to", Wid:20 Field:"Mem:Ptr->MailCode"
  737.     If (Kbd:Got!='Esc_Key')
  738.       Contact->MailCode=Mem:Ptr->MailCode
  739.     Jorf:Write(Contact)          | Write and Unlock
  740.     Win:Dsp
  741.   Return(Ok)
  742.  
  743. Contact:SetPage(Page)
  744.   Mem:Ptr->Page=Page
  745.   Return(Null)
  746.  
  747. Contact:Shift_F5_Key
  748.   Jorf:Status
  749.   Jorf:StatusClear
  750.   Return (Ok)
  751.  
  752. Contact:Show (Contact)
  753.   | The "Show" routine is used for the browser window.  The data that
  754.   | is shown changes depending on the index in use - (try switching to
  755.   | the phone number or zip code indexes to see the difference).
  756.   New (Display)                        | Create "Display"
  757.                                        | And interpret "Display" string
  758.   Switch (Mem:Ptr->IndexName)
  759.     Case ("FullName")
  760.       Display = Str:Pad(Contact->FullName,17)+' '+Str:Pad(Contact->Company,17)
  761.     Case ("Company")
  762.       Display = Str:Pad(Contact->Company,17)+' '+Str:Pad(Contact->FullName,17)
  763.     Case ("WorkPhone")
  764.       Display = Str:Pad(Contact->WorkPhone,17)+' '+Str:Pad(Contact->FullName,17)
  765.     Case ("LastName")
  766.       Display = Str:Pad(Contact->LastName,10)+' '+Str:Pad(Contact->Dear,12)
  767.       Display = Display +' '+Str:Pad(Contact->Company,17)
  768.     Case ("ZipCode")
  769.       Display = Str:Pad(Contact->ZipCode,5)+' '+Str:Pad(Contact->Company,16)
  770.       Display = Display +' '+Str:Pad(Contact->FullName,12)
  771.   Return (Display)
  772.  
  773. Contact:SplitName(Contact)
  774.   If (Contact->FullName)
  775.     If (Contact->Dear==Null)
  776.       Contact->Dear=Word:At(Contact->FullName,1)
  777.     If (Contact->LastName==Null)
  778.       Contact->LastName=Word:At(Contact->FullName,Word:Len(Contact->FullName))
  779.   Return (Ok)
  780.  
  781. Contact:Write()
  782.   If (Mem:Ptr->Locked)
  783.     Jorf:Write(Mem:Ptr->Locked)
  784.     Mem:Ptr->Locked=Null
  785.     Win:Dsp()
  786.     Win:Msg()
  787.   Return (Ok)
  788.  
  789. Contact:ZipCode (Contact)
  790.   New (Field)
  791.   If (Contact->ZipCode==Null)
  792.     If (Contact->Addr3)
  793.       Field=Contact->Addr3
  794.     Else
  795.       Field=Contact->Addr2
  796.     While (Str:In(Field," "))
  797.       Field=Str:At(Field,Str:In(Field," ")+1)
  798.     Contact->ZipCode=Field
  799.   Return (Ok)
  800.  
  801.