<> <> DIRECTORY EditGroup, EditNotify, NodeProps, Rope, UndoEvent, TextEdit, TreeSlice, TiogaLooks, TiogaNode, TiogaNodeOps, TiogaTreeOps; EditGroupImpl: CEDAR PROGRAM IMPORTS NodeProps, TextEdit, TiogaNodeOps, TiogaTreeOps, UndoEvent, TreeSlice, EditNotify EXPORTS EditGroup SHARES TiogaNode = BEGIN OPEN EditGroup; DeleteGroup: PUBLIC PROC [ root: RefBranchNode, start, end: Ref, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] = { <<>> ReplaceGroup: PUBLIC PROC [ destRoot, sourceRoot: RefBranchNode, destStart, destEnd: Ref, sourceStart, sourceEnd: Ref, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] = { <> <> <<>> CopyGroup: PUBLIC PROC [ destRoot, sourceRoot: RefBranchNode, dest: Ref, contents: BOOL, sourceStart, sourceEnd: Ref, event: Event _ NIL] = { <> <> MoveGroup: PUBLIC PROC [ destRoot, sourceRoot: RefBranchNode, dest: Ref, contents: BOOL, sourceStart, sourceEnd: Ref, event: Event _ NIL] = { <> <> IF sourceEnd # sibling* of sourceStart THEN ERROR; sourceParent _ TiogaTreeOps.Parent[sourceEnd]; IF (beforeSource _ TiogaTreeOps.Previous[sourceStart, sourceParent])=NIL THEN beforeSource _ sourceParent; afterSource _ TiogaTreeOps.Next[sourceEnd]; IF contents THEN { IF TiogaTreeOps.Contents[dest]=sourceStart THEN RETURN } -- already in position ELSE IF dest=beforeSource THEN RETURN; -- already in position IF dest # NIL AND dest in [sourceStart..LastWithin[sourceEnd]] THEN ERROR cannot; -- dest inside source IF ~contents AND (TiogaNodeOps.IsBranch[dest]#TiogaNodeOps.IsBranch[sourceStart]) THEN ERROR cannot; -- cannot mix branch and nonbranch IF contents AND TiogaNodeOps.IsBranch[dest] AND TiogaNodeOps.IsBasic[sourceStart]) THEN ERROR cannot; IF contents AND (TiogaNodeOps.IsBasic[dest] OR TiogaNodeOps.IsText[dest]) THEN ERROR cannot; IF dest=NIL THEN -- moving to limbo -- { dest _ create list node as dest; contents _ TRUE }; beforeLoc _ [TiogaTreeOps.StepBackwardNode[sourceStart].back,0]; afterLoc _ [TiogaTreeOps.StepForwardNode[TiogaTreeOps.LastWithin[sourceEnd]],0]; notify _ NEW[MovingGroup Change _ [MovingGroup[ destRoot,sourceRoot,dest,sourceStart,sourceEnd,beforeSource,(beforeSource=sourceParent)]]]; IF beforeSource=NIL THEN { notify.from _ sourceParent; notify.contents _ TRUE }; Notify[notify, before]; <> IF beforeSource=sourceParent THEN { -- moving the initial part of the contents/children list WITH sourceParent SELECT FROM br: RefBranchNode => { IF sourceStart=br.child THEN -- moving children rather than contents IF sourceEnd.last THEN br.child _ NIL -- moving all the children ELSE { -- leaving some of the children nxt: RefBranchNode = TiogaNodeOps.NarrowToBranchNode[sourceEnd.next]; IF nxt=NIL THEN ERROR; br.child _ nxt } ELSE IF sourceStart=br.contents THEN -- moving contents rather than children IF sourceEnd.last THEN br.contents _ NIL -- moving all the contents ELSE { -- leaving some of the contents nxt: RefItemNode = TiogaNodeOps.NarrowToItemNode[sourceEnd.next]; IF nxt=NIL THEN ERROR; br.contents _ nxt } ELSE ERROR }; bx: RefBoxNode => bx.contents _ afterSource; ls: RefListNode => ls.contents _ afterSource; ENDCASE => ERROR } ELSE { -- not moving the initial part of the contents list beforeSource.next _ sourceEnd.next; beforeSource.last _ sourceEnd.last }; <> IF contents THEN { -- it moves to front of contents/children of dest WITH dest SELECT FROM br: RefBranchNode => { WITH sourceStart SELECT FROM br1: RefBranchNode => { -- insert as children rather than contents IF br.child=NIL THEN { sourceEnd.next _ br; sourceEnd.last _ TRUE } ELSE { sourceEnd.next _ br.child; sourceEnd.last _ FALSE }; br.child _ br1 }; itm: RefItemNode => { -- insert as contents rather than as children IF br.contents=NIL THEN { sourceEnd.next _ br; sourceEnd.last _ TRUE } ELSE { sourceEnd.next _ br.contents; sourceEnd.last _ FALSE }; br.contents _ itm }; ENDCASE => ERROR }; bx: RefBoxNode => { IF bx.contents=NIL THEN { sourceEnd.next _ bx; sourceEnd.last _ TRUE } ELSE { sourceEnd.next _ bx.contents; sourceEnd.last _ FALSE }; bx.contents _ sourceStart }; ls: RefListNode => IF ls.contents=NIL THEN { sourceEnd.next _ ls; sourceEnd.last _ TRUE } ELSE { sourceEnd.next _ ls.contents; sourceEnd.last _ FALSE }; ls.contents _ sourceStart }; ENDCASE => ERROR } ELSE { -- moving to after dest as sibling sourceEnd.next _ dest.next; sourceEnd.last _ dest.last; dest.next _ sourceStart; dest.last _ FALSE }; Notify[notify, after]; UndoEvent.Note[event, UndoMoveGroup, notify] }; afterMoved2 _ afterMoved1; -- save previous hint afterMoved1 _ IF afterLoc.node # NIL THEN afterLoc ELSE beforeLoc; -- hint for repaint }; <<>> UndoMoveGroup: PROC [undoRef: REF, currentEvent: Event] = TRUSTED { saved: REF Change _ NARROW[undoRef]; WITH x:saved SELECT FROM MovingGroup => { [] _ MoveGroup[x.sourceRoot, x.destRoot, x.from, x.contents, x.sourceStart, x.sourceEnd, currentEvent] }; ENDCASE => ERROR }; MoveGroupOnto: PUBLIC PROC [ destRoot, sourceRoot: RefBranchNode, destStart, destEnd: Ref, sourceStart, sourceEnd: Ref, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] = { <> <> <<>> TransposeGroups: PUBLIC PROC [ alphaRoot, betaRoot: RefBranchNode, alphaStart, alphaEnd: Ref, betaStart, betaEnd: Ref, event: Event _ NIL] = { <> <> <<>> END...