DIRECTORY Buttons USING [Button, ButtonProc, Create], DefaultRemoteNames USING [DefaultNames, Get], DFToolInternal USING [Choice, DFTool, OpDefiner, Operation, OpTable, OptionSelector, Parameters, ToolParameters, UserClass], FS USING [ComponentPositions, Error, ExpandName], IO USING [Close, EndOfStream, GetTokenRope, IDProc, RIS, STREAM], Labels USING [Create, --Destroy, --Label], Rope USING [Cat, Concat, Equal, Index, ROPE, Substr], UserCredentials USING [Get], UserProfile USING [Boolean, ListOfTokens, Number, ProfileChangedProc, Token], VFonts USING [EstablishFont, Font, FontHeight, StringWidth], ViewerClasses USING [Viewer], ViewerOps USING [DestroyViewer], -- should be Labels.Destroy ViewerSpecs USING [openLeftWidth, openRightWidth], ViewerTools USING [GetContents, SetContents]; DFToolUtilitiesImpl: CEDAR MONITOR IMPORTS Buttons, DefaultRemoteNames, FS, IO, Labels, Rope, UserCredentials, UserProfile, VFonts, ViewerOps, ViewerSpecs, ViewerTools EXPORTS DFToolInternal = BEGIN OPEN Tool: DFToolInternal; ROPE: TYPE = Rope.ROPE; userClasses: PUBLIC ARRAY Tool.UserClass OF ROPE _ ["Individual", "ReleaseParticipant", "ReleaseMaster"]; parameters: Tool.Parameters; maxOps: NAT = 10; AddOpToTable: PUBLIC PROC [definer: REF Tool.OpDefiner] = { definer.opAlias _ GetOpAlias[definer.opName]; parameters.opTable.ops[parameters.opTable.nOps] _ definer; parameters.opTable.nOps _ parameters.opTable.nOps.SUCC; }; ViewerToRopeList: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [list: LIST OF ROPE _ NIL] = { tail: LIST OF ROPE _ NIL; s: IO.STREAM = IO.RIS[ViewerTools.GetContents[viewer]]; DO r: ROPE _ s.GetTokenRope[IO.IDProc ! IO.EndOfStream => EXIT].token; rL: LIST OF ROPE; rL _ CONS[r, NIL]; IF list = NIL THEN list _ rL ELSE tail.rest _ rL; tail _ rL; ENDLOOP; s.Close[]; }; EnsureDFName: PUBLIC PROC [dfBase, wDir: ROPE] RETURNS [short, long: ROPE] = { cp: FS.ComponentPositions; fullFName: ROPE _ NIL; [fullFName, cp] _ FS.ExpandName[dfBase, wDir ! FS.Error => CONTINUE]; short _ dfBase; long _ IF fullFName = NIL THEN dfBase ELSE fullFName; IF fullFName ~= NIL AND cp.ver.length = 0 AND cp.ext.length = 0 THEN { short _ short.Concat[".df"]; long _ long.Concat[".df"]; }; }; LabelWidthForChoices: PUBLIC PROC [tool: Tool.DFTool, list: LIST OF Tool.Choice] RETURNS [max: INT _ 0] = { maxRope: ROPE _ NIL; 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; ViewerOps.DestroyViewer[viewer: temp, paint: FALSE]; -- Labels.Destroy[temp] repaints }; MakeCenteredLabel: PUBLIC PROC [op: Tool.Operation, name: ROPE] = { tool: Tool.DFTool = op.tool; IF tool.parameters.compactLayout THEN RETURN; [] _ Labels.Create[ info: [name: name, wx: (OuterContainerWidth[tool] - VFonts.StringWidth[name])/2, wy: op.height, wh: tool.parameters.entryHeight, parent: op.optionsContainer, border: FALSE ], font: tool.parameters.boldFont ]; op.height _ op.height + tool.parameters.entryHeight + tool.parameters.entryVSpace; }; OuterContainerWidth: PUBLIC PROC [tool: Tool.DFTool] RETURNS [INT] = { RETURN[ IF tool.outer.column = left THEN ViewerSpecs.openLeftWidth ELSE ViewerSpecs.openRightWidth ] }; CreateSelector: PUBLIC PROC [ name: ROPE, proc: Buttons.ButtonProc, clientData: REF ANY, choices: LIST OF Tool.Choice, op: Tool.Operation, x: INTEGER _ -1] RETURNS [selector: REF Tool.OptionSelector, initialChoice: Tool.Choice, newX: INTEGER] = { tool: Tool.DFTool = op.tool; button: Buttons.Button; defaultOption: ROPE _ UserProfile.Token[Rope.Cat["DFTool.", op.definer.opAlias, ".", name]]; IF defaultOption = NIL THEN defaultOption _ UserProfile.Token[Rope.Cat["DFTool.", op.definer.opName, ".", name]]; IF x < 0 THEN x _ tool.parameters.entryHSpace; button _ Buttons.Create[ info: [name: name.Concat[":"], wx: x, wy: op.height, wh: tool.parameters.entryHeight, parent: op.optionsContainer, border: FALSE ], proc: proc, fork: FALSE, clientData: clientData, font: tool.parameters.font ]; selector _ NEW[Tool.OptionSelector _ [ name: name, choices: choices, default: (initialChoice _ choices.first).name ]]; IF defaultOption ~= NIL THEN FOR l: LIST OF Tool.Choice _ choices, l.rest UNTIL l = NIL DO IF defaultOption.Equal[l.first.name, FALSE] THEN { selector.default _ (initialChoice _ l.first).name; EXIT }; ENDLOOP; selector.displayer _ Labels.Create[ info: [ name: selector.default, wx: button.wx + button.ww + tool.parameters.entryHSpace, wy: op.height, wh: tool.parameters.entryHeight, ww: LabelWidthForChoices[op.tool, choices], parent: op.optionsContainer, border: FALSE ], font: tool.parameters.font ]; newX _ selector.displayer.wx + selector.displayer.ww; }; 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]; }; ResetOption: PUBLIC PROC [selector: REF Tool.OptionSelector] = { ViewerTools.SetContents[selector.displayer, selector.default]; }; GetToolParameters: PUBLIC ENTRY PROC RETURNS [Tool.Parameters] = {RETURN[parameters]}; ReactToProfile: PUBLIC ENTRY UserProfile.ProfileChangedProc = { ENABLE UNWIND => NULL; params: Tool.Parameters _ NEW[Tool.ToolParameters]; fontFamily: ROPE = UserProfile.Token["DFTool.FontFamily", "Tioga"]; fontSize: NAT = UserProfile.Number["DFTool.FontSize", 10]; class: ROPE = UserProfile.Token[key: "DFTool.UserClass", default: userClasses[$individual]]; userName: ROPE _ UserCredentials.Get[].name; defaultNames: DefaultRemoteNames.DefaultNames _ DefaultRemoteNames.Get[]; IF reason = firstTime THEN RETURN; -- handled by initialization code, below. userName _ userName.Substr[len: userName.Index[s2: "."]]; params.dfNamePrefixes _ UserProfile.ListOfTokens[ key: "DFTool.DFNamePrefixes", default: LIST[ Rope.Concat[defaultNames.current, "Top>"], Rope.Cat[defaultNames.userHost, "<", userName, ">"], Rope.Concat[defaultNames.previous, "Top>"] ] ]; params.userClass _ $individual; FOR userClass: Tool.UserClass IN Tool.UserClass DO IF class.Equal[userClasses[userClass], FALSE] THEN {params.userClass _ userClass; EXIT}; ENDLOOP; params.opTable _ NEW[Tool.OpTable[maxOps]]; IF parameters = NIL THEN params.opTable.nOps _ 0 -- called from this module's initialization; opTable filled in later ELSE { params.opTable.nOps _ parameters.opTable.nOps; FOR op: NAT IN [0..parameters.opTable.nOps) DO old: REF Tool.OpDefiner = parameters.opTable[op]; params.opTable.ops[op] _ NEW[Tool.OpDefiner _ [ opName: old.opName, opID: old.opID, userClass: old.userClass, proc: old.proc, opAlias: GetOpAlias[old.opName] ]]; ENDLOOP; }; params.compactLayout _ UserProfile.Boolean["DFTool.CompactLayout", FALSE]; params.font _ VFonts.EstablishFont[fontFamily, fontSize]; params.boldFont _ VFonts.EstablishFont[family: fontFamily, size: fontSize, bold: TRUE]; params.entryHeight _ VFonts.FontHeight[params.font] + 2; params.entryVSpace _ VFonts.FontHeight[params.font]*1/3; IF params.compactLayout THEN params.entryVSpace _ 1; params.entryHSpace _ 10; parameters _ params; }; GetOpAlias: PROC [opName: ROPE] RETURNS [alias: ROPE] = { RETURN[UserProfile.Token[Rope.Concat["DFTool.NameFor", opName], opName]] }; ReactToProfile[edit]; END. "DFToolUtilitiesImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Levin on December 16, 1983 2:27 pm Russ Atkinson on February 13, 1984 10:02:19 pm PST Doug Wyatt, March 6, 1985 12:10:03 pm PST Spreitzer, May 20, 1985 5:49:52 pm PDT -- ---- ---- ---- ---- ---- ---- ---- Global "Variables" (constant after init) -- ---- ---- ---- ---- ---- ---- ---- -- ---- ---- ---- ---- ---- ---- ---- Global Variables (protected by monitor) -- ---- ---- ---- ---- ---- ---- ---- -- ---- ---- ---- ---- ---- ---- ---- Configuration Parameters (private) -- ---- ---- ---- ---- ---- ---- ---- -- ---- ---- ---- ---- ---- ---- ---- Utilities (exports to DFToolInternal for individual ops) -- ---- ---- ---- ---- ---- ---- ---- assumed to be called only before 'ReactToProfile' is enabled. It is important that the entire `parameters' data structure be copied, since there is unsynchronized access to its contents elsewhere in the tool. Since this will happen rarely, the cost is acceptable. User profile fields: DFTool.DFNamePrefixes: DFTool.UserClass: {Individual, ReleaseParticipant, ReleaseMaster} DFTool.NameFor: synonym (where is "BringOver", "SModel", etc.) DFTool.FontFamily DFTool.FontSize DFTool..: (use "..." if embedded spaces) DFTool.CompactLayout: TRUE | FALSE -- ---- ---- ---- ---- ---- ---- ---- Internal Procedures -- ---- ---- ---- ---- ---- ---- ---- -- ---- ---- ---- ---- ---- ---- ---- Initialization -- ---- ---- ---- ---- ---- ---- ---- Κ υ˜codešœ™Kšœ Οmœ1™˜>K˜K˜—Kš ‘œžœžœžœžœžœ˜VK˜šœžœžœ#˜?KšœΚ™ΚKšžœžœžœ˜šœ™Kšœ5™5KšœA™AKšœS™SK™K™K™VK™"—Kšœžœ˜3Kšœ žœ3˜CKšœ žœ-˜:KšœžœQ˜\Kšœ žœ˜,KšœI˜IKšžœžœžœŸ)˜MKšœ9˜9šœ1˜1K˜šœ žœ˜Kšœ*˜*Kšœ4˜4Kšœ*˜*K˜—K˜—Kšœ˜šžœžœž˜2Kšžœ%žœžœ žœ˜XKšžœ˜—Kšœžœ˜+šžœžœž˜KšœŸD˜]—šžœ˜Kšœ.˜.šžœžœžœž˜.Kšœžœ)˜1šœžœ˜/Kšœ˜K˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšžœ˜—K˜—KšœCžœ˜JKšœ9˜9KšœQžœ˜WKšœ8˜8Kšœ8˜8Kšžœžœ˜4Kšœ˜Kšœ˜K˜—K˜Kšœ%™%K™Kšœ%™%K˜š ‘ œžœ žœžœ žœ˜9KšžœB˜HK˜—K˜Kšœ%™%K™Kšœ%™%K˜K˜Kšœ˜K˜Kšžœ˜—…—b.y