-- NutViewerImpl.mesa
-- Last edit by
-- Maxwell on September 30, 1982 10:35 am
-- Willie-Sue, January 21, 1983 8:50 am
-- Cattell, August 9, 1983 10:41 am

-- Last Edited by: Donahue, August 1, 1983 4:04 pm
DIRECTORY
Atom,
FS USING [Error],
DB,
DBEnvironment,
DBNames,
Icons USING [IconFlavor, NewIconFromFile],
DBIcons,
NutOps,
NutViewer,
Rope USING [Cat, Equal, Length, ROPE, SkipTo],
ViewerOps,
VirtualDesktops,
Whiteboard USING[ToolInfo, instructions];

NutViewerImpl: CEDAR PROGRAM
IMPORTS
Atom, FS, DB, DBEnvironment, DBNames, Icons, DBIcons, NutOps, Rope, ViewerOps, VirtualDesktops, Whiteboard
EXPORTS NutViewer =

BEGIN OPEN DB, NutViewer;

ROPE: TYPE = Rope.ROPE;


-- ****************** setting/getting icons for entities ****************

-- works for Entities or Domains

acorn: Icons.IconFlavor← NewIcon["Nut.icons", 3];

SetIcon: PUBLIC PROCEDURE[e: Entity, iconFile: ROPE, fileIndex: CARDINAL] =
BEGIN
name: ROPE = IF DB.Eq[DomainOf[e], DomainDomain] THEN DB.NameOf[e]
     ELSE DBNames.EntityToName[e, DB.SegmentOf[e]];
IF DBIcons.IsRegistered[name].file = NIL THEN
  DBIcons.RegisterIcon[ name, iconFile, fileIndex ]
END;

GetIcon: PUBLIC PROC[e: Entity, seg: Segment ← NIL] RETURNS[icon: Icons.IconFlavor] =
BEGIN
IF e = NIL THEN RETURN[acorn];
{ d: Domain = DomainOf[e];
segment: DB.Segment = IF NutOps.IsSystemDomain[d] THEN seg ELSE DB.SegmentOf[e];
dName: ROPE ← NameOf[d];
isTool: BOOL = Rope.Equal[dName, ToolViewer];
eName: ROPE = IF isTool THEN NameOf[e] ELSE DBNames.EntityToName[e, segment];
IF dName.Equal["TextViewer"] THEN RETURN[document];
icon ← unInit;
icon ← DBIcons.GetIcon[eName, IF isTool THEN tool ELSE unInit
   ! DBIcons.Failed => CONTINUE];
IF icon # unInit THEN RETURN;
IF dName.Equal["Domain"] THEN dName← NameOf[e]; -- Use domain icon for domain entity
icon ← DBIcons.GetIcon[dName, acorn] }
END;

GetIconFromName: PUBLIC PROC[ name: ROPE ] RETURNS[icon: Icons.IconFlavor] = {
domain, entity: ROPE;
isTool: BOOLEAN;
[, domain, entity] ← DBNames.DecomposeName[name];
IF Rope.Equal[domain, "TextViewer"] THEN RETURN[document];
isTool ← Rope.Equal[domain, ToolViewer];
IF isTool THEN name ← entity;
icon ← DBIcons.GetIcon[name, IF isTool THEN tool ELSE unInit
   ! DBIcons.Failed => { icon ← unInit; CONTINUE } ];
IF icon # unInit THEN RETURN;
icon ← DBIcons.GetIcon[domain, acorn] };

icons: IconList;
IconList: TYPE = LIST OF RECORD[file: ROPE, index: INTEGER, icon: Icons.IconFlavor];

NewIcon: PUBLIC PROC[file: ROPE, index: INTEGER] RETURNS[icon: Icons.IconFlavor ← acorn] =
BEGIN
ENABLE FS.Error =>
TRUSTED {IF error.group = bug OR error.group = environment THEN REJECT
     ELSE GOTO notFound};
FOR list: IconList ← icons, list.rest WHILE list # NIL DO
IF list.first.index # index THEN LOOP;
IF ~Rope.Equal[list.first.file, file] THEN LOOP;
RETURN[list.first.icon];
ENDLOOP;
icon ← Icons.NewIconFromFile[file, index];
icons ← CONS[[file, index, icon], icons];
EXITS
notFound => -- if not given full path name, then try [Indigo]<Squirrel>Icons>file
BEGIN ENABLE FS.Error =>
TRUSTED {IF error.group = bug OR error.group = environment THEN REJECT
     ELSE CONTINUE};
