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
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 ANY ← NIL, mouseButton: Menus.MouseButton ← red, shift: BOOL ← FALSE, control: BOOL ← FALSE]
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];
};
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];
};