WPBrowserToolImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Doug Terry, June 18, 1987 2:09:45 pm PDT
DIRECTORY
Commander USING [CommandProc, Handle, Register],
FS USING [ComponentPositions, ExpandName],
Icons USING [ IconFlavor, NewIconFromFile ],
IO,
LoganBerry USING [AttributeType, AttributeValue, Entry, Error, ErrorCode, Open, OpenDB ],
LoganBerryBrowser USING [CreateTool, DBInfo, DBInfoRec, DetailsProc, HistoryProc, ReadEntryForm, ReportFeedback, Tool, ToolBody],
LoganQuery USING [AbortQuery, AttributePatterns, ComplexCursor, EnableAborts, EndGenerate, MergeEntries, NextEntry, QueryEntries, QueryPlan, SyntaxError],
Menus USING [AppendMenuEntry, ClickProc, CreateEntry, CreateMenu, Menu, MenuProc ],
Rope USING [Cat, Concat, ROPE],
TiogaButtons USING [CreateButton, CreateButtonForEachNode, CreateViewer],
UserProfile USING [ Token ],
ViewerClasses USING [ Viewer, ViewerClassRec, ViewerRec ],
ViewerTools USING [GetTiogaContents, SetTiogaContents, TiogaContents],
WPDirectory;
WPBrowserToolImpl: CEDAR PROGRAM     
IMPORTS Commander, FS, Icons, IO, LoganBerry, LoganBerryBrowser, LoganQuery, Menus, Rope, TiogaButtons, UserProfile, ViewerTools, WPDirectory
= BEGIN
Types
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Viewer: TYPE = ViewerClasses.Viewer;
Variables
browserIcon: Icons.IconFlavor ← tool;
phonebookIcon: Icons.IconFlavor ← tool;
tName: LoganBerry.AttributeType = $name;
tRname: LoganBerry.AttributeType = $rname;
tOffice: LoganBerry.AttributeType = $officenumber;
tHome: LoganBerry.AttributeType = $homenumber;
tRemarks: LoganBerry.AttributeType = $remarks;
Command menu
BrowseProc: Menus.ClickProc = {
[parent: REF ANY, clientData: REF ANY ← NIL, mouseButton: Menus.MouseButton ← red, shift: BOOL ← FALSE, control: BOOL ← FALSE]
ENABLE LoganBerry.Error => {ReportLBError[ec, explanation, NARROW[clientData]]; CONTINUE};
tool: LoganBerryBrowser.Tool ← NARROW[clientData];
form: LoganQuery.AttributePatterns;
base: LoganBerry.AttributeType;
newcursor: LoganQuery.ComplexCursor;
plan: LoganQuery.QueryPlan;
entry: LoganBerry.Entry;
IF mouseButton # blue THEN
tool.inner.class.init[tool.inner];
set up query
[form, base] ← LoganBerryBrowser.ReadEntryForm[tool ! LoganQuery.SyntaxError => {ReportLBError[$MalformedInput, explanation, tool]; CONTINUE}];
tool.cursor.class ← NIL;
FOR d: LIST OF LoganBerryBrowser.DBInfo ← tool.databases, d.rest WHILE d#NIL DO
IF d.first.selected THEN {
[newcursor, plan] ← LoganQuery.QueryEntries[db: d.first.db, patterns: form, baseIndex: base];
IF tool.cursor.class=NIL
THEN tool.cursor ← newcursor
ELSE tool.cursor ← LoganQuery.MergeEntries[input1: newcursor, input2: tool.cursor, atype: plan.first.attr.type];
};
ENDLOOP;
IF tool.cursor.class=NIL THEN {
ReportLBError[$NoOp, "No database selected", tool];
RETURN;
};
tool.cursor ← LoganQuery.EnableAborts[tool.cursor];
LoganBerryBrowser.ReportFeedback[plan, tool];
retrieve entries and build directory browser
entry ← LoganQuery.NextEntry[tool.cursor];
WHILE entry # NIL DO
AddDirectoryEntry[entry, tool.inner];
entry ← LoganQuery.NextEntry[tool.cursor];
ENDLOOP;
LoganQuery.EndGenerate[tool.cursor];
};
AddDirectoryEntry: PROC [entry: LoganBerry.Entry, v: Viewer] ~ {
tdirEntry: Rope.ROPE;
val: Rope.ROPE;
tdirEntry ← GetAttributeValue[entry, tName];
val ← GetAttributeValue[entry, tRname];
IF val # NIL THEN
tdirEntry ← Rope.Cat[tdirEntry, " <", val, ">"];
val ← GetAttributeValue[entry, tOffice];
tdirEntry ← Rope.Cat[tdirEntry, "\t", IF val = NIL THEN "*" ELSE val];
val ← GetAttributeValue[entry, tHome];
tdirEntry ← Rope.Cat[tdirEntry, "\t", IF val = NIL THEN "*" ELSE val];
val ← GetAttributeValue[entry, tRemarks];
IF val # NIL THEN
tdirEntry ← Rope.Cat[tdirEntry, "\t", val];
[] ← TiogaButtons.CreateButton[viewer: v, rope: tdirEntry, format: "table1", proc: WPDirectory.DirectoryButtonNotifier, fork: FALSE];
};
ReportLBError: PROC [ec: LoganBerry.ErrorCode, explanation: ROPE, tool: LoganBerryBrowser.Tool] RETURNS [] ~ {
[] ← TiogaButtons.CreateButton[viewer: tool.inner, rope: IO.PutFR["ERROR: %g - %g", IO.atom[ec], IO.rope[explanation]]];
};
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];
};
PhoneBookProc: Menus.ClickProc = {
[parent: REF ANY, clientData: REF ANYNIL, mouseButton: Menus.MouseButton ← red, shift: BOOLFALSE, control: BOOLFALSE]
tool: LoganBerryBrowser.Tool ← NARROW[clientData];
phonebookV: Viewer;
contents: ViewerTools.TiogaContents;
phonebookV ← TiogaButtons.CreateViewer[info: [name: tool.inner.name, label: tool.inner.label, iconic: TRUE, icon: phonebookIcon, column: left, menu: NIL]];
contents ← ViewerTools.GetTiogaContents[tool.inner];
ViewerTools.SetTiogaContents[phonebookV, contents];
TiogaButtons.CreateButtonForEachNode[viewer: phonebookV, proc: WPDirectory.DirectoryButtonNotifier];
};
StopProc: PUBLIC Menus.ClickProc = TRUSTED {
[parent: REF ANY, clientData: REF ANY ← NIL, mouseButton: Menus.MouseButton ← red, shift: BOOL ← FALSE, control: BOOL ← FALSE]
tool: LoganBerryBrowser.Tool ← NARROW[clientData];
LoganQuery.AbortQuery[tool.cursor];
};
MakeMainMenu: PROC [tool: LoganBerryBrowser.Tool] RETURNS [menu: Menus.Menu] ~ {
AppendMenu: PROC[menu: Menus.Menu, name: ROPE, proc: Menus.MenuProc] = {
Menus.AppendMenuEntry[ 
menu: menu,
entry: Menus.CreateEntry[name: name, proc: proc, clientData: tool]
];
};
menu ← Menus.CreateMenu[];
AppendMenu[menu, "STOP!", StopProc];
AppendMenu[menu, "Browse", BrowseProc];
AppendMenu[menu, "PhoneBook", PhoneBookProc];
AppendMenu[menu, "AddEntry", AddEntryProc];
AppendMenu[menu, "DeleteEntry", DeleteEntryProc];
AppendMenu[menu, "Details", LoganBerryBrowser.DetailsProc];
AppendMenu[menu, "History", LoganBerryBrowser.HistoryProc];
};
Main command
MakeBrowserTool: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
ENABLE LoganBerry.Error => {
IO.PutF[cmd.err, "Error: %g - %g\n", IO.atom[ec], IO.rope[explanation]];
GOTO End;
};
tool: LoganBerryBrowser.Tool ← NEW[LoganBerryBrowser.ToolBody];
tool.name ← "Whitepages Browser";
tool.icon ← browserIcon;
tool.menu ← MakeMainMenu[tool];
tool.innerFlavor ← $TiogaButtons;
tool.databases ← GetDatabases[cmd.commandLine];
IF tool.databases = NIL THEN RETURN[result: NIL, msg: "No database name supplied.\n"];
LoganBerryBrowser.CreateTool[tool: tool];
EXITS
End => RETURN;
};
GetDatabases: PROC [directoryFiles: Rope.ROPE] RETURNS [dbs: LIST OF LoganBerryBrowser.DBInfo] ~ {
Tries to read database names from stream, if empty then try user profile entries.
s: STREAM;
dbname: ROPE;
dbs ← NIL;
IF directoryFiles#NIL THEN {
s ← IO.RIS[directoryFiles];
DO
dbname ← IO.GetTokenRope[s, IO.IDProc ! IO.EndOfStream => EXIT].token;
dbs ← CONS[NEW[LoganBerryBrowser.DBInfoRec ← [db: Open[dbname]]], dbs];
ENDLOOP;
};
IF dbs = NIL THEN {
directoryFiles ← UserProfile.Token[key: "Finch.WhitePagesDB"];
IF directoryFiles=NIL THEN RETURN[NIL];
s ← IO.RIS[directoryFiles];
DO
dbname ← IO.GetTokenRope[s, IO.IDProc ! IO.EndOfStream => EXIT].token;
dbs ← CONS[NEW[LoganBerryBrowser.DBInfoRec ← [db: Open[dbname]]], dbs];
ENDLOOP;
};
};
Open: PROC [dbname: ROPE] RETURNS [db: LoganBerry.OpenDB] ~ {
Opens the database with the given name; if the name is missing an explicit extension and version then ".df!H" is assumed.
cp: FS.ComponentPositions;
fullDBName: ROPE;
[fullDBName, cp] ← FS.ExpandName[dbname];
IF cp.ext.length = 0 AND cp.ver.length = 0 THEN
fullDBName ← Rope.Concat[fullDBName, ".df"];
db ← LoganBerry.Open[dbName: fullDBName];
};
Registration, Initialization
browserIcon ← Icons.NewIconFromFile["WPBrowser.icons", 14!ANY=>CONTINUE];
phonebookIcon ← Icons.NewIconFromFile["WPBrowser.icons", 15!ANY=>CONTINUE];
Commander.Register[key: "WPBrowser", proc: MakeBrowserTool,
doc: "Create a whitepages browser." ];
END.