<> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDCellsInteractions, CDDirectory, CDDirectoryOps, CDDefaultProcs, CDInstances, CDImports, CDOps, CDPanel, CDProperties, CDSequencer, CDTexts, CDValue, Convert, IO, PopUpSelection, Real, RefTab, Rope, RopeList, TerminalIO, TextFind, UserProfile, ViewerClasses, ViewerOps, ViewerTools; CDCellCommands: CEDAR PROGRAM IMPORTS CD, CDBasics, CDOps, CDCells, CDCellsInteractions, CDDefaultProcs, CDDirectory, CDDirectoryOps, CDInstances, CDImports, CDPanel, CDProperties, CDSequencer, CDTexts, CDValue, Convert, IO, PopUpSelection, Real, RefTab, Rope, RopeList, TerminalIO, TextFind, UserProfile, ViewerOps, ViewerTools = BEGIN interactiveKey: Rope.ROPE ~ "_ interactive"; IgnoreContext: CD.DrawContextProc = {}; Feedback: PROC [b: BOOL] = { IF b THEN TerminalIO.PutRope["done\n"] ELSE TerminalIO.PutRope["not done\n"] }; GetPattern: PROC [design: CD.Design] RETURNS [pattern: Rope.ROPE] = { pattern _ CDPanel.TakeDownText[design, $pattern]; IF Rope.IsEmpty[pattern] THEN pattern _ NIL; }; GetObjectName: PROC [design: CD.Design, prompt: Rope.ROPE] RETURNS [name: Rope.ROPE] = { name _ CDPanel.TakeDownText[design, $ObjectName]; IF Rope.IsEmpty[name] OR Rope.Equal[name, interactiveKey, FALSE] THEN name _ TerminalIO.RequestRope[prompt]; }; DrawByNameComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; ob: CD.Object; TerminalIO.PutRope["draw object; "]; name _ GetObjectName[comm.design, "object name>\n"]; ob _ FindObject[comm.design, name].object; IF ob#NIL THEN { [] _ CDOps.IncludeObjectI[comm.design, ob, comm.pos]; TerminalIO.PutRopes[name, " inserted\n"]; }; }; FindObject: PROC [design: CD.Design, name: Rope.ROPE] RETURNS [object: CD.Object_NIL] = { <<--either find object or makes a message>> address: CARD; object _ CDDirectory.Fetch[design, name]; IF object=NIL THEN { address _ Convert.CardFromRope[name ! Convert.Error => {address_0; CONTINUE}]; IF address#0 THEN { object _ Find[design, IsAddress, NEW[CARD_address]].object; IF object#NIL THEN TerminalIO.PutRopes["use ", CD.Describe[object, NIL, design], "; because of address\n"] }; IF object=NIL THEN { object _ Find[design, IsText, name].object; IF object#NIL THEN TerminalIO.PutRopes["use text object ", CD.Describe[object, NIL, design], "; because of text match\n"] }; }; IF object=NIL THEN TerminalIO.PutRopes["design does not have object ", name, "\n"]; }; RemoveObFromDirComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE_NIL; done: BOOL _ FALSE; ob: CD.Object; TerminalIO.PutRope["remove object from directory; "]; name _ GetObjectName[comm.design, "object name>\n"]; ob _ CDDirectory.Fetch[comm.design, name].object; IF ob=NIL THEN TerminalIO.PutRopes[name, " not found\n"] ELSE { IF TerminalIO.Confirm[Rope.Cat["remove ", name]] THEN { CDSequencer.MarkChangedIOOnly[comm.design]; [] _ CDDirectory.Remove[comm.design, name, ob]; }; Feedback[done]; }; }; DisplayDirectoryComm: PROC [comm: CDSequencer.Command] = { EachEntry: CDDirectory.EachEntryAction = { --[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL] -- quit _ FALSE; count _ count+1; IF finder#NIL THEN { IF ~TextFind.SearchRope[finder: finder, rope: name].found THEN RETURN; }; displayed _ displayed+1; list _ CONS[CD.Describe[ob, NIL, comm.design], list]; }; trailer, contents: Rope.ROPE _ NIL; list: LIST OF Rope.ROPE _ NIL; count: INT _ 0; displayed: INT _ 0; pattern: Rope.ROPE _ GetPattern[comm.design]; header: Rope.ROPE; finder: TextFind.Finder _ NIL; TerminalIO.PutRopes["directory\n"]; header _ Rope.Cat["directory of ", CD.DesignName[comm.design]]; IF ~Rope.IsEmpty[pattern] THEN { header _ Rope.Cat[header, " PATTERN [", pattern, "]"]; finder _ TextFind.CreateFromRope[pattern: pattern, ignoreCase: TRUE]; }; [] _ CDDirectory.Enumerate[comm.design, EachEntry]; list _ RopeList.Sort[list, RopeList.Compare]; FOR l: LIST OF Rope.ROPE _ list, l.rest WHILE l#NIL DO contents _ Rope.Cat[contents, " ", l.first, "\n"]; ENDLOOP; trailer _ IF count=displayed THEN IO.PutFR["%g objects\n", IO.int[count]] ELSE IO.PutFR["%g objects listed [out of %g objects]\n", IO.int[displayed], IO.int[count]]; contents _ Rope.Cat[header, "\n", contents, trailer]; IF displayed>9 THEN { TerminalIO.PutRopes["extra viewer opened\n", " ", trailer]; ViewerOps.OpenIcon[ViewerTools.MakeNewTextViewer[info: [name: header, data: contents]]]; } ELSE TerminalIO.PutRopes[contents]; }; CreateCellComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["create cell "]; IF ~CDCellsInteractions.CreateCellSelected[comm.design, TRUE].done THEN TerminalIO.PutRope[" not done\n"]; }; PushComm: PROC [comm: CDSequencer.Command] = { inst: CD.Instance _ CDOps.TheInstance[design: comm.design, text: "push into "]; IF inst#NIL THEN { TerminalIO.PutRopes[CD.Describe[inst.ob, inst.properties, comm.design], " "]; IF CDTexts.IsText[inst.ob] THEN { p: CDSequencer.CommandProc _ CDSequencer.FetchCommand[$PushText].proc; IF p#NIL THEN {p[comm]; RETURN}; }; IF ~CDCells.IsCell[inst.ob] THEN { TerminalIO.PutRope[" **is not cell; object expanded**"]; IF ~ inst.ob.class.composed THEN CDSequencer.Quit[" not done"]; }; TerminalIO.PutRope["\n"]; Feedback[ CDCellsInteractions.PushInCellInstance[comm.design, inst, TRUE] ]; }; }; PushIntoCellSIconic: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE _ NIL; inst: CD.Instance _ CDOps.TheInstance[design: comm.design, text: "push into representant "]; IF inst#NIL THEN { TerminalIO.PutRopes[CD.Describe[inst.ob, inst.properties, comm.design], "\n"]; WITH CDProperties.GetProp[inst.ob, $IconFor] SELECT FROM r: Rope.ROPE => name _ r; ENDCASE => NULL; IF name=NIL THEN WITH CDProperties.GetProp[inst, $IconFor] SELECT FROM r: Rope.ROPE => name _ r; ENDCASE => NULL; IF Rope.IsEmpty[name] THEN { TerminalIO.PutRope[" has no iconic property; try pushing into itself\n"]; PushComm[comm]; } ELSE { TerminalIO.PutRopes[" pushing into ", name, "\n"]; Feedback[ PushNamed[comm.design, name, comm] ]; }; }; }; ExpandComm: PROC [comm: CDSequencer.Command] = { instances: CD.InstanceList _ NIL; --this will be the instances of the design cnt: INT _ 0; someOb: CD.Object _ NIL; --if a single object is expanded we need it for its name ExpandIncludeOneCell: PROC [instOfCell: CD.Instance, cell: CD.Object] = { <<--replace the instance by an instance of the expanded cell >> <<--and include the instance into "instances" >> EachCellInst: CDCells.InstEnumerator = { new: CD.Instance _ CDInstances.Composed[inst, instOfCell.trans]; new.selected _ TRUE; instances _ CONS[new, instances]; }; [] _ CDCells.EnumerateInstances[cell, EachCellInst]; CDOps.RedrawInstance[comm.design, instOfCell]; --delayed! cnt _ cnt+1; someOb _ instOfCell.ob; }; CantAndPutBack: PROC [inst: CD.Instance, msg: Rope.ROPE] = { instances _ CONS[inst, instances]; inst.selected _ FALSE; CDOps.RedrawInstance[comm.design, inst]; TerminalIO.PutF["%g %g; deselected\n", [rope[CD.Describe[inst.ob, inst.properties, comm.design]]], [rope[msg]] ]; }; selected: CD.InstanceList _ NIL; TerminalIO.PutRope["expand\n"]; [selected, instances] _ CDInstances.SplitSelected[CDOps.InstList[comm.design]]; FOR il: CD.InstanceList _ selected, il.rest WHILE il#NIL DO IF ~il.first.ob.class.composed THEN CantAndPutBack[il.first, "atomic, can not be expanded"] ELSE { ob: CD.Object _ il.first.ob; WHILE ob#NIL AND ~CDCells.IsCell[ob] DO ob _ CDDirectory.ExpandRecursed[ob, comm.design, comm.design]; IF ob=il.first.ob THEN ob _ NIL; --to exit loop IF ob#NIL AND CDCells.IsCell[ob] THEN { TerminalIO.PutRopes[CD.Describe[il.first.ob, il.first.properties, comm.design], " converted to cell\n"]; [] _ CDDirectoryOps.RemoveIfUnused[comm.design, ob]; } ENDLOOP; IF ob#NIL AND CDCells.IsCell[ob] THEN ExpandIncludeOneCell[il.first, ob] ELSE CantAndPutBack[il.first, "can not be converted to cell to expand"] } ENDLOOP; IF cnt>0 THEN CDOps.SetInstList[comm.design, instances]; IF cnt=1 AND someOb#NIL THEN TerminalIO.PutRopes[CD.Describe[someOb, NIL, comm.design], " expanded"] ELSE TerminalIO.PutF1["%g objects expanded\n", IO.int[cnt]]; }; PopFromCellMenu: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["pop\n"]; IF ~CDCellsInteractions.PopFromCell[comm.design, interactive] THEN TerminalIO.PutRope[" not done\n"]; }; PopFromCellFlush: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["pop and flush\n"]; IF ~CDCellsInteractions.PopFromCell[comm.design, flush] THEN TerminalIO.PutRope[" not done\n"]; }; PopFromCellReplace: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["pop and replace\n"]; IF ~CDCellsInteractions.PopFromCell[comm.design, replace] THEN TerminalIO.PutRope[" not done\n"]; }; PopFromCellNew: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["pop and new\n"]; IF ~CDCellsInteractions.PopFromCell[comm.design, newcell] THEN TerminalIO.PutRope[" not done\n"]; }; PruneDirComm: PROC [comm: CDSequencer.Command] = { pattern: Rope.ROPE _ GetPattern[comm.design]; TerminalIO.PutRope["prune directory\n"]; IF ~Rope.IsEmpty[pattern] THEN TerminalIO.PutRopes[" PATTERN [", pattern, "]\n"]; CDDirectoryOps.PruneDirectory[design: comm.design, askFirst: TRUE, pattern: pattern]; }; BorderModeOnComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["set cells(s) draw mode: draw with border\n"]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected THEN { CDCells.SetBorderMode[l.first.ob, TRUE]; CDOps.RedrawInstance[comm.design, l.first, FALSE]; } ENDLOOP; }; BorderModeOffComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["set cells(s) draw mode: draw without border\n"]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected THEN { CDCells.SetBorderMode[l.first.ob, FALSE]; CDOps.RedrawInstance[comm.design, l.first]; } ENDLOOP; }; SetCellSimplificationComm: PROC [comm: CDSequencer.Command] = { inst: CD.Instance; multiple: BOOL; TerminalIO.PutRope["set cell simplification #\n"]; [inst, multiple] _ CDOps.SelectedInstance[comm.design]; IF multiple THEN TerminalIO.PutRope[" multiple selection; not done\n"] ELSE IF inst=NIL THEN TerminalIO.PutRope[" no selection; not done\n"] ELSE { TerminalIO.PutRope[inst.ob.class.describe[inst.ob]]; IF ISTYPE[inst.ob.specific, CD.CellSpecific] THEN { cptr: CD.CellSpecific ~ NARROW[inst.ob.specific]; h: CD.Number _ MAX[1, inst.ob.bbox.x2-inst.ob.bbox.x1]; TerminalIO.PutF[" [currently: simplification if height < %g pixels", [integer[Real.Round[cptr.simplifyOn*h]]]]; cptr.simplifyOn _ MIN[MAX[TerminalIO.RequestInt[" pixels] type > "], 0], LAST[NAT]]/h; CDOps.RedrawInstance[comm.design, inst]; TerminalIO.PutRope[" done\n"]; } ELSE TerminalIO.PutRope[" not a cell; not done\n"]; } }; RenameObjectComm: PROC [comm: CDSequencer.Command] = { desc: Rope.ROPE; handled: CD.Object; newName: Rope.ROPE; inst: CD.Instance _ CDOps.TheInstance[comm.design]; IF inst#NIL THEN { desc _ CD.Describe[inst.ob, inst.properties, comm.design]; newName _ GetObjectName[comm.design, " new name > "]; CDSequencer.MarkChangedIOOnly[comm.design]; IF Rope.IsEmpty[newName] THEN { handled _ CDDirectory.Remove[comm.design, CDDirectory.Name[inst.ob, comm.design], inst.ob]; IF handled#NIL THEN { TerminalIO.PutRopes[" ", desc, " removed from directory\n"]; RETURN } } ELSE { IF CDDirectory.Rename[comm.design, inst.ob, newName, FALSE].done THEN { TerminalIO.PutF[" %g renamed to %g\n", [rope[desc]], [rope[CDDirectory.Name[inst.ob, comm.design]]] ]; RETURN }; }; TerminalIO.PutRope[" not done\n"] }; }; SubstituteObjectComm: PROC [comm: CDSequencer.Command] = { newName, oldName: Rope.ROPE; old, new: CD.Object; offset: CD.Position _ [0, 0]; lambda: CD.Number _ comm.design.technology.lambda; TerminalIO.PutRope["replace object allover in design\n"]; oldName _ TerminalIO.RequestRope[" replace (name) > "]; old _ FindObject[comm.design, oldName]; IF old=NIL THEN {TerminalIO.PutRopes[" ", oldName, " not found\n"]; RETURN}; newName _ TerminalIO.RequestRope[" by (name) > "]; new _ FindObject[comm.design, newName]; IF new=NIL THEN {TerminalIO.PutRopes[" ", newName, " not found\n"]; RETURN}; IF CDImports.OccursInDrawing[x: old, in: new] THEN { TerminalIO.PutRope[" **infinite recursion; not done\n"]; RETURN }; TerminalIO.PutRope[" do you want to specify an offset?\n"]; SELECT PopUpSelection.Request[header: "offset", choice: LIST["lambda", "ints", "none"]] FROM 1 => { offset.x _ TerminalIO.RequestInt[" x in lambda >"]*lambda; offset.y _ TerminalIO.RequestInt[" y in lambda >"]*lambda; }; 2 => { offset.x _ TerminalIO.RequestInt[" x in ints >"]; offset.y _ TerminalIO.RequestInt[" y in ints >"]; }; ENDCASE => offset _ [0, 0]; CDDirectory.ReplaceObject[design: comm.design, old: old, new: new, trans: [offset, original]]; IF new.class.composed AND old.class.composed THEN SELECT PopUpSelection.Request[header: "cleanup ?", choice: LIST["remove replaced ob from dir", "remove replaced ob from dir and rename other", "no"]] FROM 1 => [] _ CDDirectoryOps.RemoveIfUnused[comm.design, old]; 2 => [] _ CDDirectory.Rename[design: comm.design, object: new, newName: oldName, removeFirst: TRUE]; ENDCASE => NULL; TerminalIO.PutRope[" end replace\n"]; }; <<--***find or push named ***>> ObPredicate: TYPE = PROC [step: StepRec, design: CD.Design, data: REF] RETURNS [BOOL_FALSE]; IsName: ObPredicate = { RETURN [ Rope.Equal[CDDirectory.Name[step.ob, design], NARROW[data], FALSE] ] }; IsOb: ObPredicate = { RETURN [ step.ob = data] }; IsText: ObPredicate = { WITH step.ob.specific SELECT FROM t: CDTexts.TextSpecific => RETURN [ Rope.Equal[t.text, NARROW[data], TRUE] ] ENDCASE => NULL }; IsAddress: ObPredicate = { RETURN [ LOOPHOLE[step.ob, CARD] = NARROW[data, REF CARD]^] }; HandleRec: TYPE = RECORD [ foundOb: CD.Object _ NIL, seen: RefTab.Ref, predicate: ObPredicate _ NIL, predicateData: REF _ NIL, drawStack: LIST OF StepRec _ NIL ]; found: ERROR[ob: CD.Object] = CODE; --not an error PrunedDrawChild: CD.DrawProc = { h: REF HandleRec _ NARROW[pr.devicePrivate]; IF ~RefTab.Insert[h.seen, ob, $x] THEN RETURN; IF h.predicate[[ob, trans, readOnlyInstProps], pr.design, h.predicateData] THEN { h.drawStack _ CONS[StepRec[ob, trans, readOnlyInstProps], h.drawStack]; h.foundOb _ ob; ERROR found[ob] }; IF ob.class.composed AND ~ob.class.xDesign THEN { h.drawStack _ CONS[StepRec[ob, trans, readOnlyInstProps], h.drawStack]; CD.DrawOb[pr: pr, ob: ob, trans: trans, readOnlyInstProps: readOnlyInstProps]; h.drawStack _ h.drawStack.rest; }; }; StepRec: TYPE = RECORD [ob: CD.Object, trans: CD.Transformation_[], readOnlyInstProps: CD.PropList_NIL]; Find: PROC [design: CD.Design, predicate: ObPredicate, predicateData: REF _ NIL, stopFlag: REF BOOL _ NIL] RETURNS [object: CD.Object_NIL, drawStack: LIST OF StepRec, pops: INT_0] = { sf: REF BOOL _ IF stopFlag#NIL THEN stopFlag ELSE NEW[BOOL_FALSE]; h: REF HandleRec = NEW[HandleRec_[ predicate: predicate, predicateData: predicateData, seen: RefTab.Create[] ]]; myDrawRef: CD.DrawRef _ CD.CreateDrawRef[[ design: design, stopFlag: sf, drawChild: PrunedDrawChild, drawRect: CDDefaultProcs.IgnoreRect, drawContext: IgnoreContext, devicePrivate: h ]]; TryFromLevel: PROC [prec: CD.PushRec] = { <<--check if it exists in an easy accessible position on this level>> FOR il: CD.InstanceList _ prec.specific.contents, il.rest WHILE il#NIL DO IF predicate[[il.first.ob, il.first.trans, il.first.properties], design, predicateData] THEN { object _ h.foundOb _ il.first.ob; h.drawStack _ LIST[[il.first.ob, il.first.trans, il.first.properties]]; EXIT }; ENDLOOP; <<--now try down the recursion>> IF h.foundOb=NIL THEN CD.DrawOb[myDrawRef, prec.dummyCell.ob ! found => {object_ob; CONTINUE}]; }; EachOb: CDDirectory.EachObjectProc = { IF predicate[[me], design, predicateData] THEN {object_me; quit_TRUE} }; FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO TryFromLevel[list.first]; IF sf^ THEN RETURN; IF h.foundOb#NIL THEN { drawStack _ h.drawStack; object _ h.foundOb; RETURN }; pops _ pops+1; ENDLOOP; <<--now use directory>> [] _ CDDirectory.EnumerateDesign[design: design, proc: EachOb, dir: TRUE, top: FALSE, recurse: TRUE, visited: h.seen]; }; ReverseStepRecList: PROC [list: LIST OF StepRec] RETURNS [rev: LIST OF StepRec_NIL] = { UNTIL list=NIL DO rev _ CONS[list.first, rev]; list _ list.rest; ENDLOOP; }; IsPushedIn: PROC [design: CD.Design, ob: CD.Object _ NIL, address: CARD_0] RETURNS [yes: BOOL_FALSE] = { FOR pl: LIST OF CD.PushRec _ design.actual, pl.rest WHILE pl#NIL DO IF pl.first.mightReplace#NIL THEN IF pl.first.mightReplace.ob=ob OR address=LOOPHOLE[pl.first.mightReplace.ob, CARD] THEN RETURN [yes_TRUE] ENDLOOP; }; FindFromRope: PROC [design: CD.Design, name: Rope.ROPE, placeifNotFound: BOOL_TRUE, commHint: REF_NIL, scale: BOOL _ TRUE, selection: BOOL_TRUE] RETURNS [inst: CD.Instance _ NIL] = { <<--comm is used to find a viewer used for scale changes...>> <<-- [using the viewer command enables its undo on the scale change]>> <<--Feedback on TerminalIO at least on failure>> Pops: PROC [design: CD.Design, pops: INT _ LAST[INT]] RETURNS [done: BOOL_TRUE] = { IF pops>0 AND CDCells.IsPushedIn[design] THEN { TerminalIO.PutRope["not found in accessible position\n try to pop out\n"]; WHILE CDCells.IsPushedIn[design] AND pops>0 DO pops _ pops-1; IF ~ CDCellsInteractions.PopFromCell[design, interactive] THEN { TerminalIO.PutRope["failed: user did not allow pop out\n"]; RETURN [FALSE] } ENDLOOP; }; }; pushStack: LIST OF StepRec _ NIL; --will be draw stack in reversed order pops: INT; address: CARD _ 0; ob: CD.Object; stopFlag: REF BOOL _ NEW[BOOL_FALSE]; CDSequencer.UseAbortFlag[design, stopFlag]; ob _ CDDirectory.Fetch[design, name]; IF ob=NIL THEN address _ Convert.CardFromRope[name ! Convert.Error => {address_0; CONTINUE}]; IF ob#NIL OR address#0 THEN IF IsPushedIn[design, ob, address] THEN { TerminalIO.PutRopes["design is pushed into", name, "\n"]; RETURN [NIL] }; IF ob#NIL THEN [drawStack: pushStack, pops: pops] _ Find[design, IsOb, ob, stopFlag] ELSE { IF address#0 THEN [object: ob, drawStack: pushStack, pops: pops] _ Find[design, IsAddress, NEW[CARD_address], stopFlag]; IF ob=NIL THEN [object: ob, drawStack: pushStack, pops: pops] _ Find[design, IsText, name, stopFlag]; IF ob=NIL THEN [object: ob, drawStack: pushStack, pops: pops] _ Find[design, IsName, name, stopFlag]; }; IF pushStack=NIL THEN { IF stopFlag^ THEN RETURN [NIL]; IF ~placeifNotFound OR ob=NIL THEN { TerminalIO.PutRope["failed: object not found\n"]; RETURN [NIL] }; IF ~Pops[design, 10000] THEN RETURN [NIL]; inst _ CDOps.PlaceInst[design, ob, commHint]; TerminalIO.PutRopes["**object ", CD.Describe[ob, NIL, design], " drawn**\n"]; pushStack _ LIST[StepRec[inst.ob, inst.trans, inst.properties]]; pops _ 0; }; IF ~Pops[design, pops] THEN RETURN [NIL]; pushStack _ ReverseStepRecList[pushStack]; WHILE pushStack#NIL DO <<--pushing-in made a copy of the instance list! check for the right object>> IF stopFlag^ THEN RETURN [NIL]; FOR il: CD.InstanceList _ CDOps.InstList[design], il.rest WHILE il#NIL DO IF il.first.ob=pushStack.first.ob THEN {inst _ il.first; EXIT}; REPEAT FINISHED => {TerminalIO.PutRope["finding object failed\n"]; RETURN [NIL]} ENDLOOP; IF pushStack.rest#NIL THEN { IF ~CDCellsInteractions.PushInCellInstance[design, inst] THEN { TerminalIO.PutRope["push failed\n"]; RETURN [NIL] }; }; pushStack _ pushStack.rest ENDLOOP; IF selection OR scale THEN { CDOps.DeselectAll[design]; inst.selected _ TRUE; CDOps.Redraw[design]; --redraw just in case scaling would fail }; IF scale THEN WITH commHint SELECT FROM comm: CDSequencer.Command => { CDSequencer.ExecuteCommand[key: $ResetScaleSel, design: design, queue: dontQueue, comm: comm]; }; ENDCASE => NULL; }; PushNamed: PROC [design: CD.Design, name: Rope.ROPE, commHint: REF] RETURNS [done: BOOL] = { inst: CD.Instance _ FindFromRope[design: design, name: name, scale: TRUE, commHint: commHint]; done _ inst#NIL AND CDCellsInteractions.PushInCellInstance[design, inst]; }; PushNamedComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; TerminalIO.PutRope["push into cell by name\n"]; WITH comm.data SELECT FROM r: Rope.ROPE => {name _ r; TerminalIO.PutRopes["push into cell", name, "\n"]}; ENDCASE => { TerminalIO.PutRope["push into cell by name\n"]; name _ GetObjectName[comm.design, " cell name >"]; TerminalIO.PutRopes[" for: ", name, "\n"]; }; Feedback[ PushNamed[comm.design, name, comm] ]; }; AccessNamedComm: PROC [comm: CDSequencer.Command] = { inst: CD.Instance; name: Rope.ROPE; TerminalIO.PutRope["access named object\n"]; WITH comm.data SELECT FROM r: Rope.ROPE => {name _ r; TerminalIO.PutRopes["access", name, "\n"]}; ENDCASE => { TerminalIO.PutRope["access by name\n"]; name _ GetObjectName[comm.design, " cell name >"]; TerminalIO.PutRopes[" for: ", name, "\n"]; }; inst _ FindFromRope[design: comm.design, name: name, scale: TRUE, commHint: comm]; Feedback[ inst#NIL ]; }; <<>> TransformToCellComm: PROC [comm: CDSequencer.Command] = { n: INT _ 0; selection: CD.InstanceList _ CDInstances.OnlySelected[CDOps.InstList[comm.design]]; TerminalIO.PutRope["transform to cell\n"]; FOR l: CD.InstanceList _ selection, l.rest WHILE l#NIL DO IF l.first.selected AND l.first.ob.class.composed AND ~CDCells.IsCell[l.first.ob] THEN { cob: CD.Object _ CDDirectory.ExpandRecursed[l.first.ob, comm.design, comm.design]; IF cob#NIL AND cob#l.first.ob THEN {l.first.ob _ cob; n _ n+1} }; ENDLOOP; TerminalIO.PutF1["%g objects transformed to cells\n", [integer[n]]]; }; CleanupComm: PROC [comm: CDSequencer.Command] = { n: INT; TerminalIO.PutRope["cleanup directory\n"]; n _ CDDirectory.DirSize[comm.design]; CDDirectoryOps.CleanUp[comm.design, NIL]; IF n = CDDirectory.DirSize[comm.design] THEN TerminalIO.PutF["design was ok; has %g entries in directory\n", [integer[n]]] ELSE TerminalIO.PutF["design was not ok; previously had %g; now has %g entries in directory\n", [integer[n]], [integer[CDDirectory.DirSize[comm.design]]] ]; }; DefaultIRComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["default the interest rect\n"]; IF comm.design.actual.rest=NIL THEN TerminalIO.PutRope[" not pushed in; not done\n"] ELSE { oldWir: CD.Rect _ comm.design^.actual.first.specific.ir; newWir: CD.Rect _ CDInstances.BoundingRectI[CDOps.InstList[comm.design]]; comm.design.actual.first.specific.ir _ newWir; comm.design.actual.first.specific.specifiedIr _ FALSE; CDOps.Redraw[comm.design, CDBasics.Surround[oldWir, newWir]]; }; }; SetIRComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["set the interest rect\n"]; IF comm.design.actual.rest=NIL THEN TerminalIO.PutRope[" not pushed in; not done\n"] ELSE { mightReplace: CD.Instance _ comm.design^.actual.first.mightReplace; oldWir: CD.Rect = comm.design^.actual.first.specific.ir; newWir: CD.Rect = CDBasics.ToRect[comm.pos, comm.sPos]; -- new interest rect comm.design.actual.first.specific.ir _ newWir; comm.design.actual.first.specific.specifiedIr _ TRUE; CDOps.Redraw[comm.design, CDBasics.Surround[oldWir, newWir]]; }; }; CDSequencer.ImplementCommand[$PopMenu, PopFromCellMenu,, doQueue]; CDSequencer.ImplementCommand[$PopNew, PopFromCellNew,, doQueue]; CDSequencer.ImplementCommand[$PopFlush, PopFromCellFlush,, doQueue]; CDSequencer.ImplementCommand[$PopReplace, PopFromCellReplace,, doQueue]; CDSequencer.ImplementCommand[$PushS, PushComm,, doQueue]; CDSequencer.ImplementCommand[$PushSIconic, PushIntoCellSIconic,, doQueue]; CDSequencer.ImplementCommand[$ExpandS, ExpandComm]; CDSequencer.ImplementCommand[$CreateCellSAndName, CreateCellComm]; CDSequencer.ImplementCommand[$DisplayCellNames, DisplayDirectoryComm,, doQueue]; CDSequencer.ImplementCommand[$DrawCell, DrawByNameComm]; CDSequencer.ImplementCommand[$RemoveCell, RemoveObFromDirComm,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedObjects, PruneDirComm,, doQueue]; CDSequencer.ImplementCommand[$CellSimplification, SetCellSimplificationComm,, doQueue]; CDSequencer.ImplementCommand[$RenameS, RenameObjectComm,, doQueue]; CDSequencer.ImplementCommand[$Replace, SubstituteObjectComm]; CDSequencer.ImplementCommand[$DrawWithoutBorder, BorderModeOffComm]; CDSequencer.ImplementCommand[$DrawWithBorder, BorderModeOnComm]; CDSequencer.ImplementCommand[$PushNamed, PushNamedComm,, doQueue]; CDSequencer.ImplementCommand[$AccessNamed, AccessNamedComm,, doQueue]; CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellComm]; CDSequencer.ImplementCommand[$CheckDir, CleanupComm,, doQueue]; CDSequencer.ImplementCommand[$DefaultIR, DefaultIRComm]; CDSequencer.ImplementCommand[$SetIR, SetIRComm]; CDValue.RegisterKey[$ObjectName, NIL, $chj]; CDValue.Store[NIL, $ObjectName, interactiveKey]; IF UserProfile.Boolean["ChipNDale.ObjectPrefix", FALSE] THEN { CDPanel.Text[text: [cdValueKey: $ObjectName], button: [text: "object name:"]]; CDPanel.Line[]; }; END.