DIRECTORY Atom, EditSpan, EditSpanSupport, InputFocus, MessageWindow, NodeAddrs, RefTab, Rope, TEditDisplay USING [EstablishLine], TEditDocument USING [LineTable, maxClip, Selection, SelectionId, SelectionRec, SpinAndLock, TEditDocumentData, Unlock], TEditInput USING [CloseEvent, closeEvent, CloseEventNow, ComIndex, CommandProc, EditState, RecordChar, RecordRef], TEditInputBackdoor USING [EditObject, SelState, PDelState, MouseColor], TEditInputExtras USING [CommandClosure, CommandClosureProc], TEditInputOps USING [BackSpace, BackWord, Break, BufferedInsertChar, BufferedInsertText, CallWithLocks, Capitalise, ChangeCaretLooks, ChangeLooks, Copy, CopyFormat, CopyLooks, Delete, DeleteNextChar, DeleteNextWord, DoPendingDelete, ExpandAbbreviation, FindPlaceholders, GetFormat, GoToNextChar, GoToNextNode, GoToNextWord, GoToPreviousChar, GoToPreviousNode, GoToPreviousWord, InsertBrackets, InsertChar, InsertLineBreak, InsertRope, InsertTime, Join, LoadAbbreviations, MakeControlCharacter, MakeOctalCharacter, ModifyCaretLook, ModifyLook, Move, Nest, NextViewer, Paste, ReloadStyle, SaveForPaste, SelectMatchingBrackets, SetCommentProp, SetFormat, SetStyle, Transpose, TransposeFormat, TransposeLooks, UnMakeControlCharacter, UnMakeOctalCharacter, WaitForInsertToFinish, UnNest], TEditInputPrivate USING [InternalCommandCounts, InternalCommandCountsRep, InternalID, TraceProcs], TEditOps USING [CopyLoadHistory, CopyPositionHistory, RememberCurrentPosition], TEditPrivate USING [ReloadReadonlyTipTable, ReloadTipTable, ReloadTypeScriptTipTable], TEditProfile USING [CategoryOfUser, ReadProfile, userCategory], TEditScrolling USING [ScrollToPosition], TEditSelection USING [CallWithSelAndDocAndTddLocks, CancelPrimary, CancelSecondary, CaretAfterSelection, CaretBeforeSelection, Copy, Create, Extend, FakeSecondary, Find, fSel, GrowSelection, GrowSelectionToBlanks, InsertionPoint, LevelChange, LockSel, MakePointSelection, MakePrimary, MakeSecondary, MakeSelection, NotPendingDeleteSelection, oldSel, PendingDeleteSelection, pSel, SelectBranch, SelectChar, SelectEverything, SelectNode, SelectWord, ShowPosition, sSel, UnlockSel, Update], TEditSelectionOpsExtras USING [CurrentPositionMessage, GoToEndOfNode], TEditSplit USING [], TEditTouchup USING [LockAfterRefresh, UnlockAfterRefresh], TextEdit USING [Size, GetNewlineDelimiter], TextLooks USING [allLooks, noLooks], TextNode USING [FirstChild, ForwardClipped, Level, Location, NodeItself, Offset, Parent, Ref, RefTextNode, Root], TiogaOps USING [], TIPUser USING [TIPScreenCoords, TIPScreenCoordsRec], UserProfile USING [CallWhenProfileChanges, ProfileChangedProc], ViewerClasses USING [NotifyProc, Viewer], ViewerForkers, ViewerLocks, ViewerOps USING [AddProp, ComputeColumn, CreateViewer, DestroyViewer, FetchProp, MoveBelowViewer, OpenIcon, SetMenu], ViewersWorld, ViewersWorldInstance, WindowManager USING [UnWaitCursor, WaitCursor]; TEditInputImpl: CEDAR MONITOR IMPORTS Atom, EditSpan, EditSpanSupport, InputFocus, MessageWindow, NodeAddrs, RefTab, Rope, TEditDisplay, TEditDocument, TEditInput, TEditInputOps, TEditOps, TEditPrivate, TEditProfile, TEditScrolling, TEditSelection, TEditSelectionOpsExtras, TEditTouchup, TextEdit, TextNode, UserProfile, ViewerForkers, ViewerLocks, ViewerOps, ViewersWorld, ViewersWorldInstance, WindowManager EXPORTS TEditInput, TEditInputBackdoor, TEditInputExtras, TEditInputPrivate, TEditPrivate, TEditSplit, TiogaOps = BEGIN OPEN TEditInput; ROPE: TYPE ~ Rope.ROPE; traceProcs: TEditInputPrivate.TraceProcs ¬ NIL; SetTraceProcs: PUBLIC PROC [procs: TEditInputPrivate.TraceProcs] ~ { traceProcs ¬ procs }; InternalCommandCounts: TYPE ~ TEditInputPrivate.InternalCommandCounts; InternalCommandCountsRep: TYPE ~ TEditInputPrivate.InternalCommandCountsRep; internalCommandCounts: InternalCommandCounts ~ NEW[InternalCommandCountsRep ¬ ALL[0]]; GetInternalCommandCounts: PUBLIC PROC RETURNS [InternalCommandCounts] ~ { RETURN[internalCommandCounts]; }; commandTable: RefTab.Ref ¬ RefTab.Create[mod: 101]; my, mx: INTEGER; -- global Coord param for ops below SelState: TYPE ~ TEditInputBackdoor.SelState; -- {reset, primary, secondary} selState: PUBLIC -- TEditInputBackdoor -- SelState ¬ reset; SelectionId: TYPE ~ TEditDocument.SelectionId; -- {primary, secondary, feedback} sel: PUBLIC -- TEditInputBackdoor -- SelectionId ¬ primary; PDelState: TYPE ~ TEditInputBackdoor.PDelState; -- {reset, pending, not} pdelState: PUBLIC -- TEditInputBackdoor -- PDelState ¬ reset; pDel: PUBLIC -- TEditInputBackdoor -- BOOL ¬ FALSE; LevelChange: TYPE ~ TEditSelection.LevelChange; -- {reduce, expand, same} changeLevel: LevelChange; EditState: TYPE ~ TEditInput.EditState; -- {reset, abort, tolimbo, toprimary, tosecondary, toboth} editState: PUBLIC EditState ¬ reset; EditObject: TYPE ~ TEditInputBackdoor.EditObject; -- {text, looks, format} editObject: PUBLIC -- TEditInputBackdoor -- EditObject ¬ text; MouseColor: TYPE ~ TEditInputBackdoor.MouseColor; -- {red, yellow, blue, dead} mouseColor: PUBLIC -- TEditInputBackdoor -- MouseColor ¬ red; prevPSel: TEditDocument.Selection ~ NEW[TEditDocument.SelectionRec]; interrupt: PUBLIC REF BOOL ¬ NEW[BOOL ¬ FALSE]; positionMessage: ROPE ¬ NIL; editMessage: PUBLIC -- TEditInputBackdoor -- ROPE ¬ NIL; EditMessage: PROC = { pPendingDelete: BOOL ~ TEditSelection.pSel.pendingDelete; sPendingDelete: BOOL ~ TEditSelection.sSel.pendingDelete; msg: ROPE ~ SELECT editState FROM tolimbo => "Select for delete", toprimary => SELECT editObject FROM text => SELECT TEditSelection.pSel.pendingDelete FROM FALSE => SELECT TEditSelection.sSel.pendingDelete FROM FALSE => "Select for copy to caret", TRUE => "Select for move to caret", ENDCASE => NIL, TRUE => SELECT TEditSelection.sSel.pendingDelete FROM FALSE => "Select replacement", TRUE => "Select for move onto", ENDCASE => NIL, ENDCASE => NIL, looks => "Select looks to copy", format => "Select format to copy", ENDCASE => NIL, tosecondary => SELECT editObject FROM text => SELECT TEditSelection.pSel.pendingDelete FROM FALSE => SELECT TEditSelection.sSel.pendingDelete FROM FALSE => "Select destination for copy", TRUE => "Select for replacement", ENDCASE => NIL, TRUE => SELECT TEditSelection.sSel.pendingDelete FROM FALSE => "Select destination for move", TRUE => "Select destination for move onto", ENDCASE => NIL, ENDCASE => NIL, looks => "Select destination for copy looks", format => "Select destination for copy format", ENDCASE => NIL, toboth => SELECT editObject FROM text => "Select for transpose", looks => "Select for transpose looks", format => "Select for transpose format", ENDCASE => NIL, ENDCASE => NIL; IF msg = NIL OR msg = editMessage THEN RETURN; MessageWindow.Append[msg,TRUE]; editMessage ¬ msg }; Interpret: PUBLIC PROC [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY] = { InterpInput[viewer,params] }; InterpretAtom: PUBLIC PROC [viewer: ViewerClasses.Viewer, atom: ATOM] = { InterpAtom[viewer: viewer, atom: atom, param: NIL]; }; TEditNotifyProc: PUBLIC ViewerClasses.NotifyProc = { InterpInput[self, input]; }; InterpAtom: PROC [viewer: ViewerClasses.Viewer, atom: ATOM, param: REF] = { closureList: LIST OF CommandClosure ~ NARROW[RefTab.Fetch[commandTable,atom].val]; IF traceProcs#NIL THEN traceProcs.TraceAtom[viewer, atom, param, closureList]; IF closureList=NIL THEN MessageWindow.Append[Rope.Concat["Unknown atom given to Tioga: ", Atom.GetPName[atom]], TRUE] ELSE { recordAtom: BOOL ¬ FALSE; TEditInputOps.WaitForInsertToFinish[]; -- make sure previous characters have gone in FOR list: LIST OF CommandClosure ¬ closureList, list.rest UNTIL list=NIL DO record, quit: BOOL; [record, quit] ¬ list.first.proc[list.first.data, viewer, param]; IF record THEN recordAtom ¬ TRUE; IF quit THEN EXIT; ENDLOOP; IF recordAtom THEN RecordRef[atom] } }; ResetInputStuff: PUBLIC PROC = { changeLevel ¬ same }; SaveCoords: PUBLIC PROC [x, y: INTEGER] = { mx ¬ x; my ¬ y }; interpreterNesting: PUBLIC INTEGER ¬ 0; InterpInput: PUBLIC PROC [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY, increaseNestingCount: BOOL ¬ TRUE] = { NormaliseSelection: PROC = INLINE --gfi saver-- { IF NOT TEditSelection.pSel.pendingDelete THEN RETURN; TEditSelection.LockSel[primary, "InterpInput"]; { ENABLE UNWIND => TEditSelection.UnlockSel[primary]; IF TEditSelection.pSel.pendingDelete THEN TEditInputOps.DoPendingDelete[]; IF NOT InsSel[] THEN TEditSelection.MakePointSelection[TEditSelection.pSel, TEditSelection.InsertionPoint[]]; }; TEditSelection.UnlockSel[primary]; }; InsSel: PROC RETURNS [BOOL] = INLINE --gfi saver-- { RETURN[TEditSelection.pSel.granularity=point AND TEditSelection.pSel.insertion=before AND TEditSelection.sSel.viewer=NIL] }; BumpNesting: ENTRY PROC = INLINE --gfi saver-- { IF (interpreterNesting ¬ interpreterNesting+1) <= 1 THEN { interpreterNesting ¬ 1; closeEvent ¬ FALSE } }; DecrementNesting: ENTRY PROC RETURNS [BOOL] = INLINE --gfi saver-- { RETURN [(interpreterNesting ¬ interpreterNesting-1) <= 0] }; AllText: PROC [LIST OF REF ANY] RETURNS [BOOL] = INLINE --gfi saver-- { FOR input: LIST OF REF ANY ¬ params, input.rest UNTIL input=NIL DO WITH input.first SELECT FROM z: REF CHAR => NULL; z: ROPE => NULL; z: REF TEXT => NULL; ENDCASE => RETURN [FALSE]; ENDLOOP; RETURN [TRUE] }; IF traceProcs#NIL THEN traceProcs.TraceInput[viewer, params, increaseNestingCount]; ResetInputStuff[]; IF interpreterNesting=0 AND NOT TEditSelection.pSel.pendingDelete AND AllText[params] THEN { FOR input: LIST OF REF ANY ¬ params, input.rest UNTIL input=NIL DO NormaliseSelection[]; WITH input.first SELECT FROM z: REF CHAR => { TEditInputOps.BufferedInsertChar[z­]; RecordChar[z­] }; z: ROPE => { TEditInputOps.BufferedInsertText[z]; RecordRef[z] }; z: REF TEXT => { TEditInputOps.BufferedInsertText[Rope.FromRefText[z]]; RecordRef[z] }; ENDCASE => ERROR; ENDLOOP; } ELSE { param: REF ¬ NIL; paramIsNext: BOOL ¬ FALSE; IF increaseNestingCount THEN BumpNesting[]; FOR input: LIST OF REF ANY ¬ params, input.rest UNTIL input=NIL DO thisIsParam: BOOL = paramIsNext; IF thisIsParam THEN param ¬ NIL; paramIsNext ¬ FALSE; WITH input.first SELECT FROM z: ATOM => { IF thisIsParam THEN { param ¬ z; RecordRef[z] } ELSE { IF z = $PARAM THEN { paramIsNext ¬ TRUE }; InterpAtom[viewer, z, param ! BadMouse, DontDoIt => EXIT]; }; }; z: TIPUser.TIPScreenCoords => { IF thisIsParam THEN RecordRef[param ¬ NEW[TIPUser.TIPScreenCoordsRec ¬ z­] ] ELSE SaveCoords[z.mouseX, viewer.ch-z.mouseY]; }; z: REF CHAR => { IF thisIsParam THEN RecordRef[param ¬ NEW[CHAR ¬ z­]] ELSE { TEditInputOps.InsertChar[z­]; RecordChar[z­] }; }; z: REF INT => { param ¬ NEW[INT ¬ z­]; -- is the copy needed? RecordRef[param] }; z: ROPE => { IF thisIsParam THEN param ¬ z ELSE TEditInputOps.InsertRope[z]; RecordRef[z] }; z: REF TEXT => { rope: ROPE ~ Rope.FromRefText[z]; IF thisIsParam THEN param ¬ rope ELSE TEditInputOps.InsertRope[rope]; RecordRef[rope]; }; ENDCASE => MessageWindow.Append["Unknown input given to Tioga.", TRUE]; IF thisIsParam AND param=NIL THEN MessageWindow.Append["Illegal PARAM input given to Tioga.", TRUE]; ENDLOOP; IF increaseNestingCount AND DecrementNesting[] AND closeEvent THEN CloseEventNow[]; }; }; NumberToLook: PROC [n: INT] RETURNS [l: CHAR] = { RETURN['a+n]; }; Normalize: PUBLIC CommandProc = { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE TEditSelection.InsertionPoint[tSel], tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; savedSelA: TEditDocument.Selection ¬ TEditSelection.Create[]; savedSelB: TEditDocument.Selection ¬ TEditSelection.Create[]; RestoreSelectionA: PUBLIC CommandProc = { IF CheckSelection[savedSelA] THEN TEditSelection.MakeSelection[selection: primary, new: savedSelA] }; SaveSelectionA: PUBLIC CommandProc = { IF TEditSelection.pSel # NIL THEN TEditSelection.Copy[source: TEditSelection.pSel, dest: savedSelA] }; RestoreSelectionB: PUBLIC CommandProc = { IF CheckSelection[savedSelB] THEN TEditSelection.MakeSelection[selection: primary, new: savedSelB] }; SaveSelectionB: PUBLIC CommandProc = { IF TEditSelection.pSel # NIL THEN TEditSelection.Copy[source: TEditSelection.pSel, dest: savedSelB] }; AllLevels: PUBLIC CommandProc = { WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { IF tdd.clipLevel # TEditDocument.maxClip THEN { [] ¬ TEditDocument.SpinAndLock[tdd, "AllLevels", TRUE]; tdd.clipLevel ¬ TEditDocument.maxClip; ForkPaint[viewer]; TEditDocument.Unlock[tdd]; }; }; ENDCASE; RETURN [FALSE]; }; FirstLevelOnly: PUBLIC CommandProc = { WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { IF tdd.clipLevel # 1 THEN { [] ¬ TEditDocument.SpinAndLock[tdd, "FirstLevelOnly", TRUE]; tdd.clipLevel ¬ 1; CheckFirstLevel[tdd]; ForkPaint[viewer]; TEditDocument.Unlock[tdd]; }; }; ENDCASE; RETURN [FALSE]; }; MoreLevels: PUBLIC CommandProc = { WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => { IF tdd.clipLevel < TEditDocument.maxClip THEN { ENABLE UNWIND => TEditTouchup.UnlockAfterRefresh[tdd]; [] ¬ TEditDocument.SpinAndLock[tdd, "MoreLevels", TRUE]; tdd.clipLevel ¬ MaxLevelShown[tdd]+1; ForkPaint[viewer]; TEditDocument.Unlock[tdd]; }; }; ENDCASE; }; FewerLevels: PUBLIC CommandProc = { WITH viewer.data SELECT FROM tdd: TEditDocument.TEditDocumentData => IF tdd.clipLevel # 1 THEN { IF TEditTouchup.LockAfterRefresh[tdd, "FewerLevels"] THEN { ENABLE UNWIND => TEditTouchup.UnlockAfterRefresh[tdd]; level: INTEGER ¬ tdd.clipLevel; IF level = TEditDocument.maxClip THEN level ¬ MaxLevelShown[tdd]; IF level # 1 THEN { tdd.clipLevel ¬ level-1; CheckFirstLevel[tdd]; ForkPaint[viewer]; }; TEditTouchup.UnlockAfterRefresh[tdd]; }; }; ENDCASE; RETURN [FALSE]; }; DoEdit: CommandProc = { SELECT TRUE FROM (TEditSelection.pSel.viewer = NIL) => { IF TEditSelection.sSel.viewer # NIL THEN TEditSelection.MakeSelection[NIL, secondary]; -- get rid of secondary recordAtom ¬ FALSE }; (editState = tolimbo) => { recordAtom ¬ FALSE; RecordRef[$Delete]; TEditInputOps.Delete[TRUE]; }; (TEditSelection.sSel.viewer = NIL) => {recordAtom ¬ FALSE}; ENDCASE => { RecordEditObject: PROC = INLINE --gfi saver-- { RecordRef[SELECT editObject FROM text => $EditText, looks => $EditLooks, format => $EditFormat, ENDCASE => ERROR]; }; recordAtom ¬ TRUE; SELECT editState FROM reset, abort => recordAtom ¬ FALSE; toprimary => { RecordRef[$GetSecondary]; RecordRef[$ToPrimary]; RecordEditObject[]; SELECT editObject FROM text => { IF TEditSelection.pSel.pendingDelete THEN RecordRef[$MakePDel]; TEditInputOps.Copy[primary] }; looks => TEditInputOps.CopyLooks[primary]; format => TEditInputOps.CopyFormat[primary]; ENDCASE => ERROR }; tosecondary => { RecordRef[$GetSecondary]; RecordRef[$ToSecondary]; RecordEditObject[]; SELECT editObject FROM text => { IF TEditSelection.pSel.pendingDelete THEN RecordRef[$MakePDel]; TEditInputOps.Copy[secondary] }; looks => TEditInputOps.CopyLooks[secondary]; format => TEditInputOps.CopyFormat[secondary]; ENDCASE => ERROR }; toboth => { RecordRef[$GetSecondary]; RecordRef[$ToBoth]; RecordEditObject[]; SELECT editObject FROM text => TEditInputOps.Transpose[]; looks => TEditInputOps.TransposeLooks[]; format => TEditInputOps.TransposeFormat[]; ENDCASE => ERROR }; ENDCASE => ERROR }; editState ¬ reset; editObject ¬ text; pdelState ¬ reset; pDel ¬ FALSE; selState ¬ reset; sel ¬ primary; mouseColor ¬ red; -- put these back to normal IF editMessage # NIL THEN MessageWindow.Clear[]; editMessage ¬ NIL }; MakePointSelection: PUBLIC CommandProc = { TEditSelection.LockSel[primary, "MakePointSelection"]; IF TEditSelection.pSel.viewer#NIL THEN TEditSelection.MakePointSelection[TEditSelection.pSel, IF TEditSelection.pSel.insertion=before THEN TEditSelection.pSel.start.pos ELSE [TEditSelection.pSel.end.pos.node, TEditSelection.pSel.end.pos.where+1]]; TEditSelection.UnlockSel[primary]; }; Split: PUBLIC PROC [old: ViewerClasses.Viewer] = { -- Export to TEditSplit tddNew, tddOld: TEditDocument.TEditDocumentData; new: ViewerClasses.Viewer; paintCaption: BOOL ¬ FALSE; selectionHistory: TEditDocument.Selection; lines: TEditDocument.LineTable; loc: TextNode.Location; tddOld ¬ NARROW[old.data]; IF tddOld = NIL THEN RETURN; new ¬ ViewerOps.CreateViewer[flavor: old.class.flavor, info: [name: old.name, column: old.column, iconic: TRUE], paint: FALSE]; ViewerOps.OpenIcon[icon: new, paint: FALSE]; ViewerOps.MoveBelowViewer[altered: new, static: old, paint: FALSE]; tddNew ¬ NARROW[new.data]; IF tddNew = NIL THEN RETURN; -- How this could happen is beyond me, but paranoia is cheap. [McGregor] selectionHistory ¬ NARROW[ViewerOps.FetchProp[old, $SelectionHistory]]; new.link ¬ old; IF old.link=NIL THEN { old.link ¬ new; paintCaption ¬ TRUE } ELSE FOR v: ViewerClasses.Viewer ¬ old.link, v.link UNTIL v.link=old DO REPEAT FINISHED => v.link ¬ new; ENDLOOP; new.newVersion ¬ old.newVersion; new.newFile ¬ old.newFile; new.file ¬ old.file; ViewerOps.ComputeColumn[column: new.column, paint: FALSE]; -- to find new height { inner: PROC = { [] ¬ TEditDocument.SpinAndLock[tddOld, "Split"]; -- must ComputeColumn before lock tdd tddNew.text ¬ tddOld.text; tddNew.tsInfo ¬ tddOld.tsInfo; tddNew.clipLevel ¬ tddOld.clipLevel; tddNew.commentFilter ¬ tddOld.commentFilter; ViewerOps.SetMenu[new, old.menu, FALSE]; IF selectionHistory # NIL THEN { -- copy it newSelectionHistory: TEditDocument.Selection ¬ NEW[TEditDocument.SelectionRec]; newSelectionHistory­ ¬ selectionHistory­; ViewerOps.AddProp[new, $SelectionHistory, newSelectionHistory]; }; TEditOps.CopyPositionHistory[from: old, to: new]; TEditOps.CopyLoadHistory[from: old, to: new]; lines ¬ tddOld.lineTable; loc ¬ lines[lines.lastLine].pos; -- in case loop doesn't find anything FOR n: INTEGER IN [0..lines.lastLine] DO -- find line that goes past new bottom IF lines[n].yOffset+lines[n].descent >= old.ch THEN { loc ¬ lines[n].pos; EXIT }; ENDLOOP; TEditDocument.Unlock[tddOld]; }; ViewerLocks.CallUnderWriteLocks[inner, old, new]; }; TEditDisplay.EstablishLine[tddNew, loc]; ViewerOps.ComputeColumn[column: new.column, paint: TRUE]; -- now do the painting FOR v: ViewerClasses.Viewer ¬ new.link, v.link WHILE v # NIL DO IF v = new THEN EXIT; IF v.iconic THEN { -- get rid of it -- ViewerOps.DestroyViewer[v]; EXIT }; IF paintCaption THEN ViewerForkers.ForkPaint[viewer: v, hint: caption, tryShortCuts: TRUE]; ENDLOOP; }; UpdateSavedSelections: PROC [ node: TextNode.RefTextNode, new: PROC [old: TextNode.Offset] RETURNS [TextNode.Offset]] = { Check: PROC [loc: TextNode.Location] RETURNS [TextNode.Location] = INLINE --gfi saver-- { IF loc.node # node THEN RETURN [loc]; RETURN [[loc.node, new[loc.where]]] }; TEditSelection.oldSel.start.pos ¬ Check[TEditSelection.oldSel.start.pos]; TEditSelection.oldSel.end.pos ¬ Check[TEditSelection.oldSel.end.pos]; savedSelA.start.pos ¬ Check[savedSelA.start.pos]; savedSelA.end.pos ¬ Check[savedSelA.end.pos]; savedSelB.start.pos ¬ Check[savedSelB.start.pos]; savedSelB.end.pos ¬ Check[savedSelB.end.pos]; TEditSelection.fSel.start.pos ¬ Check[TEditSelection.fSel.start.pos]; TEditSelection.fSel.end.pos ¬ Check[TEditSelection.fSel.end.pos]; }; CheckSelection: PUBLIC PROC [sel: TEditDocument.Selection] RETURNS [BOOL] = { root, first, last: TextNode.Ref; t1, t2: TextNode.RefTextNode; tdd: TEditDocument.TEditDocumentData; IF sel=NIL THEN RETURN [FALSE]; IF sel.viewer=NIL OR sel.viewer.destroyed THEN GOTO Failed; IF (first ¬ sel.start.pos.node)=NIL OR (last ¬ sel.end.pos.node)=NIL THEN GOTO Failed; IF (tdd ¬ NARROW[sel.viewer.data])=NIL THEN GOTO Failed; IF (root ¬ tdd.text)=NIL THEN GOTO Failed; IF TextNode.Root[first] # root THEN GOTO Failed; -- make sure still in the tree IF first # last THEN { IF EditSpan.CompareNodeOrder[first,last] # before THEN GOTO Failed; }; IF sel.start.pos.where # TextNode.NodeItself THEN { IF (t1 ¬ first)=NIL OR sel.start.pos.where NOT IN [0..TextEdit.Size[t1]] THEN GOTO Failed; }; IF sel.end.pos.where # TextNode.NodeItself THEN { IF (t2 ¬ last)=NIL OR sel.end.pos.where NOT IN [0..TextEdit.Size[t2]] THEN GOTO Failed; }; IF t1 # NIL AND t1 = t2 THEN { IF sel.start.pos.where > sel.end.pos.where THEN GOTO Failed; }; RETURN [TRUE]; EXITS Failed => { sel.viewer ¬ NIL; RETURN [FALSE] }; }; NormalizeViewer: PROC [viewer: ViewerClasses.Viewer, loc: TextNode.Location, tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { IF loc.node = NIL OR tdd.text # TextNode.Root[loc.node] THEN { loc ¬ [TextNode.FirstChild[tdd.text],0]; }; TEditOps.RememberCurrentPosition[viewer]; TEditScrolling.ScrollToPosition[viewer, loc] }; BadMouse: PUBLIC SIGNAL = CODE; AbortSecondary: PROC = { MessageWindow.Append["Make a primary selection first.",TRUE]; MessageWindow.Blink[]; editState ¬ abort; mouseColor ¬ dead }; Extend: PROC [viewer: ViewerClasses.Viewer, saveEnds: BOOL] = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting ¬ 0; IF editState=abort THEN RETURN; IF mouseColor # blue THEN { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor ¬ blue; TEditSelection.Copy[source: TEditSelection.pSel, dest: prevPSel]; saveEnds ¬ TRUE; }; TEditSelection.Extend[viewer,tdd,mx,my,sel,pDel,changeLevel,saveEnds]; IF sel=secondary THEN EditMessage[] ELSE IF sel=primary THEN CloseEvent[] }; DontDoIt: PUBLIC SIGNAL = CODE; -- raised if user category is too low CheckUser: PROC [category: TEditProfile.CategoryOfUser] = INLINE --gfi saver-- { IF TEditProfile.userCategory < category THEN SIGNAL DontDoIt }; ForkPaint: PROC [viewer: ViewerClasses.Viewer] = TRUSTED { ViewerForkers.ForkPaint[viewer: viewer, hint: client, tryShortCuts: TRUE]; }; CheckFirstLevel: PROC [tdd: TEditDocument.TEditDocumentData] = { node: TextNode.Ref; delta: INTEGER; pos: TextNode.Location; [] ¬ TEditDocument.SpinAndLock[tdd, "CheckFirstLevel", TRUE]; -- ok to interrupt repaint pos ¬ tdd.lineTable.lines[0].pos; -- the start of the first line delta ¬ TextNode.Level[pos.node]-tdd.clipLevel; -- how much too deep it is, if any IF delta > 0 THEN { FOR i:INTEGER IN [0..delta) DO -- only do this if pos is too deep pos ¬ [TextNode.Parent[pos.node],0]; ENDLOOP; IF (node ¬ TextNode.ForwardClipped[pos.node,0].nx) # NIL THEN pos ¬ [node,0]; TEditDisplay.EstablishLine[tdd, pos] }; TEditDocument.Unlock[tdd]; }; MaxLevelShown: PUBLIC PROC [tdd: TEditDocument.TEditDocumentData] RETURNS [level: INTEGER] = { node, n: TextNode.Ref; max: INTEGER ¬ 0; IF tdd = NIL THEN RETURN [0]; FOR l: INTEGER IN [0..tdd.lineTable.lastLine] DO IF (n ¬ tdd.lineTable.lines[l].pos.node) # node THEN { node ¬ n; max ¬ MAX[TextNode.Level[node], max] }; ENDLOOP; level ¬ max; }; ReadTipTables: PUBLIC PROC = { WindowManager.WaitCursor[]; TEditPrivate.ReloadTipTable[]; TEditPrivate.ReloadReadonlyTipTable[]; TEditPrivate.ReloadTypeScriptTipTable[]; InputFocus.SetInputFocus[]; -- kill selection; force ChangeTIPContext WindowManager.UnWaitCursor[]; }; ComArray: TYPE = ARRAY ComIndex OF LIST OF REF ANY; coms: REF ComArray = NEW [ComArray]; SetCommand: PUBLIC PROC [num: ComIndex, params: LIST OF REF ANY] = { coms[num] ¬ params; }; GetCommand: PUBLIC PROC [num: ComIndex] RETURNS [params: LIST OF REF ANY] = { RETURN [coms[num]]; }; DoCommand: PROC [viewer: ViewerClasses.Viewer, num: ComIndex] = { Interpret[viewer,coms[num]]; }; InternalID: TYPE ~ TEditInputPrivate.InternalID; RegisterInternal: PROC [name: ATOM, id: InternalID] ~ { RegisterClosure[[name: name, proc: DispatchInternalCommand, data: NEW[InternalID ¬ id]]]; }; CopyToWorld: PROC [delete: BOOL ¬ FALSE] ~ { vWorld: ViewersWorld.Ref ~ ViewersWorldInstance.GetWorld[]; rope: Rope.ROPE ¬ NIL; DoSelChars: PROC [root: TextNode.RefTextNode, tSel: TEditDocument.Selection] = { SelConcat: PROC [node: TextNode.RefTextNode, start, len: TextNode.Offset] RETURNS [stop: BOOL] = { rope ¬ IF rope = NIL THEN Rope.Substr[node.rope, start, len] ELSE Rope.Cat[rope, "\n", Rope.Substr[node.rope, start, len]]; RETURN [FALSE]; }; IF tSel.viewer # NIL AND tSel.granularity # point THEN EditSpanSupport.Apply[[tSel.start.pos, tSel.end.pos], SelConcat]; IF rope=NIL THEN rope ¬ ""; }; TEditInputOps.CallWithLocks[DoSelChars, read]; ViewersWorld.SetCutBuffer[vWorld, $Ascii, rope]; IF delete THEN TEditInputOps.Delete[saveForPaste: FALSE]; }; PasteFromWorld: PROC [] ~ { vWorld: ViewersWorld.Ref ~ ViewersWorldInstance.GetWorld[]; rope: Rope.ROPE ~ ViewersWorld.GetCutBuffer[vWorld, $Ascii]; TEditInputOps.InsertRope[rope]; }; DispatchInternalCommand: PUBLIC CommandClosureProc ~ { n: INT ~ WITH param SELECT FROM n: REF INT => n­ ENDCASE => 1; WITH data SELECT FROM refID: REF InternalID => { id: InternalID ~ refID­; internalCommandCounts[id] ¬ internalCommandCounts[id]+1; SELECT id FROM CopyToWorld => CopyToWorld[delete: FALSE]; CutToWorld => CopyToWorld[delete: TRUE]; PasteFromWorld => PasteFromWorld[]; CutToWorldFormatted => { }; CopyToWorldFormatted => { }; PasteFromWorldFormatted => { }; ApplyCaretLook => { TEditInputOps.ModifyCaretLook[NumberToLook[n], add] }; ApplyLook => { TEditInputOps.ModifyLook[NumberToLook[n], add] }; ClearCaretLooks => { TEditInputOps.ChangeCaretLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] }; ClearLooks => { TEditInputOps.ChangeLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] }; BackSpace => { TEditInputOps.BackSpace[n] }; BackWord => { TEditInputOps.BackWord[n] }; DeleteNextChar => { TEditInputOps.DeleteNextChar[n] }; DeleteNextWord => { TEditInputOps.DeleteNextWord[n] }; GoToPreviousWord => { TEditInputOps.GoToPreviousWord[n] }; GoToNextWord => { TEditInputOps.GoToNextWord[n] }; GoToPreviousChar => { TEditInputOps.GoToPreviousChar[n] }; GoToNextChar => { TEditInputOps.GoToNextChar[n] }; GoToPreviousNode => { TEditInputOps.GoToPreviousNode[n] }; GoToNextNode => { TEditInputOps.GoToNextNode[n] }; GoToEndOfNode => { TEditSelectionOpsExtras.GoToEndOfNode[n] }; GoToBeginningOfNode => { TEditSelectionOpsExtras.GoToEndOfNode[-n] }; Copy => { IF TEditSelection.sSel.viewer#NIL THEN { TEditInputOps.Copy[sel]; RecordRef[$GetSecondary] }; }; Delete => { TEditInputOps.Delete[saveForPaste: TRUE] }; ExpandAbbrev => { TEditInputOps.ExpandAbbreviation[] }; Move => { IF TEditSelection.sSel.viewer#NIL THEN { TEditInputOps.Move[sel]; RecordRef[$GetSecondary]; }; }; RemoveCaretLook => { TEditInputOps.ModifyCaretLook[NumberToLook[n], remove]; }; RemoveLook => { TEditInputOps.ModifyLook[NumberToLook[n], remove]; }; SetStyle => { TEditInputOps.SetStyle[] }; Time => { TEditInputOps.InsertTime[] }; RedSplit, YellowSplit, BlueSplit => { Split[viewer]; RETURN[FALSE] }; Transpose => { IF TEditSelection.sSel.viewer#NIL THEN { TEditInputOps.Transpose[sel]; RecordRef[$GetSecondary] }; }; ToBoth => { IF editState=reset OR editState=tolimbo THEN { editState ¬ toboth; EditMessage[] }; RETURN [FALSE] }; ToLimbo => { IF editState=reset THEN editState ¬ tolimbo; RETURN [FALSE] }; ToPrimary => { IF editState=reset OR editState=tolimbo THEN editState ¬ toprimary; RETURN [FALSE] }; ToSecondary => { IF editState=reset OR editState=tolimbo THEN { editState ¬ tosecondary; EditMessage[] }; RETURN [FALSE] }; EditText => { editObject ¬ text; RETURN [FALSE] }; EditLooks => { editObject ¬ looks; EditMessage[]; RETURN [FALSE] }; EditFormat => { editObject ¬ format; EditMessage[]; RETURN [FALSE] }; EditReset => { editState ¬ reset; editObject ¬ text; selState ¬ reset; pdelState ¬ reset; RETURN [FALSE] }; EditAbort => { interrupt­ ¬ TRUE; IF viewer#NIL AND TEditSelection.pSel.viewer=viewer AND TEditSelection.pSel.granularity=point AND TEditSelection.sSel.viewer=NIL THEN ViewerOps.AddProp[viewer, $Abort, NEW[BOOL ¬ FALSE]]; MessageWindow.Append["Cancelled",TRUE]; TEditSelection.MakeSelection[NIL,secondary]; TEditSelection.MakeSelection[IF CheckSelection[prevPSel] THEN prevPSel ELSE NIL, primary]; editState ¬ abort; editObject ¬ text; mouseColor ¬ dead; -- stop tracking the mouse RETURN [FALSE] }; GetSecondary => { IF TEditSelection.sSel.viewer=NIL AND CheckSelection[TEditSelection.oldSel] THEN TEditSelection.FakeSecondary[TEditSelection.oldSel]; RETURN [FALSE] }; MakePDel => { TEditSelection.pSel.pendingDelete ¬ TRUE; RETURN [FALSE] }; NormalizeToStart => { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.start.pos, tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; NormalizeToEnd => { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.end.pos, tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; FindNext => { TEditSelection.Find[viewer: viewer, findWhere: forwards]; CloseEvent[]; RETURN [FALSE] }; FindAny => { TEditSelection.Find[viewer: viewer, findWhere: anywhere]; CloseEvent[]; RETURN [FALSE] }; FindPrev => { TEditSelection.Find[viewer: viewer, findWhere: backwards]; CloseEvent[]; RETURN [FALSE] }; FindNextWord => { TEditSelection.Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindAnyWord => { TEditSelection.Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindPrevWord => { TEditSelection.Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindNextDef => { TEditSelection.Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindAnyDef => { TEditSelection.Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindPrevDef => { TEditSelection.Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindNextCaseless => { TEditSelection.Find[viewer: viewer, findWhere: forwards, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyCaseless => { TEditSelection.Find[viewer: viewer, findWhere: anywhere, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevCaseless => { TEditSelection.Find[viewer: viewer, findWhere: backwards, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindNextWordCaseless => { TEditSelection.Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyWordCaseless => { TEditSelection.Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevWordCaseless => { TEditSelection.Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindNextDefCaseless => { TEditSelection.Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyDefCaseless => { TEditSelection.Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevDefCaseless => { TEditSelection.Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; Position => { CloseEvent[]; TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: TRUE]; RETURN[FALSE] }; PositionIncludingComments => { CloseEvent[]; TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: FALSE]; RETURN[FALSE] }; MsgPosition => { positionMessage ¬ TEditSelectionOpsExtras.CurrentPositionMessage[viewer, TRUE]; MessageWindow.Append[Rope.Concat["Current position is ", positionMessage], TRUE]; }; MsgPositionIncludingComments => { positionMessage ¬ TEditSelectionOpsExtras.CurrentPositionMessage[viewer, FALSE]; MessageWindow.Append[Rope.Concat["Current position is ", positionMessage], TRUE]; }; StuffPosition => { TEditInputOps.InsertRope[positionMessage]; }; RedMouse => { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor ¬ red; TEditSelection.Copy[source: TEditSelection.pSel, dest: prevPSel]; RETURN [FALSE] }; YellowMouse => { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor ¬ yellow; TEditSelection.Copy[source: TEditSelection.pSel, dest: prevPSel]; RETURN [FALSE] }; BlueMouse => { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor ¬ blue; TEditSelection.Copy[source: TEditSelection.pSel, dest: prevPSel]; RETURN [FALSE] }; RedDown => { IF mouseColor # red THEN SIGNAL BadMouse; RETURN [FALSE] }; YellowDown => { IF mouseColor # yellow THEN SIGNAL BadMouse; RETURN [FALSE] }; BlueDown => { IF mouseColor # blue THEN SIGNAL BadMouse; RETURN [FALSE] }; SelBranch => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting ¬ 0; IF editState=abort THEN RETURN; IF sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectBranch[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelChar => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting ¬ 0; IF editState=abort THEN RETURN; IF sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectChar[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelExpand => { changeLevel ¬ expand; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelExtend => { Extend[viewer, FALSE]; RETURN [FALSE] }; SelStartExtend => { Extend[viewer, TRUE]; RETURN [FALSE] }; SelNode => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting ¬ 0; IF editState=abort THEN RETURN; IF sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectNode[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelNotPendDel => { IF pdelState=reset THEN { pdelState ¬ not; pDel ¬ FALSE; IF sel=primary THEN CloseEvent[] }; RETURN [FALSE] }; SelPendDel => { IF pdelState=reset THEN { pdelState ¬ pending; pDel ¬ TRUE; IF sel=primary THEN CloseEvent[] }; RETURN [FALSE] }; ForceSelPendDel => { -- force pending delete pdelState ¬ pending; pDel ¬ TRUE; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; ForceSelNotPendDel => { -- force not pending delete pdelState ¬ not; pDel ¬ FALSE; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelSamePendDel => { IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelPrimary => { IF selState=reset THEN { selState ¬ primary; sel ¬ primary; CloseEvent[] }; RETURN [FALSE] }; SelReduce => { changeLevel ¬ reduce; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelSame => { -- this is no longer needed. delete it after release new TIP tables }; SelSameEnd => { -- get rid of this when change Tioga.Tip RETURN [FALSE] }; SelSecondary => { IF selState=reset THEN { selState ¬ secondary; sel ¬ secondary }; RETURN [FALSE] }; SelUpdate => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; IF editState=abort THEN RETURN; IF sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.Update[viewer, tdd, mx, my, sel, pDel]; IF sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelWord => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting ¬ 0; IF editState=abort THEN RETURN; IF sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectWord[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; IntermediateUser => { CheckUser[intermediate]; RETURN [FALSE] }; AdvancedUser => { CheckUser[advanced]; RETURN [FALSE] }; ExpertUser => { CheckUser[expert]; RETURN [FALSE] }; Break => { TEditInputOps.Break[] }; Join => { TEditInputOps.Join[] }; Nest => { TEditInputOps.Nest[] }; Paste => { TEditInputOps.Paste[] }; SaveForPaste => { TEditInputOps.SaveForPaste[] }; SetFormat => { TEditInputOps.SetFormat[] }; GetFormat => { TEditInputOps.GetFormat[] }; UnNest => { TEditInputOps.UnNest[] }; AllCaps => { TEditInputOps.Capitalise[allCaps] }; AllLower => { TEditInputOps.Capitalise[allLower] }; FirstCap => { TEditInputOps.Capitalise[firstCap] }; InitialCaps => { TEditInputOps.Capitalise[initCaps] }; CaretAfter => { TEditSelection.CaretAfterSelection[] }; CaretBefore => { TEditSelection.CaretBeforeSelection[] }; Everything => { TEditSelection.SelectEverything[] }; GrowSel => { TEditSelection.GrowSelection[] }; GrowSelToBlanks => { TEditSelection.GrowSelectionToBlanks[] }; InsertLineBreak => { TEditInputOps.InsertLineBreak[] }; InsertNewline => { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; TEditInputOps.InsertRope[TextEdit.GetNewlineDelimiter[tdd.text]] }; MakeNotPendingDelete => { TEditSelection.NotPendingDeleteSelection[] }; MakePendingDelete => { TEditSelection.PendingDeleteSelection[] }; MakeControlCharacter => { TEditInputOps.MakeControlCharacter[] }; MakeOctalCharacter => { TEditInputOps.MakeOctalCharacter[] }; UnMakeControlCharacter => { TEditInputOps.UnMakeControlCharacter[] }; UnMakeOctalCharacter => { TEditInputOps.UnMakeOctalCharacter[] }; MakePrimaryOp => { TEditSelection.MakePrimary[] }; MakeSecondaryOp => { TEditSelection.MakeSecondary[] }; CancelPrimaryOp => { TEditSelection.CancelPrimary[] }; CancelSecondaryOp => { TEditSelection.CancelSecondary[] }; Paint => { ForkPaint[viewer] }; PlaceholderBrackets => { TEditInputOps.InsertBrackets[1C,2C] }; ReadTip => { ReadTipTables[] }; ReloadStyle => { TEditInputOps.ReloadStyle[] }; SelectMatchingPlaceholderBrackets => { TEditInputOps.SelectMatchingBrackets[1C,2C]; }; SelectMatchingSingleQuotes => { TEditInputOps.SelectMatchingBrackets['\140,'']; }; SelectMatchingDoubleQuotes => { TEditInputOps.SelectMatchingBrackets['",'"] }; SelectMatchingDashBrackets => { TEditInputOps.SelectMatchingBrackets['-,'-] }; PreviousPlaceholder => { TEditInputOps.FindPlaceholders[FALSE] }; PreviousViewer => { TEditInputOps.NextViewer[FALSE] }; NextPlaceholder => { TEditInputOps.FindPlaceholders[TRUE] }; NextViewer => { TEditInputOps.NextViewer[TRUE] }; ReadAbbreviations => { TEditInputOps.LoadAbbreviations["Default"] }; SelectMatchingParens => { TEditInputOps.SelectMatchingBrackets['(,')] }; SelectMatchingAngleBrackets => { TEditInputOps.SelectMatchingBrackets['<,'>] }; SelectMatchingCurlyBrackets => { TEditInputOps.SelectMatchingBrackets['{,'}] }; SelectMatchingSquareBrackets => { TEditInputOps.SelectMatchingBrackets['[,']] }; ParenBrackets => { TEditInputOps.InsertBrackets['(,')] }; DashBrackets => { TEditInputOps.InsertBrackets['-,'-] }; DoubleQuoteBrackets => { TEditInputOps.InsertBrackets['",'"] }; AngleBrackets => { TEditInputOps.InsertBrackets['<,'>] }; SingleQuoteBrackets => { TEditInputOps.InsertBrackets['\140,'']; }; CurlyBrackets => { TEditInputOps.InsertBrackets['{,'}] }; SquareBrackets => { TEditInputOps.InsertBrackets['[,']] }; Command0 => { DoCommand[viewer,0] }; Command1 => { DoCommand[viewer,1] }; Command2 => { DoCommand[viewer,2] }; Command3 => { DoCommand[viewer,3] }; Command4 => { DoCommand[viewer,4] }; Command5 => { DoCommand[viewer,5] }; Command6 => { DoCommand[viewer,6] }; Command7 => { DoCommand[viewer,7] }; Command8 => { DoCommand[viewer,8] }; Command9 => { DoCommand[viewer,9] }; SetComment => { TEditInputOps.SetCommentProp[TRUE] }; SetNotComment => { TEditInputOps.SetCommentProp[FALSE] }; PARAM => { -- Already processed in dispatch loop -- }; ENDCASE => ERROR; }; ENDCASE => ERROR; }; DispatchCommandProc: PUBLIC CommandClosureProc ~ { WITH data SELECT FROM c: REF CommandProc => [recordAtom: recordAtom, quit: quit] ¬ c­[viewer]; ENDCASE => ERROR; }; Register: PUBLIC PROC [name: ATOM, proc: CommandProc, before: BOOL ¬ TRUE] = { RegisterClosure[commandClosure: [name: name, proc: DispatchCommandProc, data: NEW[CommandProc ¬ proc]], before: before]; }; UnRegister: PUBLIC PROC [name: ATOM, proc: CommandProc] = { Match: PROC [data: REF] RETURNS [BOOL] ~ { WITH data SELECT FROM c: REF CommandProc => RETURN [c­ = proc]; ENDCASE => ERROR; }; UnRegisterClosure[name, DispatchCommandProc, Match]; }; IsRegistered: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc] RETURNS [BOOL] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable, name].val; closureList: LIST OF CommandClosure ¬ NARROW[p]; FOR l: LIST OF CommandClosure ¬ closureList, l.rest UNTIL l=NIL DO IF l.first.proc=DispatchCommandProc THEN { WITH l.first.data SELECT FROM c: REF CommandProc => IF c­ = proc THEN RETURN [TRUE]; ENDCASE => NULL; }; ENDLOOP; RETURN [FALSE] }; CommandClosure: TYPE ~ TEditInputExtras.CommandClosure; CommandClosureProc: TYPE ~ TEditInputExtras.CommandClosureProc; RegisterClosure: PUBLIC ENTRY PROC [commandClosure: CommandClosure, before: BOOL ¬ TRUE] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable, commandClosure.name].val; list: LIST OF CommandClosure ¬ NARROW[p]; IF before OR list=NIL THEN list ¬ CONS[commandClosure, list] ELSE { FOR l: LIST OF CommandClosure ¬ list, l.rest DO IF l.rest=NIL THEN { l.rest ¬ LIST[commandClosure]; EXIT }; ENDLOOP; }; [] ¬ RefTab.Store[commandTable, commandClosure.name, list]; }; UnRegisterClosure: PUBLIC ENTRY PROC [name: ATOM, proc: CommandClosureProc, match: PROC [REF] RETURNS [BOOL]] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable, name].val; head: LIST OF CommandClosure = CONS[[NIL, NIL, NIL], NARROW[p]]; prev: LIST OF CommandClosure ¬ head; FOR rem: LIST OF CommandClosure ¬ prev.rest, prev.rest UNTIL rem=NIL DO IF rem.first.name # name THEN ERROR; IF rem.first.proc = proc AND (match=NIL OR match[rem.first.data]) THEN { prev.rest ¬ rem.rest } ELSE { prev ¬ rem }; ENDLOOP; IF head.rest = NIL THEN { [] ¬ RefTab.Delete[commandTable, name] } ELSE { [] ¬ RefTab.Store[commandTable, name, head.rest] }; }; GetCommandNames: PUBLIC ENTRY PROC RETURNS [list: LIST OF ATOM ¬ NIL] ~ { ENABLE UNWIND => NULL; EachPair: RefTab.EachPairAction = { list ¬ CONS[NARROW[key], list]; }; [] ¬ RefTab.Pairs[x: commandTable, action: EachPair]; }; RegisterCommandAtoms: PROC = { RegisterInternal[$ApplyCaretLook, ApplyCaretLook]; RegisterInternal[$ApplyLook, ApplyLook]; RegisterInternal[$ClearCaretLooks, ClearCaretLooks]; RegisterInternal[$ClearLooks, ClearLooks]; RegisterInternal[$BackSpace, BackSpace]; RegisterInternal[$BackWord, BackWord]; RegisterInternal[$DeleteNextChar, DeleteNextChar]; RegisterInternal[$DeleteNextWord, DeleteNextWord]; RegisterInternal[$GoToPreviousWord, GoToPreviousWord]; RegisterInternal[$GoToNextWord, GoToNextWord]; RegisterInternal[$GoToPreviousChar, GoToPreviousChar]; RegisterInternal[$GoToNextChar, GoToNextChar]; RegisterInternal[$GoToPreviousNode, GoToPreviousNode]; RegisterInternal[$GoToNextNode, GoToNextNode]; RegisterInternal[$GoToEndOfNode, GoToEndOfNode]; RegisterInternal[$GoToBeginningOfNode, GoToBeginningOfNode]; RegisterInternal[$Copy, Copy]; RegisterInternal[$Delete, Delete]; Register [$DoEdit, DoEdit]; RegisterInternal[$ExpandAbbrev, ExpandAbbrev]; RegisterInternal[$Move, Move]; RegisterInternal[$NormalizeToStart, NormalizeToStart]; Register [$NormalizeToCaret, Normalize]; RegisterInternal[$NormalizeToEnd, NormalizeToEnd]; RegisterInternal[$RemoveCaretLook, RemoveCaretLook]; RegisterInternal[$RemoveLook, RemoveLook]; RegisterInternal[$SetStyle, SetStyle]; RegisterInternal[$Time, Time]; RegisterInternal[$RedSplit, RedSplit]; RegisterInternal[$YellowSplit, YellowSplit]; RegisterInternal[$BlueSplit, BlueSplit]; RegisterInternal[$Transpose, Transpose]; RegisterInternal[$ToBoth, ToBoth]; RegisterInternal[$ToLimbo, ToLimbo]; RegisterInternal[$ToPrimary, ToPrimary]; RegisterInternal[$ToSecondary, ToSecondary]; RegisterInternal[$CutToWorld, CutToWorld]; RegisterInternal[$CutToWorldFormatted, CutToWorldFormatted]; RegisterInternal[$CopyToWorld, CopyToWorld]; RegisterInternal[$CopyToWorldFormatted, CopyToWorldFormatted]; RegisterInternal[$Paste, Paste]; RegisterInternal[$PasteFromWorld, PasteFromWorld]; RegisterInternal[$PasteFromWorldFormatted, PasteFromWorldFormatted]; RegisterInternal[$EditReset, EditReset]; RegisterInternal[$EditAbort, EditAbort]; RegisterInternal[$EditText, EditText]; RegisterInternal[$EditFormat, EditFormat]; RegisterInternal[$EditType, EditFormat]; -- For compatability RegisterInternal[$EditLooks, EditLooks]; RegisterInternal[$GetSecondary, GetSecondary]; RegisterInternal[$MakePDel, MakePDel]; RegisterInternal[$FindNext, FindNext]; RegisterInternal[$FindAny, FindAny]; RegisterInternal[$FindPrev, FindPrev]; RegisterInternal[$FindNextDef, FindNextDef]; RegisterInternal[$FindAnyDef, FindAnyDef]; RegisterInternal[$FindPrevDef, FindPrevDef]; RegisterInternal[$FindNextWord, FindNextWord]; RegisterInternal[$FindAnyWord, FindAnyWord]; RegisterInternal[$FindPrevWord, FindPrevWord]; RegisterInternal[$FindNextCaseless, FindNextCaseless]; RegisterInternal[$FindAnyCaseless, FindAnyCaseless]; RegisterInternal[$FindPrevCaseless, FindPrevCaseless]; RegisterInternal[$FindNextDefCaseless, FindNextDefCaseless]; RegisterInternal[$FindAnyDefCaseless, FindAnyDefCaseless]; RegisterInternal[$FindPrevDefCaseless, FindPrevDefCaseless]; RegisterInternal[$FindNextWordCaseless, FindNextWordCaseless]; RegisterInternal[$FindAnyWordCaseless, FindAnyWordCaseless]; RegisterInternal[$FindPrevWordCaseless, FindPrevWordCaseless]; Register [$PushSelection, SaveSelectionA]; Register [$PopSelection, RestoreSelectionA]; Register [$SaveSelection, SaveSelectionA]; Register [$RestoreSelection, RestoreSelectionA]; Register [$SaveSelectionA, SaveSelectionA]; Register [$RestoreSelectionA, RestoreSelectionA]; Register [$SaveSelectionB, SaveSelectionB]; Register [$RestoreSelectionB, RestoreSelectionB]; RegisterInternal[$Position, Position]; RegisterInternal[$PositionIncludingComments, PositionIncludingComments]; RegisterInternal[$MsgPosition, MsgPosition]; RegisterInternal[$MsgPositionIncludingComments, MsgPositionIncludingComments]; RegisterInternal[$StuffPosition, StuffPosition]; RegisterInternal[$StuffPositionIncludingComments, StuffPosition]; RegisterInternal[$RedMouse, RedMouse]; RegisterInternal[$YellowMouse, YellowMouse]; RegisterInternal[$BlueMouse, BlueMouse]; RegisterInternal[$RedDown, RedDown]; RegisterInternal[$YellowDown, YellowDown]; RegisterInternal[$BlueDown, BlueDown]; RegisterInternal[$SelBranch, SelBranch]; RegisterInternal[$SelChar, SelChar]; RegisterInternal[$SelExpand, SelExpand]; RegisterInternal[$SelExtend, SelExtend]; RegisterInternal[$SelStartExtend, SelStartExtend]; RegisterInternal[$SelNode, SelNode]; RegisterInternal[$SelNotPendDel, SelNotPendDel]; RegisterInternal[$SelPendDel, SelPendDel]; RegisterInternal[$ForceSelPendDel, ForceSelPendDel]; RegisterInternal[$ForceSelNotPendDel, ForceSelNotPendDel]; RegisterInternal[$SelSamePendDel, SelSamePendDel]; RegisterInternal[$SelPrimary, SelPrimary]; RegisterInternal[$SelReduce, SelReduce]; RegisterInternal[$SelSame, SelSame]; RegisterInternal[$SelSameEnd, SelSameEnd]; RegisterInternal[$SelSecondary, SelSecondary]; RegisterInternal[$SelUpdate, SelUpdate]; RegisterInternal[$SelWord, SelWord]; RegisterInternal[$IntermediateUser, IntermediateUser]; RegisterInternal[$AdvancedUser, AdvancedUser]; RegisterInternal[$ExpertUser, ExpertUser]; RegisterInternal[$Break, Break]; RegisterInternal[$Join, Join]; RegisterInternal[$Nest, Nest]; RegisterInternal[$SaveForPaste, SaveForPaste]; RegisterInternal[$SetFormat, SetFormat]; RegisterInternal[$SetType, SetFormat]; -- For compatability RegisterInternal[$GetFormat, GetFormat]; RegisterInternal[$GetType, GetFormat]; -- For compatability RegisterInternal[$UnNest, UnNest]; RegisterInternal[$AllCaps, AllCaps]; RegisterInternal[$AllLower, AllLower]; RegisterInternal[$FirstCap, FirstCap]; RegisterInternal[$InitialCaps, InitialCaps]; Register [$AllLevels, AllLevels]; Register [$FewerLevels, FewerLevels]; Register [$MoreLevels, MoreLevels]; Register [$FirstLevelOnly, FirstLevelOnly]; RegisterInternal[$CaretAfter, CaretAfter]; RegisterInternal[$CaretBefore, CaretBefore]; RegisterInternal[$Everything, Everything]; RegisterInternal[$GrowSelection, GrowSel]; RegisterInternal[$GrowSelectionToBlanks, GrowSelToBlanks]; RegisterInternal[$InsertLineBreak, InsertLineBreak]; RegisterInternal[$InsertNewline, InsertNewline]; RegisterInternal[$MakeNotPendingDelete, MakeNotPendingDelete]; RegisterInternal[$MakePendingDelete, MakePendingDelete]; Register [$MakePointSelection, MakePointSelection]; RegisterInternal[$MakeControlCharacter, MakeControlCharacter]; RegisterInternal[$MakeOctalCharacter, MakeOctalCharacter]; RegisterInternal[$UnMakeControlCharacter, UnMakeControlCharacter]; RegisterInternal[$UnMakeOctalCharacter, UnMakeOctalCharacter]; RegisterInternal[$MakePrimary, MakePrimaryOp]; RegisterInternal[$MakeSecondary, MakeSecondaryOp]; RegisterInternal[$CancelPrimary, CancelPrimaryOp]; RegisterInternal[$CancelSecondary, CancelSecondaryOp]; RegisterInternal[$Paint, Paint]; RegisterInternal[$PlaceholderBrackets, PlaceholderBrackets]; RegisterInternal[$PreviousPlaceholder, PreviousPlaceholder]; RegisterInternal[$PreviousViewer, PreviousViewer]; RegisterInternal[$ReadProfile, ReadTip]; RegisterInternal[$ReloadStyle, ReloadStyle]; RegisterInternal[$SelectMatchingPlaceholderBrackets, SelectMatchingPlaceholderBrackets]; RegisterInternal[$NextPlaceholder, NextPlaceholder]; RegisterInternal[$NextViewer, NextViewer]; RegisterInternal[$ReadAbbreviations, ReadAbbreviations]; RegisterInternal[$SelectMatchingParens, SelectMatchingParens]; RegisterInternal[$SelectMatchingAngleBrackets, SelectMatchingAngleBrackets]; RegisterInternal[$SelectMatchingCurlyBrackets, SelectMatchingCurlyBrackets]; RegisterInternal[$SelectMatchingSquareBrackets, SelectMatchingSquareBrackets]; RegisterInternal[$SelectMatchingSingleQuotes, SelectMatchingSingleQuotes]; RegisterInternal[$SelectMatchingDoubleQuotes, SelectMatchingDoubleQuotes]; RegisterInternal[$SelectMatchingDashBrackets, SelectMatchingDashBrackets]; RegisterInternal[$ParenBrackets, ParenBrackets]; RegisterInternal[$DashBrackets, DashBrackets]; RegisterInternal[$AngleBrackets, AngleBrackets]; RegisterInternal[$DoubleQuoteBrackets, DoubleQuoteBrackets]; RegisterInternal[$SingleQuoteBrackets, SingleQuoteBrackets]; RegisterInternal[$CurlyBrackets, CurlyBrackets]; RegisterInternal[$SquareBrackets, SquareBrackets]; RegisterInternal[$Command0, Command0]; RegisterInternal[$Command1, Command1]; RegisterInternal[$Command2, Command2]; RegisterInternal[$Command3, Command3]; RegisterInternal[$Command4, Command4]; RegisterInternal[$Command5, Command5]; RegisterInternal[$Command6, Command6]; RegisterInternal[$Command7, Command7]; RegisterInternal[$Command8, Command8]; RegisterInternal[$Command9, Command9]; RegisterInternal[$SetComment, SetComment]; RegisterInternal[$SetNotComment, SetNotComment]; RegisterInternal[$PARAM, PARAM]; }; justRegistered: BOOL ¬ TRUE; ProfileChanged: UserProfile.ProfileChangedProc = { IF NOT justRegistered THEN TEditProfile.ReadProfile[]; justRegistered ¬ FALSE; }; RegisterCommandAtoms[]; NodeAddrs.AddNotifyProc[UpdateSavedSelections]; UserProfile.CallWhenProfileChanges[ProfileChanged]; SetCommand[9, LIST[$MakePointSelection, $ParenBrackets]]; SetCommand[0, LIST[$SelectMatchingParens, $CaretAfter]]; END. h TEditInputImpl.mesa Copyright Σ 1985, 1986, 1987, 1989, 1991, 1992 by Xerox Corporation. All rights reserved. Paxton on December 28, 1982 2:21 pm Maxwell, January 4, 1983 3:53 pm Russ Atkinson, July 25, 1983 7:02 pm Bier, April 22, 1990 1:14 pm PDT Michael Plass, March 23, 1989 2:43:33 pm PST Doug Wyatt, April 23, 1992 11:39 am PDT Documentation: Tioga's Input Format This section was written on October 23, 1987, by Michael Plass Michael Plass, October 23, 1987 5:28:55 pm PDT This module handles the input that comes from TIP, menu clicks, EditTool ops, etc. The input is a LIST OF REF, where the actual REFs must be one of: ATOM => The name of a registered operation ROPE, REF CHAR, REF TEXT => Treated as user typein (but see $PARAM, below) TIP.TIPScreenCoords => Mouse position info REF INT => A numeric parameter used by some of the ops in this interface. (ugh, global state) (New as of October 23, 1987) The ATOM $PARAM is treated specially, in that the immediately following item is coerced to a ROPE, and not treated as user typein, but instead is passed to the CommandClosureProc of the immediately following operation. Note that this param cannot be accessed from a CommandProc, because of interface restrictions. Instrumentation Input handling set by SaveCoords (called by InterpInput) used by SelChar, SelWord, SelNode, SelBranch, SelUpdate, Extend set by SelPrimary, SelSecondary reset by DoEdit, EditReset used by SelPrimary, SelSecondary (to decide whether to change sel) set by SelPrimary, SelSecondary reset by DoEdit used by Sel*, Copy, Move, Transpose set by SelPendDel, SelNotPendDel, ForceSelPendDel, ForceSelNotPendDel reset by DoEdit, EditReset used by SelPendDel, SelNotPendDel (to decide whether to change pDel) set by SelPendDel, SelNotPendDel, ForceSelPendDel, ForceSelNotPendDel reset by DoEdit used by SelChar, SelWord, SelNode, SelBranch, SelUpdate, Extend set by SelExpand, SelReduce reset by ResetInputStuff used by Extend set by ToPrimary, ToSecondary, ToBoth, ToLimbo, EditAbort, AbortSecondary reset by DoEdit, EditReset used by Sel*, EditMessage, DoEdit set by EditText, EditLooks, EditFormat reset by DoEdit, EditReset, EditAbort used by EditMessage, DoEdit set by RedMouse, YellowMouse, BlueMouse, Extend, EditAbort, AbortSecondary reset by DoEdit used by RedDown, YellowDown, BlueDown set by RedMouse, YellowMouse, BlueMouse, Extend used by EditAbort set by EditAbort saved message for StuffPosition hand it off to buffered input routines maps global value in n to => ['a..'z]; Public Command Procs Support for Internal Commands Must lock the viewers BEFORE trying for the document lock turn on [Split] oldSel is saved version of sSel for use in Repeat savedSelA is saved by SaveSelectionA and restored by RestoreSelectionA savedSelB is saved by SaveSelectionB and restored by RestoreSelectionB fSel is saved feedback selection make sure nodes in same tree and right order make sure start index is ok make sure end index is ok make sure start is not after end scroll to start of document Internal Commands look for 140C as left single quote VerifyTree => { IF pSel.viewer=NIL THEN RETURN; TreeCheck.Verify[TextNode.Root[pSel.start.pos.node]]; MessageWindow.Append["Verified", TRUE]; MessageWindow.Blink[]; }; use 140C for left single quote Registration [key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOL _ FALSE] Initialization RegisterInternal[$VerifyTree, VerifyTree]; toPrimaryMessages[FALSE][FALSE] _ "Select for copy to caret"; toPrimaryMessages[FALSE][TRUE] _ "Select for move to caret"; toPrimaryMessages[TRUE][FALSE] _ "Select replacement"; toPrimaryMessages[TRUE][TRUE] _ "Select for move onto"; toSecondaryMessages[FALSE][FALSE] _ "Select destination for copy"; toSecondaryMessages[FALSE][TRUE] _ "Select for replacement"; toSecondaryMessages[TRUE][FALSE] _ "Select destination for move"; toSecondaryMessages[TRUE][TRUE] _ "Select destination for move onto"; Κ6k–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœO™ZKšœ#™#Kšœ ™ Kšœ$™$K™ Kšœ,™,K™'K™—šΟk ˜ KšœT˜TKšœ žœ˜#Kšœžœd˜wKšœ žœb˜rKšœžœ/˜GKšœžœ&˜J™.—š œcžœžœžœžœ™•Jšžœ&™*Jš žœžœžœžœžœ2™JJšœ*™*JšžœžœV™]—Jšœ!žœUžœΩ™Χ—šœ™Kšœ+žœ˜/KšŸ œžœžœ@˜ZK˜Kšœžœ+˜FKšœžœ.˜LKšœ/žœžœ˜VšŸœžœžœžœ˜IKšžœ˜Kšœ˜——™K˜3K˜šœžœΟc#˜4K™)K™?K˜—Kšœ žœ  ˜Lšœ žœ œ˜;K™K™K™BK˜—Kšœ žœ !˜Pšœžœ œ˜;K™K™K™#K™—Kšœ žœ! ˜Hšœ žœ œ˜=KšœE™EKšœ™KšœD™DK™—š œžœ œžœžœ˜3KšœE™EKšœ™Kšœ?™?K™—Kšœ žœ ˜Išœ˜K™K™K™K™—Kšœ žœ :˜bšœ žœ˜$K™IK™K™!K˜—Kšœ žœ" ˜Jšœ žœ œ˜>K™&K™%K™K˜—Kšœ žœ" ˜Nšœ žœ œ˜=KšœJ™JK™Kšœ%™%—K˜šœ$žœ˜DKšœ/™/Kšœ™K™—š œ žœžœžœžœžœžœ˜/K™—K˜šœžœžœ˜Kšœ™K˜—Kš œ žœ œžœžœ˜8šŸ œžœ˜Kšœžœ%˜9Kšœžœ%˜9šœžœžœ ž˜!K˜šœ žœ ž˜#šœžœ#ž˜5šžœžœ#ž˜6Kšžœ˜$Kšžœ˜#Kšžœžœ˜—šžœžœ#ž˜5Kšžœ˜Kšžœ˜Kšžœžœ˜—Kšžœžœ˜—K˜ K˜"Kšžœžœ˜—šœžœ ž˜%šœžœ#ž˜5šžœžœ#ž˜6Kšžœ"˜'Kšžœ˜!Kšžœžœ˜—šžœžœ#ž˜5Kšžœ"˜'Kšžœ'˜+Kšžœžœ˜—Kšžœžœ˜—K˜-K˜/Kšžœžœ˜—šœ žœ ž˜ K˜K˜&K˜(Kšžœžœ˜—Kšžœžœ˜—Kš žœžœžœžœžœ˜.Kšœžœ˜K˜K˜—K˜šŸ œžœžœ(žœžœžœžœ˜RK˜K˜K˜—šŸ œžœžœ&žœ˜IKšœ.žœ˜3K˜K˜—šŸœžœ˜4K˜K˜K˜—šŸ œžœ&žœ žœ˜KKšœ žœžœžœ&˜RKšžœ žœžœ8˜Nšžœ ž˜KšžœYžœ˜bšžœ˜Kšœ žœžœ˜Kšœ' -˜Tš žœžœžœ)žœžœž˜KKšœžœ˜KšœA˜AKšžœžœžœ˜!Kšžœžœžœ˜Kšžœ˜—Kšžœ žœ˜#K˜——K˜K˜—šŸœžœžœ˜6K˜—šŸ œžœžœžœ˜=K˜—šœžœžœ˜'K˜—šŸ œžœžœ(žœžœžœžœžœžœžœ˜yšŸœžœžœ  œ˜1Kšžœžœ#žœžœ˜5K˜/šœžœžœ&˜5Kšžœ#žœ!˜JKšžœžœ žœY˜mK˜%—K˜—šŸœžœžœžœžœ  œžœ'žœ%˜ŠKšžœžœ˜#K˜—š Ÿ œžœžœžœ  œ˜0šžœ2žœ˜:K˜Kšœ žœ˜K˜—K˜—šŸœžœžœžœžœžœ  œ˜DKšžœ4˜:K˜—šŸœžœžœžœžœžœžœžœžœ  œ˜Gšžœžœžœžœžœžœžœž˜Bšžœ žœž˜Kšœžœžœžœ˜Kšœžœžœ˜Kšœžœžœžœ˜Kšžœžœžœ˜—Kšžœ˜—Kšžœžœ˜K˜—Kšžœ žœžœ&žœ˜SK˜šžœžœžœ#žœ˜Ušžœ˜Kšœ&™&šžœžœžœžœžœžœžœž˜BK˜šžœ žœž˜šœžœžœ˜K˜4K˜—šœžœ˜ K˜1K˜—šœžœžœ˜K˜CK˜—Kšžœžœ˜—Kšžœ˜—K˜—šžœ˜Kšœžœžœ˜Kšœ žœžœ˜Kšžœžœ˜+šžœžœžœžœžœžœžœž˜BKšœ žœ˜ Kšžœ žœ žœ˜ Kšœžœ˜šžœ žœž˜šœžœ˜ šžœ ˜Kšžœ˜ šžœž˜Kšžœ žœžœ˜*Kšœ4žœ˜:K˜——Kšœ˜—šœ ˜ šžœ ˜Kšžœžœ#˜=Kšžœ*˜.—Kšœ˜—šœžœžœ˜šžœ ˜Kšžœžœžœ˜&Kšžœ2˜6—Kšœ˜—šœžœžœ˜Kšœžœžœ ˜-Kšœ˜Kšœ˜—šœžœ˜ Kšžœ žœ žœ˜@Kšœ ˜ Kšœ˜—šœžœžœ˜Kšœžœ˜!Kšžœ žœžœ!˜FKšœ˜Kšœ˜—Kšžœ:žœ˜G—Kš žœ žœžœžœ=žœ˜dKšžœ˜—Kšžœžœžœ žœ˜SK˜——K˜K˜—š Ÿ œžœžœžœžœ˜1Kšœ&™&Kšžœ˜ K˜K˜——šœ™šŸ œžœ˜!šŸœžœJ˜T˜Kš žœ žœžœžœžœ1˜U—K˜—K˜CK˜K˜—K˜=K˜=šŸœžœ˜)KšžœžœC˜dK˜K˜—šŸœžœ˜&KšžœžœžœC˜dK˜K˜—šŸœžœ˜)KšžœžœC˜dK˜K˜—šŸœžœ˜&KšžœžœžœC˜dK˜K˜—šŸ œžœ˜!šžœ žœž˜šœ)˜)šžœ'žœ˜/Kšœ1žœ˜7K˜&Kšœ˜Kšœ˜K˜—K˜—Kšžœ˜—Kšžœžœ˜Kšœ˜K˜—šŸœžœ˜&šžœ žœž˜šœ)˜)šžœžœ˜Kšœ6žœ˜Kšœ™K˜(Kšœ˜—K˜)K˜-K˜K˜—KšŸœžœžœžœ˜šŸœžœ˜Kšœ7žœ˜=K˜K˜%K˜K˜—šŸœžœ*žœ˜?Kšœ'žœ˜;Kšžœžœžœžœ˜K˜Kšžœžœžœ˜šžœžœ˜Kšžœžœžœ ˜*K˜K˜AKšœ žœ˜Kšœ˜—K˜FKšžœžœ˜#Kšžœžœ žœ˜&K˜K˜—Kš Ÿœžœžœžœ %˜EšŸ œžœ+žœ  œ˜PKšžœ&žœžœ ˜=K˜K˜—šŸ œžœ"žœ˜:KšœDžœ˜JKšœ˜K˜—šŸœžœ+˜@K˜Kšœžœ˜Kšœ˜Kšœ7žœ ˜XKšœ" ˜@Kšœ0 "˜Ršžœ žœ˜š žœžœžœ žœ "˜AK˜$Kšžœ˜—Kšžœ3žœžœ˜MK˜'—Kšœ˜Kšœ˜K˜—š Ÿ œžœžœ(žœ žœ˜^K˜Kšœžœ˜Kšžœžœžœžœ˜šžœžœžœž˜0šžœ.žœ˜6K˜ Kšœžœ˜'—Kšžœ˜—K˜ K˜K˜—šŸ œžœžœ˜K˜K˜K˜&K˜(Kšœ )˜EK˜K˜K˜—Kšœ žœžœ žœžœžœžœžœ˜3šœžœ žœ ˜$K˜—šŸ œžœžœžœžœžœžœ˜DK˜K˜K˜—šŸ œžœžœžœ žœžœžœžœ˜MKšžœ ˜Kšœ˜K˜—šŸ œžœ2˜AKšœ˜Kšœ˜K˜—K˜—šœ™šœ žœ ˜0K˜—šŸœžœžœ˜7KšœBžœ˜YKšœ˜K˜—šŸ œžœ žœžœ˜,Kšœ;˜;Kšœ žœžœ˜šŸ œžœ@˜PšŸ œžœ;žœžœ˜bšœžœž˜Kšžœ#˜'Kšžœ:˜>—Kšžœžœ˜K˜—Kšžœžœžœžœ˜7K˜AKšžœžœžœ ˜K˜—K˜.Kšœ0˜0Kšžœžœ$žœ˜9K˜K˜—šŸœžœ˜Kšœ;˜;Kšœ žœ-˜šžœžœž˜šœžœ˜Kšœ˜Kšœ8˜8šžœž˜KšŸ œžœ˜*KšŸ œžœ˜(KšŸœ˜#šŸœ˜K˜—šŸœ˜K˜—šŸœ˜K˜—šŸœ˜Kšœ4˜4K˜—šŸ œ˜Kšœ/˜/K˜—šŸœ˜K˜SK˜—šŸ œ˜K˜NK˜—KšŸ œ#˜,KšŸœ"˜*KšŸœ(˜6KšŸœ(˜6KšŸœ*˜:KšŸ œ&˜2KšŸœ*˜:KšŸ œ&˜2KšŸœ*˜:KšŸ œ&˜2KšŸ œ1˜>KšŸœ2˜EšŸœ˜ šžœžœžœ˜(K˜K˜K˜—K˜—KšŸœ'žœ˜7KšŸ œ+˜7šŸœ˜ šžœžœžœ˜(K˜K˜K˜—K˜—šŸœ˜Kšœ7˜7K˜—šŸ œ˜Kšœ2˜2K˜—KšŸœ!˜)KšŸœ#˜'Kš ŸœŸ œŸ œžœžœ˜EšŸ œ˜šžœžœžœ˜(K˜K˜K˜—K˜—šŸœ˜ Kšžœžœžœ'˜SKšžœžœ˜K˜—Kš Ÿœžœžœžœžœ˜KšŸ œ˜Kšžœžœžœ˜CKšžœžœ˜K˜—šŸ œ˜Kšžœžœžœ,˜XKšžœžœ˜K˜—KšŸœžœžœ˜2KšŸ œ)žœžœ˜CKšŸ œ*žœžœ˜EšŸ œ˜KšœLžœžœ˜[K˜—šŸ œ˜Kšœ žœ˜Kšžœžœžœ#žœ&˜]Kšžœžœž˜'Kšœ"žœžœžœ˜5Kšœ!žœ˜'Kšœžœ ˜,Kš œžœžœ žœžœ ˜[K˜%Kšœ ˜-Kšžœžœ˜K˜—šŸ œ˜Kšžœžœžœ'žœ5˜…Kšžœžœ˜K˜—šŸœ˜ Kšœ$žœžœžœ˜9K˜—šŸœ˜šŸœžœJ˜TKš œžœ žœžœžœžœ˜XK˜—K˜CK˜—šŸœ˜šŸœžœJ˜TKš œžœ žœžœžœžœ˜VK˜—K˜CK˜—šŸœ˜ K˜9Kšœžœžœ˜K˜—šŸœ˜ K˜9Kšœžœžœ˜K˜—šŸœ˜ K˜:Kšœžœžœ˜K˜—šŸ œ˜Kšœ>žœžœ˜QKšœžœžœ˜K˜—šŸ œ˜Kšœ>žœžœ˜QKšœžœžœ˜K˜—šŸ œ˜Kšœ?žœžœ˜RKšœžœžœ˜K˜—šŸ œ˜Kšœ>žœžœ˜PKšœžœžœ˜K˜—šŸ œ˜Kšœ>žœžœ˜PKšœžœžœ˜K˜—šŸ œ˜Kšœ?žœžœ˜QKšœžœžœ˜K˜—šŸœ˜Kšœ?žœ˜FKšœžœžœ˜K˜—šŸœ˜Kšœ?žœ˜FKšœžœžœ˜K˜—šŸœ˜Kšœ@žœ˜GKšœžœžœ˜K˜—šŸœ˜Kšœ>žœžœžœ˜^Kšœžœžœ˜K˜—šŸœ˜Kšœ>žœžœžœ˜^Kšœžœžœ˜K˜—šŸœ˜Kšœ?žœžœžœ˜_Kšœžœžœ˜K˜—šŸœ˜Kšœ>žœžœžœ˜]Kšœžœžœ˜K˜—šŸœ˜Kšœ>žœžœžœ˜]Kšœžœžœ˜K˜—šŸœ˜Kšœ?žœžœžœ˜^Kšœžœžœ˜K˜—šŸœ˜ K˜ Kšœ>žœ˜DKšžœžœ˜ K˜—šŸœ˜K˜ Kšœ>žœ˜EKšžœžœ˜ K˜—šŸ œ˜KšœIžœ˜OKšœKžœ˜QKšœ˜—šŸœ˜!KšœIžœ˜PKšœKžœ˜QKšœ˜—šŸ œ˜Kšœ*˜*Kšœ˜—šŸœ˜ Kšžœžœžœ ˜*K˜K˜AKšžœžœ˜K˜—šŸ œ˜Kšžœžœžœ ˜*K˜K˜AKšžœžœ˜K˜—šŸ œ˜Kšžœžœžœ ˜*K˜K˜AKšžœžœ˜K˜—šŸœ˜ Kš žœžœžœ žœžœ˜9K˜—šŸ œ˜Kš žœžœžœ žœžœ˜KšŸœ(˜7šŸ œ˜Kšœ'žœ˜;Kšžœžœžœžœ˜Kšœ@˜@Kšœ˜—KšŸœ3˜GKšŸœ0˜AKšŸœ-˜AKšŸœ+˜=KšŸœ/˜EKšŸœ-˜AKšŸ œ%˜2KšŸœ'˜6KšŸœ'˜6KšŸœ)˜:KšŸœ˜KšŸœ,˜?KšŸœ˜KšŸ œ$˜/šŸ!œ˜&K˜,K˜—šŸœ˜Kšœ"™"K˜/K˜—KšŸœ4˜NKšŸœ4˜NKšŸœ%žœ˜AKšŸœžœ˜6KšŸœ%žœ˜˜>Kšœ ˜ Kšœ2˜2KšœD˜DKšœ(˜(Kšœ(˜(Kšœ&˜&Kšœ*˜*Kšœ* ˜>Kšœ(˜(Kšœ.˜.Kšœ&˜&Kšœ&˜&Kšœ$˜$Kšœ&˜&Kšœ,˜,Kšœ*˜*Kšœ,˜,Kšœ.˜.Kšœ,˜,Kšœ.˜.Kšœ6˜6Kšœ4˜4Kšœ6˜6Kšœ<˜˜>Kšœ<˜˜>Kšœ2˜2Kšœ4˜4Kšœ2˜2Kšœ8˜8Kšœ3˜3Kšœ9˜9Kšœ3˜3Kšœ9˜9Kšœ&˜&KšœH˜HKšœ,˜,KšœN˜NKšœ0˜0KšœA˜AKšœ&˜&Kšœ,˜,Kšœ(˜(Kšœ$˜$Kšœ*˜*Kšœ&˜&Kšœ(˜(Kšœ$˜$Kšœ(˜(Kšœ(˜(Kšœ2˜2Kšœ$˜$Kšœ0˜0Kšœ*˜*Kšœ4˜4Kšœ:˜:Kšœ2˜2Kšœ*˜*Kšœ(˜(Kšœ$˜$Kšœ*˜*Kšœ.˜.Kšœ(˜(Kšœ$˜$Kšœ6˜6Kšœ.˜.Kšœ*˜*K˜ K˜K˜K˜.K˜(Kšœ( ˜K˜8K˜;K˜>K˜:K˜BK˜>K˜.K˜2K˜2K˜6K˜ K˜K˜LK˜LK˜NK˜JK˜JK˜JK˜0K˜.K˜0K˜