DIRECTORY Atom USING [GetProp], Buttons USING [Button, ButtonProc, SetDisplayStyle, ReLabel], EditToolBuilder USING [BuildButton, BuildDataFieldPair, BuildLabel, BuildPair, BuildTriple, DataFieldButton, GetDataNode, HGap, ToMiddle, ToNext], EditToolPrivate USING [ChangeState, CycleTriple, DoButton, FixPSel, Info, Pattern, PatternRep, mainToolInfo, editTool, Register, SavePSel, SearchDir, SearchWhere], IO USING [PutFR, rope, int], Labels USING [Set], Menus USING [Menu, MenuProc, MenuEntry, FindEntry, CopyEntry, SetClientData], MessageWindow USING [Append, Clear], NodeProps USING [DoSpecs], NodeStyleOps USING [StyleNameForNode], Rope USING [Concat, ROPE], TEditDocument USING [Selection], TEditInput USING [CloseEvent, CommandProc], TEditInputOps USING [CallWithLocks], TEditOps USING [GetSelData, RememberCurrentPosition, SetTextContents], TEditProfile USING [selectionCaret], TEditRefresh USING [ScrollToEndOfSel], TEditSelection USING [LockSel, UnlockSel, MakeSelection, SetSelLooks], TextEdit, TextFind, TextNode USING [Root, FirstChild], Tioga USING [Node, Location, Looks, noLooks], TiogaFind USING [TargetFromNode, Search, Match], ViewerClasses USING [Viewer], ViewerOps USING [AddProp, BlinkDisplay, CreateViewer], ViewerSpecs USING [openRightWidth], ViewerTools USING [InhibitUserEdits]; EditToolSearchImpl: CEDAR PROGRAM IMPORTS Atom, Buttons, EditToolBuilder, EditToolPrivate, IO, Labels, MessageWindow, Menus, NodeProps, NodeStyleOps, Rope, TEditOps, TextEdit, TextFind, TextNode, TEditInput, TEditInputOps, TEditProfile, TEditRefresh, TEditSelection, TiogaFind, ViewerOps, ViewerSpecs, ViewerTools EXPORTS EditToolPrivate = BEGIN OPEN EditToolPrivate, EditToolBuilder; ROPE: TYPE ~ Rope.ROPE; Node: TYPE ~ Tioga.Node; Location: TYPE ~ Tioga.Location; Report: PROC [msg: Rope.ROPE, blink: BOOL _ TRUE] ~ { IF msg=NIL THEN MessageWindow.Clear[] ELSE { MessageWindow.Append[msg, TRUE]; IF blink THEN ViewerOps.BlinkDisplay[]; }; }; searchForwardAtom: LIST OF REF = Register[$SearchForward,SearchForwardOp]; SearchForwardOp: TEditInput.CommandProc = { Search[forwards,mainToolInfo] }; searchAnywhereAtom: LIST OF REF = Register[$SearchAnywhere,SearchAnywhereOp]; SearchAnywhereOp: TEditInput.CommandProc = { Search[anywhere,mainToolInfo] }; searchBackwardsAtom: LIST OF REF = Register[$SearchBackwards,SearchBackwardsOp]; SearchBackwardsOp: TEditInput.CommandProc = { Search[backwards,mainToolInfo] }; DoSearchMenuButton: PUBLIC Menus.MenuProc = { SELECT mouseButton FROM red => DoButton[searchForwardAtom]; yellow => DoButton[searchAnywhereAtom]; blue => DoButton[searchBackwardsAtom]; ENDCASE => ERROR; }; CheckPSel: PUBLIC PROC [pSel: TEditDocument.Selection, typescriptOK: BOOL ¬ TRUE] RETURNS [ok: BOOL] = { IF pSel#NIL AND pSel.viewer#NIL AND (pSel.viewer.class.flavor=$Text OR (typescriptOK AND pSel.viewer.class.flavor=$Typescript)) THEN RETURN [TRUE]; Report["Please make a text selection."]; RETURN [FALSE]; }; Search: PUBLIC PROC [whichDir: SearchDir, info: Info] = { found: BOOL ~ TrySearch[whichDir, info]; Report[IF found THEN NIL ELSE "Not found.", TRUE]; }; TrySearch: PUBLIC PROC [whichDir: SearchDir, info: Info] RETURNS [found: BOOL ¬ FALSE] = { IF info.ignoreText AND info.ignoreLooks AND info.ignoreFormat AND info.ignoreStyle AND info.ignoreComment THEN { Report["Pick one or more of text/looks/format/style/comment to match."]; RETURN; }; TEditSelection.LockSel[primary, "TrySearch"]; { ENABLE UNWIND => TEditSelection.UnlockSel[primary]; pSel: TEditDocument.Selection ¬ NIL; pattern: Pattern ¬ NIL; FixPSel[]; pSel ¬ TEditOps.GetSelData[]; IF ~CheckPSel[pSel] OR (pattern ¬ GetPattern[info])=NIL THEN GOTO Quit; [found, info.subs] ¬ DoSearch[whichDir: whichDir, pattern: pattern, interrupt: info.interrupt]; IF found THEN { cmdPtr: REF ANY ¬ Atom.GetProp[$CafeteriaTrayRegistryAtom, $EditToolAddToTray]; IF cmdPtr # NIL THEN { EditToolAddInterfaceProc: TYPE = PROC [operation: ATOM, opList: Rope.ROPE ¬ NIL]; -- same as EditToolCafeteria.EditToolAddInterfaceProc addProcPtr: REF EditToolAddInterfaceProc ¬ NARROW[cmdPtr, REF EditToolAddInterfaceProc]; addProcPtr[$DoSearch]; }; }; EXITS Quit => {}; }; TEditSelection.UnlockSel[primary]; }; matchFromWhere: ARRAY SearchWhere OF TiogaFind.Match ~ [anywhere: any, words: word, nodes: all]; GetPattern: PUBLIC PROC [info: EditToolPrivate.Info] RETURNS [Pattern] ~ { node: Node ~ GetDataNode[info.targetArg]; nodeSize: INT ~ TextEdit.Size[node]; checkText: BOOL ~ NOT info.ignoreText; checkLooks: BOOL ~ NOT info.ignoreLooks; checkComment: BOOL ~ NOT info.ignoreComment; checkFormat: BOOL ~ NOT info.ignoreFormat; checkStyle: BOOL ~ NOT info.ignoreStyle; target: TextFind.Target ¬ NIL; comment: BOOL ¬ FALSE; format: ATOM ¬ NIL; style: ATOM ¬ NIL; IF nodeSize=0 AND (checkText OR checkLooks) THEN { Report["Please enter a search pattern in the \"Target:\" field."]; RETURN[NIL]; }; IF checkText THEN { error: ROPE ¬ NIL; target ¬ TiogaFind.TargetFromNode[node: node, pattern: NOT info.literal ! TextFind.Error => { error ¬ IO.PutFR["Error: %g, at position %g.", IO.rope[reason], IO.int[index]]; CONTINUE }]; IF error#NIL THEN { Report[error]; RETURN[NIL] }; } ELSE IF checkLooks THEN { patternNode: Node ~ TextEdit.FromRope["**#**"]; patternLooks: Tioga.Looks ¬ Tioga.noLooks; FOR i: INT IN [0..nodeSize) DO looks: Tioga.Looks ~ TextEdit.FetchLooks[node, i]; IF i=0 THEN patternLooks ¬ looks ELSE IF looks#patternLooks THEN { Report["Search pattern has nonuniform looks; using looks from first char."]; EXIT; }; ENDLOOP; TextEdit.ChangeLooks[root: NIL, text: patternNode, add: patternLooks]; target ¬ TiogaFind.TargetFromNode[node: patternNode, pattern: TRUE]; }; IF node#NIL THEN { IF checkComment THEN comment ¬ TextEdit.GetComment[node]; IF checkFormat THEN format ¬ TextEdit.GetFormat[node]; IF checkStyle THEN style ¬ NodeStyleOps.StyleNameForNode[node]; }; RETURN[NEW[PatternRep ¬ [target: target, case: NOT info.ignoreCase, match: matchFromWhere[info.searchWhere], checkLooks: checkLooks, looksExact: info.looksExact, checkComment: checkComment, comment: comment, checkFormat: checkFormat, format: format, checkStyle: checkStyle, style: style]]]; }; DoSearch: PROC [whichDir: SearchDir, pattern: Pattern, interrupt: REF BOOL] RETURNS [found: BOOL ¬ FALSE, subs: TextFind.Subs ¬ NIL] ~ { DoSearchLocked: PROC [root: Node, tSel: TEditDocument.Selection] = { where: Node ¬ NIL; at, atEnd: INT ¬ 0; Try: PROC [dir: TextFind.Direction, loc1, loc2: Location] ~ { pat: Pattern ~ pattern; [node: where, matchStart: at, matchEnd: atEnd, subs: subs] ¬ TiogaFind.Search[ direction: dir, loc1: loc1, loc2: loc2, target: pat.target, case: pat.case, match: pat.match, checkLooks: pat.checkLooks, looksExact: pat.looksExact, checkComment: pat.checkComment, comment: pat.comment, checkFormat: pat.checkFormat, format: pat.format, checkStyle: pat.checkStyle, style: pat.style, styleProc: NodeStyleOps.StyleNameForNode, interrupt: interrupt]; }; first: Location ~ [TextNode.FirstChild[root], 0]; loc1: Location ¬ tSel.start.pos; loc2: Location ¬ tSel.end.pos; loc1.where ¬ MIN[MAX[0, loc1.where], TextEdit.Size[loc1.node]]; loc2.where ¬ MIN[MAX[0, loc2.where+1], TextEdit.Size[loc2.node]]; IF interrupt#NIL THEN interrupt­ ¬ FALSE; IF whichDir=backwards THEN Try[backward, first, loc1] ELSE Try[forward, loc2, [NIL, 0]]; IF where=NIL AND whichDir=anywhere AND NOT(interrupt#NIL AND interrupt­) THEN Try[forward, first, [NIL, 0]]; IF where=NIL THEN RETURN ELSE found ¬ TRUE; tSel.start.pos ¬ [where, at]; tSel.end.pos ¬ [where, MAX[0,atEnd-1]]; tSel.granularity ¬ IF pattern.target=NIL OR pattern.match=all THEN node ELSE IF pattern.match=word THEN word ELSE char; tSel.insertion ¬ IF TEditProfile.selectionCaret=before THEN before ELSE after; TEditOps.RememberCurrentPosition[tSel.viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel]; TEditInput.CloseEvent[]; TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE]; }; TEditInputOps.CallWithLocks[DoSearchLocked, read] }; SetUpRealText: PROC [info: EditToolPrivate.Info] = { BuildRealSearchChoiceEntries[info]; ToNext[info.layout]; ignoringCase ¬ "IgnoreCase"; matchingCase ¬ "MatchCase"; matchingWords ¬ "MatchWords"; matchingAnywhere ¬ "MatchAnywhere"; matchingNodes ¬ "MatchNodes"; matchingLiterally ¬ "MatchLiterally"; matchingAsPattern ¬ "MatchPattern"; equalLooks ¬ "EqualLooksTest"; subsetLooks ¬ "SubsetLooksTest"; }; SetUpText: PROC [info: EditToolPrivate.Info] = { BuildSearchChoiceEntries[info]; ToNext[info.layout]; ignoringCase ¬ "Ignore Case"; matchingCase ¬ "Match Case"; matchingWords ¬ "Match Words Only"; matchingAnywhere ¬ "Match Anywhere"; matchingNodes ¬ "Match Entire Nodes Only"; matchingLiterally ¬ "Match Literally"; matchingAsPattern ¬ "Match as Pattern"; equalLooks ¬ "Equal as Looks Test"; subsetLooks ¬ "Subset as Looks Test"; }; BuildSearchButtons: PUBLIC PROC [info: EditToolPrivate.Info, realNames: BOOL ¬ FALSE] = { IF realNames THEN SetUpRealText[info] ELSE SetUpText[info]; BuildCaseEntry[info]; ToMiddle[info.layout]; BuildWhereEntry[info]; ToNext[info.layout]; BuildLitOrPatternEntry[info]; ToMiddle[info.layout]; BuildLooksMatchEntry[info]; }; equalLooks: Rope.ROPE; subsetLooks: Rope.ROPE; equalLooksAtom: LIST OF REF = Register[$EqualLooksTest,EqualLooksTestOp]; subsetLooksAtom: LIST OF REF = Register[$SubsetLooksTest,SubsetLooksTestOp]; LooksMatchButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.looksExact, equalLooksAtom,subsetLooksAtom]; }; EqualLooksTestOp: TEditInput.CommandProc = { EqualLooksTest[mainToolInfo]; }; EqualLooksTest: PROC [info: Info] = { OPEN info; looksExact ¬ TRUE; Labels.Set[looksMatchLabel,equalLooks]; }; SubsetLooksTestOp: TEditInput.CommandProc = { SubsetLooksTest[mainToolInfo]; }; SubsetLooksTest: PROC [info: Info] = { OPEN info; looksExact ¬ FALSE; Labels.Set[looksMatchLabel,subsetLooks]; }; BuildRealLooksMatchEntry: PROC [info: Info] = { OPEN info; looksExact ¬ FALSE; [looksMatchLabel,] ¬ BuildPair[layout,LooksMatchButton,looksExact,"EqualLooksTest","SubsetLooksTest",info]; }; BuildLooksMatchEntry: PROC [info: Info] = { OPEN info; looksExact ¬ FALSE; [looksMatchLabel,] ¬ BuildPair[layout,LooksMatchButton,looksExact,equalLooks,subsetLooks,info]; }; BuildEntry: PROC [name: Rope.ROPE, info:Info, proc: Buttons.ButtonProc, state: BOOL] RETURNS [new: Buttons.Button] = { new ¬ BuildButton[info.layout, name, proc, info, FALSE, FALSE]; ViewerOps.AddProp[new, $DisableMBFeedback, $DisableMBFeedback]; SetButton[new, state, FALSE]; }; BuildRealSearchChoiceEntries: PROC [info: Info] = { [] ¬ BuildLabel[info.layout, "Pick one or more: "]; HGap[info.layout]; info.textButton ¬ BuildEntry["MatchText", info, MatchTextButton, info.ignoreText ¬ FALSE]; info.looksButton ¬ BuildEntry["IgnoreLooks", info, MatchLooksButton, info.ignoreLooks ¬ TRUE]; info.formatButton ¬ BuildEntry["IgnoreFormat", info, MatchFormatButton, info.ignoreFormat ¬ TRUE]; EditToolBuilder.ToNext[info.layout]; EditToolBuilder.ToMiddle[info.layout]; info.styleButton ¬ BuildEntry["IgnoreStyle", info, MatchStyleButton, info.ignoreStyle ¬ TRUE]; info.commentButton ¬ BuildEntry["IgnoreComment", info, MatchCommentButton, info.ignoreComment ¬ TRUE]; }; BuildSearchChoiceEntries: PROC [info: Info] = { [] ¬ BuildLabel[info.layout, "Pick one or more: "]; HGap[info.layout]; info.textButton ¬ BuildEntry["Text", info, MatchTextButton, info.ignoreText ¬ FALSE]; info.looksButton ¬ BuildEntry["Looks", info, MatchLooksButton, info.ignoreLooks ¬ TRUE]; info.formatButton ¬ BuildEntry["Format", info, MatchFormatButton, info.ignoreFormat ¬ TRUE]; info.styleButton ¬ BuildEntry["Style", info, MatchStyleButton, info.ignoreStyle ¬ TRUE]; info.commentButton ¬ BuildEntry["Comment", info, MatchCommentButton, info.ignoreComment ¬ TRUE]; }; SetButton: PROC [viewer: Buttons.Button, ignore: BOOL, paint: BOOL ¬ TRUE] = { Buttons.SetDisplayStyle[viewer, IF ignore THEN $BlackOnWhite ELSE $WhiteOnBlack, paint]; }; matchTextAtom: LIST OF REF = Register[$MatchText,MatchTextOp]; ignoreTextAtom: LIST OF REF = Register[$IgnoreText,IgnoreTextOp]; MatchTextButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreText, ignoreTextAtom, matchTextAtom]; }; MatchTextOp: TEditInput.CommandProc = { MatchText[mainToolInfo] }; MatchText: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.textButton, "MatchText", FALSE ]; SetButton[info.textButton, info.ignoreText ¬ FALSE]; }; IgnoreTextOp: TEditInput.CommandProc = { IgnoreText[mainToolInfo] }; IgnoreText: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.textButton, "IgnoreText", FALSE ]; SetButton[info.textButton, info.ignoreText ¬ TRUE]; }; matchLooksAtom: LIST OF REF = Register[$MatchLooks,MatchLooksOp]; ignoreLooksAtom: LIST OF REF = Register[$IgnoreLooks,IgnoreLooksOp]; MatchLooksButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreLooks, ignoreLooksAtom, matchLooksAtom]; }; MatchLooksOp: TEditInput.CommandProc = { MatchLooks[mainToolInfo]; }; MatchLooks: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.looksButton, "MatchLooks", FALSE ]; SetButton[info.looksButton, info.ignoreLooks ¬ FALSE]; }; IgnoreLooksOp: TEditInput.CommandProc = { IgnoreLooks[mainToolInfo]; }; IgnoreLooks: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.looksButton, "IgnoreLooks", FALSE ]; SetButton[info.looksButton, info.ignoreLooks ¬ TRUE]; }; matchFormatAtom: LIST OF REF = Register[$MatchFormat,MatchFormatOp]; ignoreFormatAtom: LIST OF REF = Register[$IgnoreFormat,IgnoreFormatOp]; MatchFormatButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreFormat, ignoreFormatAtom,matchFormatAtom] }; MatchFormatOp: TEditInput.CommandProc = { MatchFormat[mainToolInfo]; }; MatchFormat: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.formatButton, "MatchFormat", FALSE ]; SetButton[info.formatButton, info.ignoreFormat ¬ FALSE]; }; IgnoreFormatOp: TEditInput.CommandProc = { IgnoreFormat[mainToolInfo]; }; IgnoreFormat: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.formatButton, "IgnoreFormat", FALSE ]; SetButton[info.formatButton, info.ignoreFormat ¬ TRUE]; }; matchStyleAtom: LIST OF REF = Register[$MatchStyle,MatchStyleOp]; ignoreStyleAtom: LIST OF REF = Register[$IgnoreStyle,IgnoreStyleOp]; MatchStyleButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreStyle, ignoreStyleAtom,matchStyleAtom] }; MatchStyleOp: TEditInput.CommandProc = { MatchStyle[mainToolInfo] }; MatchStyle: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.styleButton, "MatchStyle", FALSE ]; SetButton[info.styleButton, info.ignoreStyle ¬ FALSE] }; IgnoreStyleOp: TEditInput.CommandProc = { IgnoreStyle[mainToolInfo] }; IgnoreStyle: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ mainToolInfo.styleButton, "IgnoreStyle", FALSE ]; SetButton[info.styleButton, info.ignoreStyle ¬ TRUE] }; matchCommentAtom: LIST OF REF = Register[$MatchComment,MatchCommentOp]; ignoreCommentAtom: LIST OF REF = Register[$IgnoreComment,IgnoreCommentOp]; MatchCommentButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreComment, ignoreCommentAtom,matchCommentAtom] }; MatchCommentOp: TEditInput.CommandProc = { MatchComment[mainToolInfo] }; MatchComment: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.commentButton, "MatchComment", FALSE ]; SetButton[info.commentButton, info.ignoreComment ¬ FALSE] }; IgnoreCommentOp: TEditInput.CommandProc = { IgnoreComment[mainToolInfo] }; IgnoreComment: PROC [info: Info] = { viewer: ViewerClasses.Viewer ¬ editTool; menu: Menus.Menu ¬ viewer.menu; menuEntry:Menus.MenuEntry ¬ Menus.CopyEntry[ Menus.FindEntry[ menu, "RealOps"] ]; menuClientData: REF ANY¬ Menus.SetClientData[ menuEntry, NIL ]; -- only way to query the clientData without affecting it. data: REF BOOL ¬ NARROW[menuClientData]; usingRealNames: BOOL ¬ data­; IF usingRealNames THEN Buttons.ReLabel[ info.commentButton, "IgnoreComment", FALSE ]; SetButton[info.commentButton, info.ignoreComment ¬ TRUE] }; matchingLiterally: Rope.ROPE; matchingAsPattern: Rope.ROPE; matchLitAtom: LIST OF REF = Register[$MatchLiterally,MatchLitOp]; matchPatternAtom: LIST OF REF = Register[$MatchPattern,MatchPatternOp]; LiteralButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.literal, matchLitAtom,matchPatternAtom]; }; MatchLitOp: TEditInput.CommandProc = { MatchLit[mainToolInfo]; }; MatchLit: PROC [info: Info] = { OPEN info; literal ¬ TRUE; Labels.Set[literalLabel,matchingLiterally]; }; MatchPatternOp: TEditInput.CommandProc = { MatchPattern[mainToolInfo]; }; MatchPattern: PROC [info: Info] = { OPEN info; literal ¬ FALSE; Labels.Set[literalLabel,matchingAsPattern]; }; BuildLitOrPatternEntry: PROC [info: Info] = { OPEN info; literal ¬ TRUE; [literalLabel,] ¬ BuildPair[layout,LiteralButton,literal,matchingLiterally,matchingAsPattern,info]; }; numDocRopes: NAT = 18; docRopes: REF ARRAY [0..numDocRopes) OF Rope.ROPE ¬ NEW[ARRAY [0..numDocRopes) OF Rope.ROPE]; BuildPatternDocEntry: PUBLIC PROC [info: Info] = { OPEN info.layout; lines: CARDINAL = 25; rope: Rope.ROPE; arg: ViewerClasses.Viewer ¬ ViewerOps.CreateViewer[flavor: $Text, info: [parent: container, border: FALSE, scrollable: TRUE, wx: entryLeft, wy: heightSoFar, ww: ViewerSpecs.openRightWidth-entryLeft-5, wh: entryHeight*lines], paint: FALSE]; heightSoFar ¬ heightSoFar + entryHeight*lines; FOR i:NAT IN [0..numDocRopes) DO rope ¬ Rope.Concat[rope, docRopes[i]]; ENDLOOP; TEditOps.SetTextContents[arg, rope]; }; numMiniDocRopes: NAT = 4; miniDocRopes: REF ARRAY [0..numMiniDocRopes) OF Rope.ROPE ¬ NEW[ARRAY [0..numMiniDocRopes) OF Rope.ROPE]; miniDocStyle: Rope.ROPE ~ " BeginStyle (mini) \"for small comment\" { \"TimesRoman\" family 8 pt size 9 pt leading 10 pt topIndent 0 pt bottomIndent 0 leftIndent 5 pt rightIndent } StyleRule EndStyle "; BuildMiniPatternDocEntry: PUBLIC PROC [info: Info] = { OPEN info.layout; rope: Rope.ROPE; where: Node; height: CARDINAL = numMiniDocRopes*10+3; arg: ViewerClasses.Viewer ¬ ViewerOps.CreateViewer[flavor: $Text, info: [parent: container, wx: entryLeft, wy: heightSoFar, ww: ViewerSpecs.openRightWidth-entryLeft-5, wh: height, border: FALSE, scrollable: FALSE], paint: FALSE]; heightSoFar ¬ heightSoFar + height; FOR i:NAT IN [0..numMiniDocRopes) DO rope ¬ Rope.Concat[rope, miniDocRopes[i]]; ENDLOOP; TEditOps.SetTextContents[arg, rope]; where ¬ GetDataNode[arg]; TextEdit.PutProp[node: TextNode.Root[where], name: $StyleDef, value: NodeProps.DoSpecs[$StyleDef, miniDocStyle]]; TextEdit.PutFormat[where, $mini]; ViewerTools.InhibitUserEdits[arg]; }; ignoringCase: Rope.ROPE; matchingCase: Rope.ROPE; ignoreCaseAtom: LIST OF REF = Register[$IgnoreCase,IgnoreCaseOp]; matchCaseAtom: LIST OF REF = Register[$MatchCase,MatchCaseOp]; CaseButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.ignoreCase, ignoreCaseAtom,matchCaseAtom]; }; IgnoreCaseOp: TEditInput.CommandProc = { IgnoreCase[mainToolInfo]; }; IgnoreCase: PROC [info: Info] = { OPEN info; ignoreCase ¬ TRUE; Labels.Set[caseLabel,ignoringCase]; }; MatchCaseOp: TEditInput.CommandProc = { MatchCase[mainToolInfo]; }; MatchCase: PROC [info: Info] = { OPEN info; ignoreCase ¬ FALSE; Labels.Set[caseLabel,matchingCase]; }; BuildCaseEntry: PROC [info: Info] = { OPEN info; ignoreCase ¬ FALSE; [caseLabel,] ¬ BuildPair[layout,CaseButton,ignoreCase,ignoringCase,matchingCase,info]; }; matchingWords: Rope.ROPE; matchingAnywhere: Rope.ROPE; matchingNodes: Rope.ROPE; matchWordsAtom: LIST OF REF = Register[$MatchWords,MatchWordsOp]; matchAnywhereAtom: LIST OF REF = Register[$MatchAnywhere,MatchAnywhereOp]; matchNodesAtom: LIST OF REF = Register[$MatchNodes,MatchNodesOp]; WhereButton: Buttons.ButtonProc = { CycleTriple[ORD[mainToolInfo.searchWhere], matchAnywhereAtom,matchWordsAtom,matchNodesAtom] }; MatchWordsOp: TEditInput.CommandProc = { MatchWords[mainToolInfo] }; MatchWords: PROC [info: Info] = { OPEN info; searchWhere ¬ words; Labels.Set[wordLabel,matchingWords]; }; MatchNodesOp: TEditInput.CommandProc = { MatchNodes[mainToolInfo] }; MatchNodes: PROC [info: Info] = { OPEN info; searchWhere ¬ nodes; Labels.Set[wordLabel,matchingNodes]; }; MatchAnywhereOp: TEditInput.CommandProc = { MatchAnywhere[mainToolInfo]; }; MatchAnywhere: PROC [info: Info] = { OPEN info; searchWhere ¬ anywhere; Labels.Set[wordLabel,matchingAnywhere]; }; BuildWhereEntry: PROC [info: Info] = { OPEN info; searchWhere ¬ anywhere; [wordLabel,] ¬ BuildTriple[layout, WhereButton, ORD[searchWhere], matchingAnywhere, matchingWords, matchingNodes, info]; }; targetArgAtom: LIST OF REF = Register[$SearchFor,TargetArgOp]; clearTargetArgAtom: LIST OF REF = Register[$ClearSearchFor,ClearTargetArgOp]; TargetButton: Buttons.ButtonProc = { DoButton[targetArgAtom, clearTargetArgAtom, mouseButton=red]; }; TargetArgOp: TEditInput.CommandProc = { TargetArg[mainToolInfo]; }; TargetArg: PROC [info: Info] = { SavePSel; DataFieldButton[info.targetArg,FALSE]; }; ClearTargetArgOp: TEditInput.CommandProc = { ClearTargetArg[mainToolInfo]; }; ClearTargetArg: PROC [info: Info] = { SavePSel; DataFieldButton[info.targetArg,TRUE]; }; BuildTargetEntry: PUBLIC PROC [info: Info] = { OPEN info; [,targetArg] ¬ BuildDataFieldPair[layout, "Target:", TargetButton, info, 2]; }; docRopes[0] ¬ "The following special symbols may be used in search patterns: "; docRopes[1] ¬ " ' Match the next character in the pattern exactly. "; docRopes[2] ¬ " ~ Match any character except the next one in the pattern. "; docRopes[3] ¬ " # Match any single character. "; docRopes[4] ¬ " * Match any sequence of characters. "; docRopes[5] ¬ " @ Match any single alphanumeric character (letter or digit). "; docRopes[6] ¬ " & Match any sequence of alphanumeric characters. "; docRopes[7] ¬ " ~@ Match any single non-alphanumeric character. "; docRopes[8] ¬ " ~& Match any sequence of non-alphanumeric characters. "; docRopes[9] ¬ " % Match any single blank character. "; docRopes[10] ¬ " $ Match any sequence of blank characters. "; docRopes[11] ¬ " ~% Match any single non-blank character. "; docRopes[12] ¬ " ~$ Match any sequence of non-blank characters. "; docRopes[13] ¬ " | Match start or end of node. "; docRopes[14] ¬ " { Mark start of resulting selection. "; docRopes[15] ¬ " } Mark end of resulting selection. "; docRopes[16] ¬ " < Mark start of named subpattern. "; docRopes[17] ¬ " > Mark end of named subpattern. "; miniDocRopes[0] ¬ "single character: # any; @ alpha; ~@ nonalpha; % blank; ~% nonblank; "; miniDocRopes[1] ¬ "min sequence: * any; & alpha; ~& nonalpha; $ blank; ~$ nonblank; "; miniDocRopes[2] ¬ "max sequence: ** any; && alpha; ~&~& nonalpha; $$ blank; ~$~$ nonblank; "; miniDocRopes[3] ¬ "other: 'x = x; ~x = not x; | node boundary; { } selection; < > named subpattern "; END. ͺ EditToolSearchImpl.mesa Copyright Σ 1985, 1986, 1991, 1992 by Xerox Corporation. All rights reserved. Michael Plass, March 28, 1985 9:01:55 am PST Doug Wyatt, March 16, 1992 3:34 pm PST Russ Atkinson (RRA) January 23, 1986 0:57:33 am PST Alison Lee September 8, 1986 10:03:40 pm PDT Attempt to register in EditTool Cafeteria tray if the registry operation is available. This is deferred to this late because, only properly specified commands will be recorded. -------------------------- -------------------------- If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. -------------------------- If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. -------------------------- If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. If using real names, must change the text in the button also, if not using real names then leave the text of the button the same. -------------------------- -------------------------- -------------------------- ΚΫ–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœC™NK™,K™&K™3K™,K™—šΟk ˜ Kšœžœ ˜Kšœžœ0˜=Kšœžœ}˜’KšœžœŽ˜£Kšžœžœ˜Kšœžœ˜KšœžœB˜MKšœžœ˜$Kšœ žœ ˜Kšœ žœ˜&Kšœžœ žœ˜Kšœžœ ˜ Kšœ žœ˜+Kšœžœ˜$Kšœ žœ8˜FKšœ žœ˜$Kšœ žœ˜&Kšœžœ2˜FKšœ ˜ Kšœ ˜ Kšœ žœ˜"Kšœžœ"˜-Kšœ žœ!˜0Kšœžœ ˜Kšœ žœ'˜6Kšœ žœ˜#Kšœ žœ˜%K˜—šΟnœžœž˜!Kšžœ2žœέ˜˜Kšžœ˜Kšœžœžœ"˜.—K˜Kšžœžœžœ˜Kšœžœ˜Kšœ žœ˜ K˜š Ÿœžœ žœ žœžœ˜5Kšžœžœžœ˜%šžœ˜Kšœžœ˜ Kšžœžœ˜'Kšœ˜—K˜K˜—K˜Kšœžœžœžœ,˜JKšŸœ=˜LK˜Kšœžœžœžœ.˜MKšŸœ=˜MK˜Kšœžœžœžœ0˜PKšŸœ>˜OK˜šŸœžœ˜-šžœ ž˜K˜#K˜'K˜&Kšžœžœ˜—Kšœ˜K˜—šŸ œžœžœ/žœžœžœžœ˜hš žœžœžœ žœž˜#šœ ž˜"Kšœžœ'˜8—Kšžœžœžœ˜—Kšœ(˜(Kšžœžœ˜Kšœ˜K˜—šŸœžœžœ&˜9Kšœžœ˜(Kš œžœžœžœžœžœ˜2Kšœ˜—K˜š Ÿ œžœžœ#žœ žœžœ˜Zš žœžœžœžœžœžœ˜qKšœH˜HKšžœ˜Kšœ˜—Kšœ-˜-˜Kšžœžœ&˜3Kšœ žœ˜$Kšœžœ˜K˜ K˜Kš žœžœžœžœžœ˜GK˜Kšœ`˜`K™šžœžœ˜K™²Kšœžœžœ@˜Ošžœ ž˜šžœ˜Kš œžœžœ žœžœžœΟc5˜‡Kšœ žœžœ žœ˜XKšœ˜K˜——K˜—Kšžœ ˜K˜—Kšœ"˜"K˜K˜—šœžœ žœ=˜aK˜—šŸ œžœžœžœ˜JKšœ)˜)Kšœ žœ˜$Kšœ žœžœ˜&Kšœ žœžœ˜(Kšœžœžœ˜,Kšœ žœžœ˜*Kšœ žœžœ˜(Kšœžœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœžœžœ˜šžœ žœ žœ žœ˜2KšœB˜BKšžœžœ˜ K˜—šžœ žœ˜Kšœžœžœ˜šœ7žœ#˜]Kš œžœ%žœžœžœ˜\—Kš žœžœžœžœžœ˜1K˜—šžœžœ žœ˜Kšœ/˜/Kšœ*˜*šžœžœžœž˜Kšœ2˜2Kšžœžœ˜ šžœžœžœ˜!KšœL˜LKšžœ˜K˜—Kšžœ˜—Kšœžœ(˜FKšœ>žœ˜DK˜—šžœžœžœ˜Kšžœžœ%˜9Kšžœ žœ#˜6Kšžœ žœ-˜?K˜—Kšžœžœ&žœτ˜§K˜K˜—šŸœžœ4žœžœžœ žœžœžœ˜‰šŸœžœ0˜DKšœžœ˜Kšœ žœ˜šŸœžœ4˜=K˜KšœΑ˜ΑK˜—Kšœ1˜1Kšœ ˜ Kšœ˜Kšœ žœžœ+˜?Kšœ žœžœ-˜AKšžœ žœžœžœ˜)šžœ˜Kšžœ˜Kšžœžœ˜"—šžœžœžœžœžœ žœžœ ˜HKšžœžœ˜#—Kš žœžœžœžœžœ žœ˜+Kšœ˜Kšœžœ ˜'Kšœžœžœžœžœžœžœžœžœ˜xKšœžœ$žœžœ˜NKšœ.˜.Kšœ!˜!Kšœ(˜(Kšœ˜Kšœ+žœ˜2Kšœ˜—Kšœ2˜2Kšœ˜K™—šŸ œžœ!˜4K˜8Kšœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ%˜%Kšœ#˜#Kšœ˜Kšœ ˜ K˜K˜—šŸ œžœ!˜0K˜4Kšœ˜Kšœ˜Kšœ#˜#Kšœ$˜$Kšœ*˜*Kšœ&˜&Kšœ'˜'Kšœ#˜#Kšœ%˜%K˜K˜—š Ÿœžœžœ)žœžœ˜YKšžœ žœžœ˜;Kšœ,˜,K˜+K˜4K˜K˜K˜—Kšœžœ˜Kšœžœ˜K˜Kšœžœžœžœ.˜IKšœžœžœžœ0˜LK˜šŸœ˜(K˜E˜K˜——šŸœ˜,K˜K˜—K˜šŸœžœ˜%Kšžœ˜ Kšœ žœ˜K˜'K˜K˜—šŸœ˜-K˜K˜—K˜šŸœžœ˜&Kšžœ˜ Kšœ žœ˜K˜(K˜K˜—šŸœžœ˜/Kšžœ˜ Kšœ žœ˜Kšœk˜k˜K˜——šŸœžœ˜+Kšžœ˜ Kšœ žœ˜K˜_˜K˜——Kšœ™K˜š Ÿ œžœ žœ.žœžœ˜vKšœ1žœžœ˜?Kšœ?˜?Kšœžœ˜K˜K˜—šŸœžœ˜3K˜3K˜KšœSžœ˜ZKšœXžœ˜^Kšœ\žœ˜bK˜$K˜&KšœXžœ˜^Kšœ`žœ˜fK˜K˜—šŸœžœ˜/K˜3K˜KšœNžœ˜UKšœRžœ˜XKšœVžœ˜\KšœRžœ˜XKšœZžœ˜`K˜K˜—š Ÿ œžœ"žœ žœžœ˜N˜Kšžœžœžœ˜8—šœ˜K˜——Kšœ™Kšœžœžœžœ$˜>Kšœžœžœžœ&˜AK˜šŸœ˜'K˜D˜K˜——KšŸ œ7˜BK˜šŸ œžœ˜ K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ0žœ˜NKšœ-žœ˜4Kšœ˜K˜—KšŸ œ8˜DK˜šŸ œžœ˜!K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ1žœ˜OKšœ-žœ˜3Kšœ˜K˜—Kšœ™Kšœžœžœžœ&˜AKšœžœžœžœ(˜DK˜šŸœ˜(K˜G˜K˜——šŸ œ˜(K˜K˜—K˜šŸ œžœ˜!K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ1žœ˜PKšœ/žœ˜6Kšœ˜K˜—šŸ œ˜)K˜K˜—˜K˜—šŸ œžœ˜"K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜Kšœ™Kšžœžœ3žœ˜QKšœ/žœ˜5Kšœ˜K˜—Kšœ™Kšœžœžœžœ(˜DKšœžœžœžœ*˜GK˜šŸœ˜)K˜H˜K˜——šŸ œ˜)K˜K˜—K˜šŸ œžœ˜"K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ4žœ˜RKšœ1žœ˜8Kšœ˜K˜—šŸœ˜*K˜K˜—K˜šŸ œžœ˜#K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ5žœ˜SKšœ1žœ˜7Kšœ˜K˜—Kšœžœžœžœ&˜AKšœžœžœžœ(˜DK˜šŸœ˜(K˜E˜K˜——šŸ œ˜(K˜—K˜šŸ œžœ˜!K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ1žœ˜PKšœ/žœ˜8K˜—šŸ œ˜)K˜—K˜šŸ œžœ˜"K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ;žœ˜YKšœ/žœ˜7K˜—Kšœžœžœžœ*˜GKšœžœžœžœ,˜JK˜šŸœ˜*K˜K˜K˜——šŸœ˜*K˜—K˜šŸ œžœ˜#K˜(Kšœ˜KšœQ˜QKšœžœžœ!žœ 9˜zKšœžœžœ˜(Kšœžœ ˜K™Kšžœžœ6žœ˜TKšœ3žœ˜K˜šŸ œ˜"K˜C˜K˜——šŸ œ˜(K˜K˜—K˜šŸ œžœ˜!Kšžœ˜ Kšœ žœ˜K˜#K˜K˜—šŸ œ˜'K˜K˜—K˜šŸ œžœ˜ Kšžœ˜ Kšœ žœ˜K˜#K˜K˜—šŸœžœ˜%Kšžœ˜ Kšœ žœ˜KšœV˜V˜K˜——Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜Kšœžœžœžœ&˜AKšœžœžœžœ,˜JKšœžœžœžœ&˜AK˜šŸ œ˜#šœ žœ˜*K˜3K˜——KšŸ œ8˜DK˜šŸ œžœ˜!Kšžœ˜ K˜K˜$K˜K˜—KšŸ œ8˜DK˜šŸ œžœ˜!Kšžœ˜ K˜K˜$K˜K˜—šŸœ˜+K˜K˜—K˜šŸ œžœ˜$Kšžœ˜ K˜K˜'K˜K˜—šŸœžœ˜&Kšžœ˜ K˜Kšœ0žœE˜x˜K˜——Kšœ™Kšœžœžœžœ$˜>Kšœžœžœžœ.˜MK˜šŸ œ˜$K˜=K˜K˜—šŸ œ˜'K˜K˜—K˜šŸ œžœ˜ Kšœ)žœ˜0Kšœ˜—K˜šŸœ˜,K˜K˜—K˜šŸœžœ˜%Kšœ)žœ˜/Kšœ˜—K˜šŸœžœžœ˜.Kšžœ˜ K˜LK˜K˜—Kšœ™K˜LK˜K˜K˜BK˜K˜IK˜K˜-K˜K˜3K˜K˜LK˜K˜@K˜K˜?K˜K˜EK˜K˜3K˜K˜:K˜K˜9K˜K˜?K˜K˜.K˜K˜5K˜K˜3K˜K˜2K˜K˜0K˜K˜K˜WK˜K˜SK˜K˜ZK˜K˜bK˜K˜K˜Kšžœ˜—…—e|†