ðW/Syntax10.Scn.FntnSyntax10i.Scn.Fnt0žþÿÿ€8ÀÔFoldElemsNew#Syntax10.Scn.FntÈÈ VAR name, nick, email: Elems.Elem; context: Texts.Text; BEGIN context := Elems.CmdContext; name := Elems.NamedElem("curName", context); nick := Elems.NamedElem("curNick", context); email := Elems.NamedElem("curEmail", context); Elems.SetString(name, "Value", curName); Elems.UpdateElem(name); Elems.SetString(nick, "Value", curNick); Elems.UpdateElem(nick); Elems.SetString(email, "Value", curEmail); Elems.UpdateElem(email) END UpdateCurrent; ÿÿÿÿ€8ÀÔþÿÿ€8ÀÔ#Syntax10.Scn.FntÞÞ VAR name, nick, email, group: Elems.Elem; context: Texts.Text; BEGIN context := Elems.CmdContext; name := Elems.NamedElem("curName", context); nick := Elems.NamedElem("curNick", context); email := Elems.NamedElem("curEmail", context); group := Elems.NamedElem("groups", context); Elems.GetString(name, "Value", curName); Elems.GetString(nick, "Value", curNick); Elems.GetString(email, "Value", curEmail); Elems.GetString(group, "Value", curGroupname) END GetCurrent; ÿÿÿÿ€8ÀÔ/uÿÿÿ€8ÀÔ#Syntax10.Scn.Fntii BEGIN IF g = NIL THEN RETURN END; Texts.WriteString(w, g.name^); Texts.WriteLn(w) END AddToGroupList; ÿÿÿÿ€8ÀÔ//ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt¯¯ VAR e: CheckBoxElems.Elem; BEGIN IF a = NIL THEN RETURN END; IF (curGroup = NIL) OR (AddrBook.HasGroup(a, curGroup) = hasToHaveGroup) THEN NEW(e); CheckBoxElems.Init(e); Elems.SetString(e, "Name", a.realname^); e.value := (curGroup = NIL) OR (AddrBook.HasGroup(a, curGroup)); Texts.WriteElem(w, e); Texts.Write(w, " "); IF order = 0 THEN Texts.WriteString(w, a.realname^); Texts.WriteString(w, " ("); Texts.WriteString(w, a.nickname^); Texts.Write(w, ")") ELSIF order = 1 THEN Texts.WriteString(w, a.nickname^); Texts.WriteString(w, " ("); Texts.WriteString(w, a.realname^); Texts.Write(w, ")") ELSE HALT(100) END; Texts.WriteLn(w) END END AddToAdrList; ÿÿÿÿ€8ÀÔ:ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt¤¤ VAR addresses: Elems.Elem; addressesList: Texts.Text; BEGIN addresses := Elems.NamedElem("addresses", context); Elems.GetText(addresses, "ValueT", addressesList); Texts.Delete(addressesList, 0, addressesList.len); Texts.OpenWriter(w); hasToHaveGroup := TRUE; IF order = 0 THEN AddrBook.EnumerateAdrReal(AddToAdrList); IF curGroup # NIL THEN hasToHaveGroup := FALSE; AddrBook.EnumerateAdrReal(AddToAdrList) END ELSE AddrBook.EnumerateAdrNick(AddToAdrList); IF curGroup # NIL THEN hasToHaveGroup := FALSE; AddrBook.EnumerateAdrNick(AddToAdrList) END END; Texts.Append(addressesList, w.buf); Elems.UpdateElem(addresses) END UpdateAddressList; ÿÿÿÿ€8ÀÔþÿÿ€8ÀÔ#Syntax10.Scn.FntËË VAR groupsList: Texts.Text; groups: Elems.Elem; BEGIN groups := Elems.NamedElem("groups", context); Elems.GetText(groups, "ValueT", groupsList); Texts.Delete(groupsList, 0, groupsList.len); Texts.OpenWriter(w); Texts.WriteString(w, "*"); Texts.WriteLn(w); AddrBook.EnumerateGroups(AddToGroupList); Texts.Append(groupsList, w.buf); IF curGroup = NIL THEN Elems.SetString(groups, "ComboV", "*") END; Elems.UpdateElem(groups) END UpdateGroupList; ÿÿÿÿ€8ÀÔ(1ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt­­ VAR keys: SET; x, y: INTEGER; v: Viewers.Viewer; BEGIN Input.Mouse(keys, x, y); v := Viewers.This(x, y); RETURN (x - v.X >= 142) & (x - v.X <= 153) END MouseInCheckbox; ÿÿÿÿ€8ÀÔ Syntax10b.Scn.Fntôûÿÿ€8ÀÔ#Syntax10.Scn.Fntêê VAR name, name2: Name; addresses, cb: Elems.Elem; ctx, adrText: Texts.Text; a: AddrBook.Address; res, pos: INTEGER; BEGIN ctx := Elems.CmdContext; addresses := Elems.NamedElem("addresses", ctx); Elems.GetString(addresses, "Value", name); pos := Strings.Pos("(", name, 0); Strings.Extract(name, 1, pos - 2, name2); IF MouseInCheckbox() & (curGroup # NIL)THEN Elems.GetText(addresses, "ValueT", adrText); cb := Elems.NamedElem(name2, adrText); WITH cb: CheckBoxElems.Elem DO cb.value := ~cb.value; AddrBook.SearchByName(name2, a); ASSERT(a # NIL); IF cb.value THEN AddrBook.InsertAddressIntoGroup(curGroup, a, res) ELSE AddrBook.RemoveAddressFromGroup(curGroup, a, res) END; ASSERT(res = AddrBook.ok) ELSE HALT(100) END; Elems.UpdateElem(cb) ELSE AddrBook.SearchByName(name2, curAdr); IF curAdr # NIL THEN COPY(curAdr.realname^, curName); COPY(curAdr.nickname^, curNick); COPY(curAdr.email^, curEmail) END END; UpdateCurrent END SetAdr; ÿÿÿÿ€8ÀÔ  Øþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR name: ARRAY 512 OF CHAR; groups: Elems.Elem; ctx: Texts.Text; BEGIN ctx := Elems.CmdContext; groups := Elems.NamedElem("groups", ctx); Elems.GetString(groups, "Value", name); AddrBook.SearchGroupByName(name, curGroup); UpdateAddressList END SetGroup; ÿÿÿÿ€8ÀÔ  öþÿÿ€8ÀÔ#Syntax10.Scn.Fntèè VAR rb: Elems.Elem; value: ARRAY 32 OF CHAR; BEGIN rb := Elems.NamedElem("SortOrder", context); Elems.GetString(rb, "Value", value); IF value = "nick" THEN order := 1 ELSE order := 0 END; UpdateAddressList END SetOrder; ÿÿÿÿ€8ÀÔ ãýÿÿ€8ÀÔCSyntax10.Scn.Fnt§Syntax10b.Scn.Fnt.Û VAR a: AddrBook.Address; res: INTEGER; BEGIN GetCurrent; IF (curName = "") OR (curNick = "") THEN Out.String("You have to supply a realname and a nickname$"); RETURN END; AddrBook.NewAddress (curNick, curName, curEmail, a); AddrBook.Insert (a, res); curAdr := a; IF res # AddrBook.ok THEN Out.String("AddrBook: Could not insert address. ") ; IF res = AddrBook.alreadyExists THEN Out.String("Nickname or realname not unique") END; Out.Ln END END Add; ÿÿÿÿ€8ÀÔ  ÿÿÿÿ€8ÀÔ¥Éÿÿÿÿ€8ÀÔ mþÿÿ€8ÀÔCSyntax10.Scn.FntiSyntax10b.Scn.FntâQ VAR a: AddrBook.Address; res: INTEGER; BEGIN IF curAdr = NIL THEN Out.String("No address selected$"); RETURN END; GetCurrent; AddrBook.ChangeAddress(curAdr, curNick, curName, curEmail, res); IF res # AddrBook.ok THEN Out.String("Could not edit address$"); AddrBook.Insert(curAdr, res); ASSERT(res = AddrBook.ok) END END Edit; ÿÿÿÿ€8ÀÔ  +ÿÿÿ€8ÀÔCSyntax10.Scn.FntSyntax10b.Scn.Fntn“ BEGIN IF curGroup = NIL THEN RETURN END; GetCurrent; AddrBook.SetGroupname(curGroup, curGroupname); SetGroup; UpdateGroupList END EditGroup; ÿÿÿÿ€8ÀÔ ¾þÿÿ€8ÀÔCSyntax10.Scn.FntTSyntax10b.Scn.Fnt¦ VAR res: INTEGER; BEGIN IF curAdr = NIL THEN Out.String("No address selected$"); RETURN END; AddrBook.Remove(curAdr, res); ASSERT(res = AddrBook.ok); COPY("", curName); COPY("", curNick); COPY("", curEmail); curAdr := NIL; UpdateCurrent END Delete; ÿÿÿÿ€8ÀÔTÿÿÿÿ€8ÀÔÍÿÿÿÿ€8ÀÔJÔþÿÿ€8ÀÔ#Syntax10.Scn.Fnt   VAR r: Texts.Reader; ch: CHAR; BEGIN Texts.OpenReader(r, t, pos); Texts.Read(r, ch); WHILE ~r.eot & (ch # " ") & (ch # CR) DO Texts.Read(r, ch) END; IF ~r.eot THEN pos := Texts.Pos(r); IF (ch = CR) THEN DEC(pos) END ELSE ok := FALSE END END GetFreePos; ÿÿÿÿ€8ÀÔkÿÿÿÿ€8ÀÔ¶ÿÿÿÿ€8ÀÔ/¥þÿÿ€8ÀÔ#Syntax10.Scn.Fnt99 VAR len: INTEGER; BEGIN len := Strings.Length(a.email^); IF sendAdrSize + len + 1 >= LEN(sendAdr^) THEN NEW(help, LEN(sendAdr^) * 2); COPY(sendAdr^, help^); sendAdr := help END; Strings.Append(a.email^, sendAdr^); Strings.Append(" ", sendAdr^); sendAdrSize := sendAdrSize + len + 1 END BuildSendAdr; ÿÿÿÿ€8ÀÔ  Þþÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN NEW(sendAdr, 512); sendAdrSize := 0; IF curGroup # NIL THEN AddrBook.EnumerateAdrGroup (curGroup, AddrBook.CompReal, BuildSendAdr) ELSE AddrBook.EnumerateAdrReal (BuildSendAdr) END; Mail.OpenSendNew(sendAdr^, "", "", "", "") END SendGroup; ÿÿÿÿ€8ÀÔ  Fÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt˜˜ BEGIN IF (curAdr = NIL) THEN Out.String("AddrBook: No address selected$") ELSE Mail.OpenSendNew(curAdr.email^, "", "", "", "") END END SendAdr; ÿÿÿÿ€8ÀÔ&‘þÿÿ€8ÀÔCSyntax10.Scn.Fnt–Syntax10b.Scn.Fnt‘- VAR f: TextFrames.Frame; t: Texts.Text; pos: LONGINT; w: Texts.Writer; ok: BOOLEAN; BEGIN GetDestination(f, t, pos, ok); IF ~ok THEN SendAdr; RETURN END; Texts.OpenWriter(w); Texts.WriteString(w, s); Texts.Insert(t, pos, w.buf); TextFrames.SetCaret(f, pos + Strings.Length(s)) END Insert; ÿÿÿÿ€8ÀÔ,‚ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt\\ VAR s: Name; BEGIN COPY(a.email^, s); Strings.Append(" ", s); Insert(s) END InsertAdr; ÿÿÿÿ€8ÀÔ  ­þÿÿ€8ÀÔ#Syntax10.Scn.Fnt11 VAR f: TextFrames.Frame; t: Texts.Text; pos: LONGINT; ok: BOOLEAN; BEGIN GetDestination(f, t, pos, ok); IF ok THEN IF curGroup # NIL THEN AddrBook.EnumerateAdrGroup (curGroup, AddrBook.CompReal, InsertAdr) ELSE AddrBook.EnumerateAdrReal (InsertAdr) END ELSE SendGroup END END ToGroup; ÿÿÿÿ€8ÀÔ ÿÿÿ€8ÀÔCSyntax10.Scn.FnteSyntax10b.Scn.FntOº VAR s: Name; BEGIN IF curAdr = NIL THEN Out.String("AddrBook: No address selected$"); Out.Ln; RETURN END; COPY(curAdr.email^, s); Strings.Append(" ", s); Insert(s) END ToAdr; ÿÿÿÿ€8ÀÔ=ÿÿÿÿ€8ÀÔ÷ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ{ÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ íþÿÿ€8ÀÔ#Syntax10.Scn.Fntññ VAR p: PanelElems.Panel; fnt: Fonts.Font; col: SHORTINT; BEGIN Viewers.Close(Viewers.This(Elems.CmdFrame.X, Elems.CmdFrame.Y)); Panel.LoadPanel("AddrBook2.Panel", p, fnt, col); Panel.OpenPanel(p, "AddrBook2.Panel", fnt, col) END Page2; ÿÿÿÿ€8ÀÔ  ýÿÿ€8ÀÔ#Syntax10.Scn.FntÊÊ VAR ctx: Texts.Text; e: Elems.Elem; PROCEDURE Set (fieldname: ARRAY OF CHAR; content: String); BEGIN e := Elems.NamedElem(fieldname, ctx); IF content # NIL THEN Elems.SetString(e, "Value", content^) ELSE Elems.SetString(e, "Value", "") END END Set; BEGIN IF curAdr = NIL THEN Out.String("AddrBook: No address selected$") ELSE ctx := Elems.CmdContext; Set("organization", curAdr.organization); Set("title", curAdr.title); Set("address", curAdr.address); Set("zip", curAdr.zip); Set("city", curAdr.city); Set("state", curAdr.state); Set("country", curAdr.country); Set("workPhone", curAdr.workPhone); Set("homePhone", curAdr.homePhone); Set("fax", curAdr.fax) END END InitPage2; ÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ  ÿÿÿÿ€8ÀÔuÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ+Žþÿÿ€8ÀÔ#Syntax10.Scn.FntPP BEGIN WITH n: AddrBook.AdrNotify DO UpdateAddressList; | n: AddrBook.GroupNotify DO IF n.op = AddrBook.remove THEN curGroup := NIL END; UpdateGroupList; IF (n.op = AddrBook.add) OR (n.op = AddrBook.remove) THEN SetGroup END ELSE ASSERT(n.op = AddrBook.load); UpdateAddressList; UpdateGroupList END END Notifier; ÿÿÿÿ€8ÀÔ  Rÿÿÿ€8ÀÔ#Syntax10.Scn.FntŒŒ BEGIN context := Elems.CmdContext; UpdateCurrent; UpdateAddressList; UpdateGroupList; AddrBook.InstallNotifier(Notifier) END InitGUI; ÿÿÿÿ€8ÀÔžÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt@@ curAdr := NIL; curGroup := NIL; order := 0; AddrBook.Load; ÿÿÿÿ€8ÀÔýMODULE AddrBookGUI; IMPORT AddrBook, CheckBoxElems, Display, Elems, Fonts, Oberon, Panel, PanelElems, Strings, Texts, TextFrames, Viewers, Out, Input, Mail, In; CONST CR = 0DX; TYPE String = AddrBook.String; Name = ARRAY 512 OF CHAR; VAR curAdr: AddrBook.Address; curGroup: AddrBook.Group; curName, curNick, curEmail, curGroupname: Name; order: INTEGER; (* 0 ... realname first, 1 ... nickname first *) w: Texts.Writer; context: Texts.Text; hasToHaveGroup: BOOLEAN; sendAdr, help: POINTER TO ARRAY OF CHAR; sendAdrSize: LONGINT; PROCEDURE UpdateCurrent;  PROCEDURE GetCurrent;  PROCEDURE AddToGroupList (g: AddrBook.Group);  PROCEDURE AddToAdrList (a: AddrBook.Address);  PROCEDURE UpdateAddressList;  PROCEDURE UpdateGroupList;  PROCEDURE MouseInCheckbox (): BOOLEAN; Hack PROCEDURE SetAdr*;  PROCEDURE SetGroup*;  PROCEDURE SetOrder*;  PROCEDURE Add*;  PROCEDURE AddGroup*;  VAR gName: ARRAY 32 OF CHAR; g: AddrBook.Group; res: INTEGER; BEGIN In.Open; In.String(gName); IF ~In.Done THEN Out.String("AddrBook: Need a valid name.$"); RETURN END; AddrBook.NewGroup(gName, g); curGroup := g; AddrBook.InsertGroup(g, res); IF res # AddrBook.ok THEN Out.String("Could not insert group$"); curGroup := NIL; UpdateGroupList END END AddGroup;  PROCEDURE Edit*;  PROCEDURE EditGroup*;  PROCEDURE Delete*;  PROCEDURE GetFirstWord (f: TextFrames.Frame; y: INTEGER; VAR word: ARRAY OF CHAR);  VAR s: Texts.Scanner; loc: TextFrames.Location; r: Texts.Reader; pos: LONGINT; ch: CHAR; BEGIN TextFrames.LocateLine(f, y, loc); pos := loc.pos; REPEAT IF pos > 0 THEN Texts.OpenReader(r, f.text, pos - 1); Texts.Read(r, ch); DEC(pos) END; UNTIL (pos = 0) OR (ch = CR); Texts.OpenScanner(s, f.text, pos); Texts.Scan(s); IF (s.class = Texts.String) OR (s.class = Texts.Name) THEN COPY(s.s, word) ELSE COPY("", word) END END GetFirstWord;  PROCEDURE GetFreePos (t: Texts.Text; VAR pos: LONGINT; VAR ok: BOOLEAN);  PROCEDURE GetDestination (VAR f: TextFrames.Frame; VAR t: Texts.Text; VAR pos: LONGINT; VAR ok: BOOLEAN);  VAR v: Viewers.Viewer; fieldName: Name; BEGIN ok := TRUE; v := Oberon.FocusViewer; IF ~(v.state <= 1) & (v.dsc.next IS TextFrames.Frame) THEN f := v.dsc.next(TextFrames.Frame); t := f.text; pos := f.carloc.pos; GetFirstWord(f, f.carloc.y, fieldName); IF (fieldName = "To:") OR (fieldName = "cc:") OR (fieldName = "bcc:") THEN GetFreePos(t, pos, ok) ELSE ok := FALSE END ELSE ok := FALSE END END GetDestination;  PROCEDURE BuildSendAdr (a: AddrBook.Address);  PROCEDURE SendGroup*;  PROCEDURE SendAdr*;  PROCEDURE Insert (s: ARRAY OF CHAR);  PROCEDURE InsertAdr (a: AddrBook.Address);  PROCEDURE ToGroup*;  PROCEDURE ToAdr*;  PROCEDURE Get (ctx: Texts.Text; fieldname: ARRAY OF CHAR);  VAR e: Elems.Elem; buf: ARRAY 512 OF CHAR; res: INTEGER; BEGIN e := Elems.NamedElem(fieldname, ctx); Elems.GetString(e, "Value", buf); IF buf # "" THEN AddrBook.SetValue(curAdr, fieldname, buf, res); ASSERT(res = AddrBook.ok) END END Get;  PROCEDURE WriteBackPage2;  VAR ctx: Texts.Text; BEGIN IF curAdr = NIL THEN Out.String("AddrBook: No address selected$") ELSE ctx := Elems.CmdContext; Get(ctx, "organization"); Get(ctx, "title"); Get(ctx, "address"); Get(ctx, "zip"); Get(ctx, "city"); Get(ctx, "state"); Get(ctx, "country"); Get(ctx, "workPhone"); Get(ctx, "homePhone"); Get(ctx, "fax") END END WriteBackPage2;  PROCEDURE Page1*;  VAR ctx: Texts.Text; p: PanelElems.Panel; fnt: Fonts.Font; col: SHORTINT; BEGIN WriteBackPage2; Viewers.Close(Viewers.This(Elems.CmdFrame.X, Elems.CmdFrame.Y)); Panel.LoadPanel("AddrBook.Panel", p, fnt, col); Panel.OpenPanel(p, "AddrBook.Panel", fnt, col) END Page1;  PROCEDURE Page2*;  PROCEDURE InitPage2*;  PROCEDURE Page3*;  VAR p: PanelElems.Panel; fnt: Fonts.Font; col: SHORTINT; BEGIN WriteBackPage2; Viewers.Close(Viewers.This(Elems.CmdFrame.X, Elems.CmdFrame.Y)); Panel.LoadPanel("AddrBook3.Panel", p, fnt, col); Panel.OpenPanel(p, "AddrBook3.Panel", fnt, col) END Page3;  PROCEDURE InitPage3*;  VAR ctx: Texts.Text; e: Elems.Elem; t: Texts.Text; BEGIN IF curAdr = NIL THEN Out.String("AddrBook: No address selected$") ELSE ctx := Elems.CmdContext; e := Elems.NamedElem("notes", ctx); IF (curAdr.notes # NIL) THEN Elems.SetText(e, "ValueT", curAdr.notes) ELSE Elems.GetText(e, "ValueT", t); AddrBook.SetNotes(curAdr, t) END END END InitPage3;  PROCEDURE Store*;  VAR v: Viewers.Viewer; t: Texts.Text; ch: CHAR; R: Texts.Reader; BEGIN AddrBook.Store; v := Oberon.Par.vwr; t := v.dsc(TextFrames.Frame).text; Texts.OpenReader(R, t, t.len - 1); Texts.Read(R, ch); IF ch = "!" THEN Texts.Delete(t, t.len - 1, t.len) END END Store;  PROCEDURE Notifier (n: AddrBook.Notify);  PROCEDURE InitGUI*;  BEGIN END AddrBookGUI. System.Free AddrBookGUI * ~ AddrBook.Panel AddrBook.Store AddrBook.Add badboy "Der boese Bube" "badboy@tilt.com" AddrBook.AddGroup friends AddrBook.ListGroup friends AddrBook.Load AddrBook.ListNick System.State AddrBook ~ AddrBookGUI.Init