DIRECTORY CDOrient, RefStack, IPCoTab, IPCTG, IPTop, IPTopOpRecs, IPEditPrimitives, IPTopOpsPrivate, IPTopOps; IPTopStackOpsImpl: CEDAR PROGRAM IMPORTS RefStack, IPCoTab, IPTop, IPEditPrimitives, IPTopOpsPrivate, IPTopOps EXPORTS IPTopOps = BEGIN OPEN TOR: IPTopOpRecs, EP: IPEditPrimitives, CoTab: IPCoTab, CTG: IPCTG, Top: IPTop, IPTopOps; UndoStackEmpty: PUBLIC ERROR = CODE; StackSize: PUBLIC PROC[top: Top.Ref] RETURNS [NAT] = {RETURN [top.undoStack.Size]}; --StackSize-- ResetStacks: PUBLIC PROC[top: Top.Ref] = {top.undoStack.Reset; top.redoStack.Reset}; --ResetStacks-- GetTrack: PUBLIC PROC[top: Top.Ref, after: NAT] RETURNS [LIST OF REF] ={RETURN [RefStack.Copy[top.redoStack, after]]}; --GetTrack-- Undo: PUBLIC PROC[top: Top.Ref, n: NAT] RETURNS [prevTrack: LIST OF REF _ NIL] = { THROUGH [0..n) DO prevTrack _ CONS[Undo1[top], prevTrack]; ENDLOOP; }; --Undo-- Undo1: PUBLIC PROC[top: Top.Ref] RETURNS [REF]={ opRec: REF _ RefStack.Pop1[top.undoStack ! RefStack.RStackUnderflow => GOTO reSignal]; UndoDiscrmOpRec[top, opRec]; RETURN [RefStack.Pop1[top.redoStack]]; EXITS reSignal => ERROR UndoStackEmpty}; --Undo1-- Redo: PUBLIC PROC[top: Top.Ref, track: LIST OF REF] ={ WHILE track # NIL DO Redo1[top, track.first]; track _ track.rest; ENDLOOP;}; --Redo-- Redo1: PUBLIC PROC[top: Top.Ref, step: REF] ={ [] _ RedoDiscrmOpRec[top, step, TRUE] }; --Redo1-- UndoDiscrmOpRec: PROC [top: Top.Ref, opRec: REF] = { IF opRec = NIL THEN RETURN; WITH opRec SELECT FROM bc: TOR.IRBreakCross => {top.ReActivateChannel[bc.newCh1]; EP.BreakCross[bc.refCh, bc.chToBreak, bc.newCh1]}; fc: TOR.IRFormCross => {EP.FormCross[fc.refCh, fc.negCh, fc.posCh]; top.DestroyChannel[fc.posCh]; }; ic: TOR.IRInsertCo1 => {top.ReActivateChannel[ic.newCh1]; CoTab.ReActivateComponent[ic.co]; [] _ EP.InsertCo1[ic.co, ic.chToSplit, ic.negBnd, ic.posBnd, ic.sideToOpHint, ic.newCh1]}; rc: TOR.IRRemoveCo1 => { top.DestroyChannel[EP.RemoveCo1[rc.co, rc.shrinkDirectn, rc.sideToClHint].sideCh]; CoTab.DeActivateComponent[rc.co];}; ic: TOR.IRInsertCo2 => {top.ReActivateChannel[ic.newCh1]; CoTab.ReActivateComponent[ic.co]; [] _ EP.InsertCo2[ic.co, ic.chToSplit, ic.negBnd, ic.posBnd, ic.sideToOpHint, ic.newCh1]}; rc: TOR.IRRemoveCo2 => { top.DestroyChannel[EP.RemoveCo2[rc.co, rc.shrinkDirectn, rc.sideToClHint].sideCh]; CoTab.DeActivateComponent[rc.co];}; fz: TOR.IRFormZ => {top.ReActivateChannel[fz.newCh1]; top.ReActivateChannel[fz.newCh2]; EP.FormZ[fz.refCh, fz.negComp, fz.posComp, fz.zType, fz.newCh1, fz.newCh2]}; rz: TOR.IRRemoveZ =>{ top.DestroyChannel[EP.RemoveZ[rz.zSpine].posCh]; top.DestroyChannel[rz.zSpine];}; lt: TOR.IRLtoT => {top.DestroyChannel[EP.LtoT[lt.refCh, lt.whichEnd].posCh]}; tl: TOR.IRTtoL => {top.ReActivateChannel[tl.newCh1]; EP.TtoL[tl.refCh, tl.whichEnd, tl.lType, tl.endCo, tl.newCh1]}; fk: TOR.IRFlexKnee =>{top.ReActivateChannel[fk.newCh1]; EP.FlexKnee[fk.leg, fk.floor, fk.whichEnd, fk.whichDirection, fk.newCh1]}; ek: TOR.IRExtendKnee =>{[] _ EP.ExtendKnee[ek.shin]; top.DestroyChannel[ek.shin]}; scc: REF TOR.IRSetCoCornerSpRec => [] _ IPTopOpsPrivate.SetCoCornerSp[scc.co, scc.corner, scc.cornerSpace]; or: TOR.ROrient => [] _ Orient[top, or.co, or.operation]; sc: TOR.RSetComponent => [] _ SetComponent[top, sc.co, sc.active, sc.atPosition]; tc: TOR.RMoveComponent => [] _ MoveComponent[top, tc.co, tc.by]; sc: TOR.RSwapComponents => [] _ SwapComponents[top, sc.comp1, sc.comp2]; scs: TOR.RSetCompShape => [] _ SetCompShape[top, scs.comp, scs.shape, scs.chkArgs, FALSE]; icac: TOR.IRInsertCoAtCorner => {top.ReActivateChannel[icac.newHCh1]; top.ReActivateChannel[icac.newVCh1]; CoTab.ReActivateComponent[icac.co]; EP.InsertCoAtCorner[icac.host, icac.co, icac.corner, icac.newHCh1, icac.newVCh1]}; rcac: TOR.IRRemoveCoAtCorner =>{co: CoTab.Component; hCh, vCh: CTG.Channel; [co, hCh, vCh] _ EP.RemoveCoAtCorner[rcac.host, rcac.corner]; top.DestroyChannel[hCh]; top.DestroyChannel[vCh]; CoTab.DeActivateComponent[co];}; cc2: TOR.IRCreateComp2 => []_ IPCoTab.CreateComponent2[top.coTab, NIL, cc2.comp.shape, cc2.comp.active, cc2.orient, cc2.origin, cc2.comp]; dc2: TOR.IRDestroyComp2 =>[]_IPCoTab.DestroyComponent2[top.coTab, dc2.comp]; com: TOR.RComposite => WHILE com # NIL DO UndoDiscrmOpRec[top, com.first]; com _ com.rest ENDLOOP; ENDCASE => ERROR; }; --UndoDiscrmOpRec-- RedoDiscrmOpRec: PROC [top: Top.Ref, opRec: REF, keepTrack: BOOL] RETURNS [ir: TOR.RAny] = { IF opRec = NIL THEN { IF keepTrack THEN PushStacks[top, NIL, NIL]; RETURN [NIL]}; WITH opRec SELECT FROM bc: TOR.FRBreakCross => RETURN [BreakCross[top, bc.refCh, bc.chToBreak, keepTrack].ir]; fc: TOR.FRFormCross => RETURN [FormCross[top, fc.ch1, fc.ch2, keepTrack].ir]; fz: TOR.FRFormZ => RETURN [FormZ[top, fz.comp1, fz.comp2, fz.zType, keepTrack].ir]; rz: TOR.FRRemoveZ => RETURN [RemoveZ[top, rz.zSpine, keepTrack].ir]; lt: TOR.FRLtoT => RETURN [LtoT[top, lt.ch, lt.whichEnd, keepTrack].ir]; tl: TOR.FRTtoL => RETURN [TtoL[top, tl.co, tl.ch, tl.lType, keepTrack].ir]; fk: TOR.FRFlexKnee => RETURN [FlexKnee [top, fk.leg, fk.floor, fk.whichEnd, keepTrack].ir]; ek: TOR.FRExtendKnee => RETURN [ExtendKnee [top, ek.shin, keepTrack].ir]; ft: TOR.FRFlipT => RETURN[FlipT[top, ft.chToBend, ft.attachTo, ft.whichEnd, keepTrack].ir]; g1: TOR.FRGrow1 => RETURN [Grow1 [top, g1.co, g1.host, g1.hostCorner, keepTrack].ir]; s1: TOR.FRShrink1 => RETURN [IPTopOpsPrivate.Shrink1 [top, s1.co, keepTrack].ir]; ic: TOR.FRInsertCo => RETURN [IPTopOpsPrivate.InsertCo [top, ic.co, ic.chToSplit, ic.negBnd, ic.posBnd, ic.sideHint, ic.whichFirstHint, keepTrack].ir]; rc: TOR.FRRemoveCo => RETURN [IPTopOpsPrivate.RemoveCo [top, rc.co, rc.shrinkDirectn, keepTrack].ir]; or: TOR.ROrient => RETURN [Orient[top, or.co, or.operation, keepTrack].ir]; sc: TOR.RSetComponent => RETURN [SetComponent[top, sc.co, sc.active, sc.atPosition, keepTrack].ir]; tc: TOR.RMoveComponent => RETURN [MoveComponent[top, tc.co, tc.by, keepTrack].ir]; sc: TOR.RSwapComponents => RETURN [SwapComponents[top, sc.comp1, sc.comp2, keepTrack].ir]; sc: TOR.FRSpawnComps => RETURN [SpawnComps[top, sc.comp, NIL, NIL, [], [], sc.splitDirection, sc.chkArgs, keepTrack, sc.negChild, sc.posChild].ir]; scs: TOR.RSetCompShape => RETURN [SetCompShape[top, scs.comp, scs.shape, scs.chkArgs, keepTrack].ir]; com: TOR.RComposite => {l: LIST OF REF _ NIL; FOR comRev: TOR.RComposite _ LReverse[com], comRev.rest UNTIL comRev = NIL DO l _ CONS[RedoDiscrmOpRec[top, comRev.first, FALSE], l]; ENDLOOP; IF keepTrack THEN PushStacks[top, com, l]; RETURN [l]}; ENDCASE => ERROR; }; --RedoDiscrmOpRec-- LReverse: PROC [list: LIST OF REF] RETURNS[val: LIST OF REF] = INLINE{ val _ NIL; UNTIL list = NIL DO val _ CONS[list.first, val]; list _ list.rest; ENDLOOP; RETURN[val]; }; -- LReverse-- END. zFile: IPTopStackOpsImpl.mesa Last Edited by: CSChow, January 27, 1985 6:25:01 am PST --##Private Procedures##-- ΚL˜Jšœ™J™7J™J™šΟk ˜ Jšœ ˜ J˜ J˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜J˜Jšœ ˜ J˜—šœœœ˜"JšœF˜MJšœ œœœœ$œœ˜wJ˜Jšœœœœ˜$J˜J˜IcodešΟn œœœœœœΟc œ˜bK˜Kšž œœœ=Ÿ˜dK™Kšžœœœœœœœœœ)Ÿ œ˜ƒJ˜šžœœœœœ œœœœ˜Ršœœ˜Jšœ œ˜(Jšœ˜—JšœŸœ˜ —K˜š žœœœœœ˜0Jšœœ=œ ˜VJšœ˜Kšœ ˜&š˜Jšœ œŸœ˜,——J˜K™š žœœœœœœ˜6šœ œ˜Kšœ˜K˜KšœŸž˜——šžœœœœ˜.Kšœ œ˜%KšœŸ ˜ —J˜KšŸ™K˜K˜šžœœœ˜4Kšœ œœœ˜šœœ˜šœœ3˜:Kšœ0˜2—šœœœ)˜CKšœ ˜ —K˜šœœ2˜9Kšœ!˜!KšœœS˜Z—šœœ˜Kšœœ=˜RKšœ#˜#—K˜šœœ2˜9Kšœ!˜!KšœœS˜Z—šœœ˜Kšœœ=˜RKšœ#˜#—K˜šœœP˜WKšœJ˜L—šœœ˜Kšœœ˜0Kšœ ˜ —K˜Kšœœœ%˜Mšœœ-˜4Kšœ=˜?—K˜šœœ0˜7KšœH˜J—šœœœ˜4Kšœ˜—K˜Kšœœœ`˜lK˜Kšœœ2˜9KšœœJ˜QKšœœ9˜@KšœœA˜HKšœœKœ˜Zšœœ<˜EKšœ$˜$Kšœ#˜#KšœP˜R—šœœ+˜4Kšœ œ ˜Kšœœ*˜=Kšœ˜Kšœ˜Kšœ ˜ —Kšœœ:œE˜ŠKšœœD˜Lšœœ˜Kšœœœ1œ˜K—Kšœœ˜—JšœŸ˜—J˜J˜š žœœœ œœœ ˜\šœ œœ˜Kšœ œœœ˜,Kšœœ˜—šœœ˜Kšœœœ9˜WKšœœœ0˜MKšœœ œ:˜SKšœœœ)˜DKšœœ œ/˜GKšœœ œ3˜KKšœœœ@˜\Kšœœœ+˜IKšœœ œB˜[Kšœœ œ<˜UKšœœœ6˜QKšœœœ{˜—KšœœœI˜eKšœœ œ2˜KKšœœœD˜cKšœœœ2˜RKšœœœ9˜ZKšœœœu˜“KšœœœE˜eš œœœœœœ˜-š œ œ)œ œ˜MKšœœ$œ˜7Kšœ˜—Kšœ œ˜*Kšœ˜ —Kšœœ˜—KšœŸœ˜—J˜šžœœœœœœœœœœ˜FJšœœ˜ šœœ˜Jšœœ˜J˜Jšœ˜—Jšœ˜ JšœŸ ˜—J˜Jšœ˜——…—\""