DIRECTORY Atom USING [GetPName, MakeAtom], ChoiceButtons USING [EnumTypeRef, BuildEnumTypeSelection, BuildTextPrompt, GetSelectedButton, UpdateChoiceButtons], Commander USING [CommandProc, Handle, Register], CommandTool USING [NextArgument], Containers USING [ ChildXBound, ChildYBound, Container, Create ], FS USING [ComponentPositions, ExpandName, Position], GList USING [Append], Icons USING [ IconFlavor, NewIconFromFile ], IO USING [atom, STREAM, PutRope, PutFR, RIS, RopeFromROS, rope, ROS], LoganBerryCommands USING [AttributePattern, AttributePatternRec, AttributePatterns, SyntaxError, ReadAttributePatterns, WriteAttributePatterns, PatternsToEntry, FilteredQuery], LoganBerryStub USING [AttributeType, AttributeValue, BuildIndices, Close, CompactLogs, DeleteEntry, Describe, Entry, EntryProc, Error, ErrorCode, Open, OpenDB, SchemaInfo, WriteEntry], Menus USING [AppendMenuEntry, ChangeNumberOfLines, ClickProc, CreateEntry, CreateMenu, GetNumberOfLines, Menu, MenuLine], RefTab USING [Ref, EachPairAction, Fetch, Pairs, Create, Store], Rope USING [Cat, Concat, Equal, ROPE, Substr], Rules USING [ Create, Rule ], TiogaButtons USING [CreateButton, CreateViewer, TiogaButtonProc], TypeScript USING [ Create, ChangeLooks, Reset, PutChar, PutRope ], ViewerBLT USING [ChangeNumberOfLines], ViewerClasses USING [ Viewer, ViewerClassRec, ViewerRec ], ViewerEvents USING [ EventProc, RegisterEventProc ], ViewerOps USING [AddProp, MoveViewer, PaintViewer], ViewerTools USING [GetContents, SetContents] ; LoganBerryBrowserTool: CEDAR PROGRAM IMPORTS Atom, ChoiceButtons, Commander, CommandTool, Containers, FS, GList, Icons, IO, LoganBerryCommands, LoganBerry: LoganBerryStub, Menus, RefTab, Rope, Rules, TiogaButtons, TypeScript, ViewerBLT, ViewerEvents, ViewerOps, ViewerTools = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Viewer: TYPE = ViewerClasses.Viewer; BrowserTool: TYPE = REF BrowserToolRec; BrowserToolRec: TYPE = RECORD[ outer: Containers.Container, -- main container menu: Menus.Menu, -- command menu dbFileName: ROPE, -- name of database db: LoganBerry.OpenDB, -- open database handle entryform: RefTab.Ref, -- set of "FormField"s inputArea: Viewer, -- area for type in sortButton: ChoiceButtons.EnumTypeRef, -- order of retrieval details: Containers.Container, -- container for choice buttons historyData: REF ANY, -- log of executed queries history: Viewer, -- viewer for history data inner: Viewer, -- viewer for retrieved database entries stop: BOOLEAN, -- stop database retrievals if TRUE height: CARDINAL _ 0 -- current height of tool (excluding typescript viewer) ]; FormField: TYPE = REF FormFieldRec; FormFieldRec: TYPE = RECORD [ textViewer: Viewer, patternButton: ChoiceButtons.EnumTypeRef ]; AttributePattern: TYPE = LoganBerryCommands.AttributePattern; AttributePatternRec: TYPE = LoganBerryCommands.AttributePatternRec; AttributePatterns: TYPE = LoganBerryCommands.AttributePatterns; HistoryData: TYPE = REF HistoryDataRec; HistoryDataRec: TYPE = RECORD [ tool: BrowserTool, cmd: ROPE, form: AttributePatterns, other: ROPE ]; browserIcon: Icons.IconFlavor _ tool; itemHeight: CARDINAL = 14; interItemHeight: CARDINAL = 5; ruleHeight: CARDINAL = 1; patternButtonWidth: CARDINAL = 100; patternHSpace: CARDINAL = 5; historyHeight: CARDINAL = 100; StopProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; tool.stop _ TRUE; }; BrowseProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; IF mouseButton # blue THEN TypeScript.Reset[tool.inner]; DoOp[$LBQuery, tool]; }; UpdateProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; DoOp[$LBWrite, tool]; }; DeleteProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; IF mouseButton # blue THEN TypeScript.Reset[tool.inner]; DoOp[$LBDelete, tool]; }; DetailsProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; IF tool.details.wx = 0 THEN HideViewer[tool.details] ELSE UnHideViewer[tool.details]; }; HistoryProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; IF tool.history.wx = 0 THEN { HideViewer[tool.history]; ViewerOps.MoveViewer[viewer: tool.inner, x: tool.inner.wx, y: tool.inner.wy - historyHeight, w: tool.inner.ww, h: tool.inner.wh]; tool.height _ tool.height - historyHeight; } ELSE { ViewerOps.MoveViewer[viewer: tool.inner, x: tool.inner.wx, y: tool.inner.wy + historyHeight, w: tool.inner.ww, h: tool.inner.wh]; UnHideViewer[tool.history]; tool.height _ tool.height + historyHeight; }; }; AdminOpsProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; newCount: CARDINAL _ IF Menus.GetNumberOfLines[tool.menu] = 1 THEN 2 ELSE 1; Menus.ChangeNumberOfLines[tool.menu, newCount]; ViewerBLT.ChangeNumberOfLines[tool.outer, newCount]; }; OpenProc: Menus.ClickProc = { msg: ROPE _ NIL; tool: BrowserTool _ NARROW[clientData]; tool.db _ LoganBerry.Open[dbName: tool.dbFileName ! LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}]; }; CloseProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; LoganBerry.Close[db: tool.db ! LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}]; }; BuildIndicesProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; LoganBerry.BuildIndices[db: tool.db ! LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}]; }; CompactLogsProc: Menus.ClickProc = { tool: BrowserTool _ NARROW[clientData]; LoganBerry.CompactLogs[db: tool.db ! LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}]; }; DestroyProc: ViewerEvents.EventProc = { }; MakeMainMenu: PROC [tool: BrowserTool] RETURNS [] ~ { AppendMenu: PROC[menu: Menus.Menu, name: ROPE, proc: Menus.ClickProc, line: Menus.MenuLine _ 0, guarded: BOOL _ FALSE] = { Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: name, proc: proc, clientData: tool, guarded: guarded], line: line ]; }; tool.menu _ Menus.CreateMenu[lines: 2]; AppendMenu[tool.menu, "STOP!", StopProc]; AppendMenu[tool.menu, "Browse", BrowseProc]; AppendMenu[tool.menu, "Update", UpdateProc]; AppendMenu[tool.menu, "Delete", DeleteProc, 0, TRUE]; AppendMenu[tool.menu, "History", HistoryProc]; AppendMenu[tool.menu, "Details", DetailsProc]; AppendMenu[tool.menu, "AdminOps", AdminOpsProc]; AppendMenu[tool.menu, "Open", OpenProc, 1]; AppendMenu[tool.menu, "Close", CloseProc, 1, TRUE]; AppendMenu[tool.menu, "BuildIndices", BuildIndicesProc, 1, TRUE]; AppendMenu[tool.menu, "CompactLogs", CompactLogsProc, 1, TRUE]; }; MakeEntryForm: PROC [tool: BrowserTool] RETURNS [] ~ { dbSchema: LoganBerry.SchemaInfo _ LoganBerry.Describe[db: tool.db]; tool.entryform _ RefTab.Create[]; FOR k: LIST OF LoganBerry.AttributeType _ dbSchema.keys, k.rest WHILE k # NIL DO field: FormField _ NEW[FormFieldRec]; field.patternButton _ ChoiceButtons.BuildEnumTypeSelection[viewer: tool.details, x: patternHSpace, y: tool.height, buttonNames: LIST["exact", "prefix", "wildcard", "reg. exp.", "soundex"], default: "prefix", style: flipThru, maxWidth: patternButtonWidth]; field.textViewer _ ChoiceButtons.BuildTextPrompt[viewer: tool.outer, x: field.patternButton.nextx, y: tool.height, title: Rope.Concat[Atom.GetPName[k.first], ":"]].textViewer; tool.height _ tool.height + itemHeight + interItemHeight; [] _ RefTab.Store[tool.entryform, k.first, field]; ENDLOOP; tool.inputArea _ ChoiceButtons.BuildTextPrompt[viewer: tool.outer, x: patternHSpace, y: tool.height, title: "other attributes:"].textViewer; tool.height _ tool.height + itemHeight + interItemHeight; }; MakeSortButton: PROC [tool: BrowserTool] RETURNS [] ~ { AddToSortList: RefTab.EachPairAction = { choiceList _ CONS[Atom.GetPName[NARROW[key]], choiceList]; RETURN[quit: FALSE]; }; choiceList: LIST OF ROPE _ NIL; [] _ RefTab.Pairs[x: tool.entryform, action: AddToSortList]; tool.height _ tool.height + interItemHeight; tool.sortButton _ ChoiceButtons.BuildEnumTypeSelection[viewer: tool.details, x: patternHSpace, y: tool.height, title: "Order by:", buttonNames: choiceList, default: NIL, style: menuSelection --vs. flipThru--]; tool.height _ tool.height + itemHeight + interItemHeight; }; ReadEntryForm: PROC [tool: BrowserTool] RETURNS [form: AttributePatterns, other: ROPE] ~ { NextField: RefTab.EachPairAction = { text: ROPE; label: ATOM = NARROW[key]; field: FormField = NARROW[val]; text _ ViewerTools.GetContents[field.textViewer]; IF label # form.first.attr.type AND NOT Rope.Equal[text, ""] THEN { fv: AttributePattern _ NEW[AttributePatternRec]; fv.attr.type _ label; fv.attr.value _ text; fv.ptype _ ChoiceButtons.GetSelectedButton[field.patternButton]; end.rest _ LIST[fv]; end _ end.rest; }; RETURN[quit: FALSE]; }; sort: AttributePattern _ NEW[AttributePatternRec]; end: AttributePatterns; field: FormField; sort.attr.type _ Atom.MakeAtom[ChoiceButtons.GetSelectedButton[tool.sortButton]]; field _ NARROW[RefTab.Fetch[tool.entryform, sort.attr.type].val]; sort.attr.value _ ViewerTools.GetContents[field.textViewer]; sort.ptype _ ChoiceButtons.GetSelectedButton[field.patternButton]; form _ end _ LIST[sort]; [] _ RefTab.Pairs[tool.entryform, NextField]; other _ ViewerTools.GetContents[tool.inputArea]; }; RestoreEntryForm: PROC [tool: BrowserTool, form: AttributePatterns, other: ROPE] RETURNS [] ~ { RestoreField: RefTab.EachPairAction = { label: ATOM = NARROW[key]; field: FormField = NARROW[val]; f: AttributePatterns; FOR f _ form, f.rest WHILE f # NIL DO IF f.first.attr.type = label THEN EXIT; ENDLOOP; IF f # NIL THEN { ChoiceButtons.UpdateChoiceButtons[tool.details, field.patternButton, f.first.ptype]; ViewerTools.SetContents[field.textViewer, f.first.attr.value, FALSE]; } ELSE { ViewerTools.SetContents[field.textViewer, "", FALSE]; }; RETURN[quit: FALSE]; }; ChoiceButtons.UpdateChoiceButtons[tool.details, tool.sortButton, Atom.GetPName[form.first.attr.type]]; [] _ RefTab.Pairs[tool.entryform, RestoreField]; ViewerTools.SetContents[tool.inputArea, other, FALSE]; ViewerOps.PaintViewer[viewer: tool.outer, hint: all]; }; AddToHistory: PROC [tool: BrowserTool, cmd: ROPE, form: AttributePatterns, other: ROPE] RETURNS [] ~ { data: HistoryData = NEW[HistoryDataRec _ [tool, cmd, form, other]]; line: STREAM _ IO.ROS[]; IO.PutRope[line, cmd]; IO.PutRope[line, " "]; LoganBerryCommands.WriteAttributePatterns[line, form]; IO.PutRope[line, " "]; IO.PutRope[line, other]; [] _ TiogaButtons.CreateButton[viewer: tool.history, rope: IO.RopeFromROS[line], proc: HistoryButtonProc, clientData: data]; }; HistoryButtonProc: TiogaButtons.TiogaButtonProc = { data: HistoryData _ NARROW[clientData]; RestoreEntryForm[data.tool, data.form, data.other]; }; MakeBrowserTool: Commander.CommandProc = { tool: BrowserTool _ NEW[BrowserToolRec]; shortname: ROPE; cp: FS.ComponentPositions; errormsg: ROPE _ NIL; tool.dbFileName _ CommandTool.NextArgument[cmd]; IF tool.dbFileName = NIL THEN RETURN[msg: "No database name given.\n"]; [tool.dbFileName, cp] _ FS.ExpandName[tool.dbFileName]; tool.db _ LoganBerry.Open[dbName: tool.dbFileName ! LoganBerry.Error => {errormsg _ Rope.Cat["Error: ", Atom.GetPName[ec], "  ", explanation]; CONTINUE}]; IF errormsg # NIL THEN RETURN[msg: errormsg]; shortname _ Rope.Substr[base: tool.dbFileName, start: cp.base.start, len: cp.base.length]; MakeMainMenu[tool]; tool.outer _ Containers.Create[info: [ name: Rope.Concat["LoganBerry Browser: ", tool.dbFileName], icon: browserIcon, label: shortname, iconic: FALSE, column: left, menu: tool.menu, scrollable: FALSE]]; Menus.ChangeNumberOfLines[tool.menu, 1]; ViewerBLT.ChangeNumberOfLines[tool.outer, 1]; ViewerOps.AddProp[viewer: tool.outer, prop: $BrowserTool, val: tool]; [] _ ViewerEvents.RegisterEventProc[proc: DestroyProc, event: destroy, filter: tool.outer]; tool.details _ Containers.Create[info: [ parent: tool.outer, ww: 1000, wh: 9999, scrollable: FALSE, border: FALSE]]; Containers.ChildYBound[container: tool.outer, child: tool.details]; tool.height _ interItemHeight; MakeEntryForm[tool]; MakeSortButton[tool]; DividingLine[tool]; tool.history _ TiogaButtons.CreateViewer[info: [ parent: tool.outer, wy: tool.height, ww: 1000, wh: historyHeight, border: TRUE]]; HideViewer[tool.history]; tool.inner _ TypeScript.Create[info: [ name: "LoganBerry Browser output", parent: tool.outer, wx: 0, wy: tool.height, ww: 9999, wh: 9999, border: FALSE]]; Containers.ChildXBound[tool.outer, tool.inner]; -- constrain rule to be width of parent Containers.ChildYBound[tool.outer, tool.inner]; -- constrain rule to be height of parent }; DividingLine: PROC [tool: BrowserTool] RETURNS [] ~ { rule: Rules.Rule; rule _ Rules.Create[info: [parent: tool.outer, wx: 0, wy: tool.height, ww: 9999, wh: ruleHeight]]; Containers.ChildXBound[tool.outer, rule]; -- constrain rule to be width of parent tool.height _ tool.height + ruleHeight; }; HideViewer: PROC [v: Viewer] RETURNS [] ~ { ViewerOps.MoveViewer[viewer: v, x: 2000, y: v.wy, w: v.ww, h: v.wh]; }; UnHideViewer: PROC [v: Viewer] RETURNS [] ~ { ViewerOps.MoveViewer[viewer: v, x: 0, y: v.wy, w: v.ww, h: v.wh]; }; DoOp: PROC [cmd: ATOM, tool: BrowserTool] RETURNS [] ~ { ENABLE { LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}; LoganBerryCommands.SyntaxError => {ReportLBError[$MalformedInput, explanation, tool.inner]; CONTINUE} }; PutEntry: LoganBerry.EntryProc = { FOR e: LoganBerry.Entry _ entry, e.rest UNTIL e = NIL DO TypeScript.ChangeLooks[tool.inner, 'b]; -- print atribute type in bold TypeScript.PutRope[tool.inner, Atom.GetPName[e.first.type]]; TypeScript.ChangeLooks[tool.inner, ' ]; -- restore normal looks TypeScript.PutRope[tool.inner, ": "]; TypeScript.PutRope[tool.inner, e.first.value]; TypeScript.PutChar[tool.inner, '\n]; ENDLOOP; TypeScript.PutChar[tool.inner, '\n]; RETURN[NOT tool.stop]; }; DeleteEntry: LoganBerry.EntryProc = { value: LoganBerry.AttributeValue _ GetAttributeValue[entry, primaryKey]; LoganBerry.DeleteEntry[db: tool.db, key: primaryKey, value: value]; TypeScript.PutRope[tool.inner, IO.PutFR["Deleted %g: %g\n", IO.atom[primaryKey], IO.rope[value]]]; RETURN[NOT tool.stop]; }; other: ROPE; all, form, otherPatterns: AttributePatterns; primaryKey: LoganBerry.AttributeType; entry: LoganBerry.Entry; tool.stop _ FALSE; [form, other] _ ReadEntryForm[tool]; otherPatterns _ LoganBerryCommands.ReadAttributePatterns[IO.RIS[other]]; all _ NARROW[GList.Append[form, otherPatterns]]; AddToHistory[tool, Atom.GetPName[cmd], form, other]; SELECT cmd FROM $LBQuery => { LoganBerryCommands.FilteredQuery[db: tool.db, patterns: all, proc: PutEntry]; }; $LBWrite => { entry _ LoganBerryCommands.PatternsToEntry[all]; LoganBerry.WriteEntry[db: tool.db, entry: entry]; }; $LBDelete => { primaryKey _ LoganBerry.Describe[db: tool.db].info.keys.first; LoganBerryCommands.FilteredQuery[db: tool.db, patterns: all, proc: DeleteEntry]; }; ENDCASE => NULL; }; GetAttributeValue: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType] RETURNS [LoganBerry.AttributeValue] ~ { FOR e: LoganBerry.Entry _ entry, e.rest WHILE e # NIL DO IF e.first.type = type THEN RETURN[e.first.value]; ENDLOOP; RETURN[NIL]; }; ReportLBError: PROC [ec: LoganBerry.ErrorCode, explanation: ROPE, v: Viewer] RETURNS [] ~ { TypeScript.Reset[v]; TypeScript.PutRope[v, Rope.Cat["Error: ", Atom.GetPName[ec], "  ", explanation]]; }; browserIcon _ Icons.NewIconFromFile[file: "LoganBerry.icons", n: 0 ! ANY => CONTINUE]; Commander.Register[key: "LoganBerryBrowser", proc: MakeBrowserTool, doc: "Create a LoganBerry browser." ]; Commander.Register[key: "LBBrowser", proc: MakeBrowserTool, doc: "Create a LoganBerry browser." ]; END. ÆLoganBerryBrowserTool.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Doug Terry, October 22, 1986 7:35:32 pm PDT A tool for interactively browsing LoganBerry databases. Types Viewer layout Command menu [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] [viewer: ViewerClasses.Viewer, event: ViewerEvents.ViewerEvent, before: BOOL] RETURNS [abort: BOOL _ FALSE] -- Does nothing at the moment tool: BrowserTool _ NARROW[ViewerOps.FetchProp[viewer: viewer, prop: $BrowserTool]]; LoganBerry.Close[db: tool.db ! LoganBerry.Error => {ReportLBError[ec, explanation, tool.inner]; CONTINUE}]; first line second line Entry form [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] First field in returned data is the "order by" field. [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] History viewer The History viewer contains lines representing commands that could have been typed to a commandTool to achieve the same result as the operations invoked via the browser tool. Each of these lines is a TiogaButton that, when buttoned, causes the entry form to be filled in with the various values. [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] Left mouse button => restore the entry form; Middle => restore form and re-execute (not currently implemented). Commander commands [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] open database find short database name create command section create input form Containers.ChildXBound[container: tool.outer, child: tool.details]; create history viewer Containers.ChildXBound[tool.outer, tool.history]; -- constrain rule to be width of parent create output browser Viewer stuff Database operations [entry: LoganBerry.Entry] RETURNS [continue: BOOL] [entry: LoganBerry.Entry] RETURNS [continue: BOOL] Registration, Initialization Doug Terry, November 27, 1985 3:22:06 pm PST taken from WPBrowserToolImpl.mesa changes to: DIRECTORY, LoganBerryBrowserTool, browserIcon, db, dbFileName, NamedFilter, Commander, END, BrowseProc, DetailsProc, HistoryProc, MakeMainMenu, BrowserToolRec, MakeBrowserTool, itemHeight, interItemHeight, ruleHeight, patternButtonWidth, patternHSpace, historyHeight, AppendMenu (local of MakeMainMenu), MakeEntryForm, AppendEntry (local of MakeEntryForm), MakeSortButton, DividingLine, FormFieldRec, AddToSortList (local of MakeSortButton), StopProc, BrowseProc, DoQuery, PutEntry (local of DoQuery), NewFilter (local of DoQuery), ROPE, STREAM Doug Terry, November 27, 1985 4:05:43 pm PST changes to: PutEntry (local of DoQuery), MakeSortButton, DIRECTORY Doug Terry, November 27, 1985 5:56:01 pm PST changes to: MakeSortButton, AddToSortList (local of MakeSortButton), DIRECTORY, DestroyProc, MakeMainMenu, MakeBrowserTool, browserIcon, Commander, LoganBerryBrowserTool Doug Terry, November 27, 1985 6:18:58 pm PST changes to: MakeBrowserTool Doug Terry, January 23, 1986 8:41:38 pm PST changes to: DestroyProc, MakeBrowserTool Doug Terry, January 31, 1986 2:46:52 pm PST changes to: AdminOpsProc, OpenProc, CloseProc, BuildIndiciesProc, CompactLogsProc, DestroyProc, MakeMainMenu, DIRECTORY, AppendMenu (local of MakeMainMenu), MakeBrowserTool, LoganBerryBrowserTool Doug Terry, January 31, 1986 2:53:26 pm PST changes to: AdminOpsProc, MakeMainMenu, MakeBrowserTool, AppendMenu (local of MakeMainMenu) Doug Terry, January 31, 1986 5:21:25 pm PST changes to: AppendMenu (local of MakeMainMenu), MakeMainMenu, MakeBrowserTool, BrowseProc, DIRECTORY Doug Terry, March 5, 1986 6:18:08 pm PST Now calls LoganBerry.Describe to obtain the list of available indices and catches LoganBerry.Errors. changes to: DIRECTORY, MakeEntryForm, OpenProc, CloseProc, BuildIndiciesProc, CompactLogsProc, DestroyProc, MakeBrowserTool, PutEntry (local of DoQuery) Doug Terry, April 24, 1986 9:47:20 am PST Changed to use LoganBerryStub. changes to: DIRECTORY, LoganBerryBrowserTool, BrowserToolRec, OpenProc, MakeBrowserTool, DoQuery, ReportLBError Doug Terry, April 24, 1986 9:51:16 am PST changes to: DIRECTORY, LoganBerryBrowserTool, BrowserToolRec, OpenProc, MakeBrowserTool, DoQuery, ReportLBError Doug Terry, July 1, 1986 2:16:21 pm PDT changes to: AddToHistory, RestoreFromHistory, HistoryButtonProc Doug Terry, July 1, 1986 6:00:40 pm PDT Added History facility. changes to: FormFieldRec, FormValue, FormValueRec, FormContents, MakeSortButton, ReadEntryForm, NextField (local of ReadEntryForm), AddToHistory, AddToLine (local of AddToHistory), RestoreFromHistory, HistoryButtonProc, DoQuery, BrowseProc, RestoreEntryForm, PutEntry, GetAttributeValue, DIRECTORY, LoganBerryBrowserTool, ROPE, STREAM, HistoryData, HistoryDataRec, RestoreField (local of RestoreEntryForm), HistoryProc, DetailsProc, UnHideViewer, HideViewer, MakeBrowserTool Doug Terry, July 1, 1986 9:04:42 pm PDT changes to: BuildIndicesProc, MakeMainMenu Doug Terry, October 16, 1986 5:58:19 pm PDT changes to: DoQuery Doug Terry, October 22, 1986 4:10:21 pm PDT Changed to use LoganBerryCommands and provide a similar model of operation; added support for updates and deletes. changes to: BrowserToolRec, UpdateProc, DeleteProc, DetailsProc, MakeMainMenu, MakeInputArea, MakeSortButton, MakeBrowserTool, FormContents, BrowseProc, AddToHistory, HistoryButtonProc, NextField (local of ReadEntryForm), RestoreField (local of RestoreEntryForm), RestoreEntryForm, DoQuery, AttributePattern, AttributePatternRec, HistoryDataRec, MakeEntryForm, ReadEntryForm, DoQuery, DIRECTORY, LoganBerryBrowserTool, PutEntry (local of DoOp), DeleteEntry (local of DoOp) Doug Terry, October 22, 1986 7:35:32 pm PDT changes to: Commander, Commander Êi˜– "Cedar" stylešœ™Icode– "Cedar" stylešœ Ïmœ1™ -- [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN]˜(Jš¢:™:Jšœ žœžœ˜:Jšžœžœ˜J˜—Jš œ žœžœžœžœ˜J–2[x: RefTab.Ref, action: RefTab.EachPairAction]šœ<˜ -- [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN]š£ œ˜$Kš¢:™:Jšœžœ˜ Jšœžœžœ˜Jšœžœ˜Kšœ1˜1šžœžœžœžœ˜CKšœžœ˜0Jšœ˜Jšœ˜Jšœ@˜@Jšœ žœ˜J˜J˜—Kšžœžœ˜K˜—Jšœžœ˜2Jšœ˜K˜JšœQ˜QKšœžœ3˜AKšœ<˜ -- [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN]š£ œ˜'Kš¢:™:Jšœžœžœ˜Jšœžœ˜Jšœ˜šžœžœžœž˜%Kšžœžœžœ˜'Kšžœ˜—šžœžœžœ˜KšœT˜TJšœ>žœ˜EJšœ˜—šžœ˜Jšœ.žœ˜5J˜—Kšžœžœ˜K˜—Kšœf˜fJšœ0˜0Jšœ/žœ˜6Jšœ5˜5K˜——J™™J™J™®J™xJ™š £ œžœžœ"žœžœ˜fKšœžœ,˜CKšœžœžœžœ˜Kšœ˜Kšœ˜Kšœ6˜6Kšœ˜Kšœ˜Kšœ|˜|K˜—K˜–‚ -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE]š£œ"˜3Kš¢~™~K™oKšœžœ ˜'Kšœ3˜3K˜K˜——™K˜šÐbnœ˜*Kš¢H™HKšœžœ˜(Kšœ žœ˜Kšœžœ˜Kšœ žœžœ˜Kšœ0˜0šžœžœž˜Kšžœ#˜)—Kšœžœ˜7Kšœ ™ Kšœžœ˜›šžœ žœž˜Kšžœ˜—K™K–9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]šœZ˜ZKšœ™K˜šœ&˜&Kšœ;˜;Kšœ˜Kšœ˜Kšœžœ˜K˜ Kšœ˜Kšœ žœ˜—Jšœ(˜(J˜-K–>[viewer: ViewerClasses.Viewer, prop: ATOM, val: REF ANY]šœE˜EK–s[proc: ViewerEvents.EventProc, event: ViewerEvents.ViewerEvent, filter: REF ANY _ NIL, before: BOOL _ TRUE]šœ[˜[Kšœ™šœ(˜(Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ žœ˜Jšœžœ˜—J–B[container: Containers.Container, child: ViewerClasses.Viewer]šœC™CJ–B[container: Containers.Container, child: ViewerClasses.Viewer]šœC˜CJšœ˜Jšœ˜Jšœ˜Kšœ˜Kšœ™šœ0˜0Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœžœ˜—Kšœ3 '™ZJšœ˜Kšœ™šœ&˜&Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœžœ˜—Kšœ1 '˜XKšœ1 (˜YK˜—K˜—J™ ™š£ œžœžœ˜5K˜Jšœb˜bKšœ+ '˜RJšœ'˜'K˜K˜—š£ œžœ žœ˜+K–n[viewer: ViewerClasses.Viewer, x: INTEGER, y: INTEGER, w: INTEGER, h: INTEGER, paint: BOOL _ TRUE]šœD˜DK˜—K˜š£ œžœ žœ˜-KšœA˜AK˜—J™—™K˜š£œžœžœžœ˜8šžœ˜ Jšœ@ž œ˜LJšœ[ž œ˜eJšœ˜—š¡œ˜"Kš¢2™2šžœ%žœžœž˜8Kšœ) ˜GK˜˜>JšœP˜PK˜—Kšžœžœ˜—K˜—K˜š£œžœ;žœ ˜yšžœ%žœžœž˜8šžœž˜Kšžœ˜—Kšžœ˜—Kšžœžœ˜ K˜—K˜š£ œžœ)žœ žœ˜[Jšœ˜JšœR˜RK˜K˜——™J˜J–[file: ROPE, n: CARDINAL]šœEžœž œ˜VšœC˜CJšœ&˜&—šœ;˜;Jšœ&˜&——J˜Jšžœ˜™,K™!Kš œ Ïr–œ¥œ¥;œ¥)œ¥ œ¥™¬—™,Kšœ ¥œ¥™B—™,Kšœ ¥œ¥f™©—™,Kšœ ¥™—™+Kšœ ¥™(—™+Kšœ ¥wœ¥(™Ã—™+Kšœ ¥7œ™[—™+Kšœ ¥ œ¥6™d—™(K™dKšœ ¥yœ™˜—™)K™Kšœ ¥c™o—™)Kšœ ¥c™o—™'Kšœ ¥3™?—™'K™Kšœ ¥]œ¥œ¥Æœ¥E™Ú—™'Kšœ ¥™*—™+Kšœ ¥™—™+K™rKš œ ¥·œ¥œ¥¥œ¥ œ™Ø—K™K™K™K™K™K™™+Kšœ ¥™ —K™—…—<Þu