DIRECTORY Atom USING [GetPName], EditSpan USING [CompareNodeOrder], InputFocus USING [SetInputFocus], MessageWindow USING [Append, Blink, Clear], NodeAddrs USING [AddNotifyProc], RefTab USING [Create, Delete, EachPairAction, Fetch, Pairs, Ref, Store], Rope USING [Concat, FromRefText, ROPE], TEditDisplay USING [EstablishLine], TEditDocument USING [LineTable, maxClip, Selection, SelectionId, SelectionRec, SpinAndLock, TEditDocumentData, Unlock], TEditImpl USING [ReloadReadonlyTipTable, ReloadTipTable, ReloadTypeScriptTipTable], 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, 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], TEditOps USING [CopyLoadHistory, CopyPositionHistory, RememberCurrentPosition], 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], TEditSplit USING [], TEditTouchup USING [LockAfterRefresh, UnlockAfterRefresh], TextEdit USING [Size], TextLooks USING [allLooks, Look, noLooks], TextNode USING [FirstChild, ForwardClipped, Level, Location, Node, NodeItself, Parent, Root], TiogaOps USING [], TIPUser USING [TIPScreenCoords, TIPScreenCoordsRec], UserProfile USING [CallWhenProfileChanges, ProfileChangedProc], ViewerClasses USING [NotifyProc, Viewer], ViewerForkers USING [ForkPaint], ViewerLocks USING [CallUnderWriteLocks], ViewerOps USING [AddProp, ComputeColumn, CreateViewer, DestroyViewer, FetchProp, MoveBelowViewer, OpenIcon, SetMenu], WindowManager USING [UnWaitCursor, WaitCursor]; TEditInputImpl: CEDAR MONITOR IMPORTS Atom, EditSpan, InputFocus, MessageWindow, NodeAddrs, RefTab, Rope, TEditDisplay, TEditDocument, TEditImpl, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditScrolling, TEditSelection, TEditTouchup, TextEdit, TextNode, UserProfile, ViewerForkers, ViewerLocks, ViewerOps, WindowManager EXPORTS TEditImpl, TEditInput, TEditInputBackdoor, TEditInputExtras, TEditSplit, TiogaOps = BEGIN OPEN TEditInput; Node: TYPE ~ TextNode.Node; ROPE: TYPE ~ Rope.ROPE; mx, my: INTEGER; -- global Coord param for ops below sel: PUBLIC -- TEditInputBackdoor -- TEditDocument.SelectionId _ primary; -- global sel ID; can be set to "secondary" by $SelSecondary changeLevel: TEditSelection.LevelChange; -- change granularity when extend pDel: PUBLIC -- TEditInputBackdoor -- BOOL _ FALSE; EditObject: TYPE = TEditInputBackdoor.EditObject; editState: PUBLIC EditState _ reset; editObject: PUBLIC -- TEditInputBackdoor -- EditObject _ text; SelState: TYPE = TEditInputBackdoor.SelState; selState: PUBLIC -- TEditInputBackdoor -- SelState _ reset; PDelState: TYPE = TEditInputBackdoor.PDelState; pdelState: PUBLIC -- TEditInputBackdoor -- PDelState _ reset; interrupt: PUBLIC REF BOOL _ NEW[BOOL _ FALSE]; commandTable: RefTab.Ref _ RefTab.Create[mod: 101]; editMessage: PUBLIC -- TEditInputBackdoor -- ROPE _ NIL; MessageArray: TYPE = ARRAY BOOL OF ARRAY BOOL OF ROPE; toPrimaryMessages: REF MessageArray _ NEW [MessageArray]; toSecondaryMessages: REF MessageArray _ NEW [MessageArray]; EditMessage: PROC = { msg: ROPE _ SELECT editState FROM tolimbo => "Select for delete", toprimary => SELECT editObject FROM text => toPrimaryMessages[TEditSelection.pSel.pendingDelete][TEditSelection.sSel.pendingDelete], looks => "Select looks to copy", format => "Select format to copy", ENDCASE => NIL, tosecondary => SELECT editObject FROM text => toSecondaryMessages[TEditSelection.pSel.pendingDelete][TEditSelection.sSel.pendingDelete], 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 }; prevPSel: TEditDocument.Selection _ NEW[TEditDocument.SelectionRec]; 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] = { p: REF ANY = RefTab.Fetch[commandTable,atom].val; IF p=NIL THEN MessageWindow.Append[Rope.Concat["Unknown atom given to Tioga: ", Atom.GetPName[atom]], TRUE] ELSE { closureList: LIST OF CommandClosure = NARROW[p]; 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 }; 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] }; 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 paramIsNext 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[]; }; }; interpreterNesting: PUBLIC INTEGER _ 0; 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: Node, new: PROC [old: INT] RETURNS [INT]] = { 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: Node; t1, t2: Node; 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] }; MouseColor: TYPE = TEditInputBackdoor.MouseColor; mouseColor: PUBLIC -- TEditInputBackdoor -- MouseColor _ red; 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: Node; 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,].nx) # NIL THEN pos _ [node,0]; TEditDisplay.EstablishLine[tdd, pos] }; TEditDocument.Unlock[tdd]; }; MaxLevelShown: PUBLIC PROC [tdd: TEditDocument.TEditDocumentData] RETURNS [level: INTEGER] = { node, n: Node; 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[]; TEditImpl.ReloadTipTable[]; TEditImpl.ReloadReadonlyTipTable[]; TEditImpl.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]]; }; RegisterInternal: PROC [name: ATOM, id: InternalID] ~ { RegisterClosure[[name: name, proc: DispatchInternalCommand, data: NEW[InternalID _ id]]]; }; DispatchInternalCommand: CommandClosureProc ~ { n: INT ~ WITH param SELECT FROM n: REF INT => n^ ENDCASE => 1; WITH data SELECT FROM id: REF InternalID => { SELECT id^ FROM 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] }; Copy => { IF TEditSelection.sSel.viewer#NIL THEN { TEditInputOps.Copy[sel]; RecordRef[$GetSecondary] }; }; Delete => { TEditInputOps.Delete[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] }; 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 _ reset; pdelState _ pending; pDel _ TRUE; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; ForceSelNotPendDel => { -- force not pending delete pdelState _ reset; 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[] }; 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; }; InternalID: TYPE ~ { ApplyCaretLook, ApplyLook, ClearCaretLooks, ClearLooks, BackSpace, BackWord, DeleteNextChar, DeleteNextWord, GoToPreviousWord, GoToNextWord, GoToPreviousChar, GoToNextChar, GoToPreviousNode, GoToNextNode, Copy, Delete, ExpandAbbrev, Move, NormalizeToStart, NormalizeToEnd, RemoveCaretLook, RemoveLook, SetStyle, Time, RedSplit, YellowSplit, BlueSplit, Transpose, ToBoth, ToLimbo, ToPrimary, ToSecondary, EditReset, EditAbort, EditText, EditFormat, EditLooks, GetSecondary, MakePDel, FindNext, FindAny, FindPrev, FindNextDef, FindAnyDef, FindPrevDef, FindNextWord, FindAnyWord, FindPrevWord, FindNextCaseless, FindAnyCaseless, FindPrevCaseless, FindNextDefCaseless, FindAnyDefCaseless, FindPrevDefCaseless, FindNextWordCaseless, FindAnyWordCaseless, FindPrevWordCaseless, PushSelection, PopSelection, SaveSelection, RestoreSelection, Position, PositionIncludingComments, RedMouse, YellowMouse, BlueMouse, RedDown, YellowDown, BlueDown, SelBranch, SelChar, SelExpand, SelExtend, SelStartExtend, SelNode, SelNotPendDel, SelPendDel, ForceSelPendDel, ForceSelNotPendDel, SelSamePendDel, SelPrimary, SelReduce, SelSame, SelSameEnd, SelSecondary, SelUpdate, SelWord, IntermediateUser, AdvancedUser, ExpertUser, Break, Join, Nest, Paste, SaveForPaste, SetFormat, GetFormat, UnNest, AllCaps, AllLower, FirstCap, InitialCaps, CaretAfter, CaretBefore, Everything, GrowSel, GrowSelToBlanks, InsertLineBreak, MakeNotPendingDelete, MakePendingDelete, MakeControlCharacter, MakeOctalCharacter, UnMakeControlCharacter, UnMakeOctalCharacter, MakePrimaryOp, MakeSecondaryOp, CancelPrimaryOp, CancelSecondaryOp, Paint, PlaceholderBrackets, ReadTip, ReloadStyle, SelectMatchingPlaceholderBrackets, SelectMatchingSingleQuotes, SelectMatchingDoubleQuotes, SelectMatchingDashBrackets, PreviousPlaceholder, PreviousViewer, NextPlaceholder, NextViewer, ReadAbbreviations, SelectMatchingParens, SelectMatchingAngleBrackets, SelectMatchingCurlyBrackets, SelectMatchingSquareBrackets, ParenBrackets, DashBrackets, DoubleQuoteBrackets, AngleBrackets, SingleQuoteBrackets, CurlyBrackets, SquareBrackets, Command0, Command1, Command2, Command3, Command4, Command5, Command6, Command7, Command8, Command9, SetComment, SetNotComment, PARAM }; DispatchCommandProc: 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[$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[$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[$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[$Paste, Paste]; 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[$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; }; 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"; RegisterCommandAtoms[]; NodeAddrs.AddNotifyProc[UpdateSavedSelections]; UserProfile.CallWhenProfileChanges[ProfileChanged]; END. ξTEditInputImpl.mesa Copyright Σ 1985, 1986, 1987, 1988 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 Michael Plass, February 12, 1988 4:19:47 pm PST Doug Wyatt, February 17, 1988 12:19:01 pm PST A bit of (...ahem) Documentation 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. Input handling global sel ID; can be set to TRUE by $SelPendDel, FALSE by $SelNotPendDel for EditAbort 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]; Κ1π˜codešœ™KšœN™NKšœ#™#Kšœ ™ Kšœ$™$Kšœ/™/Kšœ-™-K™—šΟk ˜ Kšœœ ˜Kšœ œ˜"Kšœ œ˜!Kšœœ˜+Kšœ œ˜ Kšœœ<˜HKšœœœ˜'Kšœ œ˜#Kšœœd˜wKšœ œD˜SKšœ œb˜rKšœœ/˜GKšœœ&˜J™.—š œcœœœœ™•Jšœ&™*Jš œœœœœ2™JJšœ*™*JšœœV™]—Jšœ!œUœΩ™Χ—™šœœΟc#˜4K˜—KšœœŸœ&Ÿ<˜†Kšœ)Ÿ!˜Jš œœŸœœœ˜3KšœI™I—K˜Kšœ œ!˜1Kšœ œ˜$Kšœ œŸœ˜>Kšœ œ˜-K˜Kšœ œŸœ˜;Kšœ œ ˜/K˜Kšœ œŸœ˜=Kš œ œœœœœœ˜/K˜3Kš œ œŸœœœ˜8Kšœœœœœœœœœ˜6Kšœœœ˜9Kšœœœ˜;šΟn œœ˜šœœœ ˜!K˜šœ œ ˜#K˜`K˜ K˜"Kšœœ˜—šœœ ˜%K˜bK˜-K˜/Kšœœ˜—šœ œ ˜ K˜K˜&K˜(Kšœœ˜—Kšœœ˜—Kš œœœœœ˜.Kšœœ˜K˜K˜—K˜Kšœ$œ˜DKšœ ™ š  œœœ(œœœœ˜RK˜K˜K˜—š  œœœ&œ˜IKšœ.œ˜3K˜K˜—š œœ˜4K˜K˜K˜—š  œœ&œ œ˜KKšœœœ'˜1šœ˜KšœYœ˜bšœ˜Kšœ œœœ˜0Kšœ œœ˜Kšœ'Ÿ-˜Tš œœœ)œœ˜KKšœœ˜KšœA˜AKšœœœ˜!Kšœœœ˜Kšœ˜—Kšœ œ˜#K˜——K˜K˜—š œœœ˜6K˜—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˜šœœœ#œ˜Ušœ˜Kšœ&™&šœœœœœœœ˜BK˜šœ œ˜šœœœ˜K˜4K˜—šœœ˜ K˜1K˜—šœœœ˜K˜CK˜—Kšœœ˜—Kšœ˜—K˜—šœ˜Kšœœœ˜Kšœ œœ˜Kšœœ˜+šœœœœœœœ˜BJšœ œ˜ 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˜—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šœ œ!˜1Kšœ œŸœ˜=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šœ2œœ˜LK˜'—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˜—šœ™š œœœ˜7JšœBœ˜YKšœ˜K˜—š œ˜/Kšœœœœœœœœ˜>šœœ˜šœœ˜šœ˜š œ˜Kšœ4˜4K˜—š  œ˜Kšœ/˜/K˜—š œ˜K˜SK˜—š  œ˜K˜NK˜—Kš  œ#˜,Kš œ"˜*Kš œ(˜6Kš œ(˜6Kš œ*˜:Kš  œ&˜2Kš œ*˜:Kš  œ&˜2Kš œ*˜:Kš  œ&˜2š œ˜ šœœœ˜(K˜K˜K˜—K˜—Kš œœ˜)Kš  œ+˜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šœœœ ˜*K˜K˜AKšœœ˜K˜—š  œ˜Kšœœœ ˜*K˜K˜AKšœœ˜K˜—š  œ˜Kšœœœ ˜*K˜K˜AKšœœ˜K˜—š œ˜ Kš œœœ œœ˜9K˜—š  œ˜Kš œœœ œœ˜Kš œ(˜7Kš œ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šœ.˜.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šœ,˜,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šœ(Ÿ˜K˜8K˜;K˜>K˜:K˜BK˜>K˜.K˜2K˜2K˜6K˜ K˜K˜LK˜LK˜NK˜JK˜JK˜JK˜0K˜.K˜0K˜