cg@3292: " cg@3292: Copyright (C) Original Authors (Kaehler, Scott Wallace and Dan Ingalls) cg@3292: Copyright (C) 2001 eXept Software AG cg@3292: cg@3292: Permission is hereby granted, free of charge, to any cg@3292: person obtaining a copy of this software and associated cg@3292: documentation files (the 'Software'), to deal in the cg@3292: Software without restriction, including without limitation cg@3292: the rights to use, copy, modify, merge, publish, distribute, cg@3292: sublicense, and/or sell copies of the Software, and to cg@3292: permit persons to whom the Software is furnished to do so, cg@3292: subject to the following conditions: cg@3292: cg@3292: The above copyright notice and this permission notice shall cg@3292: be included in all copies or substantial portions of the Software. cg@3292: cg@3292: THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, cg@3292: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES cg@3292: OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. cg@3292: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY cg@3292: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, cg@3292: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE cg@3292: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cg@3292: " james@1522: "{ Package: 'stx:libtool2' }" james@1522: cg@3193: "{ NameSpace: Smalltalk }" cg@3193: james@1522: ApplicationModel subclass:#MethodFinderWindow cg@3292: instanceVariableNames:'resultHolder selectorPatternHolder classOfResultHolder cg@3292: selectedClassOfResultHolder selectedImplementorsHolder cg@3292: argumentsEditor messageAnswerEditor receiverEditor receiver james@1522: resultSelectors arg2BoxVisible arg1BoxVisible arg4BoxVisible james@1522: arg3BoxVisible argCountHolder argCountList argument1Editor james@1522: argument2Editor argument3Editor argument4Editor resultSelected cg@2891: lookAtResultEditor codeHolder searchProcess' james@1522: classVariableNames:'' james@1522: poolDictionaries:'' cg@3215: category:'Interface-Tools' james@1522: ! james@1522: cg@1530: !MethodFinderWindow class methodsFor:'documentation'! cg@1530: cg@3292: copyright cg@3292: " cg@3292: Copyright (C) Original Authors (Kaehler, Scott Wallace and Dan Ingalls) cg@3292: Copyright (C) 2001 eXept Software AG cg@3292: cg@3292: Permission is hereby granted, free of charge, to any cg@3292: person obtaining a copy of this software and associated cg@3292: documentation files (the 'Software'), to deal in the cg@3292: Software without restriction, including without limitation cg@3292: the rights to use, copy, modify, merge, publish, distribute, cg@3292: sublicense, and/or sell copies of the Software, and to cg@3292: permit persons to whom the Software is furnished to do so, cg@3292: subject to the following conditions: cg@3292: cg@3292: The above copyright notice and this permission notice shall cg@3292: be included in all copies or substantial portions of the Software. cg@3292: cg@3292: THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, cg@3292: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES cg@3292: OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. cg@3292: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY cg@3292: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, cg@3292: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE cg@3292: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cg@3292: " cg@3292: ! cg@3292: cg@1530: documentation cg@1530: " cg@3292: a tool to find implementing methods by example. cg@3292: Give it values for a receiver, optional arguments and a desired result, cg@3292: and it will find methods which do that for you. cg@3292: Please read the online documentation for details (open via the tool's help menu). cg@3292: cg@1531: [author:] cg@3292: original squeak version by Ted Kaehler, Scott Wallace and Dan Ingalls. cg@3292: ported from Squeak and GUI enhanced 2001 by James Hayes james@exept.de. cg@3292: improved by Claus Gittinger. cg@1530: " cg@1530: ! ! james@1522: cg@1532: !MethodFinderWindow class methodsFor:'constants'! cg@1532: cg@2890: defaultIcon sv@3109: sv@3109: cg@2890: ^ ToolbarIconLibrary methodFinder24x24Icon cg@2890: cg@2890: "Created: / 01-06-2012 / 13:05:11 / cg" cg@2890: ! cg@2890: cg@1532: markerForImplementingClass cg@1532: ^ '=> '. cg@1532: ^ '*' cg@1532: cg@1532: "Created: / 13.11.2001 / 12:09:52 / cg" cg@1532: "Modified: / 13.11.2001 / 12:11:57 / cg" cg@1532: ! ! cg@1532: cg@3292: !MethodFinderWindow class methodsFor:'help specs'! cg@3292: cg@3292: flyByHelpSpec cg@3292: "This resource specification was automatically generated cg@3292: by the UIHelpTool of ST/X." cg@3292: cg@3292: "Do not manually edit this!! If it is corrupted, cg@3292: the UIHelpTool may not be able to read the specification." cg@3292: cg@3292: " cg@3292: UIHelpTool openOnClass:MethodFinderWindow cg@3292: " cg@3292: cg@3292: cg@3292: cg@3292: ^ super flyByHelpSpec addPairsFrom:#( cg@3292: cg@3292: #receiverValue cg@3292: 'Enter a receiver value here.\Can be a constant (like ''hello'')\or an expression, such as "Rectangle basicNew".' cg@3292: cg@3292: #answerValue cg@3292: 'Enter result value here.\Can be a constant (like ''hello'')\or an expression, such as "Rectangle basicNew".' cg@3292: cg@3292: #arg1Value cg@3292: 'Enter a value for the first argument here.\Can be a constant or an expression.' cg@3292: cg@3292: #arg2Value cg@3292: 'Enter a value for the second argument here.\Can be a constant or an expression.' cg@3292: cg@3292: #arg3Value cg@3292: 'Enter a value for the third argument here.\Can be a constant or an expression.' cg@3292: cg@3292: #argumentCount cg@3292: 'Specify the number of arguments here.' cg@3292: cg@3292: #clearButton cg@3292: 'Clear all sample value fields.' cg@3292: cg@3292: #startSearchButton cg@3292: 'Search for methods which answer the desired value,\given the concrete arguments' cg@3292: cg@3292: #selectorPatternSearch cg@3292: 'Search by name.\You can use match characters '*' as in GLOB patterns (i.e. like filename patterns)' cg@3292: cg@3292: ) cg@3292: ! ! cg@3292: james@1522: !MethodFinderWindow class methodsFor:'interface specs'! james@1522: james@1522: windowSpec james@1522: "This resource specification was automatically generated james@1522: by the UIPainter of ST/X." james@1522: james@1522: "Do not manually edit this!! If it is corrupted, james@1522: the UIPainter may not be able to read the specification." james@1522: james@1522: " james@1522: UIPainter new openOnClass:MethodFinderWindow andSelector:#windowSpec james@1522: MethodFinderWindow new openInterface:#windowSpec james@1522: MethodFinderWindow open james@1522: " james@1522: james@1522: james@1522: james@1522: ^ cg@3289: #(FullSpec cg@3289: name: windowSpec cg@3289: window: cg@3289: (WindowSpec cg@3289: label: 'MethodFinder' cg@3289: name: 'MethodFinder' cg@3301: bounds: (Rectangle 0 0 816 738) cg@3301: menu: menu cg@3301: icon: defaultIcon cg@3301: ) cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (VariableHorizontalPanelSpec cg@3301: name: 'VariableHorizontalPanel1' cg@3301: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3301: showHandle: true cg@3301: snapMode: both cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (VariableVerticalPanelSpec cg@3301: name: 'LeftBox' cg@3301: showHandle: true cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (ViewSpec cg@3301: name: 'MethodFinderBox' cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (ViewSpec cg@3301: name: 'ReceiverArgBox' cg@3301: layout: (LayoutFrame 0 0 0 0 0 1 -30 1) cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (LabelSpec cg@3301: label: 'Receiver' cg@3301: name: 'ReceiverLabel' cg@3301: layout: (LayoutFrame 0 0 0 0 0 0.34000000000000002 28 0) cg@3301: translateLabel: true cg@3301: ) cg@3301: (ComboListSpec cg@3301: name: 'allowedArgments' cg@3301: layout: (LayoutFrame 0 0.34000000000000002 1 0 0 0.64000000000000135 28 0) cg@3301: activeHelpKey: argumentCount cg@3301: model: argCountHolder cg@3301: comboList: argCountList cg@3301: useIndex: true cg@3301: ) cg@3301: (LabelSpec cg@3301: label: 'Answer' cg@3301: name: 'MessageAnswerLabel' cg@3301: layout: (LayoutFrame 0 0.64000000000000135 0 0 0 1 28 0) cg@3301: activeHelpKey: arg1Value cg@3301: translateLabel: true cg@3301: ) cg@3301: (HorizontalPanelViewSpec cg@3301: name: 'HorizontalPanel1' cg@3301: layout: (LayoutFrame 0 0 30 0 0 1 0 1) cg@3301: horizontalLayout: fit cg@3301: verticalLayout: fit cg@3301: horizontalSpace: 3 cg@3301: verticalSpace: 3 cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (WorkspaceSpec cg@3301: name: 'ReceiverEditor' cg@3301: activeHelpKey: receiverValue cg@3301: tabable: true cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: miniScrollerHorizontal: true cg@3301: miniScrollerVertical: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: extent: (Point 85 142) cg@3301: postBuildCallback: receiverWidgetCreated: cg@3301: ) cg@3301: (VerticalPanelViewSpec cg@3301: name: 'VerticalPanel1' cg@3301: horizontalLayout: fit cg@3301: verticalLayout: fit cg@3301: horizontalSpace: 3 cg@3301: verticalSpace: 3 cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (ViewSpec cg@3301: name: 'Box1' cg@3301: visibilityChannel: arg1BoxVisible cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (WorkspaceSpec cg@3301: name: 'Arg1Editor' cg@3301: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3301: activeHelpKey: arg1Value cg@3301: tabable: true cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: miniScrollerHorizontal: true cg@3301: miniScrollerVertical: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: postBuildCallback: argument1WidgetCreated: cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: extent: (Point 86 45) cg@3301: ) cg@3301: (ViewSpec cg@3301: name: 'Box2' cg@3301: visibilityChannel: arg2BoxVisible cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (WorkspaceSpec cg@3301: name: 'TextEditor5' cg@3301: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3301: activeHelpKey: arg2Value cg@3301: tabable: true cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: miniScrollerHorizontal: true cg@3301: miniScrollerVertical: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: postBuildCallback: argument2WidgetCreated: cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: extent: (Point 86 46) cg@3301: ) cg@3301: (ViewSpec cg@3301: name: 'Box3' cg@3301: visibilityChannel: arg3BoxVisible cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (WorkspaceSpec cg@3301: name: 'TextEditor6' cg@3301: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3301: activeHelpKey: arg3Value cg@3301: tabable: true cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: miniScrollerHorizontal: true cg@3301: miniScrollerVertical: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: postBuildCallback: argument3WidgetCreated: cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: extent: (Point 86 45) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: extent: (Point 86 142) cg@3301: ) cg@3301: (WorkspaceSpec cg@3301: name: 'AnswerEditor' cg@3301: activeHelpKey: answerValue cg@3301: tabable: true cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: miniScrollerHorizontal: true cg@3301: miniScrollerVertical: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: extent: (Point 86 142) cg@3301: postBuildCallback: messageAnswerWidgetCreated: cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: (ViewSpec cg@3301: name: 'ReceiverArgBoxActionBox' cg@3301: layout: (LayoutFrame 0 0 -30 1 0 1 0 1) cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (ActionButtonSpec cg@3301: label: 'Clear' cg@3301: name: 'Button2' cg@3301: layout: (LayoutFrame 5 0 0 0 -5 0.5 0 1) cg@3301: activeHelpKey: clearButton cg@3301: translateLabel: true cg@3301: model: clear cg@3301: ) cg@3301: (ActionButtonSpec cg@3301: label: 'Search' cg@3301: name: 'Button1' cg@3301: layout: (LayoutFrame 5 0.5 0 0 -5 1 0 1) cg@3301: activeHelpKey: startSearchButton cg@3301: translateLabel: true cg@3301: tabable: true cg@3301: model: search cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: (ViewSpec cg@3301: name: 'SelectorFinderBox' cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (ViewSpec cg@3301: name: 'MatchActionBox' cg@3301: layout: (LayoutFrame 0 0 0 0 0 1 90 0) cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (LabelSpec cg@3301: label: 'Selector Pattern:' cg@3301: name: 'Label1' cg@3301: layout: (LayoutFrame 0 0 0 0 0 0.5 25 0) cg@3301: translateLabel: true cg@3301: adjust: left cg@3301: ) cg@3301: (InputFieldSpec cg@3301: name: 'EntryField1' cg@3301: layout: (LayoutFrame 2 0 -54 1 -2 1 -29 1) cg@3301: model: selectorPatternHolder cg@3301: immediateAccept: true cg@3301: acceptOnReturn: true cg@3301: acceptOnTab: true cg@3301: acceptOnPointerLeave: true cg@3301: ) cg@3301: (ActionButtonSpec cg@3301: label: 'Search' cg@3301: name: 'Button4' cg@3301: layout: (LayoutFrame 5 0.5 -25 1 -5 1 0 1) cg@3301: translateLabel: true cg@3301: tabable: true cg@3301: model: searchPatternMatchesInBackground cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: (SequenceViewSpec cg@3301: name: 'ResultList' cg@3301: layout: (LayoutFrame 0 0 94 0 0 1 0 1) cg@3301: model: selectedImplementorsHolder cg@3301: menu: resultListMenu cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: autoHideScrollBars: true cg@3301: useIndex: true cg@3301: sequenceList: resultHolder cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: handles: (Any 0.28000000000000003 1.0) cg@3301: ) cg@3301: (VariableVerticalPanelSpec cg@3301: name: 'RightBox' cg@3301: component: cg@3301: (SpecCollection cg@3301: collection: ( cg@3301: (SequenceViewSpec cg@3301: name: 'List2' cg@3301: model: selectedClassOfResultHolder cg@3301: menu: implementorListMenu cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: autoHideScrollBars: true cg@3301: doubleClickSelector: openBrowserOn: cg@3301: valueChangeSelector: selectedClassOfResultHolderChanged cg@3301: useIndex: false cg@3301: sequenceList: classOfResultHolder cg@3301: ) cg@3301: (CodeViewSpec cg@3301: name: 'CodeView' cg@3301: model: codeHolder cg@3301: hasHorizontalScrollBar: true cg@3301: hasVerticalScrollBar: true cg@3301: autoHideScrollBars: true cg@3301: hasKeyboardFocusInitially: false cg@3301: postBuildCallback: sourceCodeWidgetCreated: cg@3301: viewClassName: 'codeViewClass' cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: handles: (Any 0.23999999999999999 1.0) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: handles: (Any 0.33000000000000002 1.0) cg@3301: ) cg@3301: ) cg@3301: cg@3301: ) cg@3301: ) cg@3301: ! cg@3301: cg@3301: windowSpec_old cg@3301: "This resource specification was automatically generated cg@3301: by the UIPainter of ST/X." cg@3301: cg@3301: "Do not manually edit this!! If it is corrupted, cg@3301: the UIPainter may not be able to read the specification." cg@3301: cg@3301: " cg@3301: UIPainter new openOnClass:MethodFinderWindow andSelector:#windowSpec cg@3301: MethodFinderWindow new openInterface:#windowSpec cg@3301: MethodFinderWindow open cg@3301: " cg@3301: cg@3301: cg@3301: cg@3301: ^ cg@3301: #(FullSpec cg@3301: name: windowSpec cg@3301: window: cg@3301: (WindowSpec cg@3301: label: 'MethodFinder' cg@3301: name: 'MethodFinder' cg@3289: bounds: (Rectangle 0 0 920 690) cg@3289: menu: menu cg@3289: icon: defaultIcon cg@3289: ) cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (VariableHorizontalPanelSpec cg@3289: name: 'VariableHorizontalPanel1' cg@3289: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3289: snapMode: both cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (ViewSpec cg@3289: name: 'LeftBox' cg@3289: level: 1 cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (ViewSpec cg@3289: name: 'ReceiverArgBox' cg@3289: layout: (LayoutFrame 0 0 0 0 0 1 -100 0.5) cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (LabelSpec cg@3289: label: 'Receiver' cg@3289: name: 'ReceiverLabel' cg@3289: layout: (LayoutFrame 0 0 0 0 0 0.34000000000000002 28 0) cg@3289: translateLabel: true cg@3289: ) cg@3289: (ComboListSpec cg@3289: name: 'allowedArgments' cg@3292: layout: (LayoutFrame 0 0.34000000000000002 1 0 0 0.64000000000000046 28 0) cg@3292: activeHelpKey: argumentCount cg@3289: model: argCountHolder cg@3289: comboList: argCountList cg@3289: useIndex: true cg@3289: ) cg@3289: (LabelSpec cg@3289: label: 'Answer' cg@3289: name: 'MessageAnswerLabel' cg@3292: layout: (LayoutFrame 0 0.64000000000000046 0 0 0 1 28 0) cg@3292: activeHelpKey: arg1Value cg@3289: translateLabel: true cg@3289: ) cg@3289: (HorizontalPanelViewSpec cg@3289: name: 'HorizontalPanel1' cg@3289: layout: (LayoutFrame 0 0 30 0 0 1 0 1) cg@3289: horizontalLayout: fit cg@3289: verticalLayout: fit cg@3289: horizontalSpace: 3 cg@3289: verticalSpace: 3 cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (WorkspaceSpec cg@3289: name: 'ReceiverEditor' cg@3292: activeHelpKey: receiverValue cg@3289: tabable: true cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: miniScrollerHorizontal: true cg@3289: miniScrollerVertical: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: extent: (Point 110 214) cg@3289: postBuildCallback: receiverWidgetCreated: cg@3289: ) cg@3289: (VerticalPanelViewSpec cg@3289: name: 'VerticalPanel1' cg@3289: horizontalLayout: fit cg@3289: verticalLayout: fit cg@3289: horizontalSpace: 3 cg@3289: verticalSpace: 3 cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (ViewSpec cg@3289: name: 'Box1' cg@3289: visibilityChannel: arg1BoxVisible cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (WorkspaceSpec cg@3289: name: 'Arg1Editor' cg@3289: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3292: activeHelpKey: arg1Value cg@3289: tabable: true cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: miniScrollerHorizontal: true cg@3289: miniScrollerVertical: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: postBuildCallback: argument1WidgetCreated: cg@1532: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: extent: (Point 110 69) cg@3289: ) cg@3289: (ViewSpec cg@3289: name: 'Box2' cg@3289: visibilityChannel: arg2BoxVisible cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (WorkspaceSpec cg@3289: name: 'TextEditor5' cg@3289: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3292: activeHelpKey: arg2Value cg@3289: tabable: true cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: miniScrollerHorizontal: true cg@3289: miniScrollerVertical: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: postBuildCallback: argument2WidgetCreated: cg@1532: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: extent: (Point 110 70) cg@3289: ) cg@3289: (ViewSpec cg@3289: name: 'Box3' cg@3289: visibilityChannel: arg3BoxVisible cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (WorkspaceSpec cg@3289: name: 'TextEditor6' cg@3289: layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) cg@3292: activeHelpKey: arg3Value cg@3289: tabable: true cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: miniScrollerHorizontal: true cg@3289: miniScrollerVertical: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: postBuildCallback: argument3WidgetCreated: cg@1532: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: extent: (Point 110 69) cg@1530: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: extent: (Point 110 214) cg@3289: ) cg@3289: (WorkspaceSpec cg@3289: name: 'AnswerEditor' cg@3292: activeHelpKey: answerValue cg@3289: tabable: true cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: miniScrollerHorizontal: true cg@3289: miniScrollerVertical: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: extent: (Point 110 214) cg@3289: postBuildCallback: messageAnswerWidgetCreated: james@1525: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) cg@3289: (ViewSpec cg@3289: name: 'ReceiverArgBoxActionBox' cg@3289: layout: (LayoutFrame 0 0 -98 0.5 0 1 -75 0.5) cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (ActionButtonSpec cg@3292: activeHelpKey: clearButton cg@3289: label: 'Clear' cg@3289: name: 'Button2' cg@3289: layout: (LayoutFrame 5 0 0 0 -5 0.5 0 1) cg@3289: translateLabel: true cg@3289: model: clear cg@1532: ) cg@3289: (ActionButtonSpec cg@3292: activeHelpKey: startSearchButton cg@3289: label: 'Search' cg@3289: name: 'Button1' cg@3289: layout: (LayoutFrame 5 0.5 0 0 -5 1 0 1) cg@3289: translateLabel: true cg@3289: tabable: true cg@3289: model: search cg@3289: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) cg@3289: (ViewSpec cg@3289: name: 'MatchActionBox' cg@3290: layout: (LayoutFrame 0 0 -70 0.5 0 1 10 0.5) cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (LabelSpec cg@3289: label: 'Selector Pattern:' cg@3289: name: 'Label1' cg@3289: layout: (LayoutFrame 0 0 0 0 0 0.5 25 0) cg@3289: translateLabel: true cg@3289: adjust: left james@1522: ) cg@3289: (InputFieldSpec cg@3289: name: 'EntryField1' cg@3290: layout: (LayoutFrame 2 0 -54 1 -2 1 -29 1) cg@3292: model: selectorPatternHolder cg@3289: immediateAccept: true cg@3289: acceptOnReturn: true cg@3289: acceptOnTab: true cg@3289: acceptOnPointerLeave: true cg@3289: ) cg@3289: (ActionButtonSpec cg@3289: label: 'Search' cg@3289: name: 'Button4' cg@3289: layout: (LayoutFrame 5 0.5 -25 1 -5 1 0 1) cg@3289: translateLabel: true cg@3289: tabable: true cg@3289: model: searchPatternMatchesInBackground cg@2886: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) cg@3289: (SequenceViewSpec cg@3289: name: 'ResultList' cg@3290: layout: (LayoutFrame 0 0 15 0.5 0 1 0 1) cg@3289: model: selectedImplementorsHolder cg@3289: menu: resultListMenu cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: autoHideScrollBars: true cg@3289: useIndex: true cg@3289: sequenceList: resultHolder cg@1530: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) cg@3289: (VariableVerticalPanelSpec cg@3289: name: 'VariableVerticalPanel1' cg@3289: component: cg@3289: (SpecCollection cg@3289: collection: ( cg@3289: (SequenceViewSpec cg@3289: name: 'List2' cg@3289: model: selectedClassOfResultHolder cg@3289: menu: implementorListMenu cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: autoHideScrollBars: true cg@3289: doubleClickSelector: openBrowserOn: cg@3289: valueChangeSelector: selectedClassOfResultHolderChanged cg@3289: useIndex: false cg@3289: sequenceList: classOfResultHolder james@1522: ) cg@3289: (CodeViewSpec cg@3289: name: 'CodeView' cg@3289: model: codeHolder cg@3289: hasHorizontalScrollBar: true cg@3289: hasVerticalScrollBar: true cg@3289: autoHideScrollBars: true cg@3289: hasKeyboardFocusInitially: false cg@3289: postBuildCallback: sourceCodeWidgetCreated: cg@3292: viewClassName: 'codeViewClass' cg@3289: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: handles: (Any 0.5 1.0) james@1522: ) cg@3289: ) cg@3289: cg@3289: ) cg@3292: handles: (Any 0.37391304347826104 1.0) james@1522: ) cg@3289: ) cg@3289: cg@3289: ) cg@3289: ) james@1522: ! ! james@1522: james@1525: !MethodFinderWindow class methodsFor:'menu specs'! james@1525: cg@1529: implementorListMenu cg@1529: "This resource specification was automatically generated cg@1529: by the MenuEditor of ST/X." cg@1529: cg@1529: "Do not manually edit this!! If it is corrupted, cg@1529: the MenuEditor may not be able to read the specification." cg@1529: cg@1529: " cg@1529: MenuEditor new openOnClass:MethodFinderWindow andSelector:#implementorListMenu cg@1529: (Menu new fromLiteralArrayEncoding:(MethodFinderWindow implementorListMenu)) startUp cg@1529: " cg@1529: cg@1529: cg@1529: cg@1529: ^ cg@1529: #(#Menu cg@1529: #( cg@1529: #(#MenuItem cg@1529: #label: 'Browse' cg@1529: #translateLabel: true cg@1529: #value: #openBrowserOnSelectedItem cg@1529: ) cg@1529: ) cg@1529: nil cg@1529: nil cg@1529: ) cg@1529: ! cg@1529: james@1525: menu james@1525: "This resource specification was automatically generated james@1525: by the MenuEditor of ST/X." james@1525: james@1525: "Do not manually edit this!! If it is corrupted, james@1525: the MenuEditor may not be able to read the specification." james@1525: james@1525: " james@1525: MenuEditor new openOnClass:MethodFinderWindow andSelector:#menu james@1525: (Menu new fromLiteralArrayEncoding:(MethodFinderWindow menu)) startUp james@1525: " james@1525: james@1525: james@1525: james@1525: ^ james@1525: #(#Menu james@1525: #( james@1525: #(#MenuItem james@1525: #label: '&File' james@1525: #activeHelpKey: #file james@1525: #submenu: james@1525: #(#Menu james@1525: #( james@1525: #(#MenuItem james@1525: #label: 'Exit' james@1525: #value: #closeRequest james@1525: #activeHelpKey: #fileExit james@1525: ) james@1525: ) james@1525: nil james@1525: nil james@1525: ) james@1525: ) james@1525: #(#MenuItem cg@3193: label: 'MENU_Help' cg@3193: startGroup: conditionalRight james@1525: #submenu: james@1525: #(#Menu james@1525: #( james@1525: #(#MenuItem james@1525: #label: 'Documentation' james@1525: #value: #openHTMLDocumentation james@1525: #activeHelpKey: #helpTutorial james@1525: ) james@1525: #(#MenuItem cg@1532: #label: 'About MethodFinder...' james@1525: #value: #openAboutThisApplication james@1525: #activeHelpKey: #aboutThisAppliaction james@1525: ) james@1525: ) james@1525: nil james@1525: nil james@1525: ) james@1525: ) james@1525: ) james@1525: nil james@1525: nil james@1525: ) cg@1532: cg@1532: "Modified: / 13.11.2001 / 12:36:39 / cg" cg@2927: ! cg@2927: cg@2927: resultListMenu cg@2927: "This resource specification was automatically generated cg@2927: by the MenuEditor of ST/X." cg@2927: cg@2927: "Do not manually edit this!! If it is corrupted, cg@2927: the MenuEditor may not be able to read the specification." cg@2927: cg@2927: " cg@2927: MenuEditor new openOnClass:MethodFinderWindow andSelector:#implementorListMenu cg@2927: (Menu new fromLiteralArrayEncoding:(MethodFinderWindow implementorListMenu)) startUp cg@2927: " cg@2927: cg@2927: cg@2927: cg@2927: ^ cg@2927: #(#Menu cg@2927: #( cg@2927: #(#MenuItem cg@3024: #label: 'Browse Senders' cg@3024: #translateLabel: true cg@3024: #value: #openBrowserOnSenderOfSelectedResultItem cg@3024: ) cg@3024: #(#MenuItem cg@2927: #label: 'Browse Implementors' cg@2927: #translateLabel: true cg@2927: #value: #openBrowserOnSelectedResultItem cg@2927: ) cg@2927: ) cg@2927: nil cg@2927: nil cg@2927: ) cg@2927: cg@2927: "Created: / 21-09-2012 / 11:05:15 / cg" james@1525: ! ! james@1525: cg@3289: !MethodFinderWindow class methodsFor:'startup'! cg@3289: cg@3289: openOnSelectorPattern:selector cg@3289: |app| cg@3289: cg@3289: app := self new. cg@3289: app allButOpen. cg@3292: app selectorPatternHolder value:selector. cg@3289: app openWindow. cg@3290: "/ app waitForBackgroundSearchFinished. cg@3290: cg@3289: ^ app cg@3289: cg@3289: " cg@3289: self openOnSelectorPattern:'asLowercase' cg@3289: " cg@3289: ! ! cg@3289: james@1522: !MethodFinderWindow methodsFor:'accessing'! james@1522: james@1522: receiver james@1525: "Return a copy of the value of the instance variable 'receiver' " james@1522: james@1522: ^ receiver copy james@1522: ! ! james@1522: james@1522: !MethodFinderWindow methodsFor:'actions'! james@1522: james@1522: clear cg@3292: "Reset the contents of all the outputs." james@1522: james@1522: receiverEditor contents:nil. james@1522: argument1Editor contents:nil. james@1522: argument2Editor contents:nil. james@1522: argument3Editor contents:nil. james@1522: messageAnswerEditor contents:nil. james@1522: self resultHolder value:nil. james@1525: self classOfResultHolder value: nil. cg@2730: codeHolder value:nil. james@1522: ! james@1522: james@1522: messageAnswerEditorContents cg@3024: "Return a cleaned up version of message answer taken from the messageAnswerEditor cg@3024: as an association. The association has cleanedAnswerString as a key and the cg@3024: compiledAnswer as value." cg@3024: cg@3024: |aCleanedAnswerString compiledAnswer| james@1522: cg@3024: aCleanedAnswerString := self cleanInputs:(messageAnswerEditor contents). cg@3024: compiledAnswer := Compiler evaluate:aCleanedAnswerString. cg@3024: ((self isExpression:aCleanedAnswerString) or:[ compiledAnswer isNil ]) ifTrue:[ cg@3024: aCleanedAnswerString := compiledAnswer printString cg@3024: ]. cg@3024: ^ aCleanedAnswerString -> compiledAnswer. james@1522: ! james@1522: james@1522: openBrowserOn:anArgument james@1522: "Opens browser on theArgument of a specific class. anArgument being a string with the james@1525: Class and the selector upon which the browser is to be opened. Return the receiver." james@1522: cg@1532: |classAndSelector| james@1522: cg@1532: classAndSelector := self extractClassAndSelectorFrom:anArgument. cg@1532: classAndSelector isNil ifTrue:[ james@1525: ^ self james@1522: ]. cg@3024: UserPreferences systemBrowserClass cg@2459: openInClass:classAndSelector key cg@2459: selector:classAndSelector value james@1525: james@1525: " james@1525: MethodFinderWindow new openBrowserOn: '*SmallInteger +' james@1525: MethodFinderWindow new openBrowserOn: 'String ,' james@1525: MethodFinderWindow new openBrowserOn: 'Number detentBy:atMultiplesOf:snap:' james@1525: james@1525: james@1525: " cg@1532: cg@1532: "Modified: / 13.11.2001 / 12:46:17 / cg" james@1522: ! james@1522: cg@1529: openBrowserOnSelectedItem cg@2927: "on the selected implementor" cg@2927: cg@1529: |sel| cg@1529: cg@1529: sel := self selectedClassOfResultHolder value. cg@1529: self openBrowserOn:sel cg@1532: cg@2927: "Modified: / 13-11-2001 / 12:47:39 / cg" cg@2927: "Modified (comment): / 21-09-2012 / 11:08:33 / cg" cg@2927: ! cg@2927: cg@2927: openBrowserOnSelectedResultItem cg@2927: "on an item in the lower left list, cg@2927: on all implementors of that message" cg@2927: cg@2927: |selIndex selector| cg@2927: cg@2927: selIndex := self selectedImplementorsHolder value. cg@2927: selIndex isNil ifTrue:[^ self]. cg@2927: cg@2927: selector := resultSelectors at:selIndex. cg@2927: UserPreferences browserClass browseImplementorsOf:selector. cg@2927: cg@2927: "Created: / 21-09-2012 / 11:05:46 / cg" cg@1529: ! cg@1529: cg@3024: openBrowserOnSenderOfSelectedResultItem cg@3024: "on an item in the lower left list, cg@3024: on all implementors of that message" cg@3024: cg@3024: |selIndex selector| james@1525: cg@3024: selIndex := self selectedImplementorsHolder value. cg@3024: selIndex isNil ifTrue:[^ self]. cg@3024: cg@3024: selector := resultSelectors at:selIndex. cg@3024: UserPreferences browserClass browseSendersOf:selector. cg@3024: ! james@1522: james@1522: search cg@3024: "Do a search based on the input in the various text editors. Return the receiver." mawalch@3322: cg@3024: |tempReceiver tempAnswer tempArguments anArray resultArray receiverWithArgument mf| james@1522: cg@3024: self resultHolder value:nil. cg@3024: self classOfResultHolder value:nil. cg@3024: self codeHolder value:nil. cg@3024: tempArguments := self argumentEditorsContents. cg@3024: tempReceiver := self receiverEditorContents. cg@3024: tempAnswer := self messageAnswerEditorContents. cg@3024: "self cleanInputRec:tempReceiver arg:tempArguments ans:tempAnswer." cg@3024: anArray := Array new:2. cg@3292: receiverWithArgument := self mergeReceiver:(tempReceiver value) cg@3292: withArgument:(tempArguments values). cg@3024: anArray cg@3024: at:1 put:receiverWithArgument; cg@3024: at:2 put:tempAnswer value. mawalch@3322: "an array now holds the following array #(#(receiver argument) answer) or #(#(receiver) answer). which should cg@3024: be suitable input for the method finder." cg@3024: self withCursor:Cursor execute cg@3024: do:[ cg@3024: mf := MethodFinder new. cg@3024: resultArray := mf cg@3024: load:anArray; cg@3024: findMessage. cg@3024: ]. cg@3024: ((resultArray at:1) includesSubString:'no single') ifTrue:[ cg@3024: self warn:(resultArray at:1). cg@3024: ^ self cg@3024: ]. cg@3024: "the following then replaces data1 and data2 created by the method finder to the appropriate arguments" mawalch@3322: resultArray mawalch@3322: keysAndValuesDo:[:key :value | cg@3024: |newValue| james@1522: cg@3024: newValue := value replString:'data1' withString:(tempReceiver key). cg@3024: (tempArguments size) >= 1 ifTrue:[ cg@3024: newValue := newValue replString:'data2' cg@3024: withString:(tempArguments keyAt:1) cg@3024: ]. cg@3024: (tempArguments size) > 1 ifTrue:[ cg@3024: newValue := newValue replString:'data3' cg@3024: withString:(tempArguments keyAt:2). cg@3024: ]. cg@3024: (tempArguments size) > 2 ifTrue:[ cg@3024: newValue := newValue replString:'data4' cg@3024: withString:(tempArguments keyAt:3). cg@3024: ]. cg@3024: (tempArguments size) > 3 ifTrue:[ cg@3024: self halt:'unimplemented'. cg@3024: ]. cg@3024: " newValue:= value replString: 'data3' withString:(self messageAnswer key). " cg@3024: newValue := newValue , ' --> ' , (tempAnswer key). cg@3024: newValue replaceAll:Character cr with:Character space. cg@3024: resultArray at:key put:newValue. cg@3024: ]. cg@3024: self resultHolder value:resultArray. cg@3024: resultSelectors := mf selectors. cg@3024: receiver := tempReceiver cg@1532: cg@2859: "Modified: / 26-09-2011 / 12:42:28 / cg" cg@1532: ! cg@1532: cg@3023: searchPatternMatchesInBackground cg@3023: "Do a search based on the pattern match as a background task" cg@2886: cg@3023: | p pattern| cg@2891: cg@2891: (p := searchProcess) notNil ifTrue:[ cg@2891: searchProcess := nil. cg@2891: p terminate. cg@2891: ]. cg@2891: cg@3292: pattern := self selectorPatternHolder value. cg@3023: pattern isEmptyOrNil ifTrue:[ cg@3023: self resultHolder value:self resultInfoText. cg@3023: self classOfResultHolder value:nil. cg@3023: self codeHolder value:nil. cg@3023: ^ self cg@3023: ]. cg@3023: cg@2891: searchProcess := cg@2891: [ cg@3290: |list counts firsts seconds selectors resultList idx match| cg@2891: cg@2891: self withCursor:Cursor execute do:[ cg@2891: pattern includesMatchCharacters ifFalse:[ cg@3290: list := SystemBrowser findImplementorsOf:pattern in:Smalltalk allClasses ignoreCase:true. cg@3292: list isEmptyOrNil ifTrue:[ cg@3292: match := pattern,'*'. cg@3292: list := SystemBrowser findImplementorsMatching:match in:Smalltalk allClasses ignoreCase:true. cg@3292: ]. cg@3290: ] ifTrue:[ cg@3292: "/ match := '*',pattern,'*'. cg@3292: match := pattern. cg@3290: list := SystemBrowser findImplementorsMatching:match in:Smalltalk allClasses ignoreCase:true. cg@2891: ]. cg@2891: ]. cg@3023: cg@3023: counts := IdentityDictionary new. cg@3023: firsts := IdentityDictionary new. cg@3023: seconds := IdentityDictionary new. cg@3023: selectors := IdentitySet new. cg@3023: list do:[:eachMethod | cg@3023: |msel| cg@3023: cg@3023: msel := eachMethod selector. cg@3023: selectors add:msel. cg@3023: (counts at:msel ifAbsentPut:[ 0 asValue ]) increment. cg@3023: (firsts includesKey:msel) ifTrue:[ cg@3023: (seconds includesKey:msel) ifFalse:[ cg@3023: seconds at:msel ifAbsentPut:[ eachMethod mclass ]. cg@3023: ]. cg@3023: ] ifFalse:[ cg@3023: firsts at:msel ifAbsentPut:[ eachMethod mclass ]. cg@3023: ]. cg@3023: ]. cg@3023: resultSelectors := selectors asOrderedCollection sort. cg@3023: resultList := resultSelectors cg@3023: collect:[:sel | cg@3023: |cnt s| cg@3023: cg@3023: s := sel allBold , ' --> '. cg@3023: cnt := (counts at:sel) value. cg@3023: cnt == 1 ifTrue:[ cg@3023: s , (firsts at:sel) name cg@3023: ] ifFalse:[ cg@3023: cnt == 2 ifTrue:[ cg@3023: s , (firsts at:sel) name , ' and ' , (seconds at:sel) name cg@3023: ] ifFalse:[ cg@3023: s , cnt printString , ' implementor(s)' cg@3023: ] cg@3023: ]. cg@3023: ]. cg@3292: cg@3290: self enqueueDelayedAction:[ self updateListAfterPatternSearch: resultList ]. cg@2891: ] fork. cg@2891: cg@2891: "Created: / 01-06-2012 / 13:16:54 / cg" cg@2891: ! cg@2891: james@1522: updateImplementorsOf:anInteger james@1525: "Request the implementors of the selected argument provided by aNumber. cg@2892: Return the receiver." cg@2892: cg@2892: |methods classList aNumber| james@1525: cg@2892: (anInteger isNil) ifTrue:[ cg@2892: ^ self cg@2892: ]. cg@2892: anInteger isNil ifTrue:[ cg@2892: aNumber := 1 cg@2892: ] ifFalse:[ cg@2892: aNumber := anInteger cg@2892: ]. cg@2892: methods := SystemBrowser cg@2892: findImplementorsOf:(resultSelectors at:aNumber) cg@2892: in:Smalltalk allClasses cg@2892: ignoreCase:false. cg@2892: classList := methods asOrderedCollection cg@2892: collect:[:m | m mclass name , ' ' , m selector ]. cg@2892: classList := (self markMatchingClasses:(resultSelectors at:aNumber) cg@2892: classesWithSelector:classList). cg@2892: self classOfResultHolder value:classList. cg@2892: classList size > 0 ifTrue:[ cg@2892: self selectedClassOfResultHolder value:(classList first). cg@2892: self selectedClassOfResultHolderChanged. cg@2892: ] ifFalse:[ cg@2892: self selectedClassOfResultHolder value:nil. cg@2892: ]. james@1522: cg@2892: "Modified (comment): / 24-06-2012 / 18:41:45 / cg" cg@2891: ! cg@2891: cg@3292: updateListAfterPatternSearch:resultList cg@3292: |searchPattern idx| cg@3292: cg@2892: self classOfResultHolder value:nil. cg@2892: self codeHolder value:nil. cg@3023: self resultHolder value:resultList. cg@2891: cg@3292: searchPattern := self selectorPatternHolder value. cg@3292: "/ is the search pattern in the list (i.e. a perfect match)? cg@3292: "/ Then select it. cg@3292: idx := resultSelectors indexOf:searchPattern. cg@3292: idx ~~ 0 ifTrue:[ cg@3292: self selectedImplementorsHolder setValue:idx; changed cg@3292: ]. james@1522: ! ! james@1522: james@1522: !MethodFinderWindow methodsFor:'aspects'! james@1522: james@1522: arg1BoxVisible cg@3292: "Determines if the box should be visible or not. cg@3292: Return a holder providing true or false" cg@3292: james@1522: arg1BoxVisible isNil ifTrue:[ james@1522: arg1BoxVisible := BlockValue james@1522: with:[:vh | vh value >= 2 ] james@1522: argument:(self argCountHolder) james@1522: ]. james@1522: ^ arg1BoxVisible. james@1522: ! james@1522: james@1522: arg2BoxVisible cg@3292: "Determines if the box should be visible or not. cg@3292: Return a holder providing true or false" cg@3292: james@1522: arg2BoxVisible isNil ifTrue:[ james@1522: arg2BoxVisible := BlockValue james@1522: with:[:vh | vh value >= 3 ] james@1522: argument:(self argCountHolder) james@1522: ]. james@1522: ^ arg2BoxVisible. james@1522: ! james@1522: james@1522: arg3BoxVisible cg@3292: "Determines if the box should be visible or not. cg@3292: Return a holder providing true or false" cg@3292: james@1522: arg3BoxVisible isNil ifTrue:[ james@1522: arg3BoxVisible := BlockValue james@1522: with:[:vh | vh value >= 4 ] james@1522: argument:(self argCountHolder) james@1522: ]. james@1522: ^ arg3BoxVisible. james@1522: ! james@1522: james@1522: arg4BoxVisible cg@3292: "Determines if the box should be visible or not. cg@3292: Return a holder providing true or false" cg@3292: james@1522: arg4BoxVisible isNil ifTrue:[ james@1522: arg4BoxVisible := BlockValue james@1522: with:[:vh | vh value >= 5 ] james@1522: argument:(self argCountHolder) james@1522: ]. james@1522: ^ arg4BoxVisible. james@1522: ! james@1522: james@1522: argCountHolder cg@3292: "Return an argCounterHolder which is initialized at 2." cg@3292: james@1522: argCountHolder isNil ifTrue:[ james@1522: argCountHolder := 2 asValue. james@1522: ]. james@1522: ^ argCountHolder. james@1522: ! james@1522: james@1522: argCountList cg@3292: "Return the argCountList (shown in the combo)" cg@3292: james@1522: argCountList isNil ifTrue:[ james@1522: argCountList := #('0 arguments' '1 argument' '2 arguments' '3 arguments') asValue james@1522: ]. james@1522: ^ argCountList. james@1522: ! james@1522: james@1522: classOfResultHolder james@1525: "Return a valueHolder which contains a collection with the names of the james@1525: implementors of a specific message. " james@1522: cg@3292: classOfResultHolder isNil ifTrue:[ cg@3292: classOfResultHolder := ValueHolder new. james@1522: ]. cg@3292: ^ classOfResultHolder james@1522: ! james@1522: cg@1532: codeHolder cg@1532: codeHolder isNil ifTrue:[ cg@1532: codeHolder := '' asValue. cg@1532: ]. cg@1532: ^ codeHolder. cg@1532: cg@1532: "Created: / 13.11.2001 / 12:44:11 / cg" cg@1532: ! cg@1532: cg@3292: codeViewClass cg@3292: "the species of view to be created as codeview" cg@3292: cg@3292: ^ Tools::CodeView2 ? CodeView cg@3292: ! cg@3292: james@1522: resultHolder james@1525: "Return a value holder which contains the results of a search as a collection." james@1522: cg@3292: resultHolder isNil ifTrue:[ cg@3292: resultHolder := ValueHolder new. cg@3292: resultHolder value:(self resultInfoText collect:[:l | l withColor:Color darkGrey]). james@1522: ]. cg@3292: ^ resultHolder. cg@2886: cg@2890: "Modified: / 01-06-2012 / 13:06:02 / cg" cg@1529: ! cg@1529: cg@3023: resultInfoText cg@3023: ^ { cg@3023: 'Please enter combination of' . cg@3023: ' ',('receiver, arg and result' allBold) . cg@3023: 'or a'. cg@3023: ' ',('selector search pattern' allBold) . cg@3289: 'into the above fields.' . cg@3289: 'Then click on either ',('"search"' allBold),'-button.' cg@3023: } cg@3023: ! cg@3023: cg@1529: selectedClassOfResultHolder cg@2927: "valueHolder which contains the index of the selected result class (right list)" cg@1529: cg@3292: selectedClassOfResultHolder isNil ifTrue:[ cg@3292: selectedClassOfResultHolder := ValueHolder new. cg@1529: ]. cg@3292: ^ selectedClassOfResultHolder cg@2927: cg@2927: "Modified (comment): / 21-09-2012 / 11:10:29 / cg" cg@2927: ! cg@2927: cg@2927: selectedImplementorsHolder cg@2927: "valueHolder which contains the index of the selected implementors list (left list)" cg@2927: cg@3292: selectedImplementorsHolder isNil ifTrue:[ cg@3292: selectedImplementorsHolder := ValueHolder new. cg@3292: selectedImplementorsHolder onChangeEvaluate:[self updateImplementorsOf:selectedImplementorsHolder value]. cg@2927: ]. cg@3292: ^ selectedImplementorsHolder cg@2927: cg@2927: "Created: / 21-09-2012 / 11:10:13 / cg" cg@2886: ! cg@2886: cg@3292: selectorPatternHolder cg@3292: selectorPatternHolder isNil ifTrue:[ cg@3292: selectorPatternHolder := ValueHolder new. cg@3292: selectorPatternHolder onChangeSend:#selectorPatternChanged to:self. cg@2886: ]. cg@3292: ^ selectorPatternHolder cg@2886: cg@2886: "Created: / 27-04-2012 / 14:44:01 / cg" james@1522: ! ! james@1522: james@1522: !MethodFinderWindow methodsFor:'controlInput'! james@1522: sv@3090: cleanInputs:aDirtyString sv@3090: "Find and remove common mistakes made by the user. Return the james@1525: 'aStringToBeCleaned' variable" sv@3090: sv@3090: |aStringToBeCleaned rs position| james@1522: sv@3090: aStringToBeCleaned := aDirtyString. sv@3090: (aStringToBeCleaned endsWith:(Character cr)) ifTrue:[ sv@3090: aStringToBeCleaned := aStringToBeCleaned copyFrom:1 to:(aStringToBeCleaned size - 1). sv@3090: ]. sv@3090: aStringToBeCleaned := aStringToBeCleaned withoutSeparators. sv@3090: rs := ReadStream on:aStringToBeCleaned. sv@3090: [ sv@3090: rs upToAll_positionBefore:'#true'. sv@3090: rs atEnd sv@3090: ] whileFalse:[ sv@3090: position := rs position. sv@3090: aStringToBeCleaned := aStringToBeCleaned sv@3090: copyReplaceFrom:position sv@3090: to:position sv@3090: with:''. sv@3090: rs := ReadStream on:aStringToBeCleaned. sv@3090: ]. sv@3090: rs := ReadStream on:aStringToBeCleaned. sv@3090: [ sv@3090: rs upToAll_positionBefore:'#false'. sv@3090: rs atEnd sv@3090: ] whileFalse:[ sv@3090: position := rs position. sv@3090: aStringToBeCleaned := aStringToBeCleaned sv@3090: copyReplaceFrom:position sv@3090: to:position sv@3090: with:''. sv@3090: rs := ReadStream on:aStringToBeCleaned. sv@3090: ]. sv@3090: [ sv@3090: rs upToAll_positionBefore:'#nil'. sv@3090: rs atEnd sv@3090: ] whileFalse:[ sv@3090: position := rs position. sv@3090: aStringToBeCleaned := aStringToBeCleaned sv@3090: copyReplaceFrom:position sv@3090: to:position sv@3090: with:''. sv@3090: rs := ReadStream on:aStringToBeCleaned. sv@3090: ]. sv@3090: ^ aStringToBeCleaned james@1522: ! james@1522: mawalch@3315: markMatchingClasses:aSelector classesWithSelector:anOrderedCollection sv@3090: " Matches the class of the receiver with all the elements in anOrderedCollection sv@3090: (which are classes with selectors). If a match is found it is marked with an asterisk. mawalch@3315: The classes are then sorted so the asterisk appears first. Return the sv@3090: markedClassList." sv@3090: sv@3090: |marker recClass unmarkedClassList markedClassList| james@1522: sv@3090: marker := self class markerForImplementingClass. sv@3090: recClass := receiver value class. sv@3090: unmarkedClassList := anOrderedCollection copy. mawalch@3315: unmarkedClassList do:[:classAndMethod | cg@3290: |className class sel| cg@1532: cg@3290: className := classAndMethod copyButLast:aSelector size. cg@3290: class := Smalltalk classNamed:className. "/ Compiler evaluate:className. mawalch@3315: sv@3090: "/ (recClass == class) mawalch@3315: sv@3090: (recClass whichClassImplements:aSelector) == class ifTrue:[ sv@3090: "/ unmarkedClassList add: marker, classAndMethod. sv@3090: unmarkedClassList add:classAndMethod allBold. sv@3090: unmarkedClassList remove:classAndMethod. cg@1532: ]. sv@3090: ]. mawalch@3315: unmarkedClassList mawalch@3315: sort:[:a :b | sv@3090: |rawA rawB| james@1522: sv@3090: rawA := a string withoutPrefix:marker. sv@3090: rawB := b string withoutPrefix:marker. sv@3090: rawA < rawB. sv@3090: ]. sv@3090: markedClassList := unmarkedClassList. sv@3090: ^ markedClassList cg@1532: cg@1532: "Modified: / 13.11.2001 / 12:16:05 / cg" james@1522: ! james@1522: cg@3292: mergeReceiver: aReceiver withArgument: arguments james@1522: james@1525: "Puts the receiver and arguments into an array so it can be of a suitable input for the james@1525: MethodFinder. Return an array." james@1525: james@1522: | tempReceiver tempArguments receiverWithArgument| james@1522: james@1522: tempReceiver:= aReceiver. james@1522: tempArguments := arguments. james@1522: james@1522: (tempArguments isEmpty or:[(tempArguments) isNil]) james@1522: ifTrue:[ receiverWithArgument:=Array new:1."no argument" james@1522: receiverWithArgument at:1 put: tempReceiver. james@1522: ] james@1522: ifFalse:[ james@1522: (tempArguments size = 1) james@1522: ifTrue:[ receiverWithArgument:=Array new:2. james@1522: receiverWithArgument at:1 put: tempReceiver. james@1522: receiverWithArgument at:2 put: (tempArguments at:1) james@1522: ]. "a receiver with an argument" james@1522: james@1522: (tempArguments size = 2) james@1522: ifTrue:[ receiverWithArgument:=Array new:3. james@1522: receiverWithArgument at:1 put: tempReceiver. james@1522: (receiverWithArgument at:2 put: (tempArguments at:1)). james@1522: (receiverWithArgument at:3 put: (tempArguments at:2)) james@1522: ]. "a receiver with an argument" james@1522: (tempArguments size = 3) james@1522: ifTrue:[ receiverWithArgument:=Array new:4. james@1522: receiverWithArgument at:1 put: tempReceiver. james@1522: (receiverWithArgument at:2 put: (tempArguments at:1)). james@1522: (receiverWithArgument at:3 put: (tempArguments at:2)). james@1522: (receiverWithArgument at:4 put: (tempArguments at:3)). james@1522: james@1522: ]. "a receiver with an argument" james@1522: james@1522: ]. james@1522: ^receiverWithArgument james@1522: ! ! james@1522: cg@3292: !MethodFinderWindow methodsFor:'initialization'! cg@3292: cg@3292: argument1WidgetCreated: aWidget cg@3292: "UI post creation hook. remember the widget as an instance variable." cg@3292: cg@3292: argument1Editor := aWidget scrolledView. cg@3292: aWidget tabMeansNextField:true. cg@3292: cg@3292: "Modified: / 13.11.2001 / 12:21:41 / cg" cg@3292: ! cg@3292: cg@3292: argument2WidgetCreated: aWidget cg@3292: "UI post creation hook. remember the widget as an instance variable." cg@3292: cg@3292: argument2Editor := aWidget scrolledView. cg@3292: aWidget tabMeansNextField:true. cg@3292: cg@3292: "Modified: / 13.11.2001 / 12:21:45 / cg" cg@3292: ! cg@3292: cg@3292: argument3WidgetCreated: aWidget cg@3292: "UI post creation hook. remember the widget as an instance variable" cg@3292: cg@3292: argument3Editor := aWidget scrolledView. cg@3292: aWidget tabMeansNextField:true. cg@3292: cg@3292: "Modified: / 13.11.2001 / 12:21:49 / cg" cg@3292: ! cg@3292: cg@3292: messageAnswerWidgetCreated: aWidget cg@3292: "UI post creation hook. remember the widget as an instance variable." cg@3292: cg@3292: messageAnswerEditor := aWidget scrolledView. cg@3292: aWidget tabMeansNextField:true. cg@3292: cg@3292: "Modified: / 13.11.2001 / 12:24:55 / cg" cg@3292: ! cg@3292: cg@3292: receiverWidgetCreated: aWidget cg@3292: "UI post creation hook. remember the widget as an instance variable." cg@3292: cg@3292: receiverEditor := aWidget scrolledView. cg@3292: aWidget tabMeansNextField:true. cg@3292: cg@3292: "Modified: / 13.11.2001 / 12:24:49 / cg" cg@3292: ! cg@3292: cg@3292: sourceCodeWidgetCreated: aWidget cg@3292: "UI post creation hook. make the codeView readonly" cg@3292: cg@3292: aWidget acceptAction:nil. cg@3292: aWidget readOnly:true cg@3292: cg@3292: "Created: / 13.11.2001 / 12:50:27 / cg" cg@3292: "Modified: / 13.11.2001 / 12:51:23 / cg" cg@3292: ! ! cg@3292: cg@3292: !MethodFinderWindow methodsFor:'menu actions'! cg@1532: cg@1532: aboutThisApplicationText cg@1532: |msg| cg@1532: cg@1532: msg := super aboutThisApplicationText. cg@3292: msg := msg , '\\Original written by Ted Kaehler, Scott Wallace and Dan Ingalls. cg@3292: Ported from Squeak to ST/X by James Hayes (2001 james@exept.de). cg@3292: Improved by Claus Gittinger. cg@3292: '. cg@1532: ^msg withCRs. cg@1532: cg@1532: "Modified: / 13.11.2001 / 12:56:44 / cg" cg@3292: ! cg@3292: cg@3292: openHTMLDocumentation cg@3292: "about/help menu action" cg@3292: cg@3292: HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#METHODFINDER' cg@3292: ! ! cg@3292: cg@3292: !MethodFinderWindow methodsFor:'private'! cg@3292: cg@3292: argumentEditorsContents cg@3292: cg@3292: "Determine how many text editors of the arguments are used and store the result cg@3292: as argCounter. The result being the minimum between how many editors have cg@3292: expressions in and how many are displayed. cg@3292: cg@3292: Add each argument string (key)and the evaluated version (value) to an Ordered Dictionary cg@3292: from each of the text editors. cg@3292: cg@3292: Return the OrderedDictionary with the expressions from all the text editors. " cg@3292: cg@3292: | tempArguments argCounter tempArgument1Editor tempArgument2Editor tempArgument3Editor cg@3292: associationKey associationValue| cg@3292: cg@3292: argCounter:=0. cg@3292: cg@3292: tempArgument1Editor:= (self cleanInputs: argument1Editor contents). cg@3292: tempArgument2Editor:= (self cleanInputs: argument2Editor contents). cg@3292: tempArgument3Editor:= (self cleanInputs: argument3Editor contents). cg@3292: cg@3292: tempArgument1Editor = '' ifFalse:[argCounter:=argCounter +1]. cg@3292: tempArgument2Editor = '' ifFalse:[argCounter:=argCounter +1]. cg@3292: tempArgument3Editor = '' ifFalse:[argCounter:=argCounter +1]. cg@3292: cg@3292: cg@3292: argCounter:= (argCounter min: (self argCountHolder value -1)). cg@3292: tempArguments:= OrderedDictionary new:argCounter. cg@3292: cg@3292: (argCounter value >= 1) cg@3292: ifTrue:[associationValue:= (Compiler evaluate: tempArgument1Editor). cg@3292: ((self isExpression:tempArgument1Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" cg@3292: associationKey:=associationValue printString] cg@3292: ifFalse:[ cg@3292: associationKey:=tempArgument1Editor]. cg@3292: cg@3292: tempArguments add: associationKey-> associationValue. cg@3292: ]. cg@3292: (argCounter value >= 2) cg@3292: ifTrue:[ associationValue:= (Compiler evaluate: tempArgument2Editor). cg@3292: (((self isExpression:tempArgument2Editor) or:[ associationValue isNil])) ifTrue:[ "looks if an expression is typed in" cg@3292: associationKey:=associationValue printString] cg@3292: ifFalse:[ cg@3292: associationKey:=tempArgument2Editor]. cg@3292: cg@3292: tempArguments add: associationKey-> associationValue]. cg@3292: cg@3292: (argCounter value >= 3) cg@3292: ifTrue:[ associationValue:= (Compiler evaluate: tempArgument3Editor). cg@3292: ((self isExpression:tempArgument3Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" cg@3292: associationKey:=associationValue printString] cg@3292: ifFalse:[ cg@3292: associationKey:=tempArgument3Editor]. cg@3292: cg@3292: tempArguments add: associationKey-> associationValue]. cg@3292: cg@3292: cg@3292: ^tempArguments cg@3292: ! cg@3292: cg@3292: extractClassAndSelectorFrom:anArgument cg@3292: "Opens browser on theArgument of a specific class. anArgument being a string with the cg@3292: Class and the selector upon which the browser is to be opened. Return the receiver." cg@3292: cg@3292: |aClass aSelector x theArgument marker| cg@3292: cg@3292: anArgument isNil ifTrue:[ cg@3292: ^ nil cg@3292: ]. cg@3292: marker := self class markerForImplementingClass. cg@3292: cg@3292: theArgument := anArgument string withoutPrefix:marker. cg@3292: aClass := theArgument copyUpTo:(Character space). cg@3292: x := aClass size + 2. cg@3292: aSelector := theArgument copyFrom:x. cg@3292: aClass := Smalltalk classNamed:aClass. cg@3292: (aSelector startsWith:'class ') ifTrue:[ cg@3292: aSelector := aSelector withoutPrefix:'class '. cg@3292: aClass := aClass class. cg@3292: ]. cg@3292: ^ aClass -> aSelector asSymbol cg@3292: cg@3292: " cg@3292: MethodFinderWindow new extractClassAndSelectorFrom: '*SmallInteger +' cg@3292: MethodFinderWindow new extractClassAndSelectorFrom: 'String ,' cg@3292: MethodFinderWindow new extractClassAndSelectorFrom: 'Number detentBy:atMultiplesOf:snap:' cg@3292: cg@3292: cg@3292: " cg@3292: cg@3292: "Modified: / 27-04-2012 / 15:05:53 / cg" cg@3292: ! cg@3292: cg@3292: isExpression:aString cg@3292: "Return true or false depending on if the subString includes certain characters" cg@3292: cg@3292: "/ cg: this is naive - why not ask the parser, if it is a literal? cg@3292: (aString includesSubString:': ') ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$+) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$-) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$*) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$/) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$>) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$<) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includesSubString:' new') ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: (aString includes:$[) cg@3292: & (aString includes:$]) cg@3292: & (aString includes:$.) ifTrue:[ ^ false ]. cg@3292: cg@3292: (aString includes:$.) ifTrue:[ cg@3292: ^ true cg@3292: ]. cg@3292: ^ false cg@3292: ! cg@3292: cg@3292: receiverEditorContents cg@3292: "Return a cleaned up version of receiver taken from the receiverEditor mawalch@3322: as an association. The association has aCleanedReceiverString as a key and the cg@3292: compiledReceiver as value." mawalch@3322: mawalch@3322: |aCleanedReceiverString compiledReceiver| cg@3292: mawalch@3322: aCleanedReceiverString := self cleanInputs:(receiverEditor contents). mawalch@3322: compiledReceiver := Compiler evaluate:aCleanedReceiverString. mawalch@3322: ((self isExpression:aCleanedReceiverString) or:[ compiledReceiver isNil ]) ifTrue:[ mawalch@3322: aCleanedReceiverString := compiledReceiver printString cg@3292: ]. mawalch@3322: ^ aCleanedReceiverString -> compiledReceiver. cg@3292: ! cg@3292: cg@3292: waitForBackgroundSearchFinished cg@3292: | p | cg@3292: cg@3292: (p := searchProcess) isNil ifTrue:[^ self]. cg@3292: p isDead ifTrue:[^ self]. cg@3292: p waitUntilTerminated cg@3292: ! ! cg@3292: cg@3292: !MethodFinderWindow methodsFor:'user actions'! cg@3292: cg@3292: selectedClassOfResultHolderChanged cg@3292: |sel classAndSelector mthd| cg@3292: cg@3292: sel := self selectedClassOfResultHolder value. cg@3292: cg@3292: classAndSelector := self extractClassAndSelectorFrom:sel. cg@3292: classAndSelector isNil ifTrue:[ cg@3292: ^ self cg@3292: ]. cg@3292: mthd := classAndSelector key >> classAndSelector value. cg@3292: mthd notNil ifTrue:[ cg@3292: self withWaitCursorDo:[ cg@3292: self codeHolder value:mthd source cg@3292: ] cg@3292: ] ifFalse:[ cg@3292: self codeHolder value:nil cg@3292: ]. cg@3292: cg@3292: "Created: / 13.11.2001 / 12:43:43 / cg" cg@3292: "Modified: / 13.11.2001 / 12:48:56 / cg" cg@3292: ! cg@3292: cg@3292: selectorPatternChanged cg@3292: self searchPatternMatchesInBackground cg@3292: cg@3292: "Created: / 01-06-2012 / 13:18:16 / cg" cg@1532: ! ! cg@1532: james@1522: !MethodFinderWindow class methodsFor:'documentation'! james@1522: james@1522: version james@1522: ^ '$Header$' cg@2730: ! cg@2730: cg@2730: version_CVS cg@2730: ^ '$Header$' james@1522: ! ! cg@3003: