# HG changeset patch # User Claus Gittinger # Date 1005652856 -3600 # Node ID 318c295490c15b48bff17ffc6a761a791d28adba # Parent 9d4f8cd101fa33fd6261cf846331c064d1500fd5 GUI enhanced diff -r 9d4f8cd101fa -r 318c295490c1 MethodFinderWindow.st --- a/MethodFinderWindow.st Fri Nov 09 09:13:06 2001 +0100 +++ b/MethodFinderWindow.st Tue Nov 13 13:00:56 2001 +0100 @@ -5,7 +5,7 @@ resultSelectors arg2BoxVisible arg1BoxVisible arg4BoxVisible arg3BoxVisible argCountHolder argCountList argument1Editor argument2Editor argument3Editor argument4Editor resultSelected - lookAtResultEditor' + lookAtResultEditor codeHolder' classVariableNames:'' poolDictionaries:'' category:'MethodFinder' @@ -20,6 +20,16 @@ " ! ! +!MethodFinderWindow class methodsFor:'constants'! + +markerForImplementingClass + ^ '=> '. + ^ '*' + + "Created: / 13.11.2001 / 12:09:52 / cg" + "Modified: / 13.11.2001 / 12:11:57 / cg" +! ! + !MethodFinderWindow class methodsFor:'interface specs'! windowSpec @@ -53,85 +63,59 @@ #component: #(#SpecCollection #collection: #( - #(#ViewSpec - #name: 'Box6' + #(#VariableHorizontalPanelSpec + #name: 'VariableHorizontalPanel1' #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #level: 1 + #snapMode: #both #component: #(#SpecCollection #collection: #( - #(#SequenceViewSpec - #name: 'List1' - #layout: #(#LayoutFrame 0 0 0 0.5 0 0.65 0 1) - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #autoHideScrollBars: true - #valueChangeSelector: #updateImplementorsOf: - #useIndex: true - #sequenceList: #resultHolder - ) - #(#SequenceViewSpec - #name: 'List2' - #layout: #(#LayoutFrame 0 0.65 0 0 0 1 0 1) - #model: #selectedClassOfResultHolder - #menu: #implementorListMenu - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #autoHideScrollBars: true - #doubleClickSelector: #openBrowserOn: - #useIndex: false - #sequenceList: #classOfResultHolder - ) #(#ViewSpec - #name: 'Box4' - #layout: #(#LayoutFrame 0 0 0 0 0 0.65 -25 0.5) + #name: 'Box6' + #level: 1 #component: #(#SpecCollection #collection: #( - #(#LabelSpec - #label: 'Receiver' - #name: 'ReceiverLabel' - #layout: #(#LayoutFrame -4 0.0162791 0 0 -4 0.293023 24 0) - #translateLabel: true - #adjust: #left - ) - #(#ComboListSpec - #name: 'allowedArgments' - #layout: #(#LayoutFrame 0 0.339535 1 0 0 0.653488 23 0) - #model: #argCountHolder - #comboList: #argCountList + #(#SequenceViewSpec + #name: 'List1' + #layout: #(#LayoutFrame 0 0 0 0.5 0 1 0 1) + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #autoHideScrollBars: true + #valueChangeSelector: #updateImplementorsOf: #useIndex: true + #sequenceList: #resultHolder ) - #(#LabelSpec - #label: 'MessageAnswer' - #name: 'MessageAnswerLabel' - #layout: #(#LayoutFrame 0 0.6693 0 0 0 0.99023 24 0) - #translateLabel: true - #adjust: #left - ) - #(#HorizontalPanelViewSpec - #name: 'HorizontalPanel1' - #layout: #(#LayoutFrame 0 0 25 0 0 1 0 1) - #horizontalLayout: #fit - #verticalLayout: #fit - #horizontalSpace: 3 - #verticalSpace: 3 + #(#ViewSpec + #name: 'Box4' + #layout: #(#LayoutFrame 0 0 0 0 0 1 -25 0.5) #component: #(#SpecCollection #collection: #( - #(#WorkspaceSpec - #name: 'ReceiverEditor' - #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #autoHideScrollBars: true - #extent: #(#Point 116 149) - #postBuildCallback: #receiverWidgetCreated: + #(#LabelSpec + #label: 'Receiver' + #name: 'ReceiverLabel' + #layout: #(#LayoutFrame -4 0.0162791 0 0 -4 0.293023 24 0) + #translateLabel: true + #adjust: #center ) - #(#VerticalPanelViewSpec - #name: 'VerticalPanel1' + #(#ComboListSpec + #name: 'allowedArgments' + #layout: #(#LayoutFrame 0 0.339535 1 0 0 0.653488 23 0) + #model: #argCountHolder + #comboList: #argCountList + #useIndex: true + ) + #(#LabelSpec + #label: 'Answer' + #name: 'MessageAnswerLabel' + #layout: #(#LayoutFrame 0 0.6693 0 0 0 0.99023 24 0) + #translateLabel: true + #adjust: #center + ) + #(#HorizontalPanelViewSpec + #name: 'HorizontalPanel1' + #layout: #(#LayoutFrame 0 0 25 0 0 1 0 1) #horizontalLayout: #fit #verticalLayout: #fit #horizontalSpace: 3 @@ -139,87 +123,136 @@ #component: #(#SpecCollection #collection: #( - #(#ViewSpec - #name: 'Box1' - #visibilityChannel: #arg1BoxVisible + #(#WorkspaceSpec + #name: 'ReceiverEditor' + #tabable: true + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: true + #extent: #(#Point 87 149) + #postBuildCallback: #receiverWidgetCreated: + ) + #(#VerticalPanelViewSpec + #name: 'VerticalPanel1' + #horizontalLayout: #fit + #verticalLayout: #fit + #horizontalSpace: 3 + #verticalSpace: 3 #component: #(#SpecCollection #collection: #( - #(#WorkspaceSpec - #name: 'Arg1Editor' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #autoHideScrollBars: true - #postBuildCallback: #argument1WidgetCreated: + #(#ViewSpec + #name: 'Box1' + #visibilityChannel: #arg1BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'Arg1Editor' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: true + #postBuildCallback: #argument1WidgetCreated: + ) + ) + + ) + #extent: #(#Point 87 48) + ) + #(#ViewSpec + #name: 'Box2' + #visibilityChannel: #arg2BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'TextEditor5' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: true + #postBuildCallback: #argument2WidgetCreated: + ) + ) + + ) + #extent: #(#Point 87 47) + ) + #(#ViewSpec + #name: 'Box3' + #visibilityChannel: #arg3BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'TextEditor6' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: true + #postBuildCallback: #argument3WidgetCreated: + ) + ) + + ) + #extent: #(#Point 87 48) ) ) ) - #extent: #(#Point 117 48) + #extent: #(#Point 87 149) ) - #(#ViewSpec - #name: 'Box2' - #visibilityChannel: #arg2BoxVisible - #component: - #(#SpecCollection - #collection: #( - #(#WorkspaceSpec - #name: 'TextEditor5' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #autoHideScrollBars: true - #postBuildCallback: #argument2WidgetCreated: - ) - ) - - ) - #extent: #(#Point 117 47) - ) - #(#ViewSpec - #name: 'Box3' - #visibilityChannel: #arg3BoxVisible - #component: - #(#SpecCollection - #collection: #( - #(#WorkspaceSpec - #name: 'TextEditor6' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #autoHideScrollBars: true - #postBuildCallback: #argument3WidgetCreated: - ) - ) - - ) - #extent: #(#Point 117 48) + #(#WorkspaceSpec + #name: 'AnswerEditor' + #tabable: true + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #autoHideScrollBars: true + #extent: #(#Point 88 149) + #postBuildCallback: #messageAnswerWidgetCreated: ) ) ) - #extent: #(#Point 117 149) ) - #(#WorkspaceSpec - #name: 'AnswerEditor' + ) + + ) + ) + #(#ViewSpec + #name: 'Box5' + #layout: #(#LayoutFrame 53 0.224737 -23 0.5 0 1 0 0.5) + #component: + #(#SpecCollection + #collection: #( + #(#ActionButtonSpec + #label: 'Clear' + #name: 'Button2' + #layout: #(#LayoutFrame 0 0 0 0 -5 0.5 0 1) + #translateLabel: true + #model: #clear + ) + #(#ActionButtonSpec + #label: 'Search' + #name: 'Button1' + #layout: #(#LayoutFrame 5 0.5 0 0 0 1 0 1) + #translateLabel: true #tabable: true - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #miniScrollerVertical: true - #autoHideScrollBars: true - #extent: #(#Point 117 149) - #postBuildCallback: #messageAnswerWidgetCreated: + #model: #search ) ) @@ -229,41 +262,47 @@ ) ) - #(#ViewSpec - #name: 'Box5' - #layout: #(#LayoutFrame 53 0.224737 -23 0.5 0 0.65 0 0.5) + #(#VariableVerticalPanelSpec + #name: 'VariableVerticalPanel1' #component: #(#SpecCollection #collection: #( - #(#ActionButtonSpec - #label: 'Clear' - #name: 'Button2' - #layout: #(#LayoutFrame 0 0 0 0 -5 0.5 0 1) - #translateLabel: true - #model: #clear + #(#SequenceViewSpec + #name: 'List2' + #model: #selectedClassOfResultHolder + #menu: #implementorListMenu + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #autoHideScrollBars: true + #doubleClickSelector: #openBrowserOn: + #valueChangeSelector: #selectedClassOfResultHolderChanged + #useIndex: false + #sequenceList: #classOfResultHolder ) - #(#ActionButtonSpec - #label: 'Search' - #name: 'Button1' - #layout: #(#LayoutFrame 5 0.5 0 0 0 1 0 1) - #translateLabel: true - #tabable: true - #model: #search + #(#CodeViewSpec + #name: 'CodeView' + #model: #codeHolder + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #autoHideScrollBars: true + #postBuildCallback: #sourceCodeWidgetCreated: ) ) ) + #handles: #(#Any 0.5 1.0) ) ) ) + #handles: #(#Any 0.5 1.0) ) ) ) ) - "Modified: / 9.11.2001 / 08:45:48 / cg" + "Modified: / 13.11.2001 / 12:53:50 / cg" ! ! !MethodFinderWindow class methodsFor:'menu specs'! @@ -341,7 +380,7 @@ #activeHelpKey: #helpTutorial ) #(#MenuItem - #label: 'About MenuEditor...' + #label: 'About MethodFinder...' #value: #openAboutThisApplication #activeHelpKey: #aboutThisAppliaction ) @@ -354,6 +393,8 @@ nil nil ) + + "Modified: / 13.11.2001 / 12:36:39 / cg" ! ! !MethodFinderWindow methodsFor:'accessing'! @@ -437,6 +478,38 @@ self classOfResultHolder value: nil. ! +extractClassAndSelectorFrom:anArgument + "Opens browser on theArgument of a specific class. anArgument being a string with the + Class and the selector upon which the browser is to be opened. Return the receiver." + + |aClass aSelector x theArgument marker| + + anArgument isNil ifTrue:[ + ^ nil + ]. + marker := self class markerForImplementingClass. + + theArgument := anArgument string. + (theArgument startsWith:marker) ifTrue:[ + theArgument := theArgument copyFrom:marker size+1 + ]. + aClass := theArgument copyUpTo:(Character space). + x := aClass size + 2. + aSelector := theArgument copyFrom:x. + aClass := Smalltalk classNamed:aClass. + ^ aClass -> aSelector asSymbol + +" +MethodFinderWindow new extractClassAndSelectorFrom: '*SmallInteger +' +MethodFinderWindow new extractClassAndSelectorFrom: 'String ,' +MethodFinderWindow new extractClassAndSelectorFrom: 'Number detentBy:atMultiplesOf:snap:' + + +" + + "Modified: / 13.11.2001 / 12:45:43 / cg" +! + isExpression: aString "Return true or false depending on if the subString includes certain characters" (aString includesSubString:': ') ifTrue:[^true]. @@ -474,21 +547,13 @@ "Opens browser on theArgument of a specific class. anArgument being a string with the Class and the selector upon which the browser is to be opened. Return the receiver." - |aClass aSelector x theArgument| + |classAndSelector| - anArgument isNil ifTrue:[ + classAndSelector := self extractClassAndSelectorFrom:anArgument. + classAndSelector isNil ifTrue:[ ^ self ]. - (anArgument at:1) == $* ifTrue:[ - theArgument := anArgument copyFrom:2 - ] ifFalse:[ - theArgument := anArgument - ]. - aClass := theArgument copyUpTo:(Character space). - x := aClass size + 2. - aSelector := theArgument copyFrom:x. - aClass := Smalltalk classNamed:aClass. - SystemBrowser openInClass:(aClass) selector:(aSelector asSymbol) + SystemBrowser openInClass:classAndSelector key selector:classAndSelector value " MethodFinderWindow new openBrowserOn: '*SmallInteger +' @@ -497,14 +562,17 @@ " + + "Modified: / 13.11.2001 / 12:46:17 / cg" ! openBrowserOnSelectedItem |sel| sel := self selectedClassOfResultHolder value. - sel isNil ifTrue:[^ self]. self openBrowserOn:sel + + "Modified: / 13.11.2001 / 12:47:39 / cg" ! receiverEditorContents @@ -552,7 +620,6 @@ self warn: (resultArray at: 1 ). ^self ]. - "the following then replaces data1 and data2 created by the method finder to the appropriate arguments" resultArray keysAndValuesDo:[:key :value | | newValue | newValue:= value replString: 'data1' withString:(tempReceiver key). @@ -565,10 +632,13 @@ (tempArguments size) > 2 ifTrue:[ newValue:= newValue replString: 'data4' withString:(tempArguments keyAt:3).]. +(tempArguments size) > 3 ifTrue:[ self halt. ]. + " newValue:= value replString: 'data3' withString:(self messageAnswer key). " newValue:=newValue, ' --> ', (tempAnswer key). + newValue replaceAll:Character cr with:Character space. resultArray at: key put: newValue. @@ -577,6 +647,30 @@ self resultHolder value: resultArray. resultSelectors:= mf selectors. "used to find implementors so we do not have to " receiver:=tempReceiver "search the string for the selector found. Stored as an ordered collection" + + "Modified: / 13.11.2001 / 12:01:35 / cg" +! + +selectedClassOfResultHolderChanged + |sel classAndSelector mthd| + + sel := self selectedClassOfResultHolder value. + + classAndSelector := self extractClassAndSelectorFrom:sel. + classAndSelector isNil ifTrue:[ + ^ self + ]. + mthd := classAndSelector key >> classAndSelector value. + mthd notNil ifTrue:[ + self withWaitCursorDo:[ + self codeHolder value:mthd source + ] + ] ifFalse:[ + self codeHolder value:nil + ]. + + "Created: / 13.11.2001 / 12:43:43 / cg" + "Modified: / 13.11.2001 / 12:48:56 / cg" ! updateImplementorsOf:anInteger @@ -594,6 +688,9 @@ classList:=(self markMatchingClasses:(resultSelectors at:aNumber) classesWithSelector:classList). self classOfResultHolder value: classList. + self selectedClassOfResultHolder value:nil. + + "Modified: / 13.11.2001 / 12:07:31 / cg" ! ! !MethodFinderWindow methodsFor:'aspects'! @@ -666,6 +763,15 @@ ^ holder ! +codeHolder + codeHolder isNil ifTrue:[ + codeHolder := '' asValue. + ]. + ^ codeHolder. + + "Created: / 13.11.2001 / 12:44:11 / cg" +! + resultHolder "Return a value holder which contains the results of a search as a collection." @@ -696,6 +802,9 @@ argument1Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:41 / cg" ! argument2WidgetCreated: aWidget @@ -703,6 +812,9 @@ argument2Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:45 / cg" ! argument3WidgetCreated: aWidget @@ -710,12 +822,18 @@ argument3Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:49 / cg" ! messageAnswerWidgetCreated: aWidget "Store the widget as an instance variable. Return the receiver" messageAnswerEditor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:24:55 / cg" ! openHTMLDocumentation @@ -726,6 +844,17 @@ "Store the widget as an instance variable. Return the receiver" receiverEditor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:24:49 / cg" +! + +sourceCodeWidgetCreated: aWidget + aWidget acceptAction:nil. + aWidget readOnly:true + + "Created: / 13.11.2001 / 12:50:27 / cg" + "Modified: / 13.11.2001 / 12:51:23 / cg" ! ! !MethodFinderWindow methodsFor:'controlInput'! @@ -769,25 +898,36 @@ The classes are then sorted so the the asterisk appears first. Return the markedClassList." - | unmarkedClassList firstPartOfSelector markedClassList| + | marker recClass unmarkedClassList firstPartOfSelector markedClassList| + marker := self class markerForImplementingClass. + + recClass := receiver value class. unmarkedClassList:=anOrderedCollection copy. - unmarkedClassList do: [:classAndMethod | | class | class:=Compiler evaluate: ((ReadStream on: classAndMethod) upToAll: aSelector). - (receiver value class == class) ifTrue: - [unmarkedClassList add: '*', classAndMethod. - unmarkedClassList remove: classAndMethod]]. + "/ (recClass == class) + (recClass whichClassImplements:aSelector) == class + ifTrue: + ["/ unmarkedClassList add: marker, classAndMethod. + unmarkedClassList add: classAndMethod allBold. + unmarkedClassList remove: classAndMethod. + ]. + ]. unmarkedClassList sort:[:a :b | |rawA rawB| - rawA := (a startsWith:'*') ifTrue:[a copyFrom:2] ifFalse:[a]. - rawB := (b startsWith:'*') ifTrue:[b copyFrom:2] ifFalse:[b]. - rawA > rawB. ]. + rawA := a string. + (rawA startsWith:marker) ifTrue:[rawA := rawA copyFrom:marker size+1]. + rawB := b string. + (rawB startsWith:marker) ifTrue:[rawB := rawB copyFrom:marker size+1]. + rawA < rawB. ]. markedClassList:= unmarkedClassList. ^markedClassList + + "Modified: / 13.11.2001 / 12:16:05 / cg" ! mergReciever: aReceiver WithArgument: arguments @@ -830,6 +970,18 @@ ^receiverWithArgument ! ! +!MethodFinderWindow methodsFor:'misc'! + +aboutThisApplicationText + |msg| + + msg := super aboutThisApplicationText. + msg := msg , '\\Ported from Squeak to ST/X by James Hayes (james@exept.de)'. + ^msg withCRs. + + "Modified: / 13.11.2001 / 12:56:44 / cg" +! ! + !MethodFinderWindow class methodsFor:'documentation'! version