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