MethodFinderWindow.st
author Claus Gittinger <cg@exept.de>
Sat, 21 Jul 2012 18:58:03 +0200
changeset 2898 c7f6c498df6a
parent 2892 a1349bc5e2fe
child 2927 558cd901ebce
permissions -rw-r--r--
category of:15 methods
     1 "{ Package: 'stx:libtool2' }"
     2 
     3 ApplicationModel subclass:#MethodFinderWindow
     4 	instanceVariableNames:'argumentsEditor messageAnswerEditor receiverEditor receiver
     5 		resultSelectors arg2BoxVisible arg1BoxVisible arg4BoxVisible
     6 		arg3BoxVisible argCountHolder argCountList argument1Editor
     7 		argument2Editor argument3Editor argument4Editor resultSelected
     8 		lookAtResultEditor codeHolder searchProcess'
     9 	classVariableNames:''
    10 	poolDictionaries:''
    11 	category:'Interface-MethodFinder'
    12 !
    13 
    14 !MethodFinderWindow class methodsFor:'documentation'!
    15 
    16 documentation
    17 "
    18   [author:]
    19     ported from Squeak and GUI enhanced by James Hayes james@exept.de
    20 "
    21 ! !
    22 
    23 !MethodFinderWindow class methodsFor:'constants'!
    24 
    25 defaultIcon
    26     ^ ToolbarIconLibrary methodFinder24x24Icon
    27 
    28     "Created: / 01-06-2012 / 13:05:11 / cg"
    29 !
    30 
    31 markerForImplementingClass
    32     ^ '=> '.
    33     ^ '*'
    34 
    35     "Created: / 13.11.2001 / 12:09:52 / cg"
    36     "Modified: / 13.11.2001 / 12:11:57 / cg"
    37 ! !
    38 
    39 !MethodFinderWindow class methodsFor:'interface specs'!
    40 
    41 windowSpec
    42     "This resource specification was automatically generated
    43      by the UIPainter of ST/X."
    44 
    45     "Do not manually edit this!! If it is corrupted,
    46      the UIPainter may not be able to read the specification."
    47 
    48     "
    49      UIPainter new openOnClass:MethodFinderWindow andSelector:#windowSpec
    50      MethodFinderWindow new openInterface:#windowSpec
    51      MethodFinderWindow open
    52     "
    53 
    54     <resource: #canvas>
    55 
    56     ^ 
    57      #(FullSpec
    58         name: windowSpec
    59         window: 
    60        (WindowSpec
    61           label: 'MethodFinder'
    62           name: 'MethodFinder'
    63           bounds: (Rectangle 0 0 798 595)
    64           menu: menu
    65           icon: defaultIcon
    66         )
    67         component: 
    68        (SpecCollection
    69           collection: (
    70            (VariableHorizontalPanelSpec
    71               name: 'VariableHorizontalPanel1'
    72               layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
    73               snapMode: both
    74               component: 
    75              (SpecCollection
    76                 collection: (
    77                  (ViewSpec
    78                     name: 'LeftBox'
    79                     level: 1
    80                     component: 
    81                    (SpecCollection
    82                       collection: (
    83                        (ViewSpec
    84                           name: 'ReceiverArgBox'
    85                           layout: (LayoutFrame 0 0 0 0 0 1 -100 0.5)
    86                           component: 
    87                          (SpecCollection
    88                             collection: (
    89                              (LabelSpec
    90                                 label: 'Receiver'
    91                                 name: 'ReceiverLabel'
    92                                 layout: (LayoutFrame 0 0 0 0 0 0.34 24 0)
    93                                 translateLabel: true
    94                               )
    95                              (ComboListSpec
    96                                 name: 'allowedArgments'
    97                                 layout: (LayoutFrame 0 0.34 1 0 0 0.64 23 0)
    98                                 model: argCountHolder
    99                                 comboList: argCountList
   100                                 useIndex: true
   101                               )
   102                              (LabelSpec
   103                                 label: 'Answer'
   104                                 name: 'MessageAnswerLabel'
   105                                 layout: (LayoutFrame 0 0.64 0 0 0 1 24 0)
   106                                 translateLabel: true
   107                               )
   108                              (HorizontalPanelViewSpec
   109                                 name: 'HorizontalPanel1'
   110                                 layout: (LayoutFrame 0 0 25 0 0 1 0 1)
   111                                 horizontalLayout: fit
   112                                 verticalLayout: fit
   113                                 horizontalSpace: 3
   114                                 verticalSpace: 3
   115                                 component: 
   116                                (SpecCollection
   117                                   collection: (
   118                                    (WorkspaceSpec
   119                                       name: 'ReceiverEditor'
   120                                       tabable: true
   121                                       hasHorizontalScrollBar: true
   122                                       hasVerticalScrollBar: true
   123                                       miniScrollerHorizontal: true
   124                                       miniScrollerVertical: true
   125                                       autoHideScrollBars: true
   126                                       hasKeyboardFocusInitially: false
   127                                       extent: (Point 113 172)
   128                                       postBuildCallback: receiverWidgetCreated:
   129                                     )
   130                                    (VerticalPanelViewSpec
   131                                       name: 'VerticalPanel1'
   132                                       horizontalLayout: fit
   133                                       verticalLayout: fit
   134                                       horizontalSpace: 3
   135                                       verticalSpace: 3
   136                                       component: 
   137                                      (SpecCollection
   138                                         collection: (
   139                                          (ViewSpec
   140                                             name: 'Box1'
   141                                             visibilityChannel: arg1BoxVisible
   142                                             component: 
   143                                            (SpecCollection
   144                                               collection: (
   145                                                (WorkspaceSpec
   146                                                   name: 'Arg1Editor'
   147                                                   layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   148                                                   tabable: true
   149                                                   hasHorizontalScrollBar: true
   150                                                   hasVerticalScrollBar: true
   151                                                   miniScrollerHorizontal: true
   152                                                   miniScrollerVertical: true
   153                                                   autoHideScrollBars: true
   154                                                   hasKeyboardFocusInitially: false
   155                                                   postBuildCallback: argument1WidgetCreated:
   156                                                 )
   157                                                )
   158                                              
   159                                             )
   160                                             extent: (Point 114 55)
   161                                           )
   162                                          (ViewSpec
   163                                             name: 'Box2'
   164                                             visibilityChannel: arg2BoxVisible
   165                                             component: 
   166                                            (SpecCollection
   167                                               collection: (
   168                                                (WorkspaceSpec
   169                                                   name: 'TextEditor5'
   170                                                   layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   171                                                   tabable: true
   172                                                   hasHorizontalScrollBar: true
   173                                                   hasVerticalScrollBar: true
   174                                                   miniScrollerHorizontal: true
   175                                                   miniScrollerVertical: true
   176                                                   autoHideScrollBars: true
   177                                                   hasKeyboardFocusInitially: false
   178                                                   postBuildCallback: argument2WidgetCreated:
   179                                                 )
   180                                                )
   181                                              
   182                                             )
   183                                             extent: (Point 114 56)
   184                                           )
   185                                          (ViewSpec
   186                                             name: 'Box3'
   187                                             visibilityChannel: arg3BoxVisible
   188                                             component: 
   189                                            (SpecCollection
   190                                               collection: (
   191                                                (WorkspaceSpec
   192                                                   name: 'TextEditor6'
   193                                                   layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
   194                                                   tabable: true
   195                                                   hasHorizontalScrollBar: true
   196                                                   hasVerticalScrollBar: true
   197                                                   miniScrollerHorizontal: true
   198                                                   miniScrollerVertical: true
   199                                                   autoHideScrollBars: true
   200                                                   hasKeyboardFocusInitially: false
   201                                                   postBuildCallback: argument3WidgetCreated:
   202                                                 )
   203                                                )
   204                                              
   205                                             )
   206                                             extent: (Point 114 55)
   207                                           )
   208                                          )
   209                                        
   210                                       )
   211                                       extent: (Point 114 172)
   212                                     )
   213                                    (WorkspaceSpec
   214                                       name: 'AnswerEditor'
   215                                       tabable: true
   216                                       hasHorizontalScrollBar: true
   217                                       hasVerticalScrollBar: true
   218                                       miniScrollerHorizontal: true
   219                                       miniScrollerVertical: true
   220                                       autoHideScrollBars: true
   221                                       hasKeyboardFocusInitially: false
   222                                       extent: (Point 114 172)
   223                                       postBuildCallback: messageAnswerWidgetCreated:
   224                                     )
   225                                    )
   226                                  
   227                                 )
   228                               )
   229                              )
   230                            
   231                           )
   232                         )
   233                        (ViewSpec
   234                           name: 'ReceiverArgBoxActionBox'
   235                           layout: (LayoutFrame 0 0 -98 0.5 0 1 -75 0.5)
   236                           component: 
   237                          (SpecCollection
   238                             collection: (
   239                              (ActionButtonSpec
   240                                 label: 'Clear'
   241                                 name: 'Button2'
   242                                 layout: (LayoutFrame 5 0 0 0 -5 0.5 0 1)
   243                                 translateLabel: true
   244                                 model: clear
   245                               )
   246                              (ActionButtonSpec
   247                                 label: 'Search'
   248                                 name: 'Button1'
   249                                 layout: (LayoutFrame 5 0.5 0 0 -5 1 0 1)
   250                                 translateLabel: true
   251                                 tabable: true
   252                                 model: search
   253                               )
   254                              )
   255                            
   256                           )
   257                         )
   258                        (ViewSpec
   259                           name: 'MatchActionBox'
   260                           layout: (LayoutFrame 0 0 -70 0.5 0 1 -20 0.5)
   261                           component: 
   262                          (SpecCollection
   263                             collection: (
   264                              (LabelSpec
   265                                 label: 'Selector Pattern:'
   266                                 name: 'Label1'
   267                                 layout: (LayoutFrame 0 0 0 0 0 0.5 25 0)
   268                                 translateLabel: true
   269                                 adjust: left
   270                               )
   271                              (InputFieldSpec
   272                                 name: 'EntryField1'
   273                                 layout: (LayoutFrame 0 0 -25 1 0 0.5 -5 1)
   274                                 model: selectorPattern
   275                                 immediateAccept: true
   276                                 acceptOnReturn: true
   277                                 acceptOnTab: true
   278                                 acceptOnPointerLeave: true
   279                               )
   280                              (ActionButtonSpec
   281                                 label: 'Search'
   282                                 name: 'Button4'
   283                                 layout: (LayoutFrame 5 0.5 -25 1 -5 1 0 1)
   284                                 translateLabel: true
   285                                 tabable: true
   286                                 model: searchPatternMatches
   287                               )
   288                              )
   289                            
   290                           )
   291                         )
   292                        (SequenceViewSpec
   293                           name: 'ResultList'
   294                           layout: (LayoutFrame 0 0 -15 0.5 0 1 0 1)
   295                           hasHorizontalScrollBar: true
   296                           hasVerticalScrollBar: true
   297                           autoHideScrollBars: true
   298                           valueChangeSelector: updateImplementorsOf:
   299                           useIndex: true
   300                           sequenceList: resultHolder
   301                         )
   302                        )
   303                      
   304                     )
   305                   )
   306                  (VariableVerticalPanelSpec
   307                     name: 'VariableVerticalPanel1'
   308                     component: 
   309                    (SpecCollection
   310                       collection: (
   311                        (SequenceViewSpec
   312                           name: 'List2'
   313                           model: selectedClassOfResultHolder
   314                           menu: implementorListMenu
   315                           hasHorizontalScrollBar: true
   316                           hasVerticalScrollBar: true
   317                           autoHideScrollBars: true
   318                           doubleClickSelector: openBrowserOn:
   319                           valueChangeSelector: selectedClassOfResultHolderChanged
   320                           useIndex: false
   321                           sequenceList: classOfResultHolder
   322                         )
   323                        (CodeViewSpec
   324                           name: 'CodeView'
   325                           model: codeHolder
   326                           hasHorizontalScrollBar: true
   327                           hasVerticalScrollBar: true
   328                           autoHideScrollBars: true
   329                           hasKeyboardFocusInitially: false
   330                           postBuildCallback: sourceCodeWidgetCreated:
   331                         )
   332                        )
   333                      
   334                     )
   335                     handles: (Any 0.5 1.0)
   336                   )
   337                  )
   338                
   339               )
   340               handles: (Any 0.443786982248521 1.0)
   341             )
   342            )
   343          
   344         )
   345       )
   346 ! !
   347 
   348 !MethodFinderWindow class methodsFor:'menu specs'!
   349 
   350 implementorListMenu
   351     "This resource specification was automatically generated
   352      by the MenuEditor of ST/X."
   353 
   354     "Do not manually edit this!! If it is corrupted,
   355      the MenuEditor may not be able to read the specification."
   356 
   357     "
   358      MenuEditor new openOnClass:MethodFinderWindow andSelector:#implementorListMenu
   359      (Menu new fromLiteralArrayEncoding:(MethodFinderWindow implementorListMenu)) startUp
   360     "
   361 
   362     <resource: #menu>
   363 
   364     ^ 
   365      #(#Menu
   366         #(
   367          #(#MenuItem
   368             #label: 'Browse'
   369             #translateLabel: true
   370             #value: #openBrowserOnSelectedItem
   371           )
   372          )
   373         nil
   374         nil
   375       )
   376 !
   377 
   378 menu
   379     "This resource specification was automatically generated
   380      by the MenuEditor of ST/X."
   381 
   382     "Do not manually edit this!! If it is corrupted,
   383      the MenuEditor may not be able to read the specification."
   384 
   385     "
   386      MenuEditor new openOnClass:MethodFinderWindow andSelector:#menu
   387      (Menu new fromLiteralArrayEncoding:(MethodFinderWindow menu)) startUp
   388     "
   389 
   390     <resource: #menu>
   391 
   392     ^ 
   393      #(#Menu
   394         #(
   395          #(#MenuItem
   396             #label: '&File'
   397             #activeHelpKey: #file
   398             #submenu: 
   399            #(#Menu
   400               #(
   401                #(#MenuItem
   402                   #label: 'Exit'
   403                   #value: #closeRequest
   404                   #activeHelpKey: #fileExit
   405                 )
   406                )
   407               nil
   408               nil
   409             )
   410           )
   411          #(#MenuItem
   412             #label: 'Help'
   413             #startGroup: #right
   414             #submenu: 
   415            #(#Menu
   416               #(
   417                #(#MenuItem
   418                   #label: 'Documentation'
   419                   #value: #openHTMLDocumentation
   420                   #activeHelpKey: #helpTutorial
   421                 )
   422                #(#MenuItem
   423                   #label: 'About MethodFinder...'
   424                   #value: #openAboutThisApplication
   425                   #activeHelpKey: #aboutThisAppliaction
   426                 )
   427                )
   428               nil
   429               nil
   430             )
   431           )
   432          )
   433         nil
   434         nil
   435       )
   436 
   437     "Modified: / 13.11.2001 / 12:36:39 / cg"
   438 ! !
   439 
   440 !MethodFinderWindow methodsFor:'accessing'!
   441 
   442 receiver
   443     "Return a copy of the value of the instance variable 'receiver' "
   444 
   445     ^ receiver copy
   446 ! !
   447 
   448 !MethodFinderWindow methodsFor:'actions'!
   449 
   450 argumentEditorsContents
   451 
   452 "Determine how many text editors of the arguments are used and store the result
   453 as argCounter. The result being the minimum between how many editors have
   454 expressions in and how many are displayed.
   455 
   456 Add each argument string (key)and the evaluated version (value) to an Ordered Dictionary
   457 from each of the text editors.
   458 
   459 Return the OrderedDictionary with the expressions from all the text editors. "
   460 
   461      | tempArguments argCounter tempArgument1Editor tempArgument2Editor tempArgument3Editor
   462 associationKey associationValue|
   463 
   464 argCounter:=0.
   465 
   466 tempArgument1Editor:= (self cleanInputs: argument1Editor contents).
   467 tempArgument2Editor:=  (self cleanInputs: argument2Editor contents).
   468 tempArgument3Editor:= (self cleanInputs: argument3Editor contents).
   469 
   470 tempArgument1Editor = '' ifFalse:[argCounter:=argCounter +1].
   471 tempArgument2Editor = '' ifFalse:[argCounter:=argCounter +1].
   472 tempArgument3Editor = '' ifFalse:[argCounter:=argCounter +1].
   473 
   474 
   475 argCounter:= (argCounter min: (self argCountHolder value -1)).
   476 tempArguments:= OrderedDictionary new:argCounter. 
   477 
   478 (argCounter value >= 1) 
   479                 ifTrue:[associationValue:= (Compiler evaluate: tempArgument1Editor).
   480                         ((self isExpression:tempArgument1Editor) or:[ associationValue isNil]) ifTrue:[                  "looks if an expression is typed in"
   481                                         associationKey:=associationValue printString]
   482                                                           ifFalse:[
   483                                         associationKey:=tempArgument1Editor].
   484 
   485                         tempArguments add: associationKey-> associationValue.
   486                         ].
   487 (argCounter value >= 2) 
   488                 ifTrue:[ associationValue:= (Compiler evaluate: tempArgument2Editor).
   489                         (((self isExpression:tempArgument2Editor) or:[ associationValue isNil])) ifTrue:[                  "looks if an expression is typed in"
   490                                         associationKey:=associationValue printString]
   491                                                           ifFalse:[
   492                                         associationKey:=tempArgument2Editor].
   493 
   494                         tempArguments add: associationKey-> associationValue].
   495 
   496 (argCounter value >= 3)
   497                 ifTrue:[ associationValue:= (Compiler evaluate: tempArgument3Editor).
   498                         ((self isExpression:tempArgument3Editor) or:[ associationValue isNil]) ifTrue:[                  "looks if an expression is typed in"
   499                                         associationKey:=associationValue printString]
   500                                                           ifFalse:[
   501                                         associationKey:=tempArgument3Editor].
   502 
   503                         tempArguments add: associationKey-> associationValue].
   504 
   505 
   506 ^tempArguments
   507 !
   508 
   509 clear
   510     "Reset the contents of all the outputs. Return the receiver."
   511 
   512     receiverEditor contents:nil.
   513     argument1Editor contents:nil.
   514     argument2Editor contents:nil.
   515     argument3Editor contents:nil.
   516     messageAnswerEditor contents:nil.
   517     self resultHolder value:nil.
   518     self classOfResultHolder value: nil.
   519     codeHolder value:nil.
   520 !
   521 
   522 extractClassAndSelectorFrom:anArgument 
   523     "Opens browser on theArgument of a specific class. anArgument being a string with the
   524        Class and the selector upon which the browser is to be opened. Return the receiver."
   525 
   526     |aClass aSelector x theArgument marker|
   527 
   528     anArgument isNil ifTrue:[
   529         ^ nil
   530     ].
   531     marker := self class markerForImplementingClass.
   532 
   533     theArgument := anArgument string.
   534     (theArgument startsWith:marker) ifTrue:[
   535         theArgument := theArgument copyFrom:marker size+1
   536     ].
   537     aClass := theArgument copyUpTo:(Character space).
   538     x := aClass size + 2.
   539     aSelector := theArgument copyFrom:x.
   540     aClass := Smalltalk classNamed:aClass.
   541     (aSelector startsWith:'class ') ifTrue:[
   542         aSelector := aSelector copyFrom:'class 'size+1.
   543         aClass := aClass class.
   544     ].
   545     ^ aClass -> aSelector asSymbol
   546 
   547 "
   548 MethodFinderWindow new extractClassAndSelectorFrom: '*SmallInteger +'
   549 MethodFinderWindow new extractClassAndSelectorFrom: 'String ,'       
   550 MethodFinderWindow new extractClassAndSelectorFrom: 'Number detentBy:atMultiplesOf:snap:' 
   551 
   552 
   553 "
   554 
   555     "Modified: / 27-04-2012 / 15:05:53 / cg"
   556 !
   557 
   558 isExpression: aString
   559       "Return true or false depending on if the subString includes certain characters"
   560 (aString includesSubString:': ') ifTrue:[^true].
   561 (aString includesSubString:'+') ifTrue:[^true].
   562 (aString includesSubString:'-') ifTrue:[^true].
   563 (aString includesSubString:'*') ifTrue:[^true].
   564 (aString includesSubString:'/') ifTrue:[^true].
   565 (aString includesSubString:'>') ifTrue:[^true].
   566 (aString includesSubString:'<') ifTrue:[^true].
   567 (aString includesSubString:' new') ifTrue:[^true].
   568 (aString includesSubString:'[') &  (aString includesSubString:']') & (aString includesSubString:'.')
   569                                 ifTrue:[^false].
   570 (aString includesSubString:'.') ifTrue:[^true].
   571 
   572  ^false
   573 !
   574 
   575 messageAnswerEditorContents
   576    "Return a cleaned up version of message answer taken from the messageAnswerEditor
   577     as an association. The association has cleanedAnswerString as a key and the 
   578     compiledAnswer as value."
   579 
   580     |   aCleanedAnswerString   compiledAnswer  |
   581 
   582 aCleanedAnswerString:=self cleanInputs: (messageAnswerEditor contents). 
   583 compiledAnswer:=Compiler evaluate: aCleanedAnswerString.
   584 ((self isExpression:aCleanedAnswerString) or:[compiledAnswer isNil]) ifTrue:[
   585                         aCleanedAnswerString:=compiledAnswer printString].
   586 
   587 ^aCleanedAnswerString->compiledAnswer.
   588 !
   589 
   590 openBrowserOn:anArgument 
   591     "Opens browser on theArgument of a specific class. anArgument being a string with the
   592        Class and the selector upon which the browser is to be opened. Return the receiver."
   593 
   594     |classAndSelector|
   595 
   596     classAndSelector := self extractClassAndSelectorFrom:anArgument.
   597     classAndSelector isNil ifTrue:[
   598         ^ self
   599     ].
   600     UserPreferences current systemBrowserClass
   601         openInClass:classAndSelector key 
   602         selector:classAndSelector value   
   603 
   604 "
   605 MethodFinderWindow new openBrowserOn: '*SmallInteger +'
   606 MethodFinderWindow new openBrowserOn: 'String ,'
   607 MethodFinderWindow new openBrowserOn: 'Number detentBy:atMultiplesOf:snap:' 
   608 
   609 
   610 "
   611 
   612     "Modified: / 13.11.2001 / 12:46:17 / cg"
   613 !
   614 
   615 openBrowserOnSelectedItem 
   616     |sel|
   617 
   618     sel := self selectedClassOfResultHolder value.
   619     self openBrowserOn:sel
   620 
   621     "Modified: / 13.11.2001 / 12:47:39 / cg"
   622 !
   623 
   624 receiverEditorContents
   625    "Return a cleaned up version of receiver taken from the receiverEditor
   626     as an association. The association has aCleanedRecieverString as a key and the 
   627     compiledReceiver as value."
   628 
   629     |   aCleanedRecieverString   compiledReceiver  |
   630 
   631 aCleanedRecieverString:=self cleanInputs: (receiverEditor contents). 
   632 
   633 compiledReceiver:=Compiler evaluate: aCleanedRecieverString.
   634 
   635 ((self isExpression:aCleanedRecieverString) or:[compiledReceiver isNil]) ifTrue:[
   636                         aCleanedRecieverString:=compiledReceiver printString].
   637 ^aCleanedRecieverString->compiledReceiver.
   638 !
   639 
   640 search
   641 "Do a search based on the input in the various text editors. Return the receiver."
   642 | tempReceiver tempAnswer tempArguments anArray resultArray receiverWithArgument mf|
   643 
   644 self resultHolder value: nil.                "reset the result list"
   645 self classOfResultHolder value: nil.        "reset the implementorOf list"
   646 self codeHolder value: nil.                  "reset the source"
   647 
   648 tempArguments:=self argumentEditorsContents.
   649 tempReceiver :=self receiverEditorContents .  
   650 tempAnswer:= self messageAnswerEditorContents.   
   651 
   652 "self cleanInputRec:tempReceiver arg:tempArguments ans:tempAnswer."
   653 
   654 
   655 anArray:=Array new:2.  "creates an array which is to be used as input for the method finder."
   656 
   657 receiverWithArgument:=self mergReciever: (tempReceiver value) WithArgument: (tempArguments values).
   658 
   659 anArray at:1 put:receiverWithArgument;
   660         at:2 put: tempAnswer value.             
   661 
   662 "an array now holds the following array #(#(receiver argument) answer) or #(#(reciever) answer). which should
   663 be suitable input for the method finder."
   664 self withCursor:Cursor execute do:[
   665     mf:= MethodFinder new.
   666     resultArray:= mf load: anArray; findMessage. 
   667 ].
   668 
   669 ((resultArray at:  1 )includesSubString: 'no single') ifTrue:[
   670                                 self warn: (resultArray at:  1 ).
   671                                 ^self
   672                                                               ].  
   673 "the following then replaces data1 and data2 created by the method finder to the appropriate arguments"
   674 
   675 resultArray keysAndValuesDo:[:key :value |   | newValue | 
   676       newValue:= value replString: 'data1' withString:(tempReceiver key).
   677 (tempArguments size) >= 1 ifTrue:[
   678       newValue:= newValue replString: 'data2' withString:(tempArguments keyAt:1)].
   679 
   680 (tempArguments size) > 1 ifTrue:[
   681       newValue:= newValue replString: 'data3' withString:(tempArguments keyAt:2).].
   682 
   683 (tempArguments size) > 2 ifTrue:[
   684       newValue:= newValue replString: 'data4' withString:(tempArguments keyAt:3).].
   685 
   686 (tempArguments size) > 3 ifTrue:[ self halt:'unimplemented'. ].
   687 
   688 
   689                         "    newValue:= value replString: 'data3' withString:(self messageAnswer key). " 
   690 
   691       newValue:=newValue, ' --> ', (tempAnswer key).
   692       newValue replaceAll:Character cr with:Character space.
   693 
   694       resultArray at: key put: newValue.
   695 
   696               ].
   697 
   698 self resultHolder value: resultArray.
   699 resultSelectors:= mf selectors.   "used to find implementors so we do not have to "
   700 receiver:=tempReceiver            "search the string for the selector found. Stored as an ordered collection"
   701 
   702     "Modified: / 26-09-2011 / 12:42:28 / cg"
   703 !
   704 
   705 searchPatternChanged
   706     "/ self searchPatternMatches
   707     self searchPatternMatchesInBackground
   708 
   709     "Created: / 01-06-2012 / 13:18:16 / cg"
   710 !
   711 
   712 searchPatternMatches
   713     "Do a search based on the pattern match"
   714 
   715     | pattern list selectors counts|
   716 
   717     pattern := self selectorPattern value.
   718 
   719     self resultHolder value: nil.                "reset the result list"
   720     self classOfResultHolder value: nil.        "reset the implementorOf list"
   721     self codeHolder value: nil.                  "reset the source"
   722 
   723     self withCursor:Cursor execute do:[
   724         pattern includesMatchCharacters ifFalse:[   
   725             pattern := '*',pattern,'*'
   726         ].
   727         list := SystemBrowser findImplementorsMatching:pattern in:Smalltalk allClasses ignoreCase:true.
   728     ].
   729 
   730     counts := IdentityDictionary new.
   731     selectors := IdentitySet new.
   732 
   733     list do:[:eachMethod |
   734         selectors add: eachMethod selector.
   735         (counts at:(eachMethod selector) ifAbsentPut:[0 asValue]) increment
   736     ].
   737 
   738     resultSelectors := selectors asOrderedCollection sort.
   739 
   740     self resultHolder value: (resultSelectors collect:[:sel | sel,' --> ',(counts at:sel) value printString,' implementor(s)']).
   741 
   742     "Created: / 27-04-2012 / 14:46:35 / cg"
   743 !
   744 
   745 searchPatternMatchesInBackground
   746     "Do a search based on the pattern match"
   747 
   748     | p pattern list|
   749 
   750     (p := searchProcess) notNil ifTrue:[
   751         searchProcess := nil.
   752         p terminate.
   753     ].
   754 
   755     searchProcess := 
   756         [
   757             pattern := self selectorPattern value.
   758 
   759             self withCursor:Cursor execute do:[
   760                 pattern includesMatchCharacters ifFalse:[   
   761                     pattern := '*',pattern,'*'
   762                 ].
   763                 list := SystemBrowser findImplementorsMatching:pattern in:Smalltalk allClasses ignoreCase:true.
   764             ].
   765             self enqueueDelayedAction:[ self updateListAfterPatternSearch: list ]
   766         ] fork.
   767 
   768     "Created: / 01-06-2012 / 13:16:54 / cg"
   769 !
   770 
   771 selectedClassOfResultHolderChanged
   772     |sel classAndSelector mthd|
   773 
   774     sel := self selectedClassOfResultHolder value.
   775 
   776     classAndSelector := self extractClassAndSelectorFrom:sel.
   777     classAndSelector isNil ifTrue:[
   778         ^ self
   779     ].
   780     mthd := classAndSelector key >> classAndSelector value.   
   781     mthd notNil ifTrue:[
   782         self withWaitCursorDo:[
   783             self codeHolder value:mthd source
   784         ]
   785     ] ifFalse:[
   786         self codeHolder value:nil
   787     ].
   788 
   789     "Created: / 13.11.2001 / 12:43:43 / cg"
   790     "Modified: / 13.11.2001 / 12:48:56 / cg"
   791 !
   792 
   793 updateImplementorsOf:anInteger 
   794     "Request the implementors of the selected argument provided by aNumber.
   795      Return the receiver."
   796     
   797     |methods classList aNumber|
   798 
   799     (anInteger isNil) ifTrue:[
   800         ^ self
   801     ].
   802     anInteger isNil ifTrue:[
   803         aNumber := 1
   804     ] ifFalse:[
   805         aNumber := anInteger
   806     ].
   807     methods := SystemBrowser 
   808             findImplementorsOf:(resultSelectors at:aNumber)
   809             in:Smalltalk allClasses
   810             ignoreCase:false.
   811     classList := methods asOrderedCollection 
   812             collect:[:m | m mclass name , ' ' , m selector ].
   813     classList := (self markMatchingClasses:(resultSelectors at:aNumber)
   814             classesWithSelector:classList).
   815     self classOfResultHolder value:classList.
   816     classList size > 0 ifTrue:[
   817         self selectedClassOfResultHolder value:(classList first).
   818         self selectedClassOfResultHolderChanged.
   819     ] ifFalse:[
   820         self selectedClassOfResultHolder value:nil.
   821     ].
   822 
   823     "Modified (comment): / 24-06-2012 / 18:41:45 / cg"
   824 !
   825 
   826 updateListAfterPatternSearch:list 
   827     "Do a search based on the pattern match"
   828     
   829     |selectors counts firsts|
   830 
   831     self resultHolder value:nil.
   832     self classOfResultHolder value:nil.
   833     self codeHolder value:nil.
   834     counts := IdentityDictionary new.
   835     firsts := IdentityDictionary new.
   836     selectors := IdentitySet new.
   837     list do:[:eachMethod | 
   838         selectors add:eachMethod selector.
   839         (counts at:(eachMethod selector) ifAbsentPut:[ 0 asValue ]) increment.
   840         firsts at:(eachMethod selector) ifAbsentPut:[ eachMethod mclass ].
   841     ].
   842     resultSelectors := selectors asOrderedCollection sort.
   843     self resultHolder value:(resultSelectors 
   844                 collect:[:sel | 
   845                     |cnt|
   846 
   847                     cnt := (counts at:sel) value.
   848                     cnt == 1 ifTrue:[
   849                         sel , ' --> ' , (firsts at:sel) name
   850                     ] ifFalse:[
   851                         sel , ' --> ' , cnt printString , ' implementor(s)'
   852                     ].
   853                 ]).
   854 
   855     "Created: / 01-06-2012 / 13:17:34 / cg"
   856 ! !
   857 
   858 !MethodFinderWindow methodsFor:'aspects'!
   859 
   860 arg1BoxVisible
   861 "Determines if the box should be visble or not. Return true or false"
   862     arg1BoxVisible isNil ifTrue:[
   863         arg1BoxVisible := BlockValue
   864                               with:[:vh | vh value >= 2 ]
   865                               argument:(self argCountHolder)
   866     ].
   867     ^ arg1BoxVisible.
   868 !
   869 
   870 arg2BoxVisible
   871 "Determines if the box should be visble or not. Return true or false"
   872     arg2BoxVisible isNil ifTrue:[
   873         arg2BoxVisible := BlockValue
   874                               with:[:vh | vh value >= 3 ]
   875                               argument:(self argCountHolder)
   876     ].
   877     ^ arg2BoxVisible.
   878 !
   879 
   880 arg3BoxVisible
   881 "Determines if the box should be visble or not. Return true or false"
   882     arg3BoxVisible isNil ifTrue:[
   883         arg3BoxVisible := BlockValue
   884                               with:[:vh | vh value >= 4 ]
   885                               argument:(self argCountHolder)
   886     ].
   887     ^ arg3BoxVisible.
   888 !
   889 
   890 arg4BoxVisible
   891 "Determines if the box should be visble or not. Return true or false"
   892     arg4BoxVisible isNil ifTrue:[
   893         arg4BoxVisible := BlockValue
   894                               with:[:vh | vh value >= 5 ]
   895                               argument:(self argCountHolder)
   896     ].
   897     ^ arg4BoxVisible.
   898 !
   899 
   900 argCountHolder
   901 "Return the value of argCounterHolder which is initialized at 2."
   902     argCountHolder isNil ifTrue:[
   903         argCountHolder := 2 asValue.
   904     ].     
   905     ^ argCountHolder.
   906 !
   907 
   908 argCountList
   909 "Return the argCountList"
   910     argCountList isNil ifTrue:[
   911         argCountList := #('0 arguments' '1 argument' '2 arguments' '3 arguments') asValue  
   912     ].
   913     ^ argCountList.
   914 !
   915 
   916 classOfResultHolder
   917     "Return a valueHolder which contains a collection with the names of the 
   918      implementors of a specific message.   "
   919 
   920     |holder|
   921     (holder := builder bindingAt:#classOfResultHolder) isNil ifTrue:[
   922         holder := ValueHolder new.
   923         builder aspectAt:#classOfResultHolder put:holder
   924     ].
   925     ^ holder
   926 !
   927 
   928 codeHolder
   929     codeHolder isNil ifTrue:[
   930         codeHolder := '' asValue.
   931     ].
   932     ^ codeHolder.
   933 
   934     "Created: / 13.11.2001 / 12:44:11 / cg"
   935 !
   936 
   937 resultHolder
   938     "Return a value holder which contains the results of a search as a collection."
   939 
   940     |holder|
   941     (holder := builder bindingAt:#resultHolder) isNil ifTrue:[
   942         holder := ValueHolder new.
   943         builder aspectAt:#resultHolder put:holder.
   944         holder value:{
   945                         'Please enter combination of' .
   946                         '    ',('receiver, arg and result' allBold) .
   947                         'or a'.
   948                         '    ',('selector search pattern' allBold) .
   949                         'into the above fields, then click on either ',('"search"' allBold),'-button.'
   950                      }
   951     ].
   952     ^ holder.
   953 
   954     "Modified: / 01-06-2012 / 13:06:02 / cg"
   955 !
   956 
   957 selectedClassOfResultHolder
   958     "Return a valueHolder which contains the index of the selected result class
   959      (right list)"
   960 
   961     |holder|
   962     (holder := builder bindingAt:#selectedClassOfResultHolder) isNil ifTrue:[
   963         holder := ValueHolder new.
   964         builder aspectAt:#selectedClassOfResultHolder put:holder
   965     ].
   966     ^ holder
   967 !
   968 
   969 selectorPattern
   970     |holder|
   971     (holder := builder bindingAt:#selectorPattern) isNil ifTrue:[
   972         holder := ValueHolder new.
   973         builder aspectAt:#selectorPattern put:holder.
   974         holder onChangeSend:#searchPatternChanged to:self.
   975     ].
   976     ^ holder
   977 
   978     "Created: / 27-04-2012 / 14:44:01 / cg"
   979 ! !
   980 
   981 !MethodFinderWindow methodsFor:'callBacks'!
   982 
   983 argument1WidgetCreated: aWidget
   984 "Store the widget as an instance variable. Return the receiver"
   985 
   986 
   987         argument1Editor := aWidget scrolledView.
   988         aWidget tabMeansNextField:true.
   989 
   990     "Modified: / 13.11.2001 / 12:21:41 / cg"
   991 !
   992 
   993 argument2WidgetCreated: aWidget
   994 "Store the widget as an instance variable. Return the receiver"
   995 
   996 
   997         argument2Editor := aWidget scrolledView.
   998         aWidget tabMeansNextField:true.
   999 
  1000     "Modified: / 13.11.2001 / 12:21:45 / cg"
  1001 !
  1002 
  1003 argument3WidgetCreated: aWidget
  1004 "Store the widget as an instance variable. Return the receiver"
  1005 
  1006 
  1007         argument3Editor := aWidget scrolledView.
  1008         aWidget tabMeansNextField:true.
  1009 
  1010     "Modified: / 13.11.2001 / 12:21:49 / cg"
  1011 !
  1012 
  1013 messageAnswerWidgetCreated: aWidget
  1014 "Store the widget as an instance variable. Return the receiver"
  1015 
  1016         messageAnswerEditor := aWidget scrolledView.
  1017         aWidget tabMeansNextField:true.
  1018 
  1019     "Modified: / 13.11.2001 / 12:24:55 / cg"
  1020 !
  1021 
  1022 openHTMLDocumentation
  1023     HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#METHODFINDER'
  1024 !
  1025 
  1026 receiverWidgetCreated: aWidget
  1027 "Store the widget as an instance variable. Return the receiver"
  1028 
  1029         receiverEditor := aWidget scrolledView.
  1030         aWidget tabMeansNextField:true.
  1031 
  1032     "Modified: / 13.11.2001 / 12:24:49 / cg"
  1033 !
  1034 
  1035 sourceCodeWidgetCreated: aWidget
  1036         aWidget acceptAction:nil.
  1037         aWidget readOnly:true
  1038 
  1039     "Created: / 13.11.2001 / 12:50:27 / cg"
  1040     "Modified: / 13.11.2001 / 12:51:23 / cg"
  1041 ! !
  1042 
  1043 !MethodFinderWindow methodsFor:'controlInput'!
  1044 
  1045 cleanInputs: aDirtyString
  1046      "Find and remove common mistakes made by the user. Return the 
  1047      'aStringToBeCleaned' variable"
  1048        | aStringToBeCleaned rs position|
  1049 
  1050    aStringToBeCleaned:=aDirtyString.
  1051 
  1052 (aStringToBeCleaned endsWith:(Character cr)) ifTrue:[
  1053                         aStringToBeCleaned:=aStringToBeCleaned copyFrom:1 to: (aStringToBeCleaned size -1).].
  1054 aStringToBeCleaned:= aStringToBeCleaned withoutSeparators.
  1055 
  1056 
  1057 rs:=ReadStream on: aStringToBeCleaned.
  1058 [rs upToAll: '#true'.  rs atEnd] whileFalse: [
  1059                         position:= rs position. 
  1060                         aStringToBeCleaned:=aStringToBeCleaned copyReplaceFrom: position to: position with: ''. "remove #"
  1061                         rs:=ReadStream on: aStringToBeCleaned.
  1062                         ].
  1063 
  1064 rs:=ReadStream on: aStringToBeCleaned.
  1065 [rs upToAll: '#false'.  rs atEnd] whileFalse: [
  1066                         position:= rs position. 
  1067                         aStringToBeCleaned:=aStringToBeCleaned copyReplaceFrom: position to: position with: ''. "remove #"
  1068                         rs:=ReadStream on: aStringToBeCleaned.
  1069                         rs:=ReadStream on: aStringToBeCleaned. ].
  1070 
  1071 [rs upToAll: '#nil'.  rs atEnd] whileFalse: [
  1072                         position:= rs position. 
  1073                         aStringToBeCleaned:=aStringToBeCleaned copyReplaceFrom: position to: position with: ''. "remove #"
  1074                         rs:=ReadStream on: aStringToBeCleaned.  ].
  1075                    ^aStringToBeCleaned    
  1076 !
  1077 
  1078 markMatchingClasses: aSelector  classesWithSelector:anOrderedCollection
  1079    " Matches the class of the receiver with all the elements in anOrderedCollection
  1080     (which are classes with selectors). If a match is found it is marked with an asterisk. 
  1081     The classes are then sorted so the the asterisk appears first. Return the 
  1082     markedClassList."
  1083 
  1084         | marker recClass unmarkedClassList markedClassList|
  1085 
  1086         marker := self class markerForImplementingClass.
  1087 
  1088         recClass := receiver value class.
  1089         unmarkedClassList:=anOrderedCollection copy.
  1090         unmarkedClassList do:
  1091                 [:classAndMethod | | class |
  1092                 class:=Compiler evaluate:
  1093                                 ((ReadStream on: classAndMethod) upToAll: aSelector).
  1094                 "/ (recClass == class)
  1095                 (recClass whichClassImplements:aSelector) == class
  1096                 ifTrue:
  1097                         ["/ unmarkedClassList add: marker, classAndMethod.
  1098                         unmarkedClassList add: classAndMethod allBold.
  1099                         unmarkedClassList remove: classAndMethod.
  1100                         ].
  1101         ].
  1102 
  1103       unmarkedClassList sort:[:a :b | |rawA rawB|
  1104                     rawA := a string.
  1105                     (rawA startsWith:marker) ifTrue:[rawA := rawA copyFrom:marker size+1].
  1106                     rawB := b string.
  1107                     (rawB startsWith:marker) ifTrue:[rawB := rawB copyFrom:marker size+1].
  1108                     rawA < rawB.  ].
  1109       markedClassList:= unmarkedClassList. 
  1110 
  1111          ^markedClassList
  1112 
  1113     "Modified: / 13.11.2001 / 12:16:05 / cg"
  1114 !
  1115 
  1116 mergReciever: aReceiver WithArgument: arguments
  1117 
  1118 "Puts the receiver and arguments into an array so it can be of a suitable input for the
  1119  MethodFinder. Return an array."
  1120 
  1121 | tempReceiver tempArguments receiverWithArgument|
  1122 
  1123   tempReceiver:= aReceiver.
  1124  tempArguments :=  arguments.
  1125 
  1126 (tempArguments isEmpty or:[(tempArguments) isNil])
  1127                 ifTrue:[  receiverWithArgument:=Array new:1."no argument"
  1128                           receiverWithArgument at:1 put: tempReceiver.     
  1129                         ]
  1130                 ifFalse:[
  1131         (tempArguments size = 1)
  1132                         ifTrue:[ receiverWithArgument:=Array new:2.
  1133                                   receiverWithArgument at:1 put: tempReceiver.      
  1134                                   receiverWithArgument at:2 put: (tempArguments at:1)
  1135                                 ].  "a receiver with an argument"
  1136 
  1137         (tempArguments size = 2)
  1138                         ifTrue:[ receiverWithArgument:=Array new:3.
  1139                                   receiverWithArgument at:1 put: tempReceiver.      
  1140                                   (receiverWithArgument at:2 put: (tempArguments at:1)).
  1141                                   (receiverWithArgument at:3 put: (tempArguments at:2))
  1142                                 ].  "a receiver with an argument"
  1143         (tempArguments size = 3)
  1144                         ifTrue:[ receiverWithArgument:=Array new:4.
  1145                                   receiverWithArgument at:1 put: tempReceiver.      
  1146                                   (receiverWithArgument at:2 put: (tempArguments at:1)).
  1147                                   (receiverWithArgument at:3 put: (tempArguments at:2)).
  1148                                   (receiverWithArgument at:4 put: (tempArguments at:3)).
  1149 
  1150                                 ].  "a receiver with an argument"
  1151 
  1152                         ].
  1153 ^receiverWithArgument
  1154 ! !
  1155 
  1156 !MethodFinderWindow methodsFor:'misc'!
  1157 
  1158 aboutThisApplicationText
  1159     |msg|
  1160 
  1161     msg := super aboutThisApplicationText.
  1162     msg := msg , '\\Ported from Squeak to ST/X by James Hayes (james@exept.de).
  1163 Original written by Ted Kaehler, Scott Wallace and Dan Ingalls.'.
  1164     ^msg withCRs.
  1165 
  1166     "Modified: / 13.11.2001 / 12:56:44 / cg"
  1167 ! !
  1168 
  1169 !MethodFinderWindow class methodsFor:'documentation'!
  1170 
  1171 version
  1172     ^ '$Header$'
  1173 !
  1174 
  1175 version_CVS
  1176     ^ '$Header$'
  1177 ! !