DIRECTORY EditSpan USING [CannotDoEdit, Transpose], EditSpanSupport USING [CopySpan], MessageWindow USING [Append, Blink], NodeProps, TextEdit, TextNode, TEditDocument USING [Selection, TEditDocumentData], TEditInput USING [currentEvent], TEditInputOps USING [CallWithLocks, Delete], TEditSelection USING [GetSelectionGrain, MakeSelection], Tioga, TiogaAccess USING [Reader, Writer, FinishWrite, FromNode], TiogaAccessViewers USING [], ViewerClasses USING [Viewer], ViewerOps USING [PaintViewer]; TiogaAccessViewersImpl: CEDAR PROGRAM IMPORTS EditSpan, EditSpanSupport, MessageWindow, TEditInput, TEditInputOps, TEditSelection, TiogaAccess, ViewerOps, NodeProps, TextEdit, TextNode EXPORTS TiogaAccessViewers ~ BEGIN Node: TYPE ~ Tioga.Node; Span: TYPE ~ Tioga.Span; NodeItself: INT ~ Tioga.NodeItself; Viewer: TYPE ~ ViewerClasses.Viewer; Selection: TYPE ~ TEditDocument.Selection; Reader: TYPE ~ TiogaAccess.Reader; Writer: TYPE ~ TiogaAccess.Writer; SelectionSpan: PROC [sel: Selection] RETURNS [span: Span] ~ { start: Tioga.Location ~ sel.start.pos; end: Tioga.Location ~ sel.end.pos; IF TEditSelection.GetSelectionGrain[sel] 0 THEN { TakeNodeSubstr[copy.start.node, copy.start.where, INT.LAST]; copy.start.where ¬ 0; }; textNode ¬ copy.start.node; CopyNodeProps[root: root, newRoot: TextNode.Root[textNode]]; }; }; TEditInputOps.CallWithLocks[LockedCopySelection, read]; }; FromSelection: PUBLIC PROC RETURNS [Reader] ~ { textNode: Node ¬ NIL; myOffset: INT ¬ 0; [textNode, myOffset] ¬ CopySelection[]; RETURN [TiogaAccess.FromNode[textNode, myOffset]] }; CopyDoc: PUBLIC PROC [root: Node] RETURNS [copy: Node ¬ NIL] ~ { r: Node ¬ TextNode.Root[ EditSpanSupport.CopySpan[ -- adds an extra r node TextNode.MakeNodeSpan[root, TextNode.LastWithin[root]] ] .start.node ]; copy ¬ TextNode.FirstChild[r]; -- get rid of the extra r node copy.parent ¬ copy.next ¬ NIL; -- no parent or siblings r.child ¬ NIL; r ¬ NIL;-- don't want r any more }; FromViewer: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [Reader] ~ { textNode: Node ¬ NIL; WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => textNode ¬ CopyDoc[tdd.text]; ENDCASE => NULL; RETURN [TiogaAccess.FromNode[textNode]] }; SetSelectionFromSpan: PROC [tSel: Selection, span: TextNode.Span] ~ { IF span.start.node = span.end.node THEN { IF (span.start.where = NodeItself) # (span.end.where = NodeItself) THEN ERROR; -- someone made a bogus span. IF span.start.where = NodeItself THEN { span.start.where ¬ 0; span.end.where ¬ MAX[TextEdit.Size[span.end.node]-1, 0]; tSel.granularity ¬ node; } ELSE { tSel.granularity ¬ MIN[tSel.granularity, word]; IF span.start.where <= span.end.where THEN { tSel.granularity ¬ MAX[tSel.granularity, char]; } ELSE { tSel.granularity ¬ point; span.end.where ¬ span.start.where; }; }; } ELSE { IF span.start.where = NodeItself AND span.end.where = NodeItself THEN { tSel.granularity ¬ MAX[tSel.granularity, node]; } ELSE { tSel.granularity ¬ char; }; IF span.start.where=NodeItself THEN span.start.where ¬ 0; IF span.end.where=NodeItself THEN span.end.where ¬ MAX[TextEdit.Size[span.end.node]-1, 0]; }; tSel.start.pos ¬ span.start; tSel.end.pos ¬ span.end; }; WriteSelection: PUBLIC PROC [writer: Writer] ~ { action: PROC [root, first, last: Node] ~ { IF root = NIL THEN TEditInputOps.Delete[] ELSE { success: BOOL ¬ FALSE; lastSize: INT ¬ TextEdit.Size[last]; startOffset: INT ¬ IF lastSize=0 AND first=last THEN NodeItself ELSE 0; endOffset: INT ¬ IF lastSize=0 THEN NodeItself ELSE lastSize-1; alpha: Span ¬ [start: [node: first, where: startOffset], end: [node: last, where: endOffset]]; DoTranspose: PROC [root: Node, tSel: Selection] ~ { beta: Span ¬ SelectionSpan[tSel]; documentRoot: Node ¬ TextNode.Root[beta.start.node]; IF tSel.granularity = node OR tSel.granularity = branch THEN { alpha.start.where ¬ alpha.end.where ¬ NodeItself; }; success ¬ TRUE; [alpha, beta] ¬ EditSpan.Transpose[alphaRoot: root, betaRoot: documentRoot, alpha: alpha, beta: beta, event: TEditInput.currentEvent ! EditSpan.CannotDoEdit => {success ¬ FALSE; CONTINUE}]; IF success THEN { tSel.pendingDelete ¬ FALSE; SetSelectionFromSpan[tSel, alpha]; TEditSelection.MakeSelection[new: tSel, selection: primary]; }; }; TEditInputOps.CallWithLocks[DoTranspose, write]; IF NOT success THEN { MessageWindow.Append["Can't do it.", TRUE]; MessageWindow.Blink[]; }; }; }; TiogaAccess.FinishWrite[writer, action]; }; WriteViewer: PUBLIC PROC [writer: Writer, viewer: ViewerClasses.Viewer] ~ { action: PROC [root, first, last: Node] ~ { IF viewer # NIL AND viewer.data # NIL AND viewer.class.set # NIL THEN { viewer.class.set[viewer, root, FALSE, $TiogaDocument]; ViewerOps.PaintViewer[viewer, all]; }; }; TiogaAccess.FinishWrite[writer, action]; }; END. ˆ TiogaAccessViewersImpl.mesa Copyright Σ 1991, 1992 by Xerox Corporation. All rights reserved. Doug Wyatt, December 18, 1991 0:24 am PST Provides a TiogaAccess interface to text viewers and the current selection. [name: ATOM, value: REF] RETURNS [quit: BOOL ¬ FALSE]; style ¬ Atom.GetPName[NodeStyleOps.StyleNameForNode[root]]; span is exactly one node. part of a node last before first means a point selection crosses multiple nodes includes all entire nodes. includes partial nodes. Now span has been sanitized of NodeItself flag, with the information (mostly) relayed to tSel.granularity. All that's left is to plug in the locations. Κ.–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ7™BK™)K˜K™KK™—šΟk ˜ Kšœ žœ˜)Kšœžœ ˜!Kšœžœ˜$Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœžœ ˜3Kšœ žœ˜ Kšœžœ˜,Kšœžœ$˜8Kšœ˜Kšœ žœ)˜:Kšœžœ˜Kšœžœ ˜Kšœ žœ˜—K˜KšΟnœžœž˜%Kšžœ‹˜’Kšžœ˜Kšœž˜K˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜#Kšœžœ˜$Kšœ žœ˜*Kšœžœ˜"Kšœžœ˜"K˜šŸ œžœžœ˜=Kšœ&˜&Kšœ"˜"Kšžœ,žœžœ˜GKšžœžœ.˜9K˜K˜—šŸœžœžœ žœ˜;K˜Kšœx˜xK˜K˜—šŸ œžœ˜-šŸœ˜,Kš œžœ žœžœžœžœ™7KšœB˜BKšžœžœ˜K˜—K•StartOfExpansionn[n: TextNode.Ref, action: NodeProps.MapPropsAction, formatFlag: BOOL _ TRUE, commentFlag: BOOL _ TRUE]šœ9˜9Kšœ˜K˜—š Ÿ œžœžœžœžœ žœ ˜NšŸœžœ"˜;Kšœ;™;šžœžœ˜"Kšœ!˜!Kšœ,˜,Kšœbžœ˜hšžœžœžœžœ˜=Kšœ3˜3Kšœ˜—šžœžœ˜Kšœ2žœžœ˜Kšœ1˜1Kšœ˜—Kšœ žœ˜Kšœ«žœžœ˜½šžœ žœ˜Kšœžœ˜Kšœ"˜"Kšœ<˜