DIRECTORY TextLooks, TextNode, TextEdit, UndoEvent; EditSpan: CEDAR DEFINITIONS = BEGIN Ref: TYPE = TextNode.Ref; RefTextNode: TYPE = TextNode.RefTextNode; RefOtherNode: TYPE = TextNode.RefOtherNode; Offset: TYPE = TextNode.Offset; MaxLen: Offset = LAST[Offset]; Location: TYPE = TextNode.Location; Span: TYPE = TextNode.Span; Event: TYPE = UndoEvent.Ref; CannotDoEdit: ERROR; afterMoved1, afterMoved2: Location; Looks: TYPE = TextLooks.Looks; noLooks: Looks = TextLooks.noLooks; allLooks: Looks = TextLooks.allLooks; ChangeLooks: PROC [root: Ref, span: Span, remove, add: Looks, event: Event _ NIL]; AddLooks: PROC [root: Ref, span: Span, add: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, noLooks, add, event] }; RemoveLooks: PROC [root: Ref, span: Span, remove: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, remove, noLooks, event] }; SetLooks: PROC [root: Ref, span: Span, new: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, allLooks, new, event] }; ClearLooks: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeLooks[root, span, allLooks, noLooks, event] }; Replace: PROC [destRoot, sourceRoot: Ref, dest, source: Span, words: BOOLEAN _ FALSE, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] RETURNS [result: Span]; Delete: PROC [root: Ref, del: Span, event: Event _ NIL, saveForPaste: BOOLEAN _ TRUE]; SaveForPaste: PROC [span: Span, event: Event _ NIL]; SavedForPaste: PROC RETURNS [span: Span]; Place: TYPE = { before, after, sibling, child }; Copy: PROC [destRoot, sourceRoot: Ref, dest: Location, source: Span, words: BOOLEAN _ FALSE, where: Place _ after, nesting: INTEGER _ 0, event: Event _ NIL] RETURNS [result: Span]; Move: PROC [destRoot, sourceRoot: Ref, dest: Location, source: Span, words: BOOLEAN _ FALSE, where: Place _ after, nesting: INTEGER _ 0, event: Event _ NIL] RETURNS [result: Span]; MoveOnto: PROC [destRoot, sourceRoot: Ref, dest, source: Span, words: BOOLEAN _ FALSE, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] RETURNS [result: Span]; Transpose: PROC [alphaRoot, betaRoot: Ref, alpha, beta: Span, words: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [newAlpha, newBeta: Span]; Insert: PROC [root, old: Ref, where: Place _ after, event: Event _ NIL] RETURNS [new: Ref]; Inherit: PROC [old, new: Ref, allprops: BOOL _ FALSE]; InsertTextNode: PROC [root, old: Ref, where: Place _ after, inherit: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [new: RefTextNode]; InsertOtherNode: PROC [root, old: Ref, where: Place _ after, inherit: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [new: RefOtherNode]; Split: PROC [root: Ref, loc: Location, event: Event _ NIL] RETURNS [new: Ref]; Merge: PROC [root, node: Ref, event: Event _ NIL] RETURNS [loc: Location]; Nest: PROC [root: Ref, span: Span, event: Event _ NIL] RETURNS [new: Span] = INLINE { new _ ChangeNesting[root,span,1,event] }; UnNest: PROC [root: Ref, span: Span, event: Event _ NIL] RETURNS [new: Span] = INLINE { new _ ChangeNesting[root,span,-1,event] }; ChangeNesting: PROC [root: Ref, span: Span, change: INTEGER, event: Event _ NIL] RETURNS [new: Span]; AllCaps: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,allCaps,event] }; AllLower: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,allLower,event] }; InitialCaps: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,initCaps,event] }; CapChange: TYPE = TextEdit.CapChange; ChangeCaps: PROC [root: Ref, span: Span, how: CapChange _ allCaps, event: Event _ NIL]; NodeOrder: TYPE = { before, same, after, disjoint }; CompareNodeOrder: PROC [node1, node2: Ref] RETURNS [order: NodeOrder]; Start: PROC; -- for initialization only END. R-- EditSpan.mesa -- written by Bill Paxton, June 1981 -- last edit by Bill Paxton, October 13, 1982 2:22 pm -- last edit by Russ Atkinson, July 22, 1983 9:50 am -- Miscellaneous -- hints for repaint set by Move, MoveOnto, and Transpose -- gives pointers to locs after the moved spans -- **** Operations to add or delete looks **** -- first remove then add in the given span -- ***** Editing operations on spans -- replace dest span by copy of source span -- if words flag is true, does ReplaceWords instead of ReplaceText -- result is the new copy of source -- result is last thing deleted or explicitly saved for Paste -- these are modifiers for the destination of a Move or Copy or Insert -- only apply when destination is an entire node (i.e., dest.where = NodeItself) -- place = before means insert as sibling before dest -- place = after means insert as sibling after dest; inherit children of dest -- place = sibling means insert as sibling after dest; don't inherit children of dest -- place = child means insert as first child of dest -- result is the new copy of source -- dest cannot be within source or get error BadMove -- result is moved span -- nesting is relative to dest -- e.g., where=after and nesting=1 makes source be child of dest -- like Replace, but moves source instead of copying it -- result is moved span -- alpha and beta must not overlap or get error BadTranspose -- newAlpha is new location of alpha span; ditto for newBeta -- ***** New nodes; split & merge -- empty copy of old node is inserted in tree in position determined by "where" -- empty text node is inserted in tree -- empty "other" kind of node is inserted in tree -- inserts copy of loc.node is inserted directly before loc.node (as sibling) -- new adopts children of old (if any) -- if loc.where # NodeItself and loc.node is a text node, then -- text after loc.where moves to new node -- text before loc.where stays in old node -- returns the new node -- copies text of node to end of previous node -- then deletes node -- ***** Nesting -- moves span to a deeper nesting level in tree -- moves all nodes of span, even if don't have entire node selected -- moves span to a shallower nesting level in tree -- ***** Cap's and Lowercase -- force specified span to all uppercase -- force specified span to all lowercase -- force first letter of words uppercase -- ***** Miscellaneous -- determines relative order in tree of the nodes -- returns "same" if node1 = node2 -- returns "before" if node1 comes before node2 -- returns "after" if node1 comes after node2 -- returns "disjoint" if nodes are not from the same tree -- ***** Initialization Ê6˜JšÏc™Jš$™$Jš5™5Jš4™4J˜JšÏk ˜ J˜ J˜ J˜ J˜ J˜šœ žœž œ˜Jšœž˜—J˜Jšœžœ˜Jšœ žœ˜)Jšœžœ˜+Jšœžœ˜Jšœžœ ˜Jšœ žœ˜#Jšœžœ˜Jšœžœ˜J˜Jš™J˜Jšœžœ˜J˜˜#Jš9™9Jš/™/J˜—Jš.™.J˜Jšœžœ˜J˜#J˜%J˜šÏn œžœ<žœ˜RJš*™*J˜—šŸœžœ4žœ˜FJšœžœ2˜:J˜—šŸ œžœ7žœ˜LJšœžœ5˜=J˜—šŸœžœ4žœ˜FJšœžœ3˜;J˜—šŸ œžœ(žœ˜Jš œžœžœžœžœžœ˜IJšžœ˜Jš7™7Jš™J˜—š Ÿ œžœ6žœžœžœ˜iJšžœ˜"Jš<™™>Jš)™)Jš*™*—Jš™J˜—šŸœžœ"žœžœ˜JJš.™.Jš™J˜—Jš™J˜š Ÿœžœ(žœžœžœ˜UJš/™/JšD™DJ˜)J˜—š Ÿœžœ(žœžœžœ˜WJš2™2J˜*J˜—šŸ œžœ!žœžœ˜PJšžœ ˜J˜J˜—Jš™J˜šŸœžœ(žœ˜;Jšžœ)˜/Jš(™(J˜—šŸœžœ(žœ˜