CDPopUpMenusImpl.mesa (a ChipNDale module)
Copyright © 1986 by Xerox Corporation. All rights reserved.
Created by: Ch. Jacobi, September 18, 1984 3:24:53 pm PDT
Last edited by: Christian Jacobi, September 4, 1986 3:56:50 pm PDT
DIRECTORY
Ascii,
Atom,
CD,
CDEnvironment,
CDPopUpMenus,
CDSequencer,
Commander,
FS,
IO,
PopUpMenus,
RefTab,
Rope,
TEditProfile USING [DoList];
CDPopUpMenusImpl:
CEDAR
PROGRAM
IMPORTS Atom, CDEnvironment, CDSequencer, Commander, FS, IO, PopUpMenus, RefTab, Rope, TEditProfile
EXPORTS CDPopUpMenus
SHARES PopUpMenus =
BEGIN
UnknownMenu: PUBLIC SIGNAL = CODE;
menuTab: RefTab.Ref ~ RefTab.Create[];
garbageMenu: PopUpMenus.Menu ~ MakeMenu[$GarbageMenu, "garbage menu", "used if command is registered with unknown menu"];
GetMenu:
PUBLIC PROC [key:
REF, check:
BOOL←
FALSE]
RETURNS [PopUpMenus.Menu] = {
WITH key
SELECT
FROM
pm: PopUpMenus.Menu => RETURN [pm];
ENDCASE => NULL;
WITH RefTab.Fetch[menuTab, key].val
SELECT
FROM
pm: PopUpMenus.Menu => RETURN [pm];
ENDCASE => NULL;
IF check THEN SIGNAL UnknownMenu;
RETURN [garbageMenu];
};
MakeMenu:
PUBLIC PROC [key:
ATOM, header, doc: Rope.
ROPE, tech:
CD.Technology←
NIL]
RETURNS [menu: PopUpMenus.Menu] = {
menu ← PopUpMenus.Create[header, doc];
[] ← RefTab.Store[menuTab, key, menu];
CDSequencer.ImplementCommand[key, CallMenuComm, tech, dontQueue];
};
CallMenuComm:
PROC [comm: CDSequencer.Command] = {
menu: PopUpMenus.Menu ← GetMenu[comm.key];
WITH PopUpMenus.Call[menu, comm]
SELECT
FROM
a: ATOM => CDSequencer.ExecuteCommand[comm: comm, key: a];
ENDCASE => NULL;
};
--====================================
InitMenus:
PROC [] = {
[] ← MakeMenu[$GlobalMenu, "Global menu", "all entries are menus again"];
[] ← MakeMenu[$RectGlobalMenu, "Global on rects", "all entries are menus again"];
[] ← MakeMenu[$ProgramMenu, "Additional Programs", "additional programs"];
[] ← MakeMenu[$RectProgramMenu, "Programs on Rects", "additional programs using coordinates"];
[] ← MakeMenu[$OtherProgramMenu, "Other Programs", "additional programs"];
[] ← MakeMenu[$CellMenu, "Cell (s)", ""];
[] ← MakeMenu[$IOMenu, "Input / Output", ""];
[] ← MakeMenu[$DirectoryMenu, "Directory options", ""];
[] ← MakeMenu[$ViewerMenu, "Viewer options", ""];
[] ← MakeMenu[$DrawModeMenu, "Draw Modes", "set drawing modes for the viewer"];
[] ← MakeMenu[$SpecialMenu, "Special commands", ""];
[] ← MakeMenu[$RectSpecialMenu, "Special on rects", ""];
[] ← MakeMenu[$HardCopyMenu, "Hard copy", ""];
[] ← MakeMenu[$DisplayMenu, "Display options", ""];
[] ← MakeMenu[$ImportMenu, "Import and remote", ""];
[] ← MakeMenu[$GeneratorMenu, "Generator options", ""];
[] ← MakeMenu[$TextPropertyMenu, "Text & Properties", ""];
[] ← MakeMenu[$PolygonMenu, "Polygons & Splines", ""];
[] ← MakeMenu[$OperatorMenu, "Operators", "Operations on the current selection"];
[] ← MakeMenu[$RectOperatorMenu, "Operators on rects", ""];
[] ← MakeMenu[$DRCMenu, "DRC and friends", "Design rule checks and extractions"];
[] ← MakeMenu[$RectDRCMenu, "DRC ... on rects", ""];
[] ← MakeMenu[$SelectionMenu, "Selections", ""];
[] ← MakeMenu[$RectSelectionMenu, "Selections on rects", ""];
[] ← MakeMenu[$RectDrawMenu, "Draw", "draw certain types of objects"];
[] ← MakeMenu[$CommentLayerMenu, "set current layer comment", "select color or discard"];
};
SkipLeading:
PROC [line: Rope.
ROPE, start:
INT𡤀]
RETURNS [Rope.
ROPE] = {
removes leading spaces spaces and tabs
ignores one leading /
leng: INT ← Rope.Length[line];
WHILE start<leng
DO
SELECT Rope.Fetch[line, start]
FROM
Ascii.SP, Ascii.TAB => start ← start+1;
'/ => {start ← start+1; EXIT};
ENDCASE => EXIT;
ENDLOOP;
RETURN [ Rope.Substr[line, start] ];
};
SkipTrailing:
PROC [line: Rope.
ROPE, last:
INT←-1]
RETURNS [Rope.
ROPE] = {
removes trailing spaces spaces and tabs
ignores one trailing /
IF last<0 THEN last ← Rope.Length[line]-1;
WHILE last>0
DO
SELECT Rope.Fetch[line, last]
FROM
Ascii.SP, Ascii.TAB => last ← last-1;
'/ => {last ← last-1; EXIT};
ENDCASE => EXIT;
ENDLOOP;
RETURN [ Rope.Substr[line, 0, last+1] ];
};
SplitText:
PROC [line: Rope.
ROPE]
RETURNS [first, rest: Rope.
ROPE←
NIL] = {
Split line according to the following syntax
first | rest
represent | as ||
removes spaces and tabs adjacent to the |
ignores one / adjacent the |
nextPos: INT ← 0;
leng: INT ← Rope.Length[line];
WHILE nextPos<leng
DO
IF Rope.Fetch[line, nextPos]='|
THEN {
IF nextPos+1>leng
OR Rope.Fetch[line, nextPos+1]='|
THEN {
line ← Rope.Replace[line, nextPos, 1, NIL]; leng ← leng-1;
}
ELSE {
first ← SkipTrailing[line, nextPos-1];
rest ← SkipLeading[line, nextPos+1];
RETURN;
};
};
nextPos ← nextPos+1;
ENDLOOP;
first ← line
};
MakeMenuLine:
PROC [line: Rope.
ROPE] = {
Syntax of menu lines
menuKey | entryKey | entryText
lines starting with "-" are comment lines and ignored
"/" adjacent to a | are ignored
entryKey = "NIL": removes the entry
menuR, keyR, textR, restR, docR: Rope.ROPE ← NIL; key: ATOM←NIL;
line ← SkipLeading[line];
IF Rope.IsEmpty[line] THEN RETURN;
[menuR, restR] ← SplitText[line];
IF Rope.IsEmpty[menuR] OR Rope.Fetch[menuR, 0]='- THEN RETURN;
[keyR, textR] ← SplitText[restR];
IF Rope.IsEmpty[keyR] THEN RETURN;
IF ~Rope.IsEmpty[textR] THEN [textR, docR] ← SplitText[textR];
IF ~Rope.Equal[keyR, "NIL"] THEN key ← Atom.MakeAtom[keyR];
[] ← GetMenu[Atom.MakeAtom[menuR]].Entry[textR, NIL, key, docR];
};
InstallOneMenuFile:
PROC [fileName: Rope.
ROPE] = {
file: IO.STREAM; line: Rope.ROPE;
file ← FS.StreamOpen[fileName ! FS.Error => GOTO finish];
DO
line ← IO.GetLineRope[file ! IO.EndOfStream => GOTO finish];
IF ~Rope.IsEmpty[line] THEN MakeMenuLine[line];
ENDLOOP;
EXITS finish => NULL;
};
ReInstallMenus:
PROC = {
--Menu entries are installed in opposite order as found in user profile
--to allow client installations overwrite standard installation.
--Menu entries are not removed if not explicitely requested to allow permanent
--installation of menu entries by programs.
list: LIST OF Rope.ROPE ← NIL;
Each:
PROC [r: Rope.
ROPE] = {
IF Rope.Equal[r, "Default"] THEN r ← CDEnvironment.MakeName["ChipNDale", "MenuTable", CDEnvironment.GetWorkingDirectory[NIL]];
list ← CONS[r, list];
};
TEditProfile.DoList["ChipNDale.MenuTable", Each, "Default"];
WHILE list#
NIL
DO
InstallOneMenuFile[list.first];
list ← list.rest
ENDLOOP
};
ReInstallMenusCommand: Commander.CommandProc = {
ReInstallMenus[];
};
InitMenus[];
Commander.Register["///Commands/CDReInstallMenus", ReInstallMenusCommand, "re-read the ChipNDale menus"];
ReInstallMenus[];
END.