DIRECTORY Convert USING [Error, IntFromRope], MessageWindow USING [Append, Blink, Clear], NodeProps USING [GetProp], Rope USING [Concat, IsEmpty, ROPE, Size, Substr], TEditDocument USING [Selection, SelectionId, TEditDocumentData], TEditInput USING [CloseEvent], TEditLocks USING [LockDocAndTdd, LockRef, UnlockDocAndTdd], TEditOps USING [GetSelContents, RememberCurrentPosition], TEditProfile USING [selectionCaret], TEditRefresh USING [ScrollToEndOfSel], TEditSelection USING [Alloc, Copy, Free, FindWhere, LockSel, MakeSelection, sSel, fSel, pSel, SetSelLooks, UnlockSel], TEditSelectionOps USING [], TextEdit USING [RefTextNode], TextFind USING [MalformedPattern], TextNode USING [EndPos, FirstChild, Location, LocWithin, Offset, Ref, RefTextNode], TreeFind USING [CreateFromRope, Finder, Try, TryBackwards], ViewerClasses USING [Viewer], ViewerOps USING [BlinkDisplay]; TEditSelectionOpsImpl: CEDAR PROGRAM IMPORTS Convert, MessageWindow, NodeProps, Rope, TEditInput, TEditLocks, TEditOps, TEditProfile, TEditRefresh, TEditSelection, TextFind, TextNode, TreeFind, ViewerOps EXPORTS TEditSelection, TEditSelectionOps = BEGIN ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; SelectionId: TYPE ~ TEditDocument.SelectionId; Selection: TYPE ~ TEditDocument.Selection; CallWithSelAndDocAndTddLocks: PUBLIC PROC [viewer: Viewer, id: SelectionId _ primary, proc: PROC [tdd: TEditDocument.TEditDocumentData, tSel: Selection]] = { IF viewer # NIL THEN WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { tSel: Selection _ NIL; lockRef: TEditLocks.LockRef _ NIL; Cleanup: PROC = { TEditSelection.UnlockSel[id]; IF lockRef # NIL THEN TEditLocks.UnlockDocAndTdd[tdd]; IF tSel # NIL THEN TEditSelection.Free[tSel] }; IF tdd # NIL THEN { ENABLE UNWIND => Cleanup[]; TEditSelection.LockSel[id, "CallWithSelAndDocAndTddLocks"]; lockRef _ TEditLocks.LockDocAndTdd[tdd, "CallWithSelAndDocAndTddLocks", read]; IF lockRef#NIL THEN { sel: Selection = SELECT id FROM primary => TEditSelection.pSel, secondary => TEditSelection.sSel, feedback => TEditSelection.fSel, ENDCASE => ERROR; tSel _ TEditSelection.Alloc[]; TEditSelection.Copy[source: sel, dest: tSel]; proc[tdd, tSel] }; Cleanup[]; }; }; ENDCASE; }; ShowPosition: PUBLIC PROC[viewer: Viewer, skipCommentNodes: BOOL _ TRUE] = { count: INT _ -1; sel: ROPE _ TEditOps.GetSelContents[]; count _ Convert.IntFromRope[sel ! Convert.Error => CONTINUE]; IF count>=0 THEN ShowGivenPosition[viewer, count, skipCommentNodes] ELSE { MessageWindow.Append["Select character count for position.", TRUE]; MessageWindow.Blink[] }; }; Position: PUBLIC PROC[viewer: Viewer] ~ { ShowPosition[viewer: viewer, skipCommentNodes: TRUE]; }; ShowGivenPosition: PUBLIC PROC [viewer: Viewer, pos: INT, skipCommentNodes: BOOL _ TRUE] = { DoPosition: PROC [tdd: TEditDocument.TEditDocumentData, tSel: Selection] = { tiogaFile: BOOL _ (NodeProps.GetProp[tdd.text, $FromTiogaFile] = $Yes); IF NOT tiogaFile THEN pos _ pos+1; -- hack to compensate for leading CR tSel.start.pos _ tSel.end.pos _ TextNode.LocWithin[tdd.text, pos, 1, skipCommentNodes]; tSel.end.pos.where _ MIN[tSel.end.pos.where+3, TextNode.EndPos[tSel.end.pos.node]]; tSel.start.pos.where _ MIN[tSel.end.pos.where, tSel.start.pos.where]; IF tSel.start.pos.where=tSel.end.pos.where AND tSel.start.pos.where > 0 THEN tSel.start.pos.where _ tSel.start.pos.where-1; tSel.granularity _ char; tSel.viewer _ viewer; tSel.data _ tdd; tSel.pendingDelete _ FALSE; tSel.insertion _ IF TEditProfile.selectionCaret=before THEN before ELSE after; TEditOps.RememberCurrentPosition[viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel, selection: feedback]; TEditRefresh.ScrollToEndOfSel[viewer, FALSE, feedback]; }; CallWithSelAndDocAndTddLocks[viewer, feedback, DoPosition]; }; targetOfLastSearch: ROPE _ NIL; Find: PUBLIC PROC [viewer: Viewer, findWhere: TEditSelection.FindWhere _ anywhere, def, word: BOOL _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] ~ { rope: ROPE _ TEditOps.GetSelContents[]; IF Rope.IsEmpty[rope] THEN rope _ targetOfLastSearch ELSE targetOfLastSearch _ rope; IF Rope.IsEmpty[rope] THEN { MessageWindow.Append["Select target for search.", TRUE]; MessageWindow.Blink[]; } ELSE FindRope[viewer, rope, findWhere, def, word, id, case]; }; FindRope: PUBLIC PROC [viewer: Viewer, rope: ROPE, findWhere: TEditSelection.FindWhere _ anywhere, def, word: BOOL _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] = { IF NOT DoFind[viewer, rope, findWhere, def, word, id, case] THEN { target: ROPE _ rope; IF Rope.Size[target]>50 THEN target _ Rope.Concat[Rope.Substr[target, 0, 47], "..."]; MessageWindow.Append[Rope.Concat[target, " not found."], TRUE]; ViewerOps.BlinkDisplay[]; } ELSE MessageWindow.Clear[]; }; DoFind: PUBLIC PROC [viewer: Viewer, rope: ROPE, findWhere: TEditSelection.FindWhere _ anywhere, def, word: BOOL _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] RETURNS [found: BOOL] = { finder: TreeFind.Finder _ NIL; where: TextNode.RefTextNode; first: TextNode.Ref; start, at, atEnd: TextNode.Offset; DoFindIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: Selection] = { visible: BOOL _ SelectionVisibleInViewer[]; Forward: PROC = { IF visible THEN { first _ tSel.end.pos.node; start _ tSel.end.pos.where+1 } ELSE { first _ tdd.lineTable.lines[0].pos.node; start _ tdd.lineTable.lines[0].pos.where }; [found,where,at,atEnd,,] _ TreeFind.Try[finder,first,start] }; Backward: PROC = { IF visible THEN { first _ tSel.start.pos.node; start _ tSel.start.pos.where } ELSE { first _ tdd.lineTable.lines[0].pos.node; start _ tdd.lineTable.lines[0].pos.where }; [found,where,at,atEnd,,] _ TreeFind.TryBackwards[finder,first,start] }; FromStart: PROC = { first _ TextNode.FirstChild[tdd.text]; start _ 0; [found,where,at,atEnd,,] _ TreeFind.Try[finder,first,start] }; SelectionVisibleInViewer: PROC RETURNS [BOOL] = { RETURN [tSel.viewer=viewer AND tSel.end.line IN [0..tdd.lineTable.lastLine]] }; SELECT findWhere FROM forwards => Forward[]; backwards => Backward[]; anywhere => { Forward[]; IF NOT found THEN FromStart[] }; ENDCASE => ERROR; IF NOT found THEN RETURN; IF def THEN atEnd _ atEnd-1; -- skip the trailing : tSel.start.pos _ [where,at]; tSel.end.pos _ [where,MAX[0,atEnd-1]]; tSel.granularity _ IF word THEN word ELSE char; tSel.viewer _ viewer; tSel.data _ tdd; tSel.insertion _ IF TEditProfile.selectionCaret=before THEN before ELSE after; tSel.insertion _ after; tSel.pendingDelete _ FALSE; TEditOps.RememberCurrentPosition[viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel, selection: id]; TEditInput.CloseEvent[]; TEditRefresh.ScrollToEndOfSel[viewer, FALSE, id]; }; found _ FALSE; IF Rope.Size[rope] = 0 THEN RETURN; IF def THEN rope _ Rope.Concat[rope,":"]; finder _ TreeFind.CreateFromRope[pattern: rope, literal: TRUE, ignoreCase: NOT case, word: word ! TextFind.MalformedPattern => IF ec=toobig THEN GOTO TooBig ]; IF finder#NIL THEN CallWithSelAndDocAndTddLocks[viewer, id, DoFindIt]; EXITS TooBig => { MessageWindow.Append["Pattern too long", TRUE]; MessageWindow.Blink[]; }; }; END. rTEditSelectionOpsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Plass, March 21, 1985 12:54:53 pm PST Doug Wyatt, June 20, 1985 3:11:02 pm PDT Russ Atkinson (RRA) January 22, 1986 11:59:50 pm PST Exported to TEditSelectionOps (new for 6.0) sets bit to cause scroll after refresh since literal=TRUE, no other PatternErrorCode should occur Ê)˜codešœ™Kšœ Ïmœ1™˜MKšžœW˜[K˜EK˜—š  œžœ˜K˜1K˜