IF file.SkipTo[pos: 0, skip: "[/"] # file.Length[] THEN RETURN; --given full path, give up
icon ← Icons.NewIconFromFile[Rope.Cat["[Indigo]<Squirrel>Icons>", file], index];
icons ← CONS[[file, index, icon], icons];
END;
END;


-- ****************** converting from viewer to entity ****************

ToolViewer: PUBLIC Rope.ROPE ← "ToolViewer";

TextViewer: PUBLIC Rope.ROPE ← "TextViewer";

FindViewerForEntity: PUBLIC PROC[e: DB.Entity, segment: DB.Segment ← NIL]
     RETURNS[viewer: Viewer] =
BEGIN
domain: Domain = DomainOf[e];
dName: ROPE = NameOf[domain];
isText: BOOLEAN = Rope.Equal[dName, TextViewer];
isTool: BOOLEAN = Rope.Equal[dName, ToolViewer];
name: ROPE = NameOf[e];
seg: DB.Segment = IF NutOps.IsSystemDomain[domain] THEN segment ELSE SegmentOf[e];
entity: ROPE = DBNames.EntityToName[e, seg];
FindEntity: ViewerOps.EnumProc = {
IF v.destroyed THEN RETURN[TRUE];
{ eHandle: Entity = V2E[ ViewerOps.FetchProp[ v, $EntityHandle ] ];
IF eHandle#NIL AND DB.Eq[eHandle, e] THEN { viewer ← v; RETURN[FALSE] };
IF isText AND v.class.flavor = $Text AND v.name = name
THEN { viewer ← v; RETURN[FALSE] };
IF isTool AND v.name = name THEN { viewer ← v; RETURN[FALSE] };
RETURN[ TRUE ] } };
viewer ← NIL;
  VirtualDesktops.EnumerateViewers[FindEntity];
END;

-- this procedure will return either the entity or the entity name for the viewer if the
-- segment in which the entity would live is not currently open
-- the name returned may be NIL if none of the heuristics work or no $Squirrel segment
-- is open
ConvertViewerToEntity: PUBLIC PROC[v: Viewer, create: BOOLTRUE] RETURNS[e: Entity, name: ROPE] =
BEGIN
name ← NARROW[ViewerOps.FetchProp[v, $Entity]];
IF name # NIL THEN { e ← DBNames.NameToEntity[name]; RETURN };
IF e # NIL THEN RETURN;
-- make a guess at the entity type
{ squirrelName: ROPE = DB.GetSegmentInfo[$Squirrel].filePath;
IF squirrelName = NIL THEN RETURN;
-- if there is a ToolInfo record, then it must be a toolviewer
{toolInfo: REF Whiteboard.ToolInfo = NARROW[ViewerOps.FetchProp[v, $ToolInfo]];
IF toolInfo # NIL THEN
{toolDomain: Domain;
toolDomain ← DeclareDomain[ToolViewer, $Squirrel !
     DB.Error => {toolDomain ← NIL; CONTINUE} ];
IF toolDomain # NIL THEN
{ name ← DBNames.MakeName[$Squirrel, toolDomain, Atom.GetPName[toolInfo.tool]];
e ← DeclareEntity[toolDomain, v.name, IF create THEN NewOrOld ELSE OldOnly];
IF e # NIL AND Rope.Equal[V2S[GetP[e, Whiteboard.instructions]], ""]
THEN [] ← SetP[e, Whiteboard.instructions, S2V[toolInfo.commandLine]] };
RETURN } };
IF v.icon = document OR v.icon = dirtyDocument THEN
{ textDomain: Domain;
textDomain ← DeclareDomain[TextViewer, $Squirrel !
          DB.Error => {textDomain ← NIL; CONTINUE}];
IF textDomain # NIL THEN
{ name ← DBNames.MakeName[$Squirrel, textDomain, v.name];
e ← DeclareEntity[textDomain, v.name, IF create THEN NewOrOld ELSE OldOnly] } } }
END;

GetNutInfo: PUBLIC PROC[v: Viewer]
RETURNS[segment: Segment, domain: Domain, entity: ROPE] = {
-- Returns segment, domain, and entity name (if any) using the $Segment, $DomainName,
-- and $EntityName properties set up by CreateNut.
entity← NARROW[ViewerOps.FetchProp[v, $EntityName]];
segment← NARROW[ViewerOps.FetchProp[v, $Segment]];
domain← DB.DeclareDomain[V2S[ ViewerOps.FetchProp[v, $DomainName]], segment, OldOnly !
DBEnvironment.Error => CHECKED { domain ← NIL; CONTINUE } ];
};


END.