ButtonOpenImpl.mesa
Copyright Ó 1988, 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Last edited by Bier on January 3, 1989 11:36:46 pm PST
Bier, June 16, 1991 4:02 pm PDT
Doug Wyatt, April 14, 1992 12:39 pm PDT
Contents: Implements a tool which displays a list of items, such as file names, as TiogaButtons and allows a procedure to be registered with each item, that is performed when that button is pressed.
DIRECTORY
Args, Commander, Containers, DFUtilities, FileNames, FS, IO, MessageWindow, PFS, Rope, TiogaButtons, TiogaMenuOps, ViewerClasses, ViewerOps;
ButtonOpenImpl: CEDAR PROGRAM
IMPORTS Args, Commander, Containers, DFUtilities, FileNames, FS, IO, MessageWindow, PFS, Rope, TiogaButtons, TiogaMenuOps, ViewerOps
EXPORTS = BEGIN
ROPE: TYPE = Rope.ROPE;
Viewer: TYPE = ViewerClasses.Viewer;
MacroToolRef: TYPE = REF MacroToolObj;
MacroToolObj: TYPE = RECORD [
container: Viewer,
buttons: Viewer,
workingDirectory: Rope.ROPE,
headerButton: TiogaButtons.TiogaButton,
prevButton: TiogaButtons.TiogaButton
];
CreateMacroTool: PROC [name: Rope.ROPE, workingDirectory: Rope.ROPE] RETURNS [macroTool: MacroToolRef] = {
macroTool ¬ NEW[MacroToolObj];
macroTool.workingDirectory ¬ workingDirectory;
macroTool.container ¬
Containers.Create[
info: [
name: name,
iconic: TRUE,
column: left,
scrollable: FALSE]];  -- inhibit user from scrolling contents
MakeTiogaButtons[macroTool];
};
MakeTiogaButtons: PROC [macroTool: MacroToolRef] = {
lineHeight: INTEGER ¬ 15;
macroTool.buttons ¬ TiogaButtons.CreateViewer[
info: [
wx: 0, wy: 0, ww: macroTool.container.ww, wh: macroTool.container.wh,
parent: macroTool.container,
border: FALSE]
];
macroTool.container.class.set[self: macroTool.container, data: macroTool.buttons, op: $XBound];
macroTool.container.class.set[self: macroTool.container, data: macroTool.buttons, op: $YBound];
macroTool.headerButton ¬ macroTool.prevButton ¬ NewHeaderButton[macroTool.buttons, NIL];
};
NewHeaderButton: PROC [v: Viewer, name: Rope.ROPE] RETURNS [button: TiogaButtons.TiogaButton] = {
button ¬ TiogaButtons.CreateButton[
viewer: v,
rope: name,
format: "",
looks: "",
proc: NIL,
clientData: NIL];
};
ButtonData: TYPE = REF ButtonDataObj;
ButtonDataObj: TYPE = RECORD [
localName: Rope.ROPE,
inDFName: Rope.ROPE,
macroTool: MacroToolRef
];
FileExists: PROC [name: ROPE] RETURNS [BOOL] = {
path: PFS.PATH ¬ PFS.PathFromRope[name];
fullName: PFS.PATH;
fullName ¬ PFS.FileInfo[name: path ! PFS.Error=> CONTINUE].fullFName;
RETURN[fullName#NIL];
};
OpenFile: TiogaButtons.TiogaButtonProc = {
TryRemote: PROC [] = {
IF buttonData.inDFName # NIL THEN {
IF FileExists[buttonData.inDFName]
THEN {
MessageWindow.Append[Rope.Concat["Opening ", buttonData.inDFName], TRUE];
[] ¬ TiogaMenuOps.Open[fileName: buttonData.inDFName, column: left];
}
ELSE {
MessageWindow.Append[IO.PutFR1["ButtonOpen: Couldn't find %g ... giving up", [rope[buttonData.inDFName]]], TRUE];
MessageWindow.Blink[];
};
};
};
buttonData: ButtonData ¬ NARROW[clientData];
macroTool: MacroToolRef ¬ buttonData.macroTool;
IF mouseButton = red OR mouseButton = yellow THEN {
IF buttonData.localName # NIL
THEN {
IF FileExists[buttonData.localName]
THEN {
MessageWindow.Append[Rope.Concat["Opening ", buttonData.localName], TRUE];
[] ¬ TiogaMenuOps.Open[fileName: buttonData.localName, column: left];
}
ELSE {
MessageWindow.Append[IO.PutFR1["ButtonOpen: Couldn't find %g ... trying released version", [rope[buttonData.localName]]], TRUE];
MessageWindow.Blink[];
TryRemote[];
};
}
ELSE TryRemote[];
}
ELSE TryRemote[];
};
ButtonOpenDF: TiogaButtons.TiogaButtonProc = {
TryRemote: PROC RETURNS [errorMsg: ROPE ¬ NIL] = {
MessageWindow.Append[Rope.Concat["ButtonOpen DF: ", buttonData.inDFName], TRUE];
IF buttonData.inDFName # NIL THEN errorMsg ¬ ButtonOpen[dfName: buttonData.inDFName, wDir: macroTool.workingDirectory, column: right];
};
buttonData: ButtonData ¬ NARROW[clientData];
macroTool: MacroToolRef ¬ buttonData.macroTool;
errorMsg: ROPE;
IF mouseButton = red OR mouseButton = yellow THEN {
MessageWindow.Append[Rope.Concat["ButtonOpen DF: ", buttonData.localName], TRUE];
IF buttonData.localName # NIL THEN errorMsg ¬ ButtonOpen[dfName: buttonData.localName, wDir: macroTool.workingDirectory, column: right];
IF errorMsg # NIL THEN errorMsg ¬ TryRemote[];
}
ELSE errorMsg ¬ TryRemote[];
IF errorMsg # NIL THEN {
MessageWindow.Append[errorMsg, TRUE];
MessageWindow.Blink[];
};
};
PressDirectory: TiogaButtons.TiogaButtonProc = {
buttonData: ButtonData ¬ NARROW[clientData];
macroTool: MacroToolRef ¬ buttonData.macroTool;
MessageWindow.Append[Rope.Concat["Creating viewer in directory: ", buttonData.inDFName], TRUE];
[] ¬ TiogaMenuOps.Open[fileName: buttonData.inDFName, column: left];
};
ExpandFileName: PROC [name: Rope.ROPE, wDir: ROPE] RETURNS [fullName: Rope.ROPE, success: BOOL ¬ TRUE] = {
name ¬ FileNames.StripVersionNumber[name];
[fullName, ----, ----] ¬ FS.ExpandName[name, wDir ! FS.Error => {
success ¬ FALSE;
CONTINUE;
}
];
IF NOT success THEN fullName ¬ NIL;
};
AddFile: PROC [fileName, comment: ROPE, macroTool: MacroToolRef, inDFDirectory: ROPE] RETURNS [success: BOOL ¬ FALSE] = {
buttonData: ButtonData ¬ NEW[ButtonDataObj];
[buttonData.localName, success] ¬ ExpandFileName[fileName, macroTool.workingDirectory];
[buttonData.inDFName, success] ¬ ExpandFileName[fileName, inDFDirectory];
buttonData.macroTool ¬ macroTool;
macroTool.prevButton ¬ TiogaButtons.AppendToButton[
button: macroTool.prevButton,
rope: Rope.Cat[" ", comment, FileNames.StripVersionNumber[fileName], "\n"],
looks: "",
proc: OpenFile,
clientData: buttonData,
fork: FALSE];
};
AddDF: PROC [localName, remoteName, comment: ROPE, macroTool: MacroToolRef] RETURNS [success: BOOL ¬ TRUE] = {
buttonData: ButtonData ¬ NEW[ButtonDataObj];
buttonData.localName ¬ localName;
buttonData.inDFName ¬ remoteName;
buttonData.macroTool ¬ macroTool;
macroTool.prevButton ¬ TiogaButtons.AppendToButton[
button: macroTool.prevButton,
rope: " [ ] ",
looks: "b",
proc: ButtonOpenDF,
clientData: buttonData,
fork: FALSE];
macroTool.prevButton ¬ TiogaButtons.AppendToButton[
button: macroTool.prevButton,
rope: Rope.Cat[" ", comment, FileNames.StripVersionNumber[remoteName], "\n"],
looks: "",
proc: OpenFile,
clientData: buttonData,
fork: FALSE];
};
AddDirectory: PROC [path1: Rope.ROPE, macroTool: MacroToolRef] = {
buttonData: ButtonData ¬ NEW[ButtonDataObj];
buttonData.inDFName ¬ path1;
buttonData.macroTool ¬ macroTool;
macroTool.prevButton ¬ TiogaButtons.AppendToButton[
button: macroTool.prevButton,
rope: Rope.Concat[buttonData.inDFName, "\n"],
looks: "",
proc: PressDirectory,
clientData: buttonData,
fork: FALSE];
};
ButtonOpenCommand: Commander.CommandProc = {
CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL];
dfName: ROPE;
wDir: Rope.ROPE ¬ FileNames.CurrentWorkingDirectory[];
IF Args.NArgs[cmd] > 0 THEN {
dfName ¬ Args.GetRope[cmd, 0];
msg ¬ ButtonOpen[dfName, wDir, right];
};
};
ButtonOpen: PROC [dfName, wDir: ROPE, column: ViewerOps.Column ¬ right] RETURNS [errorMsg: ROPE] = {
fullDFName, badName: ROPE;
successSoFar: BOOL ¬ TRUE;
cp: FS.ComponentPositions;
dfFilter: DFUtilities.Filter ¬ [
comments: FALSE,
filterA: all,
filterB: all,
filterC: all,
list: NIL
];
dfStream: IO.STREAM;
macroTool: MacroToolRef;
AddToMacroTool: DFUtilities.ProcessItemProc = {
ProcessItemProc: TYPE = PROC [item: REF ANY] RETURNS [stop: BOOL ← FALSE];
WITH item SELECT FROM
fileItem: REF DFUtilities.FileItem => {
success: BOOL;
fullName: Rope.ROPE;
[fullName, cp] ¬ FS.ExpandName[fileItem.name, macroTool.workingDirectory];
success ¬ AddFile[fileItem.name, NIL, macroTool, inDFDirectory];
IF NOT success AND successSoFar THEN {
badName ¬ fileItem.name;
successSoFar ¬ FALSE;
};
};
directoryItem: REF DFUtilities.DirectoryItem => {
inDFDirectory ¬ directoryItem.path1;
AddDirectory[directoryItem.path1, macroTool];
};
includeItem: REF DFUtilities.IncludeItem => {
success: BOOL;
shortName, localName, remoteName: ROPE;
[remoteName, cp,] ¬ FS.ExpandName[includeItem.path1];
shortName ¬ Rope.Concat[Rope.Substr[remoteName, cp.base.start, cp.base.length], ".df"];
[localName, cp,] ¬ FS.ExpandName[shortName, macroTool.workingDirectory];
success ¬ AddDF[localName, remoteName, "Include ", macroTool];
IF NOT success AND successSoFar THEN {
badName ¬ includeItem.path1;
successSoFar ¬ FALSE;
};
};
importsItem: REF DFUtilities.ImportsItem => {
success: BOOL;
shortName, localName, remoteName: ROPE;
[remoteName, cp,] ¬ FS.ExpandName[importsItem.path1];
shortName ¬ Rope.Concat[Rope.Substr[remoteName, cp.base.start, cp.base.length], ".df"];
[localName, cp,] ¬ FS.ExpandName[shortName, macroTool.workingDirectory];
success ¬ AddDF[localName, remoteName, "Imports ", macroTool];
IF NOT success AND successSoFar THEN {
badName ¬ importsItem.path1;
successSoFar ¬ FALSE;
};
};
ENDCASE;
};
inDFDirectory: ROPE ¬ NIL;
[fullDFName, cp] ¬ FS.ExpandName[dfName, wDir];
IF NOT Rope.Equal[Rope.Substr[fullDFName, cp.ext.start, cp.ext.length], "df", FALSE] THEN {
RETURN["ButtonOpen only works on DF files"];
};
dfStream ¬ FS.StreamOpen[dfName, $read
! FS.Error => {errorMsg ¬ Rope.Concat[error.explanation, "\n"]; CONTINUE}];
IF errorMsg # NIL THEN RETURN;
IF dfStream # NIL THEN {
macroTool ¬ CreateMacroTool[Rope.Cat[dfName, ", ", wDir], wDir];
DFUtilities.ParseFromStream[dfStream, AddToMacroTool, dfFilter];
IF NOT successSoFar THEN
MessageWindow.Append[Rope.Concat["FS Error during name expansion of ", badName], TRUE]
ELSE {
ViewerOps.ChangeColumn[macroTool.container, column];
ViewerOps.OpenIcon[macroTool.container];
};
};
};
Commander.Register[key: "ButtonOpen", proc: ButtonOpenCommand, doc: "Takes a DF file name. Opens a TiogaButton files with one button for each file mentioned in the DF file", clientData: NIL, interpreted: TRUE]
END.