<> <> <> <> DIRECTORY Ascii, CD, CDBasics, CDCells, CDCellsInteractions, CDDirectory, CDDirectoryOps, CDInstances, CDMarks, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, IO, PopUpSelection, Real, Rope, RopeList, TerminalIO, UserProfile, ViewerClasses, ViewerOps, ViewerTools; CDCellCommands: CEDAR PROGRAM IMPORTS Ascii, CD, CDOps, CDCells, CDCellsInteractions, CDDirectory, CDDirectoryOps, CDInstances, CDMarks, CDPanel, CDProperties, CDSequencer, CDValue, IO, PopUpSelection, Real, Rope, RopeList, TerminalIO, UserProfile, ViewerOps, ViewerTools = BEGIN interactiveKey: Rope.ROPE ~ "_ interactive"; DesignRope: PROC [design: CD.Design] RETURNS [Rope.ROPE] = { RETURN [IF design.name#NIL THEN design.name ELSE "un-named design"] }; GetObjectName: PROC [design: CD.Design, prompt: Rope.ROPE] RETURNS [name: Rope.ROPE] = { name _ CDPanel.FromDisplayRope[design, $ObjectName]; IF Rope.IsEmpty[name] OR Rope.Equal[name, interactiveKey, FALSE] THEN name _ TerminalIO.RequestRope[prompt]; }; DrawObjectByNameComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; ob: CD.Object; TerminalIO.PutRope["draw object; "]; 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 { CDOps.IncludeObjectI[comm.design, ob, comm.pos]; TerminalIO.PutRopes[name, " inserted\n"]; }; }; RemoveObFromDirComm: PROC [comm: CDSequencer.Command] = { name, msg: 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 { [done, msg] _ CDDirectoryOps.RemoveIfUnused[comm.design, ob]; CDSequencer.MarkChangedIOOnly[comm.design]; TerminalIO.PutRope[msg]; }; IF ~done THEN TerminalIO.PutRope[" not "]; TerminalIO.PutRope["done\n"]; }; }; DisplayCellNames: PROC [comm: CDSequencer.Command] = { EachEntry: CDDirectory.EachEntryAction = { --[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL] -- quit _ FALSE; count _ count+1; IF comm.key=$RestricedDisplayCellNames THEN { IF Rope.Length[name]<=0 THEN RETURN ELSE { ch: CHAR = Rope.Fetch[name]; IF ~Ascii.Letter[ch] AND ~Ascii.Digit[ch] THEN RETURN } }; displayed _ displayed+1; WITH ob.specific SELECT FROM cp: CD.CellSpecific => list _ CONS[cp.name, list]; ENDCASE => list _ CONS[Rope.Cat[name, " [", CDOps.ObjectRope[ob], "]"], list]; }; sz: INT _ CDDirectory.DirSize[comm.design]; extraViewer: BOOL _ sz>9; trailer, contents: Rope.ROPE _ NIL; list: LIST OF Rope.ROPE _ NIL; count: INT _ 0; displayed: INT _ 0; header: Rope.ROPE _ Rope.Cat["Directory of ", DesignRope[comm.design]]; IF extraViewer THEN TerminalIO.PutRope["open directory viewer\n"]; [] _ 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 _ IO.PutFR["%g objects counted ", IO.int[count]]; IF count#displayed THEN trailer _ IO.PutFR["%g %g displayed", IO.rope[trailer], IO.int[displayed]]; trailer _ Rope.Cat[trailer, "\n"]; contents _ Rope.Cat[header, "\n", contents, trailer]; IF extraViewer THEN { TerminalIO.PutRopes["open directory viewer\n", " ", trailer]; ViewerOps.OpenIcon[ViewerTools.MakeNewTextViewer[info: [name: header, data: contents]]]; } ELSE TerminalIO.PutRopes[contents]; }; CreateCellAndName: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["create cell "]; IF ~CDCellsInteractions.CreateCellSelected[comm.design].done THEN TerminalIO.PutRope[" not done\n"]; }; CreateCellDefaultName: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["create cell without name\n"]; IF ~CDCellsInteractions.CreateCellSelected[comm.design, "-no name-"].done THEN TerminalIO.PutRope[" not done\n"]; }; PushIntoCellS: PROC [comm: CDSequencer.Command] = { inst: CD.Instance _ CDOps.TheInstance[design: comm.design, text: "push into "]; IF inst#NIL THEN { TerminalIO.PutRope[CDOps.ObjectRope[inst.ob]]; IF ~CDCells.IsCell[inst.ob] THEN { TerminalIO.PutRope[" **is not cell; object expanded**"]; IF ~ inst.ob.class.inDirectory THEN CDSequencer.Quit[" not done"]; }; TerminalIO.PutRope["\n"]; IF CDCellsInteractions.PushInCellInstance[comm.design, inst, TRUE] THEN TerminalIO.PutRope["done\n"] ELSE TerminalIO.PutRope["not done\n"]; }; }; PushIntoCellSIconic: PROC [comm: CDSequencer.Command] = { done: BOOL; name: Rope.ROPE _ NIL; inst: CD.Instance _ CDOps.TheInstance[design: comm.design, text: "push into representant "]; IF inst#NIL THEN { TerminalIO.PutRopes[CDOps.ObjectRope[inst.ob], "\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[" no iconic property; not done\n"] ELSE { TerminalIO.PutRopes[" pushing into ", name, "\n"]; done _ PushByName[comm.design, name, comm]; IF done THEN TerminalIO.PutRope["done\n"] ELSE TerminalIO.PutRope["failed\n"]; }; }; }; 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.PutRopes[CDOps.ObjectRope[inst.ob], " "]; TerminalIO.PutRopes[msg, "; deselected\n"]; }; 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.inDirectory 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.ExpandComplete[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[CDOps.ObjectRope[il.first.ob], " 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[CDOps.ObjectRope[someOb], " 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] = { autoOnly: BOOL _ comm.key#$DeleteUnUsedObjects; TerminalIO.PutRope["prune directory\n"]; CDDirectoryOps.PruneDirectory[design: comm.design, autoOnly: autoOnly, askFirst: TRUE]; }; DrawWithBorder: 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; }; DrawWithoutBorder: 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; inst: CD.Instance _ CDOps.TheInstance[comm.design]; IF inst#NIL THEN { desc _ CDOps.ObjectRope[inst.ob]; IF ~inst.ob.class.inDirectory THEN TerminalIO.PutRopes[" ", desc, " can not have name\n"] ELSE { newName: Rope.ROPE _ GetObjectName[comm.design, " new name > "]; IF Rope.IsEmpty[newName] THEN newName _ "-"; IF CDDirectory.Rename[comm.design, inst.ob, newName] THEN { CDSequencer.MarkChangedIOOnly[comm.design]; TerminalIO.PutRope[Rope.Cat[" ", desc, " renamed to ", CDDirectory.Name[inst.ob], "\n"]]; } ELSE TerminalIO.PutRope[" not done\n"] }; }; }; ReplaceObjectComm: PROC [comm: CDSequencer.Command] = { newName, oldName: Rope.ROPE; old, new: CD.Object; found: BOOL; 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) > "]; [found, old] _ CDDirectory.Fetch[comm.design, oldName]; IF ~found THEN {TerminalIO.PutRopes[" ", oldName, " not found\n"]; RETURN}; newName _ TerminalIO.RequestRope[" by (name) > "]; [found, new] _ CDDirectory.Fetch[comm.design, newName]; IF ~found THEN {TerminalIO.PutRopes[" ", newName, " not found\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]]; 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 => CDDirectoryOps.RenameNRemove[comm.design, new, oldName]; ENDCASE => NULL; TerminalIO.PutRope[" end replace\n"]; }; <<>> PushNamedComm: PROC [comm: CDSequencer.Command] = { done: BOOL; name: Rope.ROPE; TerminalIO.PutRope["push into cell by name\n"]; WITH comm.data SELECT FROM r: Rope.ROPE => { TerminalIO.PutRopes["push into cell", r, "\n"]; name _ r; }; ENDCASE => { TerminalIO.PutRope["push into cell by name\n"]; name _ GetObjectName[comm.design, " cell name >"]; TerminalIO.PutRopes[" for: ", name, "\n"]; }; done _ PushByName[comm.design, name, comm]; IF done THEN TerminalIO.PutRope["done\n"] ELSE TerminalIO.PutRopes["failed\n"] }; <<>> <<--**PushByName ************************>> foundAndStop: SIGNAL = CODE; HandleRec: TYPE = RECORD [ stopFlag: REF BOOL _ NIL, iDidIt: BOOL _ FALSE, gMark: CDMarks.MarkRange, cell: CD.Object _ NIL, drawStack: CD.InstanceList _ NIL ]; MyDrawChild: CD.DrawProc = { IF inst.ob.class.inDirectory THEN { h: REF HandleRec _ NARROW[pr.devicePrivate]; IF inst.ob=h.cell THEN { h.drawStack _ CONS[inst, h.drawStack]; h.iDidIt _ TRUE; SIGNAL foundAndStop }; WITH inst.ob.specific SELECT FROM cp: CD.CellSpecific => { IF inst.ob.marked#h.gMark THEN { inst.ob.marked _ h.gMark; h.drawStack _ CONS[inst, h.drawStack]; inst.ob.class.drawMe[inst: inst, trans: inst.trans, pr: pr]; h.drawStack _ h.drawStack.rest; }; }; ENDCASE => NULL; } }; PushByName: PROC [design: CD.Design, name: Rope.ROPE, comm: CDSequencer.Command_NIL] RETURNS [done: BOOL_FALSE] = { <<--comm is used to find a viewer used for scale changes...>> <<-- [using the viewer command enables its undo on the scale change]>> h: REF HandleRec = NEW[HandleRec_[ stopFlag: NEW[BOOL], gMark: 0 ]]; myDrawRef: CD.DrawRef _ CD.CreateDrawRef[[ design: design, interestClip: CDBasics.universe, drawChild: MyDrawChild, devicePrivate: h ]]; pushStack: CD.InstanceList _ NIL; --will be draw stack in reversed order MyDrawWithMark: PROC [mark: CDMarks.MarkRange] = { h.gMark _ mark; <<--draw only from pushed in cell point in hierarchy>> design.actual.first.dummyCell.ob.class.drawMe[inst: design.actual.first.dummyCell, trans: [[0, 0], original], pr: myDrawRef ! foundAndStop => CONTINUE]; }; ReverseInstanceList: PROC [list: CD.InstanceList] RETURNS[val: CD.InstanceList] = { val _ NIL; UNTIL list = NIL DO val _ CONS[list.first, val]; list _ list.rest; ENDLOOP; RETURN[val]; }; <<--set up>> h.cell _ CDDirectory.Fetch[design, name].object; IF h.cell=NIL THEN { TerminalIO.PutRopes["design does not have object ", name, "\n"]; RETURN }; <<--if we are already pushed in, it would not harm the program, >> <<--but it is checked because it would confuse the designer>> FOR pl: LIST OF CD.PushRec _ design.actual, pl.rest WHILE pl#NIL DO IF pl.first.mightReplace#NIL AND pl.first.mightReplace.ob=h.cell THEN { TerminalIO.PutRopes["design is already pushed into", name, "\n"]; RETURN } ENDLOOP; <<--check if a path to the cell exists, and build the path >> BEGIN markFailed: BOOL _ FALSE; TryFromCurrentLevel: PROC [] = { <<--check first if it exists in an easy accessible position on top level>> FOR il: CD.InstanceList _ CDOps.InstList[design], il.rest WHILE il#NIL DO IF il.first.ob=h.cell THEN { h.iDidIt _ TRUE; h.drawStack _ LIST[il.first]; EXIT }; ENDLOOP; <<--now try really hard>> IF ~ h.iDidIt THEN CDMarks.DoWithMark[design, MyDrawWithMark ! CDMarks.MarkOccupied => {markFailed _ TRUE; CONTINUE} ]; }; TryFromCurrentLevel[]; WHILE ~h.iDidIt AND ~markFailed AND CDCells.IsPushedIn[design] DO TerminalIO.PutRope["not found in accessible position\n try to pop\n"]; IF ~CDCellsInteractions.PopFromCell[design, interactive] THEN { TerminalIO.PutRope["failed: user did not allow pop out\n"]; RETURN }; TryFromCurrentLevel[]; ENDLOOP; IF markFailed THEN { TerminalIO.PutRope["**inconsistent use of mark\n"]; RETURN }; IF ~h.iDidIt THEN { h.drawStack _ LIST[CDOps.PlaceInst[design, h.cell, comm]]; TerminalIO.PutRopes["**object ", CDDirectory.Name[h.cell], " drawn**\n"]; }; END; <<--there is a path>> <<--make pushStack in push order; (reverse order as drawStack)>> pushStack _ ReverseInstanceList[h.drawStack]; --Don't trust that silly List module; <<--do the pushes>> WHILE pushStack#NIL DO <<--select exclusively the application we want to push in>> <<--pushing in makes a copy of the application list! check for the right object>> inst: CD.Instance _ NIL; CDSequencer.CheckAborted[design]; 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 cell failed\n"]; RETURN } ENDLOOP; IF ~CDCellsInteractions.PushInCellInstance[design, inst] THEN { TerminalIO.PutRope["push failed\n"]; IF comm#NIL THEN CDSequencer.ExecuteCommand[$ResetScaleTop, design, dontQueue, comm]; RETURN }; pushStack _ pushStack.rest ENDLOOP; <<--we are successully pushed in>> done _ TRUE; <<--position the viewer>> IF comm#NIL THEN CDSequencer.ExecuteCommand[$ResetScaleTop, design, dontQueue, comm]; <<--help the garbage collector>> h.drawStack _ NIL; myDrawRef.viewerPrivate _ NIL; myDrawRef _ NIL; pushStack _ NIL; }; TransformToCellS: 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.inDirectory AND ~CDCells.IsCell[l.first.ob] THEN { cob: CD.Object _ CDDirectory.ExpandComplete[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]]]; }; CDSequencer.ImplementCommand[$PopMenu, PopFromCellMenu,, doQueue]; CDSequencer.ImplementCommand[$PopNew, PopFromCellNew,, doQueue]; CDSequencer.ImplementCommand[$PopFlush, PopFromCellFlush,, doQueue]; CDSequencer.ImplementCommand[$PopReplace, PopFromCellReplace,, doQueue]; CDSequencer.ImplementCommand[$PushS, PushIntoCellS,, doQueue]; CDSequencer.ImplementCommand[$PushSIconic, PushIntoCellSIconic,, doQueue]; CDSequencer.ImplementCommand[$ExpandS, ExpandComm]; CDSequencer.ImplementCommand[$CreateCellSAndName, CreateCellAndName]; CDSequencer.ImplementCommand[$CreateCellSUnNamed, CreateCellDefaultName]; CDSequencer.ImplementCommand[$DisplayCellNames, DisplayCellNames,, doQueue]; CDSequencer.ImplementCommand[$RestricedDisplayCellNames, DisplayCellNames,, doQueue]; CDSequencer.ImplementCommand[$DrawCell, DrawObjectByNameComm]; CDSequencer.ImplementCommand[$RemoveCell, RemoveObFromDirComm,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedObjects, PruneDirComm,, doQueue]; CDSequencer.ImplementCommand[$DeleteUnUsedAutoObs, PruneDirComm,, doQueue]; CDSequencer.ImplementCommand[$CellSimplification, SetCellSimplificationComm,, doQueue]; CDSequencer.ImplementCommand[$RenameS, RenameObjectComm,, doQueue]; CDSequencer.ImplementCommand[$Replace, ReplaceObjectComm]; CDSequencer.ImplementCommand[$DrawWithoutBorder, DrawWithoutBorder]; CDSequencer.ImplementCommand[$DrawWithBorder, DrawWithBorder]; CDSequencer.ImplementCommand[$PushNamed, PushNamedComm,, doQueue]; CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellS]; CDValue.RegisterKey[$ObjectName, NIL, $chj]; CDValue.Store[NIL, $ObjectName, interactiveKey]; IF UserProfile.Boolean["ChipNDale.ObjectPrefix", FALSE] THEN { CDPanel.DefineRopeEntry[cdValueKey: $ObjectName, button: "object name:"]; CDPanel.DefineNewLine[]; }; END.