IndividualOpsImpl.mesa
last edited by Levin on October 7, 1983 1:58 pm
DIRECTORY
Buttons USING [ButtonProc, Create],
Containers USING [ChildXBound, Create],
DFOperations USING [
BringOver, BringOverAction, BringOverFilter, BringOverFilterA, BringOverFilterB, BringOverFilterC, InteractionProc, SModel, SModelAction],
DFToolInternal USING [
boldFont, Choice, DFTool, entryHeight, entryHSpace, entryVSpace, font, offScreenY, OpDefiner, Operation, OpsInteraction, OpSpecificProc, opTable, OptionSelector, OuterContainerWidth],
IO USING [card, EndOfStream, GetTokenRope, IDProc, PutFR, PutRope, RIS, rope, STREAM],
Labels USING [Create, Destroy, Label],
MBQueue USING [CreateButton],
Rope USING [Concat, Equal, Find, Length, ROPE],
UserProfile USING [Token],
VFonts USING [StringWidth],
ViewerClasses USING [Viewer],
ViewerOps USING [MoveViewer],
ViewerTools USING [GetContents, MakeNewTextViewer, SetContents, SetSelection];
IndividualOpsImpl: CEDAR PROGRAM
IMPORTS
Buttons, Containers, DFOperations, DFToolInternal, IO, Labels, MBQueue, Rope, UserProfile, VFonts, ViewerOps, ViewerTools
EXPORTS DFToolInternal =
BEGIN
OPEN Ops: DFOperations, Tool: DFToolInternal;
ROPE: TYPE = Rope.ROPE;
---- ---- ---- ---- ---- ---- ---- ----
BringOver-specific Code
---- ---- ---- ---- ---- ---- ---- ----
BringOverData: TYPE = RECORD [
filter: Ops.BringOverFilter ← [],
filterASelector: REF Tool.OptionSelector ← NIL,
filterBSelector: REF Tool.OptionSelector ← NIL,
filterCSelector: REF Tool.OptionSelector ← NIL,
action: Ops.BringOverAction ← enter,
actionSelector: REF Tool.OptionSelector ← NIL,
usingList: ViewerClasses.Viewer ← NIL -- undigested TEXT for filter.list
];
selectedFilesLines: NAT = 2;
BringOverSpecific: Tool.OpSpecificProc = {
SELECT action FROM
$createOptions => {
op: Tool.Operation = NARROW[param];
tool: Tool.DFTool = op.tool;
selector: REF Tool.OptionSelector;
prev: ViewerClasses.Viewer;
data: REF BringOverData = NEW[BringOverData ← []];
op.options ← data;
op.optionsContainer ← Containers.Create[info: [
wx: 0, wy: Tool.offScreenY,
ww: 9999, -- arbitrary; Containers.ChildXBound overrides
wh: 0,
parent: tool.inner,
border: FALSE,
scrollable: FALSE
]];
Containers.ChildXBound[tool.inner, op.optionsContainer];
MakeCenteredLabel[op, op.definer.opAlias.Concat[" Options"]];
prev ← tool.q.CreateButton[
info: [name: "Origin:",
wx: Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectBringOverFilterA,
clientData: data,
font: Tool.font
];
selector ← data.filterASelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["all", NEW[Ops.BringOverFilterA ← all]],
["derived", NEW[Ops.BringOverFilterA ← derived]],
["source", NEW[Ops.BringOverFilterA ← source]]
]]];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
prev ← tool.q.CreateButton[
info: [name: "Access:",
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectBringOverFilterB,
clientData: data,
font: Tool.font
];
selector ← data.filterBSelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["all", NEW[Ops.BringOverFilterB ← all]],
["private", NEW[Ops.BringOverFilterB ← private]],
["public", NEW[Ops.BringOverFilterB ← public]]
]]];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
prev ← tool.q.CreateButton[
info: [name: "Reference:",
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectBringOverFilterC,
clientData: data,
font: Tool.font
];
selector ← data.filterCSelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["all", NEW[Ops.BringOverFilterC ← all]],
["imported", NEW[Ops.BringOverFilterC ← imported]],
["defining", NEW[Ops.BringOverFilterC ← defining]]
]]];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
op.height ← op.height + Tool.entryHeight + Tool.entryVSpace;
data.usingList ← ViewerTools.MakeNewTextViewer[info: [
wx: 0, -- we'll move it soon
wy: op.height,
ww: 9999, -- arbitrary; Containers.ChildXBound overrides
wh: selectedFilesLines*Tool.entryHeight,
data: NIL,
parent: op.optionsContainer,
scrollable: TRUE,
border: FALSE
]];
prev ← Buttons.Create[
info: [name: "Selected files:",
wx: Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectUsingList,
fork: FALSE,
clientData: data.usingList,
font: Tool.font
];
ViewerOps.MoveViewer[
viewer: data.usingList,
x: prev.wx + prev.ww + Tool.entryHSpace, y: data.usingList.wy,
w: data.usingList.ww, h: data.usingList.wh
];
Containers.ChildXBound[op.optionsContainer, data.usingList];
op.height ← op.height + selectedFilesLines*Tool.entryHeight + Tool.entryVSpace;
prev ← tool.q.CreateButton[
info: [name: "Action for each file:",
wx: Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectBringOverAction,
clientData: data,
font: Tool.font
];
selector ← data.actionSelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["enter in directory as attachment", NEW[Ops.BringOverAction ← enter]],
["check remote server", NEW[Ops.BringOverAction ← check]],
["check remote server, then enter in directory",
NEW[Ops.BringOverAction ← checkAndEnter]],
["enter in directory and fetch", NEW[Ops.BringOverAction ← fetch]]
]]];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
op.height ← op.height + Tool.entryHeight + Tool.entryVSpace;
ViewerOps.MoveViewer[
viewer: op.optionsContainer,
x: op.optionsContainer.wx, y: op.optionsContainer.wy,
w: op.optionsContainer.ww, h: op.height,
paint: FALSE
];
};
$doOp => {
op: Tool.Operation = NARROW[param];
tool: Tool.DFTool = op.tool;
Interact: Ops.InteractionProc = {
IF ~tool.abortRequested THEN response ← Tool.OpsInteraction[tool, interaction];
IF tool.abortRequested THEN {
abort ← TRUE;
abortMessageForLog ← "(user generated)";
tool.abortRequested ← FALSE;
};
};
data: REF BringOverData = NARROW[op.options];
Copy out option information to prevent user edits while operation is in progress
dfNames: IO.STREAM = IO.RIS[ViewerTools.GetContents[tool.dfNames]];
filter: Ops.BringOverFilter ← data.filter;
action: Ops.BringOverAction = data.action;
usingList: IO.STREAM = IO.RIS[ViewerTools.GetContents[data.usingList]];
last: LIST OF ROPENIL;
filter.list ← NIL;
DO
name: ROPE = usingList.GetTokenRope[IO.IDProc ! IO.EndOfStream => EXIT].token;
nameL: LIST OF ROPE;
nameL ← CONS[name, NIL];
IF last = NIL THEN filter.list ← nameL
ELSE last.rest ← nameL;
last ← nameL;
ENDLOOP;
DO
errors, warnings, filesActedUpon: INT;
dfName: ROPE = DFToDo[dfNames];
IF dfName.Length = 0 THEN EXIT;
[errors: errors, warnings: warnings, filesActedUpon: filesActedUpon] ← Ops.BringOver[
dfFile: dfName,
filter: filter, action: action,
interact: Interact,
log: tool.log
];
tool.feedback.PutRope[MakeOutcomeRope[errors, warnings, filesActedUpon]];
ENDLOOP;
};
ENDCASE;
};
SelectBringOverFilterA: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF BringOverData = NARROW[clientData];
data.filter.filterA ←
NARROW[SelectOption[data.filterASelector].value, REF Ops.BringOverFilterA]^;
};
SelectBringOverFilterB: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF BringOverData = NARROW[clientData];
data.filter.filterB ←
NARROW[SelectOption[data.filterBSelector].value, REF Ops.BringOverFilterB]^;
};
SelectBringOverFilterC: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF BringOverData = NARROW[clientData];
data.filter.filterC ←
NARROW[SelectOption[data.filterCSelector].value, REF Ops.BringOverFilterC]^;
};
SelectBringOverAction: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF BringOverData = NARROW[clientData];
data.action ← NARROW[SelectOption[data.actionSelector].value, REF Ops.BringOverAction]^;
};
SelectUsingList: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of the using list is atomic.
usingList: ViewerClasses.Viewer = NARROW[clientData];
IF mouseButton = blue THEN ViewerTools.SetContents[usingList, NIL]
ELSE ViewerTools.SetSelection[usingList, NIL];
};
---- ---- ---- ---- ---- ---- ---- ----
SModel-specific Code
---- ---- ---- ---- ---- ---- ---- ----
SModelData: TYPE = RECORD [
action: Ops.SModelAction ← [],
checkOptionSelector: REF Tool.OptionSelector ← NIL,
storeOptionSelector: REF Tool.OptionSelector ← NIL
];
SModelSpecific: Tool.OpSpecificProc = {
SELECT action FROM
$createOptions => {
op: Tool.Operation = NARROW[param];
tool: Tool.DFTool = op.tool;
selector: REF Tool.OptionSelector;
prev: ViewerClasses.Viewer;
data: REF SModelData = NEW[SModelData ← []];
op.options ← data;
op.optionsContainer ← Containers.Create[info: [
wx: 0, wy: Tool.offScreenY,
ww: 9999, -- arbitrary; Containers.ChildXBound overrides
wh: 0,
parent: tool.inner,
border: FALSE,
scrollable: FALSE
]];
Containers.ChildXBound[tool.inner, op.optionsContainer];
MakeCenteredLabel[op, op.definer.opAlias.Concat[" Options"]];
selector ← data.checkOptionSelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["no", NEW[BOOLFALSE]],
["yes", NEW[BOOLTRUE]]
]]];
prev ← tool.q.CreateButton[
info: [name: "Check existence on server:",
wx: Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectSModelCheckOption,
clientData: data,
font: Tool.font
];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
selector ← data.storeOptionSelector ← NEW[Tool.OptionSelector ← [choices: LIST[
["yes", NEW[BOOLTRUE]],
["no", NEW[BOOLFALSE]]
]]];
prev ← tool.q.CreateButton[
info: [name: "Store changed files:",
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer, 
border: FALSE
],
proc: SelectSModelStoreOption,
clientData: data,
font: Tool.font
];
prev ← selector.displayer ← Labels.Create[
info: [name: selector.choices.first.name,
wx: prev.wx + prev.ww + Tool.entryHSpace,
wy: op.height,
wh: Tool.entryHeight,
ww: LabelWidthForChoices[tool, selector.choices],
parent: op.optionsContainer,
border: FALSE
],
font: Tool.font
];
op.height ← op.height + Tool.entryHeight + Tool.entryVSpace;
ViewerOps.MoveViewer[
viewer: op.optionsContainer,
x: op.optionsContainer.wx, y: op.optionsContainer.wy,
w: op.optionsContainer.ww, h: op.height,
paint: FALSE
];
};
$doOp => {
op: Tool.Operation = NARROW[param];
tool: Tool.DFTool = op.tool;
Interact: Ops.InteractionProc = {
IF ~op.tool.abortRequested THEN response ← Tool.OpsInteraction[op.tool, interaction];
IF op.tool.abortRequested THEN {
abort ← TRUE;
abortMessageForLog ← "(user generated)";
op.tool.abortRequested ← FALSE;
};
};
data: REF SModelData = NARROW[op.options];
Copy out option information to prevent user edits while operation is in progress
dfNames: IO.STREAM = IO.RIS[ViewerTools.GetContents[tool.dfNames]];
action: Ops.SModelAction = data.action;
DO
errors, warnings, filesActedUpon: INT;
dfName: ROPE = DFToDo[dfNames];
IF dfName.Length[] = 0 THEN EXIT;
[errors: errors, warnings: warnings, filesActedUpon: filesActedUpon] ← Ops.SModel[
dfFile: dfName,
action: action,
interact: Interact,
log: tool.log
];
tool.feedback.PutRope[MakeOutcomeRope[errors, warnings, filesActedUpon]];
ENDLOOP;
};
ENDCASE;
};
SelectSModelCheckOption: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF SModelData = NARROW[clientData];
data.action.remoteCheck ← NARROW[SelectOption[data.checkOptionSelector].value, REF BOOL]^;
};
SelectSModelStoreOption: Buttons.ButtonProc = {
Note: runs synchronously with Viewers' notifier to ensure than manipulation of `selector.displayer' is atomic.
data: REF SModelData = NARROW[clientData];
data.action.storeChanged ← NARROW[SelectOption[data.storeOptionSelector].value, REF BOOL]^;
};
---- ---- ---- ---- ---- ---- ---- ----
Utilities (exported for other OpImpls)
---- ---- ---- ---- ---- ---- ---- ----
AddOpToTable: PUBLIC PROC [definer: REF Tool.OpDefiner] = {
definer.opAlias ←
UserProfile.Token[Rope.Concat["DFTool.NameFor", definer.opName], definer.opName];
Tool.opTable.ops[Tool.opTable.nOps] ← definer;
Tool.opTable.nOps ← Tool.opTable.nOps.SUCC;
};
DFToDo: PUBLIC PROC [s: IO.STREAM] RETURNS [r: ROPENIL] = {
dfExt: ROPE = ".df";
r ← s.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token;
IF r.Length >= dfExt.Length[] AND r.Find[dfExt, r.Length[] - dfExt.Length[], FALSE] = -1 THEN
r ← r.Concat[dfExt];
};
LabelWidthForChoices: PUBLIC PROC [tool: Tool.DFTool, list: LIST OF Tool.Choice]
RETURNS [max: INT ← 0] = {
maxRope: ROPENIL;
temp: Labels.Label;
IF list = NIL THEN RETURN;
FOR l: LIST OF Tool.Choice ← list, l.rest UNTIL l = NIL DO
w: INT = VFonts.StringWidth[l.first.name];
IF w > max THEN {maxRope ← l.first.name; max ← w};
ENDLOOP;
temp ← Labels.Create[
info: [name: maxRope, wx: 0, wy: 0, parent: tool.outer, border: FALSE],
paint: FALSE
];
max ← temp.cw;
Labels.Destroy[temp];
};
MakeCenteredLabel: PUBLIC PROC [op: Tool.Operation, name: ROPE] = {
[] ← Labels.Create[
info: [name: name,
wx: (Tool.OuterContainerWidth[op.tool] - VFonts.StringWidth[name])/2,
wy: op.height,
wh: Tool.entryHeight,
parent: op.optionsContainer,
border: FALSE
],
font: Tool.boldFont
];
op.height ← op.height + Tool.entryHeight + Tool.entryVSpace;
};
MakeOutcomeRope: PUBLIC PROC [errors, warnings, filesActedUpon: INT] RETURNS [ROPE] = {
RETURN[
IO.PutFR["%d files retrieved%g\N", IO.card[filesActedUpon],
IO.rope[
IF errors + warnings ~= 0 THEN
IO.PutFR[" (with %d errors, %d warnings)", IO.card[errors], IO.card[warnings]]
ELSE NIL
]
]
]
};
SelectOption: PUBLIC PROC [selector: REF Tool.OptionSelector] RETURNS [choice: Tool.Choice] = {
NextChoice: PROC [this: ROPE, list: LIST OF Tool.Choice]
RETURNS [next: Tool.Choice ← [NIL, NIL]] = {
IF list = NIL THEN RETURN;
FOR l: LIST OF Tool.Choice ← list, l.rest UNTIL l = NIL DO
IF this.Equal[l.first.name, FALSE] THEN
RETURN[IF l.rest = NIL THEN list.first ELSE l.rest.first]
ENDLOOP;
RETURN[list.first]
};
choice ← NextChoice[ViewerTools.GetContents[selector.displayer], selector.choices];
ViewerTools.SetContents[selector.displayer, choice.name];
};
---- ---- ---- ---- ---- ---- ---- ----
Initialization
---- ---- ---- ---- ---- ---- ---- ----
AddOpToTable[NEW[Tool.OpDefiner ← ["BringOver", $individual, BringOverSpecific]]];
AddOpToTable[NEW[Tool.OpDefiner ← ["SModel", $individual, SModelSpecific]]];
END.