SBrowser.st
changeset 52 7b48409ae088
parent 49 6fe62433cfa3
child 53 2fc78a0165e7
equal deleted inserted replaced
51:57c1ccc3d7e0 52:7b48409ae088
     1 "{ Package: 'Programming Tools' }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1989 by Claus Gittinger
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     5 	      All Rights Reserved
     3 	      All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
    10  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    11  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    12  hereby transferred.
    10  hereby transferred.
    13 "
    11 "
    14 
    12 
       
    13 'From Smalltalk/X, Version:2.10.4 on 7-nov-1994 at 14:56:27'!
       
    14 
    15 StandardSystemView subclass:#SystemBrowser
    15 StandardSystemView subclass:#SystemBrowser
    16        instanceVariableNames:'classCategoryListView classListView
    16 	 instanceVariableNames:'classCategoryListView classListView methodCategoryListView
    17 			      methodCategoryListView methodListView
    17 		methodListView classMethodListView codeView classToggle
    18 			      classMethodListView
    18 		instanceToggle currentClassCategory currentClassHierarchy
    19 			      codeView classToggle instanceToggle
    19 		currentClass currentMethodCategory currentMethod currentSelector
    20 			      currentClassCategory currentClassHierarchy
    20 		showInstance actualClass fullClass lastMethodCategory aspect
    21 			      currentClass
    21 		variableListView fullProtocol lockUpdates autoSearch myLabel'
    22 			      currentMethodCategory currentMethod
    22 	 classVariableNames:'CheckForInstancesWhenRemovingClasses'
    23 			      showInstance actualClass fullClass
    23 	 poolDictionaries:''
    24 			      lastMethodCategory aspect variableListView'
    24 	 category:'Interface-Browsers'
    25        classVariableNames:''
       
    26        poolDictionaries:''
       
    27        category:'Interface-Browsers'
       
    28 !
    25 !
    29 
    26 
    30 SystemBrowser comment:'
    27 SystemBrowser comment:'
    31 COPYRIGHT (c) 1989 by Claus Gittinger
    28 COPYRIGHT (c) 1989 by Claus Gittinger
    32 	     All Rights Reserved
    29 	     All Rights Reserved
    33 
    30 
    34 $Header: /cvs/stx/stx/libtool/Attic/SBrowser.st,v 1.14 1994-10-28 03:29:32 claus Exp $
    31 $Header: /cvs/stx/stx/libtool/Attic/SBrowser.st,v 1.15 1994-11-17 14:47:02 claus Exp $
    35 '!
    32 '!
    36 
    33 
    37 !SystemBrowser class methodsFor:'documentation'!
    34 !SystemBrowser class methodsFor:'documentation'!
    38 
    35 
    39 copyright
    36 copyright
    50 "
    47 "
    51 !
    48 !
    52 
    49 
    53 version
    50 version
    54 "
    51 "
    55 $Header: /cvs/stx/stx/libtool/Attic/SBrowser.st,v 1.14 1994-10-28 03:29:32 claus Exp $
    52 $Header: /cvs/stx/stx/libtool/Attic/SBrowser.st,v 1.15 1994-11-17 14:47:02 claus Exp $
    56 "
    53 "
    57 !
    54 !
    58 
    55 
    59 documentation
    56 documentation
    60 "
    57 "
    61     this class implements all kinds of class browsers.
    58     this class implements all kinds of class browsers.
    62     Stypically, it is started with SystemBrowser open, but there are many other startup
    59     Typically, it is started with 'SystemBrowser open', but there are many other 
    63     messages, to launch special browsers.
    60     startup messages, to launch special browsers.
    64     See the extra document 'doc/misc/sbrowser.doc' for how to use this browser.
    61     See the categories 'startup' and 'special search startup' in the classes
       
    62     protocol.
       
    63 
       
    64     Alse, see the extra document 'doc/misc/sbrowser.doc' or the HTML online doc
       
    65     for how to use the browser.
    65 
    66 
    66     written winter 89 by claus
    67     written winter 89 by claus
    67 "
    68 "
    68 ! !
    69 ! !
    69 
    70 
    70 !SystemBrowser class methodsFor:'general startup'!
    71 !SystemBrowser class methodsFor:'initialization'!
    71 
    72 
    72 open
    73 initialize
    73     "launch a standard browser"
    74     "SystemBrowser configuration;
    74 
    75      (values can be changed from your private startup file)"
    75     ^ self openOnDisplay:Display
    76 
    76 
    77     "
    77     "SystemBrowser open"
    78      setting this to false, the removeClass function will remove
    78 !
    79      classes WITHOUT checking for instances. Otherwise,
    79 
    80      it will check and let you confirm in case there are instances.
    80 openOnDisplay:aDisplay
    81      Checking for instances may be a bit time consuming, though.
    81     "launch a standard browser on another display.
    82      The default is true - therefore, it will check
    82      Does not work currently - still being developped."
    83     "
    83 
    84     CheckForInstancesWhenRemovingClasses := true
    84     ^ self newWithLabel:(self classResources string:'System Browser')
    85 
    85 	     setupBlock:[:browser | browser setupForAll]
    86     "
    86 		     on:aDisplay
    87      CheckForInstancesWhenRemovingClasses := true
    87 
    88      CheckForInstancesWhenRemovingClasses := false
    88     "
       
    89      SystemBrowser openOnDisplay:(XWorkstation new initializeFor:'porty:0')
       
    90     "
    89     "
    91 ! !
    90 ! !
    92 
    91 
    93 !SystemBrowser class methodsFor:'startup'!
    92 !SystemBrowser class methodsFor:'startup'!
    94 
    93 
    95 browseFullClasses
       
    96     "launch a browser showing all methods at once"
       
    97 
       
    98     ^ self newWithLabel:'Full Class Browser'
       
    99 	     setupBlock:[:browser | browser setupForFullClass]
       
   100 
       
   101     "SystemBrowser browseFullClasses"
       
   102 !
       
   103 
       
   104 browseClassCategory:aClassCategory
       
   105     "launch a browser for all classes under aCategory"
       
   106 
       
   107     ^ self newWithLabel:aClassCategory
       
   108 	     setupBlock:[:browser | browser setupForClassCategory:aClassCategory]
       
   109 
       
   110     "SystemBrowser browseClassCategory:'Kernel-Objects'"
       
   111 !
       
   112 
       
   113 browseClass:aClass
       
   114     "launch a browser for aClass"
       
   115 
       
   116     ^ self newWithLabel:aClass name
       
   117 	     setupBlock:[:browser | browser setupForClass:aClass]
       
   118 
       
   119     "SystemBrowser browseClass:Object"
       
   120 !
       
   121 
       
   122 browseClassHierarchy:aClass
       
   123     "launch a browser for aClass and all its superclasses"
       
   124 
       
   125     ^ self newWithLabel:(aClass name , '-' , 'hierarchy')
       
   126 	     setupBlock:[:browser | browser setupForClassHierarchy:aClass]
       
   127 
       
   128     "SystemBrowser browseClassHierarchy:Number"
       
   129 !
       
   130 
       
   131 browseClasses:aList title:title
       
   132     "launch a browser for all classes in aList"
       
   133 
       
   134     ^ self newWithLabel:title
       
   135 	     setupBlock:[:browser | browser setupForClassList:aList]
       
   136 
       
   137     "
       
   138      SystemBrowser browseClasses:(Array with:Object
       
   139 					with:Float)
       
   140 			   title:'two classes'
       
   141     "
       
   142 !
       
   143 
       
   144 browseClass:aClass methodCategory:aCategory
       
   145     "launch a browser for all methods under aCategory in aClass"
       
   146 
       
   147     ^ self newWithLabel:(aClass name , ' ' , aCategory)
       
   148 	  setupBlock:[:browser | browser setupForClass:aClass methodCategory:aCategory]
       
   149 
       
   150     "SystemBrowser browseClass:String methodCategory:'copying'"
       
   151 !
       
   152 
       
   153 browseClass:aClass selector:selector
       
   154     "launch a browser for the method at selector in aClass"
       
   155 
       
   156     ^ self newWithLabel:(aClass name , ' ' , selector)
       
   157 	  setupBlock:[:browser | browser setupForClass:aClass selector:selector]
       
   158 
       
   159     "SystemBrowser browseClass:Object selector:#printString"
       
   160 !
       
   161 
       
   162 browseMethods:aList title:aString
    94 browseMethods:aList title:aString
   163     "launch a browser for an explicit list of class/selectors"
    95     "launch a browser for an explicit list of class/selectors.
       
    96      Each entry in the list must consist of the classes name and the selector,
       
    97      separated by spaces. For class methods, the string 'class' must be
       
    98      appended to the classname."
   164 
    99 
   165     (aList size == 0) ifTrue:[
   100     (aList size == 0) ifTrue:[
   166 	self showNoneFound:aString.
   101 	self showNoneFound:aString.
   167 	^ nil
   102 	^ nil
   168     ].
   103     ].
   173     "
   108     "
   174      SystemBrowser browseMethods:#('Object printOn:' 
   109      SystemBrowser browseMethods:#('Object printOn:' 
   175 				   'Collection add:')
   110 				   'Collection add:')
   176 			   title:'some methods'
   111 			   title:'some methods'
   177     "
   112     "
   178 !
   113     "
   179 
   114      SystemBrowser browseMethods:#('Behavior new:' 
   180 browseMethodCategory:aCategory
   115 				   'Setclass new:')
   181     "launch a browser for all methods where category = aCategory"
   116 			   title:'some new: methods'
   182 
   117     "
   183     |searchBlock|
   118 
   184 
       
   185     aCategory includesMatchCharacters ifTrue:[
       
   186 	searchBlock := [:c :m :s | aCategory match:m category].
       
   187     ] ifFalse:[
       
   188 	searchBlock := [:c :m :s | m category = aCategory]
       
   189     ].
       
   190 
       
   191     self browseMethodsWhere:searchBlock title:('all methods with category of ' , aCategory)
       
   192 
       
   193     "
       
   194      SystemBrowser browseMethodCategory:'printing & storing'
       
   195      SystemBrowser browseMethodCategory:'print*'
       
   196     "
       
   197 !
       
   198 
       
   199 browseAllSelect:aBlock
       
   200     "launch a browser for all methods where aBlock returns true.
       
   201      The block is called with 3 arguments, class, method and seelctor."
       
   202 
       
   203     ^ self browseMethodsWhere:aBlock title:'selected messages'
       
   204 !
       
   205 
       
   206 browseMethodsWhere:aBlock title:title
       
   207     "launch a browser for all methods where aBlock returns true.
       
   208      The block is called with 3 arguments, class, method and seelctor."
       
   209 
       
   210     ^ self browseMethodsIn:(Smalltalk allClasses) where:aBlock title:title
       
   211 !
       
   212 
       
   213 browseMethodsOf:aClass where:aBlock title:title
       
   214     "launch a browser for all instance- and classmethods in aClass 
       
   215      where aBlock evaluates to true.
       
   216      The block is called with 3 arguments, class, method and seelctor."
       
   217 
       
   218     ^ self browseMethodsIn:(Array with:aClass) where:aBlock title:title
       
   219 !
       
   220 
       
   221 browseMethodsFrom:aClass where:aBlock title:title
       
   222     "launch a browser for all instance- and classmethods in aClass
       
   223      and all its subclasses where aBlock evaluates to true.
       
   224      The block is called with 3 arguments, class, method and seelctor."
       
   225 
       
   226     ^ self browseMethodsIn:(aClass withAllSubclasses) where:aBlock title:title
       
   227 !
       
   228 
       
   229 browseMethodsIn:aCollectionOfClasses where:aBlock title:title
       
   230     "launch a browser for all instance- and classmethods from 
       
   231      all classes in aCollectionOfClasses where aBlock evaluates to true.
       
   232      The block is called with 3 arguments, class, method and seelctor."
       
   233 
       
   234     ^ self browseMethodsIn:aCollectionOfClasses inst:true class:true where:aBlock title:title
       
   235 !
   119 !
   236 
   120 
   237 browseMethodsIn:aCollectionOfClasses inst:wantInst class:wantClass where:aBlock title:title
   121 browseMethodsIn:aCollectionOfClasses inst:wantInst class:wantClass where:aBlock title:title
   238     "launch a browser for all instance- (if wantInst is true) and/or
   122     "launch a browser for all instance- (if wantInst is true) and/or
   239      classmethods (if wantClass is true) from classes in aCollectionOfClasses,
   123      classmethods (if wantClass is true) from classes in aCollectionOfClasses,
   270 		checkedClasses add:cls.
   154 		checkedClasses add:cls.
   271 	    ]
   155 	    ]
   272 	].
   156 	].
   273 
   157 
   274 	aCollectionOfClasses do:[:aClass |
   158 	aCollectionOfClasses do:[:aClass |
       
   159 	    "
       
   160 	     output disabled - it slows down things too much (when searching for
       
   161 	     implementors or senders)
       
   162 	    "
   275 "/            Transcript show:'searching '; show:aClass name; showCr:' ...'; endEntry.
   163 "/            Transcript show:'searching '; show:aClass name; showCr:' ...'; endEntry.
   276 	    wantInst ifTrue:[checkBlock value:aClass].
   164 	    wantInst ifTrue:[checkBlock value:aClass].
   277 	    wantClass ifTrue:[checkBlock value:(aClass class)].
   165 	    wantClass ifTrue:[checkBlock value:(aClass class)].
   278 	    Processor yield
   166 	    Processor yield
   279 	]
   167 	]
   280     ].
   168     ].
   281 
   169 
   282     ^ self browseMethods:list title:title
   170     ^ self browseMethods:list title:title
   283 !
   171 !
   284 
   172 
       
   173 browseMethodsIn:aCollectionOfClasses where:aBlock title:title
       
   174     "launch a browser for all instance- and classmethods from 
       
   175      all classes in aCollectionOfClasses where aBlock evaluates to true.
       
   176      The block is called with 3 arguments, class, method and seelctor."
       
   177 
       
   178     ^ self browseMethodsIn:aCollectionOfClasses inst:true class:true where:aBlock title:title
       
   179 !
       
   180 
       
   181 browseClassCategory:aClassCategory
       
   182     "launch a browser for all classes under aCategory"
       
   183 
       
   184     ^ self newWithLabel:aClassCategory
       
   185 	     setupBlock:[:browser | browser setupForClassCategory:aClassCategory]
       
   186 
       
   187     "SystemBrowser browseClassCategory:'Kernel-Objects'"
       
   188 !
       
   189 
       
   190 browseFullClasses
       
   191     "launch a browser showing all methods at once"
       
   192 
       
   193     ^ self newWithLabel:'Full Class Browser'
       
   194 	     setupBlock:[:browser | browser setupForFullClass]
       
   195 
       
   196     "SystemBrowser browseFullClasses"
       
   197 !
       
   198 
       
   199 browseClass:aClass
       
   200     "launch a browser for aClass"
       
   201 
       
   202     ^ self newWithLabel:aClass name
       
   203 	     setupBlock:[:browser | browser setupForClass:aClass]
       
   204 
       
   205     "SystemBrowser browseClass:Object"
       
   206 !
       
   207 
       
   208 browseClass:aClass selector:selector
       
   209     "launch a browser for the method at selector in aClass"
       
   210 
       
   211     ^ self 
       
   212 	newWithLabel:(aClass name , ' ' , selector , ' ' , selector)
       
   213 	setupBlock:[:browser | browser setupForClass:aClass selector:selector]
       
   214 
       
   215     "
       
   216      SystemBrowser browseClass:Object selector:#printString
       
   217     "
       
   218 !
       
   219 
       
   220 browseClassHierarchy:aClass
       
   221     "launch a browser for aClass and all its superclasses.
       
   222      this is different from the fullProtocol browser."
       
   223 
       
   224     ^ self newWithLabel:(aClass name , '-' , 'hierarchy')
       
   225 	     setupBlock:[:browser | browser setupForClassHierarchy:aClass]
       
   226 
       
   227     "
       
   228      SystemBrowser browseClassHierarchy:Number
       
   229     "
       
   230 !
       
   231 
       
   232 browseFullClassProtocol:aClass
       
   233     "launch a browser for aClasses full protocol.
       
   234      This is different from hierarchy browsing."
       
   235 
       
   236     ^ self newWithLabel:(aClass name , '-' , 'full protocol')
       
   237 	     setupBlock:[:browser | browser setupForFullClassProtocol:aClass]
       
   238 
       
   239     "
       
   240      SystemBrowser browseFullClassProtocol:Number
       
   241     "
       
   242 !
       
   243 
       
   244 browseClasses:aList title:title
       
   245     "launch a browser for all classes in aList"
       
   246 
       
   247     ^ self newWithLabel:title
       
   248 	     setupBlock:[:browser | browser setupForClassList:aList]
       
   249 
       
   250     "
       
   251      SystemBrowser browseClasses:(Array with:Object
       
   252 					with:Float)
       
   253 			   title:'two classes'
       
   254     "
       
   255 !
       
   256 
       
   257 browseClass:aClass methodCategory:aCategory
       
   258     "launch a browser for all methods under aCategory in aClass"
       
   259 
       
   260     ^ self newWithLabel:(aClass name , ' ' , aCategory)
       
   261 	  setupBlock:[:browser | browser setupForClass:aClass methodCategory:aCategory]
       
   262 
       
   263     "SystemBrowser browseClass:String methodCategory:'copying'"
       
   264 !
       
   265 
       
   266 browseMethodCategory:aCategory
       
   267     "launch a browser for all methods where category = aCategory"
       
   268 
       
   269     |searchBlock|
       
   270 
       
   271     aCategory includesMatchCharacters ifTrue:[
       
   272 	searchBlock := [:c :m :s | aCategory match:m category].
       
   273     ] ifFalse:[
       
   274 	searchBlock := [:c :m :s | m category = aCategory]
       
   275     ].
       
   276 
       
   277     self browseMethodsWhere:searchBlock title:('all methods with category of ' , aCategory)
       
   278 
       
   279     "
       
   280      SystemBrowser browseMethodCategory:'printing & storing'
       
   281      SystemBrowser browseMethodCategory:'print*'
       
   282     "
       
   283 !
       
   284 
       
   285 browseAllSelect:aBlock
       
   286     "launch a browser for all methods where aBlock returns true.
       
   287      The block is called with 3 arguments, class, method and seelctor."
       
   288 
       
   289     ^ self browseMethodsWhere:aBlock title:'selected messages'
       
   290 
       
   291     "
       
   292      SystemBrowser browseAllSelect:[:aClass :aMethod :selector | selector numArgs == 3]
       
   293     "
       
   294 !
       
   295 
       
   296 browseMethodsWhere:aBlock title:title
       
   297     "launch a browser for all methods where aBlock returns true.
       
   298      The block is called with 3 arguments, class, method and seelctor."
       
   299 
       
   300     ^ self browseMethodsIn:(Smalltalk allClasses) where:aBlock title:title
       
   301 !
       
   302 
       
   303 browseMethodsOf:aClass where:aBlock title:title
       
   304     "launch a browser for all instance- and classmethods in aClass 
       
   305      where aBlock evaluates to true.
       
   306      The block is called with 3 arguments, class, method and seelctor."
       
   307 
       
   308     ^ self browseMethodsIn:(Array with:aClass) where:aBlock title:title
       
   309 !
       
   310 
       
   311 browseMethodsFrom:aClass where:aBlock title:title
       
   312     "launch a browser for all instance- and classmethods in aClass
       
   313      and all its subclasses where aBlock evaluates to true.
       
   314      The block is called with 3 arguments, class, method and seelctor."
       
   315 
       
   316     ^ self browseMethodsIn:(aClass withAllSubclasses) where:aBlock title:title
       
   317 !
       
   318 
   285 browseInstMethodsOf:aClass where:aBlock title:title
   319 browseInstMethodsOf:aClass where:aBlock title:title
   286     "launch a browser for all instance methods in aClass
   320     "launch a browser for all instance methods in aClass
   287      where aBlock evaluates to true"
   321      where aBlock evaluates to true"
   288 
   322 
   289     ^ self browseMethodsIn:(Array with:aClass) inst:true class:false where:aBlock title:title
   323     ^ self browseMethodsIn:(Array with:aClass) inst:true class:false where:aBlock title:title
   290 !
   324 !
   291 
   325 
       
   326 browseInstMethodsIn:aCollectionOfClasses where:aBlock title:title
       
   327     "launch a browser for all instance methods of all classes in
       
   328      aCollectionOfClasses where aBlock evaluates to true"
       
   329 
       
   330     ^ self browseMethodsIn:aCollectionOfClasses inst:true class:false 
       
   331 		     where:aBlock title:title
       
   332 !
       
   333 
   292 browseInstMethodsFrom:aClass where:aBlock title:title
   334 browseInstMethodsFrom:aClass where:aBlock title:title
   293     "launch a browser for all instance methods in aClass and all subclasses
   335     "launch a browser for all instance methods in aClass and all subclasses
   294      where aBlock evaluates to true"
   336      where aBlock evaluates to true"
   295 
   337 
   296     ^ self browseMethodsIn:(aClass withAllSubclasses) inst:true class:false where:aBlock title:title
   338     ^ self browseMethodsIn:(aClass withAllSubclasses) inst:true class:false where:aBlock title:title
   297 !
   339 !
   298 
   340 
   299 browseInstMethodsIn:aCollectionOfClasses where:aBlock title:title
   341 browseFullClassHierarchy:aClass
   300     "launch a browser for all instance methods of all classes in
   342     "launch a browser for aClass and all its superclasses"
   301      aCollectionOfClasses where aBlock evaluates to true"
   343 
   302 
   344     ^ self newWithLabel:(aClass name , '-' , 'full protocol')
   303     ^ self browseMethodsIn:aCollectionOfClasses inst:true class:false 
   345 	     setupBlock:[:browser | browser setupForFullClassHierarchy:aClass]
   304 		     where:aBlock title:title
   346 
       
   347     "
       
   348      SystemBrowser browseFullClassHierarchy:Number
       
   349     "
   305 ! !
   350 ! !
   306 
   351 
   307 !SystemBrowser class methodsFor:'special search startup'!
   352 !SystemBrowser class methodsFor:'special search startup'!
   308 
       
   309 browseImplementorsOf:aSelectorString in:aCollectionOfClasses title:title
       
   310     "launch a browser for all implementors of aSelector in
       
   311      the classes contained in aCollectionOfClasses and its metaclasses"
       
   312 
       
   313     |list sel|
       
   314 
       
   315     list := OrderedCollection new.
       
   316 
       
   317     ((aSelectorString ~= '*') and:[aSelectorString includesMatchCharacters]) ifTrue:[
       
   318 	"a matchString"
       
   319 
       
   320 	aCollectionOfClasses do:[:aClass |
       
   321 	    aClass selectorArray do:[:aSelector |
       
   322 		(aSelectorString match:aSelector) ifTrue:[
       
   323 		    list add:(aClass name , ' ' , aSelector)
       
   324 		]
       
   325 	    ].
       
   326 	    aClass class selectorArray do:[:aSelector |
       
   327 		(aSelectorString match:aSelector) ifTrue:[
       
   328 		    list add:(aClass name , 'class ' , aSelector)
       
   329 		]
       
   330 	    ]
       
   331 	]
       
   332     ] ifFalse:[
       
   333 	"can do a faster search"
       
   334 
       
   335 	aSelectorString knownAsSymbol ifFalse:[
       
   336 	    self showNoneFound:title.
       
   337 	    ^ nil
       
   338 	].
       
   339 
       
   340 	sel := aSelectorString asSymbol.
       
   341 	aCollectionOfClasses do:[:aClass |
       
   342 	    (aClass implements:sel) ifTrue:[
       
   343 		list add:(aClass name , ' ' , aSelectorString)
       
   344 	    ].
       
   345 	    (aClass class implements:sel) ifTrue:[
       
   346 		list add:(aClass name , 'class ' , aSelectorString)
       
   347 	    ]
       
   348 	]
       
   349     ].
       
   350     ^ self browseMethods:list title:title
       
   351 
       
   352     "
       
   353      SystemBrowser browseImplementorsOf:#+
       
   354 				     in:(Array with:Number
       
   355 					       with:Float
       
   356 					       with:SmallInteger)
       
   357 				  title:'some implementors of +'
       
   358     "
       
   359 !
       
   360 
       
   361 browseImplementorsOf:aSelectorString
       
   362     "launch a browser for all implementors of aSelector"
       
   363 
       
   364     ^ self browseImplementorsOf:aSelectorString
       
   365 			     in:(Smalltalk allClasses)
       
   366 			  title:('implementors of: ' , aSelectorString)
       
   367 
       
   368     "
       
   369      SystemBrowser browseImplementorsOf:#+
       
   370     "
       
   371 !
       
   372 
       
   373 browseImplementorsOf:aSelectorString under:aClass
       
   374     "launch a browser for all implementors of aSelector in aClass
       
   375      and its subclasses"
       
   376 
       
   377     ^ self browseImplementorsOf:aSelectorString
       
   378 			     in:(aClass withAllSubclasses)
       
   379 			  title:('implementors of: ' , 
       
   380 				 aSelectorString , 
       
   381 				 ' (in or below ' , aClass name , ')')
       
   382 
       
   383     "
       
   384      SystemBrowser browseImplementorsOf:#+ under:Integer
       
   385     "
       
   386 !
       
   387 
   353 
   388 browseAllCallsOn:aSelectorString in:aCollectionOfClasses title:title
   354 browseAllCallsOn:aSelectorString in:aCollectionOfClasses title:title
   389     "launch a browser for all senders of aSelector in aCollectionOfClasses"
   355     "launch a browser for all senders of aSelector in aCollectionOfClasses"
   390 
   356 
   391     |sel browser searchBlock|
   357     |sel browser searchBlock|
   424 				  where:[:class :method :s | method sends:sel]
   390 				  where:[:class :method :s | method sends:sel]
   425 				  title:title
   391 				  title:title
   426     ].
   392     ].
   427 
   393 
   428     browser notNil ifTrue:[
   394     browser notNil ifTrue:[
   429 	browser setSearchPattern:aSelectorString
   395 	|s|
       
   396 
       
   397 	"
       
   398 	 kludge for now, if its a multipart selector,
       
   399 	 no easy search is (as yet) possible
       
   400 	"
       
   401 	s := aSelectorString.
       
   402 	(s includes:$:) ifTrue:[
       
   403 	    s := s copyTo:(s indexOf:$:)
       
   404 	].
       
   405 	browser autoSearch:s 
   430     ].
   406     ].
   431     ^ browser
   407     ^ browser
       
   408 !
       
   409 
       
   410 browseImplementorsOf:aSelectorString
       
   411     "launch a browser for all implementors of aSelector"
       
   412 
       
   413     ^ self browseImplementorsOf:aSelectorString
       
   414 			     in:(Smalltalk allClasses)
       
   415 			  title:('implementors of: ' , aSelectorString)
       
   416 
       
   417     "
       
   418      SystemBrowser browseImplementorsOf:#+
       
   419     "
       
   420 !
       
   421 
       
   422 browseImplementorsOf:aSelectorString in:aCollectionOfClasses title:title
       
   423     "launch a browser for all implementors of aSelector in
       
   424      the classes contained in aCollectionOfClasses and its metaclasses"
       
   425 
       
   426     |list sel|
       
   427 
       
   428     list := OrderedCollection new.
       
   429 
       
   430     ((aSelectorString ~= '*') and:[aSelectorString includesMatchCharacters]) ifTrue:[
       
   431 	"a matchString"
       
   432 
       
   433 	aCollectionOfClasses do:[:aClass |
       
   434 	    aClass selectorArray do:[:aSelector |
       
   435 		(aSelectorString match:aSelector) ifTrue:[
       
   436 		    list add:(aClass name , ' ' , aSelector)
       
   437 		]
       
   438 	    ].
       
   439 	    aClass class selectorArray do:[:aSelector |
       
   440 		(aSelectorString match:aSelector) ifTrue:[
       
   441 		    list add:(aClass name , 'class ' , aSelector)
       
   442 		]
       
   443 	    ]
       
   444 	]
       
   445     ] ifFalse:[
       
   446 	"can do a faster search"
       
   447 
       
   448 	aSelectorString knownAsSymbol ifFalse:[
       
   449 	    self showNoneFound:title.
       
   450 	    ^ nil
       
   451 	].
       
   452 
       
   453 	sel := aSelectorString asSymbol.
       
   454 	aCollectionOfClasses do:[:aClass |
       
   455 	    (aClass implements:sel) ifTrue:[
       
   456 		list add:(aClass name , ' ' , aSelectorString)
       
   457 	    ].
       
   458 	    (aClass class implements:sel) ifTrue:[
       
   459 		list add:(aClass name , 'class ' , aSelectorString)
       
   460 	    ]
       
   461 	]
       
   462     ].
       
   463     ^ self browseMethods:list title:title
       
   464 
       
   465     "
       
   466      SystemBrowser browseImplementorsOf:#+
       
   467 				     in:(Array with:Number
       
   468 					       with:Float
       
   469 					       with:SmallInteger)
       
   470 				  title:'some implementors of +'
       
   471     "
   432 !
   472 !
   433 
   473 
   434 browseAllCallsOn:aSelectorString
   474 browseAllCallsOn:aSelectorString
   435     "launch a browser for all senders of aSelector"
   475     "launch a browser for all senders of aSelector"
   436 
   476 
   452 			     aSelectorString , 
   492 			     aSelectorString , 
   453 			     ' (in or below ' , aClass name , ')')
   493 			     ' (in or below ' , aClass name , ')')
   454 
   494 
   455     "
   495     "
   456      SystemBrowser browseAllCallsOn:#+ under:Number
   496      SystemBrowser browseAllCallsOn:#+ under:Number
       
   497     "
       
   498 !
       
   499 
       
   500 browseImplementorsOf:aSelectorString under:aClass
       
   501     "launch a browser for all implementors of aSelector in aClass
       
   502      and its subclasses"
       
   503 
       
   504     ^ self browseImplementorsOf:aSelectorString
       
   505 			     in:(aClass withAllSubclasses)
       
   506 			  title:('implementors of: ' , 
       
   507 				 aSelectorString , 
       
   508 				 ' (in or below ' , aClass name , ')')
       
   509 
       
   510     "
       
   511      SystemBrowser browseImplementorsOf:#+ under:Integer
   457     "
   512     "
   458 !
   513 !
   459 
   514 
   460 browseForSymbol:aSymbol title:title warnIfNone:doWarn
   515 browseForSymbol:aSymbol title:title warnIfNone:doWarn
   461     "launch a browser for all methods referencing aSymbol"
   516     "launch a browser for all methods referencing aSymbol"
   505 			    found
   560 			    found
   506 		       ].
   561 		       ].
   507     ].
   562     ].
   508     browser := self browseMethodsWhere:[:c :m :s | searchBlock value:(m literals)] title:title.
   563     browser := self browseMethodsWhere:[:c :m :s | searchBlock value:(m literals)] title:title.
   509     browser notNil ifTrue:[
   564     browser notNil ifTrue:[
   510 	browser setSearchPattern:aSymbol
   565 	browser autoSearch:aSymbol
   511     ].
   566     ].
   512     ^ browser
   567     ^ browser
   513 !
   568 !
   514 
   569 
   515 browseForSymbol:aSymbol
   570 filterToSearchInstRefsTo:varName modificationsOnly:modsOnly
   516     "launch a browser for all methods referencing aSymbol"
   571     "return a block to search for instvar accesses"
   517 
   572 
   518     ^ self browseForSymbol:aSymbol title:('users of ' , aSymbol) warnIfNone:true
   573     |searchBlock|
   519 !
       
   520 
       
   521 browseReferendsOf:aGlobalName warnIfNone:doWarn
       
   522     "launch a browser for all methods referencing a global
       
   523      named aGlobalName.
       
   524     "
       
   525 
       
   526     ^ self browseForSymbol:aGlobalName title:('users of: ' , aGlobalName) warnIfNone:doWarn 
       
   527 !
       
   528 
       
   529 browseReferendsOf:aGlobalName
       
   530     "launch a browser for all methods referencing a global
       
   531      named aGlobalName.
       
   532     "
       
   533 
       
   534     ^ self browseReferendsOf:aGlobalName warnIfNone:true 
       
   535 
       
   536    "
       
   537     Browser browseReferendsOf:#Transcript
       
   538    "
       
   539 !
       
   540 
       
   541 browseForString:aString in:aCollectionOfClasses
       
   542     "launch a browser for all methods in aCollectionOfClasses  
       
   543      containing a string-constant"
       
   544 
       
   545     |browser searchBlock title|
       
   546 
       
   547     title := 'methods containing: ' , aString displayString.
       
   548 
       
   549     (aString includesMatchCharacters) ifTrue:[
       
   550 	"a matchString"
       
   551 	searchBlock := [:lits |
       
   552 			    |found|
       
   553 
       
   554 			    found := false.
       
   555 			    lits notNil ifTrue:[
       
   556 				lits do:[:aLiteral |
       
   557 				    found ifFalse:[
       
   558 					(aLiteral isMemberOf:String) ifTrue:[
       
   559 					    found := (aString match:aLiteral)
       
   560 					]
       
   561 				    ]
       
   562 				]
       
   563 			    ].
       
   564 			    found
       
   565 		       ].
       
   566     ] ifFalse:[
       
   567 	searchBlock := [:lits |
       
   568 			    |found|
       
   569 
       
   570 			    found := false.
       
   571 			    lits notNil ifTrue:[
       
   572 				lits do:[:aLiteral |
       
   573 				    found ifFalse:[
       
   574 					(aLiteral isMemberOf:String) ifTrue:[
       
   575 					    found := (aLiteral = aString)
       
   576 					]
       
   577 				    ]
       
   578 				]
       
   579 			    ].
       
   580 			    found
       
   581 		       ].
       
   582     ].
       
   583     browser := self browseMethodsIn:aCollectionOfClasses 
       
   584 			      where:[:c :m :s | searchBlock value:(m literals)] 
       
   585 			      title:title.
       
   586 
       
   587     browser notNil ifTrue:[
       
   588 	browser setSearchPattern:aString
       
   589     ].
       
   590     ^ browser
       
   591 
       
   592     "SystemBrowser browseForString:'*all*'"
       
   593     "SystemBrowser browseForString:'*should*'"
       
   594     "SystemBrowser browseForString:'*[eE]rror*'"
       
   595 !
       
   596 
       
   597 browseForString:aString
       
   598     "launch a browser for all methods containing a string"
       
   599 
       
   600     ^ self browseForString:aString in:(Smalltalk allClasses)
       
   601 !
       
   602 
       
   603 aproposSearch:aString in:aCollectionOfClasses
       
   604     "browse all methods, which have aString in their selector or
       
   605      in the methods comment.
       
   606      This is relatively slow, since all source must be processed."
       
   607 
       
   608     |matchString list|
       
   609 
       
   610     matchString := '*' , aString , '*'.
       
   611 
       
   612     list := OrderedCollection new.
       
   613 
       
   614     ^ self browseMethodsIn:aCollectionOfClasses 
       
   615 		     where:[:class :method :sel |
       
   616 				(matchString match:sel) ifTrue:[
       
   617 				    list add:(class name , '>>' , sel)
       
   618 				] ifFalse:[
       
   619 				    (matchString match:(method comment)) ifTrue:[
       
   620 					list add:(class name , '>>' , sel)
       
   621 				    ]
       
   622 				].
       
   623 				Processor yield.
       
   624 			   ]
       
   625 		     title:('apropos: ' , aString)
       
   626 
       
   627     "SystemBrowser aproposSearch:'append'"
       
   628     "SystemBrowser aproposSearch:'add'"
       
   629     "SystemBrowser aproposSearch:'sort'"
       
   630 !
       
   631 
       
   632 aproposSearch:aString
       
   633     "browse all methods, which have aString in their selector or
       
   634      in the methods comment.
       
   635      This is relatively slow, since all source must be processed."
       
   636 
       
   637     ^ self aproposSearch:aString in:(Smalltalk allClasses)
       
   638 !
       
   639 
       
   640 browseInstRefsTo:varName in:aCollectionOfClasses modificationsOnly:modsOnly title:title
       
   641     "launch a browser for all methods in aClass where the instVar named
       
   642      varName is referenced; if modsOnly is true, browse only methods where the
       
   643      instvar is modified"
       
   644 
       
   645     |searchBlock browser needMatch|
       
   646 
       
   647     needMatch := varName includesMatchCharacters.
       
   648 
   574 
   649     searchBlock := [:c :m :s |
   575     searchBlock := [:c :m :s |
   650 	|src result parser instvars|
   576 	|src result parser instvars needMatch|
       
   577 
       
   578 	needMatch := varName includesMatchCharacters.
   651 
   579 
   652 	src := m source.
   580 	src := m source.
   653 	src isNil ifTrue:[
   581 	src isNil ifTrue:[
   654 	    result := false
   582 	    result := false
   655 	] ifFalse:[
   583 	] ifFalse:[
   684 	    ].
   612 	    ].
   685 	].
   613 	].
   686 	Processor yield.
   614 	Processor yield.
   687 	result
   615 	result
   688     ].
   616     ].
   689     browser := self browseInstMethodsIn:aCollectionOfClasses where:searchBlock title:title.
   617     ^ searchBlock
       
   618 !
       
   619 
       
   620 browseForSymbol:aSymbol
       
   621     "launch a browser for all methods referencing aSymbol"
       
   622 
       
   623     ^ self browseForSymbol:aSymbol title:('users of ' , aSymbol) warnIfNone:true
       
   624 !
       
   625 
       
   626 browseReferendsOf:aGlobalName warnIfNone:doWarn
       
   627     "launch a browser for all methods referencing a global
       
   628      named aGlobalName.
       
   629     "
       
   630 
       
   631     ^ self browseForSymbol:aGlobalName title:('users of: ' , aGlobalName) warnIfNone:doWarn 
       
   632 !
       
   633 
       
   634 browseReferendsOf:aGlobalName
       
   635     "launch a browser for all methods referencing a global
       
   636      named aGlobalName.
       
   637     "
       
   638 
       
   639     ^ self browseReferendsOf:aGlobalName warnIfNone:true 
       
   640 
       
   641    "
       
   642     Browser browseReferendsOf:#Transcript
       
   643    "
       
   644 !
       
   645 
       
   646 browseUsesOf:aClass
       
   647     |dict owners offsets
       
   648      sz  "{ Class: SmallInteger }"
       
   649      n   "{ Class: SmallInteger }"
       
   650      removeSet newDict|
       
   651 
       
   652     owners := ObjectMemory whoReferencesInstancesOf:aClass.
       
   653 
       
   654     "
       
   655      collect set of offsets in dict; key is class
       
   656     "
       
   657     dict := IdentityDictionary new.
       
   658     owners do:[:someObject |
       
   659 	|cls create|
       
   660 
       
   661 	someObject isContext ifFalse:[
       
   662 	    "
       
   663 	     someObject refers to an instance of aClass;
       
   664 	     find out, which instVar(s)
       
   665 	    "
       
   666 	    cls := someObject class.
       
   667 	    cls ~~ Array ifTrue:[
       
   668 		n := cls instSize.
       
   669 		create := [|s| s := Set new. dict at:cls put:s. s].
       
   670 
       
   671 		1 to:n do:[:i |
       
   672 		    |ref|
       
   673 
       
   674 		    ref := someObject instVarAt:i.
       
   675 		    (ref isMemberOf:aClass) ifTrue:[
       
   676 			offsets := dict at:cls ifAbsent:create.
       
   677 			offsets add:i.
       
   678 		    ]
       
   679 		].
       
   680 		cls isVariable ifTrue:[
       
   681 		    cls isPointers ifTrue:[
       
   682 			| idx "{ Class: SmallInteger }" |
       
   683 
       
   684 			sz := someObject basicSize.
       
   685 			idx := 1.
       
   686 			[idx <= sz] whileTrue:[
       
   687 			    |ref|
       
   688 
       
   689 			    ref := someObject basicAt:idx.
       
   690 			    (ref isMemberOf:aClass) ifTrue:[
       
   691 				offsets := dict at:cls ifAbsent:create.
       
   692 				offsets add:0.
       
   693 				idx := sz
       
   694 			    ].
       
   695 			    idx := idx + 1
       
   696 			]
       
   697 		    ]        
       
   698 		]
       
   699 	    ]
       
   700 	]
       
   701     ].
       
   702 
       
   703     "
       
   704      merge with superclass refs
       
   705     "
       
   706     dict keysAndValuesDo:[:cls :set |
       
   707 	cls allSuperclasses do:[:aSuperclass |
       
   708 	    |superSet|
       
   709 
       
   710 	    superSet := dict at:aSuperclass ifAbsent:[].
       
   711 	    superSet notNil ifTrue:[
       
   712 		|removeSet|
       
   713 
       
   714 		superSet := dict at:aSuperclass.
       
   715 		removeSet := Set new.
       
   716 		set do:[:offset |
       
   717 		    (superSet includes:offset) ifTrue:[
       
   718 			removeSet add:offset
       
   719 		    ]
       
   720 		].
       
   721 		set removeAll:removeSet
       
   722 	    ]
       
   723 	]
       
   724     ].
       
   725 
       
   726     "
       
   727      remove empty ones
       
   728     "
       
   729     removeSet := Set new.
       
   730     dict keysAndValuesDo:[:cls :set |
       
   731 	set isEmpty ifTrue:[
       
   732 	    removeSet add:cls
       
   733 	]
       
   734     ].
       
   735     removeSet do:[:cls |
       
   736 	dict removeKey:cls
       
   737     ].
       
   738 
       
   739     "
       
   740      replace the indices by real names
       
   741     "
       
   742     newDict := IdentityDictionary new.
       
   743     dict keysAndValuesDo:[:cls :set |
       
   744 	|newSet names|
       
   745 
       
   746 	names := cls allInstVarNames.
       
   747 	newSet := set collect:[:index | 
       
   748 		index == 0 ifTrue:['*indexed*'] ifFalse:[names at:index].
       
   749 	].
       
   750 	newDict at:cls put:newSet
       
   751     ].
       
   752 
       
   753     newDict inspect
       
   754 
       
   755 !
       
   756 
       
   757 browseForString:aString in:aCollectionOfClasses
       
   758     "launch a browser for all methods in aCollectionOfClasses  
       
   759      containing a string-constant"
       
   760 
       
   761     |browser searchBlock title|
       
   762 
       
   763     title := 'methods containing: ' , aString displayString.
       
   764 
       
   765     (aString includesMatchCharacters) ifTrue:[
       
   766 	"a matchString"
       
   767 	searchBlock := [:lits |
       
   768 			    |found|
       
   769 
       
   770 			    found := false.
       
   771 			    lits notNil ifTrue:[
       
   772 				lits do:[:aLiteral |
       
   773 				    found ifFalse:[
       
   774 					(aLiteral isMemberOf:String) ifTrue:[
       
   775 					    found := (aString match:aLiteral)
       
   776 					]
       
   777 				    ]
       
   778 				]
       
   779 			    ].
       
   780 			    found
       
   781 		       ].
       
   782     ] ifFalse:[
       
   783 	searchBlock := [:lits |
       
   784 			    |found|
       
   785 
       
   786 			    found := false.
       
   787 			    lits notNil ifTrue:[
       
   788 				lits do:[:aLiteral |
       
   789 				    found ifFalse:[
       
   790 					(aLiteral isMemberOf:String) ifTrue:[
       
   791 					    found := (aLiteral = aString)
       
   792 					]
       
   793 				    ]
       
   794 				]
       
   795 			    ].
       
   796 			    found
       
   797 		       ].
       
   798     ].
       
   799     browser := self browseMethodsIn:aCollectionOfClasses 
       
   800 			      where:[:c :m :s | searchBlock value:(m literals)] 
       
   801 			      title:title.
   690 
   802 
   691     browser notNil ifTrue:[
   803     browser notNil ifTrue:[
   692 	browser setSearchPattern:varName
   804 	browser autoSearch:aString
   693     ].
   805     ].
   694     ^ browser
   806     ^ browser
       
   807 
       
   808     "SystemBrowser browseForString:'*all*'"
       
   809     "SystemBrowser browseForString:'*should*'"
       
   810     "SystemBrowser browseForString:'*[eE]rror*'"
       
   811 !
       
   812 
       
   813 browseForString:aString
       
   814     "launch a browser for all methods containing a string"
       
   815 
       
   816     ^ self browseForString:aString in:(Smalltalk allClasses)
       
   817 !
       
   818 
       
   819 browseInstRefsTo:varName in:aCollectionOfClasses modificationsOnly:modsOnly title:title
       
   820     "launch a browser for all methods in aClass where the instVar named
       
   821      varName is referenced; if modsOnly is true, browse only methods where the
       
   822      instvar is modified"
       
   823 
       
   824     |filter browser|
       
   825 
       
   826     filter := self filterToSearchInstRefsTo:varName modificationsOnly:modsOnly.
       
   827     browser := self browseInstMethodsIn:aCollectionOfClasses where:filter title:title.
       
   828 
       
   829     browser notNil ifTrue:[
       
   830 	browser autoSearch:varName 
       
   831     ].
       
   832     ^ browser
       
   833 !
       
   834 
       
   835 aproposSearch:aString in:aCollectionOfClasses
       
   836     "browse all methods, which have aString in their selector or
       
   837      in the methods comment.
       
   838      This is relatively slow, since all source must be processed."
       
   839 
       
   840     |matchString list|
       
   841 
       
   842     matchString := '*' , aString , '*'.
       
   843 
       
   844     list := OrderedCollection new.
       
   845 
       
   846     ^ self browseMethodsIn:aCollectionOfClasses 
       
   847 		     where:[:class :method :sel |
       
   848 				(matchString match:sel) ifTrue:[
       
   849 				    list add:(class name , '>>' , sel)
       
   850 				] ifFalse:[
       
   851 				    (matchString match:(method comment)) ifTrue:[
       
   852 					list add:(class name , '>>' , sel)
       
   853 				    ]
       
   854 				].
       
   855 				Processor yield.
       
   856 			   ]
       
   857 		     title:('apropos: ' , aString)
       
   858 
       
   859     "SystemBrowser aproposSearch:'append'"
       
   860     "SystemBrowser aproposSearch:'add'"
       
   861     "SystemBrowser aproposSearch:'sort'"
   695 !
   862 !
   696 
   863 
   697 browseInstRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly
   864 browseInstRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly
   698     "launch a browser for all methods in aClass where the instVar named
   865     "launch a browser for all methods in aClass where the instVar named
   699      aString is referenced; if modsOnly is true, browse only methods where the
   866      aString is referenced; if modsOnly is true, browse only methods where the
   710 			 in:aCollectionOfClasses 
   877 			 in:aCollectionOfClasses 
   711 	  modificationsOnly:modsOnly 
   878 	  modificationsOnly:modsOnly 
   712 		      title:(title , aString)
   879 		      title:(title , aString)
   713 !
   880 !
   714 
   881 
       
   882 aproposSearch:aString
       
   883     "browse all methods, which have aString in their selector or
       
   884      in the methods comment.
       
   885      This is relatively slow, since all source must be processed."
       
   886 
       
   887     ^ self aproposSearch:aString in:(Smalltalk allClasses)
       
   888 !
       
   889 
   715 browseInstRefsTo:aString under:aClass modificationsOnly:modsOnly
   890 browseInstRefsTo:aString under:aClass modificationsOnly:modsOnly
   716     "launch a browser for all methods in aClass and subclasses
   891     "launch a browser for all methods in aClass and subclasses
   717      where the instVar named aString is referenced; 
   892      where the instVar named aString is referenced; 
   718      if modsOnly is true, browse only methods where the instvar is modified"
   893      if modsOnly is true, browse only methods where the instvar is modified"
   719 
   894 
   723 browseClassRefsTo:varName in:aCollectionOfClasses modificationsOnly:modsOnly title:title
   898 browseClassRefsTo:varName in:aCollectionOfClasses modificationsOnly:modsOnly title:title
   724     "launch a browser for all methods in aCollectionOfClasses,
   899     "launch a browser for all methods in aCollectionOfClasses,
   725      where the classVar named aString is referenced; 
   900      where the classVar named aString is referenced; 
   726      if modsOnly is true, browse only methods where the classvar is modified"
   901      if modsOnly is true, browse only methods where the classvar is modified"
   727 
   902 
   728     |needMatch searchBlock browser|
   903     |searchBlock browser|
   729 
   904 
   730     needMatch := varName includesMatchCharacters.
   905     searchBlock := self filterToSearchClassRefsTo:varName modificationsOnly:modsOnly.
       
   906     browser := self browseMethodsIn:aCollectionOfClasses where:searchBlock title:title.
       
   907 
       
   908     browser notNil ifTrue:[
       
   909 	browser autoSearch:varName
       
   910     ].
       
   911     ^ browser
       
   912 !
       
   913 
       
   914 browseClassRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly
       
   915     "launch a browser for all methods in aClass where the classVar named
       
   916      aString is referenced; if modsOnly is true, browse only methods where the
       
   917      classvar is modified"
       
   918 
       
   919     |title|
       
   920 
       
   921     modsOnly ifTrue:[
       
   922 	title := 'modifications of '
       
   923     ] ifFalse:[
       
   924 	title := 'references to '
       
   925     ].
       
   926     ^ self browseClassRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly title:(title , aString)
       
   927 !
       
   928 
       
   929 browseClassRefsTo:aString under:aClass modificationsOnly:modsOnly
       
   930     "launch a browser for all methods in aClass and subclasses
       
   931      where the classVar named aString is referenced; 
       
   932      if modsOnly is true, browse only methods where the classvar is modified"
       
   933 
       
   934     ^ self browseClassRefsTo:aString in:(aClass withAllSubclasses) modificationsOnly:modsOnly
       
   935 !
       
   936 
       
   937 filterToSearchClassRefsTo:varName modificationsOnly:modsOnly
       
   938     "return a searchblock for class variable references"
       
   939 
       
   940     |searchBlock|
   731 
   941 
   732     searchBlock := [:c :m :s |
   942     searchBlock := [:c :m :s |
   733 	|src result parser classvars|
   943 	|src result parser classvars needMatch|
       
   944 
       
   945 	needMatch := varName includesMatchCharacters.
   734 
   946 
   735 	src := m source.
   947 	src := m source.
   736 	src isNil ifTrue:[
   948 	src isNil ifTrue:[
   737 	    result := false
   949 	    result := false
   738 	] ifFalse:[
   950 	] ifFalse:[
   767 	    ].
   979 	    ].
   768 	].
   980 	].
   769 	Processor yield.
   981 	Processor yield.
   770 	result
   982 	result
   771     ].
   983     ].
   772     browser := self browseMethodsIn:aCollectionOfClasses where:searchBlock title:title.
   984     ^ searchBlock
   773 
       
   774     browser notNil ifTrue:[
       
   775 	browser setSearchPattern:varName
       
   776     ].
       
   777     ^ browser
       
   778 !
       
   779 
       
   780 browseClassRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly
       
   781     "launch a browser for all methods in aClass where the classVar named
       
   782      aString is referenced; if modsOnly is true, browse only methods where the
       
   783      classvar is modified"
       
   784 
       
   785     |title|
       
   786 
       
   787     modsOnly ifTrue:[
       
   788 	title := 'modifications of '
       
   789     ] ifFalse:[
       
   790 	title := 'references to '
       
   791     ].
       
   792     ^ self browseClassRefsTo:aString in:aCollectionOfClasses modificationsOnly:modsOnly title:(title , aString)
       
   793 !
       
   794 
       
   795 browseClassRefsTo:aString under:aClass modificationsOnly:modsOnly
       
   796     "launch a browser for all methods in aClass and subclasses
       
   797      where the classVar named aString is referenced; 
       
   798      if modsOnly is true, browse only methods where the classvar is modified"
       
   799 
       
   800     ^ self browseClassRefsTo:aString in:(aClass withAllSubclasses) modificationsOnly:modsOnly
       
   801 ! !
   985 ! !
   802 
   986 
   803 !SystemBrowser class methodsFor:'private'!
   987 !SystemBrowser class methodsFor:'private'!
       
   988 
       
   989 newWithLabel:aString setupBlock:aBlock on:aWorkstation
       
   990     "common helper method for all creation methods"
       
   991 
       
   992     |newBrowser|
       
   993 
       
   994     newBrowser := self on:aWorkstation.
       
   995     newBrowser title:aString.
       
   996     aBlock value:newBrowser.
       
   997 
       
   998     newBrowser open.
       
   999     ^ newBrowser
       
  1000 !
       
  1001 
       
  1002 newWithLabel:aString setupBlock:aBlock
       
  1003     "common helper method for all creation methods"
       
  1004 
       
  1005     ^ self newWithLabel:aString setupBlock:aBlock on:Display
       
  1006 !
   804 
  1007 
   805 showNoneFound:what
  1008 showNoneFound:what
   806 "/    DialogView warn:(self classResources string:('no ' , what , ' found')).
  1009 "/    DialogView warn:(self classResources string:('no ' , what , ' found')).
   807     self showNoneFound
  1010     self showNoneFound
   808 !
  1011 !
   809 
  1012 
   810 showNoneFound
  1013 showNoneFound
   811     DialogView warn:(self classResources string:'None found').
  1014     DialogView warn:(self classResources string:'None found').
   812 !
  1015 ! !
   813 
  1016 
   814 newWithLabel:aString setupBlock:aBlock on:aWorkstation
  1017 !SystemBrowser class methodsFor:'general startup'!
   815     "common helper method for all creation methods"
  1018 
   816 
  1019 openOnDisplay:aDisplay
   817     |newBrowser|
  1020     "launch a standard browser on another display.
   818 
  1021      Does not work currently - still being developped."
   819     newBrowser := self on:aWorkstation.
  1022 
   820     newBrowser label:aString.
  1023     ^ self newWithLabel:(self classResources string:'System Browser')
   821     aBlock value:newBrowser.
  1024 	     setupBlock:[:browser | browser setupForAll]
   822 
  1025 		     on:aDisplay
   823     newBrowser open.
  1026 
   824     ^ newBrowser
  1027     "
   825 !
  1028      SystemBrowser openOnDisplay:(XWorkstation new initializeFor:'porty:0')
   826 
  1029     "
   827 newWithLabel:aString setupBlock:aBlock
  1030 !
   828     "common helper method for all creation methods"
  1031 
   829 
  1032 open
   830     ^ self newWithLabel:aString setupBlock:aBlock on:Display
  1033     "launch a standard browser"
       
  1034 
       
  1035     ^ self openOnDisplay:Display
       
  1036 
       
  1037     "SystemBrowser open"
       
  1038 ! !
       
  1039 
       
  1040 !SystemBrowser methodsFor:'dependencies'!
       
  1041 
       
  1042 update:something with:someArgument from:changedObject
       
  1043 
       
  1044     "
       
  1045      avoid update/warn after my own changes
       
  1046     "
       
  1047     lockUpdates == true ifTrue:[
       
  1048 "/         'ignored my change' printNL.
       
  1049 	^ self
       
  1050     ].
       
  1051 
       
  1052 "/ changedObject print. ' ' print. someArgument print. ' ' print.
       
  1053 "/ something printNL.
       
  1054 
       
  1055     (changedObject == Smalltalk) ifTrue:[
       
  1056 	something == #newClass ifTrue:[
       
  1057 	    ((someArgument category = currentClassCategory)
       
  1058 	    or:[currentClassCategory notNil
       
  1059 		and:[currentClassCategory startsWith:'*']]) ifTrue:[
       
  1060 		self updateClassListWithScroll:false.
       
  1061 	    ].
       
  1062 
       
  1063 	    someArgument category ~= currentClassCategory ifTrue:[
       
  1064 		"
       
  1065 		 category new ?
       
  1066 		"
       
  1067 		(classCategoryListView notNil 
       
  1068 		and:[classCategoryListView list notNil
       
  1069 		and:[(classCategoryListView list includes:someArgument category) not]])
       
  1070 		ifTrue:[
       
  1071 		    self updateClassCategoryListWithScroll:false.
       
  1072 		]
       
  1073 	    ].
       
  1074 	    ^ self
       
  1075 	].
       
  1076 
       
  1077 	something == #classRemove ifTrue:[
       
  1078 	    someArgument = currentClass ifTrue:[
       
  1079 		self warnLabel:'the selected class was removed'.
       
  1080 		^ self
       
  1081 	    ].
       
  1082 	    " fall into general update "
       
  1083 	].
       
  1084 
       
  1085 	"
       
  1086 	 any other (unknown) change 
       
  1087 	 with the Smalltalk dictionary ...
       
  1088 	"
       
  1089 	self updateClassCategoryListWithScroll:false.
       
  1090 	self updateClassListWithScroll:false.
       
  1091 	^ self
       
  1092     ].
       
  1093 
       
  1094     changedObject isBehavior ifTrue:[
       
  1095 	"
       
  1096 	 its a class, that has changed
       
  1097 	"
       
  1098 	(currentClass notNil 
       
  1099 	and:[changedObject name = currentClass name]) ifTrue:[
       
  1100 	    "
       
  1101 	     its the current class that has changed
       
  1102 	    "
       
  1103 	    something == #methodDictionary ifTrue:[
       
  1104 		(someArgument isSymbol) ifTrue:[
       
  1105 		    |changedMethod|
       
  1106 
       
  1107 		    "
       
  1108 		     the method with selector someArgument was changed or removed
       
  1109 		    "
       
  1110 		    self updateMethodCategoryListWithScroll:false.
       
  1111 		    self updateMethodListWithScroll:false.
       
  1112 
       
  1113 		    someArgument == currentSelector ifTrue:[
       
  1114 			"
       
  1115 			 special care here: the currently shown method has been
       
  1116 			 changed somehow in another browser (or via fileIn)
       
  1117 			"
       
  1118 			changedMethod := currentClass compiledMethodAt:currentSelector.
       
  1119 			changedMethod isNil ifTrue:[
       
  1120 			    self warnLabel:'the method shown was removed'.
       
  1121 			    ^ self
       
  1122 			].
       
  1123 			"compare the source codes"
       
  1124 			self warnLabel:'the code shown may not up to date'.
       
  1125 			^ self    
       
  1126 		    ].
       
  1127 		    ^ self
       
  1128 		]
       
  1129 	    ].
       
  1130 
       
  1131 	    something == #comment ifTrue:[
       
  1132 		"
       
  1133 		 the class has changed its comment; we dont care, except if
       
  1134 		 currently showing the comment
       
  1135 		"
       
  1136 		aspect == #comment ifTrue:[
       
  1137 		    self warnLabel:'the comment shown may not up to date'.
       
  1138 		].
       
  1139 		^ self
       
  1140 	    ].
       
  1141 	    something == #definition ifTrue:[
       
  1142 		"
       
  1143 		 the class has changed its definition.
       
  1144 		 Warn, except if showing a method.
       
  1145 		"
       
  1146 		aspect notNil ifTrue:[
       
  1147 		    self warnLabel:'the classes definition has changed'.
       
  1148 		].
       
  1149 		^ self
       
  1150 	    ].
       
  1151 
       
  1152 	    "
       
  1153 	     get the class again - in case of a changed class definition,
       
  1154 	     we are otherwise refering to the obsolete old class
       
  1155 	    "
       
  1156 	    currentClass := Smalltalk at:(currentClass name asSymbol).
       
  1157 	    showInstance ifTrue:[
       
  1158 		actualClass := currentClass
       
  1159 	    ] ifFalse:[
       
  1160 		actualClass := currentClass class
       
  1161 	    ].
       
  1162 
       
  1163 	    self updateMethodCategoryListWithScroll:false.
       
  1164 
       
  1165 	    "dont update codeView ...."
       
  1166 	    "self update"
       
  1167 	    ^ self
       
  1168 	].
       
  1169 
       
  1170 	"
       
  1171 	 any other class has changed (but not its organization, since
       
  1172 	 that is cought in the above case).
       
  1173 	 We are not interrested in it - except, if showing fullProtocol
       
  1174 	 or hierarchy ...
       
  1175 	"
       
  1176 	currentClassHierarchy notNil ifTrue:[
       
  1177 	    fullProtocol ifTrue:[
       
  1178 		(currentClass isSubclassOf:changedObject) ifTrue:[
       
  1179 		]
       
  1180 	    ] ifFalse:[
       
  1181 		((currentClass isSubclassOf:changedObject)
       
  1182 		or:[changedObject isSubclassOf:currentClass]) ifTrue:[
       
  1183 		]                
       
  1184 	    ]
       
  1185 	].
       
  1186 
       
  1187 	^ self
       
  1188     ].
       
  1189 
       
  1190     (changedObject isKindOf:Method) ifTrue:[
       
  1191 
       
  1192     ]
       
  1193 ! !
       
  1194 
       
  1195 !SystemBrowser methodsFor:'private'!
       
  1196 
       
  1197 normalLabel
       
  1198     "set the normal (inactive) window- and icon labels"
       
  1199 
       
  1200     |l il sel|
       
  1201 
       
  1202     myLabel notNil ifTrue:[
       
  1203 	l := il := myLabel
       
  1204     ] ifFalse:[    
       
  1205 	l := resources string:'System Browser'.
       
  1206 
       
  1207 	currentClass notNil ifTrue:[
       
  1208 	    l := l, ': ', currentClass name.
       
  1209 	    classListView isNil ifTrue:[
       
  1210 		currentSelector notNil ifTrue:[
       
  1211 		    l := l , ' ' ,  currentSelector
       
  1212 		]
       
  1213 	    ].
       
  1214 	    il := currentClass name
       
  1215 	] ifFalse:[
       
  1216 	    il := l.
       
  1217 	]
       
  1218     ].
       
  1219     self label:l.
       
  1220     self iconLabel:il.
       
  1221 
       
  1222 !
       
  1223 
       
  1224 setAcceptAndExplainActionsForMethod
       
  1225     "tell the codeView what to do on accept and explain"
       
  1226 
       
  1227     codeView acceptAction:[:theCode |
       
  1228 	|cat|
       
  1229 
       
  1230 	codeView cursor:Cursor execute.
       
  1231 
       
  1232 	(cat := currentMethodCategory) = '* all *' ifTrue:[
       
  1233 	    "must check from which category this code came from ...
       
  1234 	     ... thanks to Arno for pointing this out"
       
  1235 
       
  1236 	    cat := self askForMethodCategory.
       
  1237 	].
       
  1238 	(cat notNil and:[cat notEmpty]) ifTrue:[
       
  1239 	    Object abortSignal catch:[
       
  1240 		lockUpdates := true.
       
  1241 
       
  1242 		actualClass compiler 
       
  1243 		    compile:theCode asString
       
  1244 		    forClass:actualClass
       
  1245 		    inCategory:cat 
       
  1246 		    notifying:codeView.
       
  1247 
       
  1248 		codeView modified:false.
       
  1249 		self updateMethodListWithScroll:false.
       
  1250 	    ].
       
  1251 	    lockUpdates := false.
       
  1252 	].
       
  1253 	codeView cursor:Cursor normal.
       
  1254     ].
       
  1255 
       
  1256     codeView explainAction:[:theCode :theSelection |
       
  1257 	self showExplanation:(Explainer 
       
  1258 				explain:theSelection 
       
  1259 				in:theCode
       
  1260 				forClass:actualClass)
       
  1261     ].
       
  1262 !
       
  1263 
       
  1264 checkSelectionChangeAllowed
       
  1265     "return true, if selection change is ok;
       
  1266      its not ok, if code has been changed.
       
  1267      in this case, return the result of a user query"
       
  1268 
       
  1269     |box|
       
  1270 
       
  1271     codeView modified ifFalse:[
       
  1272 	^ true
       
  1273     ].
       
  1274 "/    fullProtocol ifTrue:[^ true].
       
  1275     box := YesNoBox 
       
  1276 	       title:(resources at:'contents in codeview has not been accepted.\\Modifications will be lost when continuing.') withCRs
       
  1277 	       yesText:(resources at:'continue')
       
  1278 	       noText:(resources at:'abort').
       
  1279     ^ box confirm
       
  1280 !
       
  1281 
       
  1282 selectorToSearchFor
       
  1283     "look in codeView and methodListView for a search-string when searching for selectors"
       
  1284 
       
  1285     |sel t|
       
  1286 
       
  1287     sel := codeView selection.
       
  1288     sel notNil ifTrue:[
       
  1289 	sel := sel asString.
       
  1290 	t := Parser selectorInExpression:sel.
       
  1291 	t notNil ifTrue:[
       
  1292 	    sel := t
       
  1293 	].
       
  1294 	sel := sel withoutSpaces.
       
  1295 	sel == #>> ifTrue:[
       
  1296 	    "oops - thats probably not what we want here ..."
       
  1297 	    self extractClassAndSelectorFromSelectionInto:[:c :s :m |
       
  1298 		sel := s
       
  1299 	    ]
       
  1300 	]
       
  1301     ] ifFalse:[
       
  1302 	methodListView notNil ifTrue:[
       
  1303 	    sel := methodListView selectionValue
       
  1304 	] ifFalse:[
       
  1305 	    classMethodListView notNil ifTrue:[
       
  1306 		sel := classMethodListView selectionValue.
       
  1307 		sel notNil ifTrue:[
       
  1308 		    sel := self selectorFromClassMethodString:sel
       
  1309 		]
       
  1310 	    ]
       
  1311 	].
       
  1312 	sel notNil ifTrue:[
       
  1313 	    sel := sel withoutSpaces
       
  1314 	] ifFalse:[
       
  1315 	    sel := ''
       
  1316 	]
       
  1317     ].
       
  1318     ^ sel
       
  1319 !
       
  1320 
       
  1321 enterBoxTitle:title okText:okText
       
  1322     "convenient method: setup enterBox"
       
  1323 
       
  1324     |box|
       
  1325 
       
  1326     box := EnterBox new.
       
  1327     box title:(resources string:title) okText:(resources string:okText).
       
  1328     ^ box
       
  1329 !
       
  1330 
       
  1331 askAndBrowseSelectorTitle:title action:aBlock
       
  1332     "convenient method: setup enterBox with text from codeView or selected
       
  1333      method for browsing based on a selector. Set action and launch box"
       
  1334 
       
  1335     |box|
       
  1336 
       
  1337     box := self enterBoxTitle:title okText:'browse'.
       
  1338     box initialText:(self selectorToSearchFor).
       
  1339     box action:[:aString | self withCursor:(Cursor questionMark) do:[aBlock value:aString]].
       
  1340     box showAtPointer
       
  1341 !
       
  1342 
       
  1343 setSearchPattern:aString
       
  1344     codeView setSearchPattern:aString
       
  1345 !
       
  1346 
       
  1347 listBoxTitle:title okText:okText list:aList
       
  1348     "convenient method: setup a listBox & return it"
       
  1349 
       
  1350     |box|
       
  1351 
       
  1352     box := ListSelectionBox new.
       
  1353     box okText:(resources string:okText).
       
  1354     box title:(resources string:title).
       
  1355     box list:aList.
       
  1356     ^ box
       
  1357 !
       
  1358 
       
  1359 showExplanation:someText
       
  1360     "show explanation from Parser"
       
  1361 
       
  1362     self notify:someText
       
  1363 !
       
  1364 
       
  1365 stringToSearchFor
       
  1366     "look in codeView and methodListView for a search-string when searching for classes/names"
       
  1367 
       
  1368     |sel|
       
  1369 
       
  1370     sel := codeView selection.
       
  1371     sel notNil ifTrue:[
       
  1372 	sel := sel asString withoutSpaces
       
  1373     ] ifFalse:[
       
  1374 	sel isNil ifTrue:[
       
  1375 	    currentClass notNil ifTrue:[
       
  1376 		sel := currentClass name
       
  1377 	    ]
       
  1378 	].
       
  1379 	sel notNil ifTrue:[
       
  1380 	    sel := sel withoutSpaces
       
  1381 	] ifFalse:[
       
  1382 	    sel := ''
       
  1383 	]
       
  1384     ].
       
  1385     ^ sel
       
  1386 !
       
  1387 
       
  1388 findClassOfVariable:aVariableName accessWith:aSelector
       
  1389     "this method returns the class, in which a variable
       
  1390      is defined; 
       
  1391      needs either #instVarNames or #classVarNames as aSelector."
       
  1392 
       
  1393     |cls homeClass|
       
  1394 
       
  1395     "
       
  1396      first, find the class, where the variable is declared
       
  1397     "
       
  1398     cls := currentClass.
       
  1399     [cls notNil] whileTrue:[
       
  1400 	((cls perform:aSelector) includes:aVariableName) ifTrue:[
       
  1401 	    homeClass := cls.
       
  1402 	    cls := nil.
       
  1403 	] ifFalse:[
       
  1404 	    cls := cls superclass
       
  1405 	]
       
  1406     ].
       
  1407     homeClass isNil ifTrue:[
       
  1408 	"nope, must be one below ... (could optimize a bit, by searching down
       
  1409 	 for the declaring class ...
       
  1410 	"
       
  1411 	homeClass := currentClass
       
  1412     ] ifFalse:[
       
  1413 "/        Transcript showCr:'starting search in ' , homeClass name.
       
  1414     ].
       
  1415     ^ homeClass
       
  1416 !
       
  1417 
       
  1418 enterBoxForSearchSelectorTitle:title
       
  1419     "convenient method: setup enterBox with text from codeView or selected
       
  1420      method for browsing based on a selector"
       
  1421 
       
  1422     |box|
       
  1423 
       
  1424     box := self enterBoxTitle:title okText:'search'.
       
  1425     box initialText:(self selectorToSearchFor).
       
  1426     ^ box
       
  1427 !
       
  1428 
       
  1429 enterBoxForCodeSelectionTitle:title okText:okText
       
  1430     "convenient method: setup enterBox with text from codeview"
       
  1431 
       
  1432     |sel box|
       
  1433 
       
  1434     box := self enterBoxTitle:(resources string:title) okText:(resources string:okText).
       
  1435     sel := codeView selection.
       
  1436     sel notNil ifTrue:[
       
  1437 	box initialText:(sel asString withoutSeparators)
       
  1438     ].
       
  1439     ^ box
       
  1440 !
       
  1441 
       
  1442 classesInFullProtocolHierarchy:aClass do:aBlock
       
  1443     "evaluate aBlock for all non-striked out classes in
       
  1444      the hierarchy"
       
  1445 
       
  1446     |index|
       
  1447 
       
  1448     index := (classListView list size).
       
  1449     aClass withAllSuperclasses do:[:c |
       
  1450 	(classListView isInSelection:index) ifFalse:[
       
  1451 	    aBlock value:c
       
  1452 	].
       
  1453 	index := index - 1
       
  1454     ]
       
  1455 
       
  1456 !
       
  1457 
       
  1458 enterBoxForBrowseTitle:title action:aBlock
       
  1459     "convenient method: setup enterBox with text from codeView or selected
       
  1460      method for method browsing based on className/variable"
       
  1461 
       
  1462     |box|
       
  1463 
       
  1464     box := self enterBoxTitle:title okText:'browse'.
       
  1465     box initialText:(self stringToSearchFor).
       
  1466     box action:[:aString | self withWaitCursorDo:[aBlock value:aString]].
       
  1467     box showAtPointer
       
  1468 !
       
  1469 
       
  1470 askBoxTitle:title okText:okText initialText:initialText action:aBlock
       
  1471     "convenient method: setup enterBox, and open it"
       
  1472 
       
  1473     |box|
       
  1474 
       
  1475     box := EnterBox new.
       
  1476     box title:(resources string:title) okText:(resources string:okText).
       
  1477     box initialText:initialText.
       
  1478     box action:[:aString | self withWaitCursorDo:aBlock value:aString].
       
  1479     box showAtPointer
       
  1480 !
       
  1481 
       
  1482 askAndBrowseMethodCategory:title action:aBlock
       
  1483     "convenient method: setup enterBox with initial being current method category"
       
  1484 
       
  1485     |sel box|
       
  1486 
       
  1487     box := self enterBoxTitle:title okText:'browse'.
       
  1488     sel := codeView selection.
       
  1489     sel isNil ifTrue:[
       
  1490 	currentMethodCategory notNil ifTrue:[
       
  1491 	    sel := currentMethodCategory
       
  1492 	]
       
  1493     ].
       
  1494     sel notNil ifTrue:[
       
  1495 	box initialText:(sel asString withoutSpaces)
       
  1496     ].
       
  1497     box action:[:aString | self withWaitCursorDo:[aBlock value:aString]].
       
  1498     box showAtPointer
       
  1499 !
       
  1500 
       
  1501 classHierarchyDo:aBlock
       
  1502     "eavluate the 2-arg block for every class,
       
  1503      starting at Object; passing class and nesting level to the block."
       
  1504 
       
  1505     |classes s classDict l|
       
  1506 
       
  1507     classes := Smalltalk allClasses.
       
  1508     classDict := IdentityDictionary new:classes size.
       
  1509     classes do:[:aClass |
       
  1510 	s := aClass superclass.
       
  1511 	s notNil ifTrue:[
       
  1512 	    l := classDict at:s ifAbsent:[nil].
       
  1513 	    l isNil ifTrue:[
       
  1514 		l := OrderedCollection new:5.
       
  1515 		classDict at:s put:l
       
  1516 	    ].
       
  1517 	    l add:aClass
       
  1518 	]
       
  1519     ].
       
  1520     self classHierarchyOf:Object level:0 do:aBlock using:classDict
       
  1521 !
       
  1522 
       
  1523 classHierarchyOf:aClass level:level do:aBlock using:aDictionary
       
  1524     "evaluate the 2-arg block for every subclass of aClass,
       
  1525      passing class and nesting level to the block."
       
  1526 
       
  1527     |names subclasses|
       
  1528 
       
  1529     aBlock value:aClass value:level.
       
  1530     subclasses := aDictionary at:aClass ifAbsent:[nil].
       
  1531     (subclasses size == 0) ifFalse:[
       
  1532 	names := subclasses collect:[:class | class name].
       
  1533 	names sortWith:subclasses.
       
  1534 	subclasses do:[:aSubClass |
       
  1535 	    self classHierarchyOf:aSubClass level:(level + 1) do:aBlock using:aDictionary
       
  1536 	]
       
  1537     ]
       
  1538 !
       
  1539 
       
  1540 compileCode:someCode
       
  1541     (ReadStream on:someCode) fileIn
       
  1542 !
       
  1543 
       
  1544 extractClassAndSelectorFromSelectionInto:aBlock
       
  1545     "given a string which can be either 'class>>sel' or
       
  1546      'class sel', extract className and selector, and call aBlock with
       
  1547     the result."
       
  1548 
       
  1549     |sel clsName isMeta sep s|
       
  1550 
       
  1551     sel := codeView selection.
       
  1552     sel notNil ifTrue:[
       
  1553 	sel := sel asString withoutSeparators.
       
  1554 	('*>>*' match:sel) ifTrue:[
       
  1555 	    sep := $>
       
  1556 	] ifFalse:[
       
  1557 	    ('* *' match:sel) ifTrue:[
       
  1558 		sep := Character space
       
  1559 	    ]
       
  1560 	].
       
  1561 	sep notNil ifTrue:[
       
  1562 	    "
       
  1563 	     extract class/sel from selection
       
  1564 	    "
       
  1565 	    s := ReadStream on:sel.
       
  1566 	    clsName := s upTo:sep.
       
  1567 	    [s peek == sep] whileTrue:[s next].
       
  1568 	    sel := s upToEnd.
       
  1569 
       
  1570 	    (clsName endsWith:'class') ifTrue:[
       
  1571 		isMeta := true.
       
  1572 		clsName := clsName copyTo:(clsName size - 5)
       
  1573 	    ] ifFalse:[
       
  1574 		isMeta := false
       
  1575 	    ].
       
  1576 	]
       
  1577     ].
       
  1578     aBlock value:clsName value:sel value:isMeta
       
  1579 
       
  1580 
       
  1581 !
       
  1582 
       
  1583 classesInHierarchy:aClass do:aBlock
       
  1584     |index|
       
  1585 
       
  1586     index := (classListView list size).
       
  1587     aClass withAllSuperclasses do:[:c |
       
  1588 	(classListView isInSelection:index) ifFalse:[
       
  1589 	    aBlock value:c
       
  1590 	].
       
  1591 	index := index - 1
       
  1592     ]
       
  1593 
       
  1594 !
       
  1595 
       
  1596 askForMethodCategory
       
  1597     |someCategories box txt|
       
  1598 
       
  1599     someCategories := actualClass categories sort.
       
  1600     box := self listBoxTitle:'accept in which method category ?' okText:'accept' list:someCategories.
       
  1601 
       
  1602     lastMethodCategory isNil ifTrue:[
       
  1603 	txt := 'new methods'
       
  1604     ] ifFalse:[
       
  1605 	txt := lastMethodCategory
       
  1606     ].
       
  1607     box initialText:txt.
       
  1608     box action:[:aString |
       
  1609 		    ^ aString
       
  1610 	       ].
       
  1611     box showAtPointer.
       
  1612     ^ nil
       
  1613 !
       
  1614 
       
  1615 warnLabel:what
       
  1616     "set the title for some warning"
       
  1617 
       
  1618     self label:('System Browser WARNING: ' , what)
       
  1619 !
       
  1620 
       
  1621 busyLabel:what with:someArgument
       
  1622     "set the title for some warning"
       
  1623 
       
  1624     self label:('System Browser:' , (resources string:what with:someArgument))
       
  1625 
       
  1626 ! !
       
  1627 
       
  1628 !SystemBrowser methodsFor:'method stuff'!
       
  1629 
       
  1630 updateMethodListWithScroll:scroll
       
  1631     |selectors scr first last|
       
  1632 
       
  1633     methodListView notNil ifTrue:[
       
  1634 	currentMethodCategory notNil ifTrue:[
       
  1635 	    fullProtocol ifTrue:[
       
  1636 		selectors := self listOfAllSelectorsInCategory:currentMethodCategory 
       
  1637 					    inFullProtocolHierarchyOfClass:actualClass
       
  1638 	    ] ifFalse:[
       
  1639 		selectors := self listOfAllSelectorsInCategory:currentMethodCategory
       
  1640 						       ofClass:actualClass
       
  1641 	    ]
       
  1642 	].
       
  1643 	scr := scroll.
       
  1644 	first := methodListView firstLineShown.
       
  1645 	first ~~ 1 ifTrue:[
       
  1646 	    last := methodListView lastLineShown.
       
  1647 	    selectors size <= (last - first + 1) ifTrue:[
       
  1648 		scr := true
       
  1649 	    ]
       
  1650 	].
       
  1651 	methodListView list = selectors ifFalse:[
       
  1652 	    scr ifTrue:[
       
  1653 		methodListView contents:selectors
       
  1654 	    ] ifFalse:[
       
  1655 		methodListView setContents:selectors
       
  1656 	    ]
       
  1657 	].
       
  1658     ]
       
  1659 !
       
  1660 
       
  1661 methodSelectionChanged
       
  1662     "method selection has changed - update dependent views"
       
  1663 
       
  1664     self withWaitCursorDo:[
       
  1665 	|index cls|
       
  1666 
       
  1667 	self updateCodeView.
       
  1668 	self setAcceptAndExplainActionsForMethod.
       
  1669 
       
  1670 	"
       
  1671 	 if there is any autoSearch string, do the search
       
  1672 	"
       
  1673 	autoSearch notNil ifTrue:[
       
  1674 	    codeView searchFwd:autoSearch ifAbsent:[]
       
  1675 	].
       
  1676 
       
  1677 	fullProtocol ifTrue:[
       
  1678 	    "
       
  1679 	     remove any bold attribute from classList
       
  1680 	    "
       
  1681 	    1 to:classListView list size do:[:i |
       
  1682 		classListView attributeAt:i remove:#bold.
       
  1683 	    ].
       
  1684 	    "
       
  1685 	     boldify the class where this method is implemented
       
  1686 	    "
       
  1687 	    currentMethod notNil ifTrue:[
       
  1688 		cls := currentMethod who at:1.
       
  1689 		index := classListView list indexOf:(cls name).
       
  1690 		index ~~ 0 ifTrue:[
       
  1691 		    classListView attributeAt:index add:#bold.
       
  1692 		].
       
  1693 		currentClass := cls.
       
  1694 
       
  1695 	    ]
       
  1696 	].
       
  1697     ]
       
  1698 !
       
  1699 
       
  1700 updateMethodList
       
  1701     self updateMethodListWithScroll:true
       
  1702 !
       
  1703 
       
  1704 methodSelection:lineNr
       
  1705     "user clicked on a method line - show code"
       
  1706 
       
  1707     |selectorString selectorSymbol index|
       
  1708 
       
  1709     (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self].
       
  1710 
       
  1711     selectorString := methodListView selectionValue.
       
  1712     "
       
  1713      kludge: check if its a wrapped one
       
  1714     "
       
  1715     (selectorString endsWith:' !!') ifTrue:[
       
  1716 	selectorString := selectorString copyTo:(selectorString size - 2)
       
  1717     ].
       
  1718     selectorSymbol := selectorString asSymbol.
       
  1719     fullProtocol ifTrue:[
       
  1720 	currentMethod := currentSelector := nil.
       
  1721 	"
       
  1722 	 search which class implements the selector
       
  1723 	"
       
  1724 	self classesInFullProtocolHierarchy:actualClass do:[:c |
       
  1725 	    (currentMethod isNil 
       
  1726 	     and:[c implements:selectorSymbol]) ifTrue:[
       
  1727 		currentSelector := selectorSymbol.
       
  1728 		currentMethod := c compiledMethodAt:selectorSymbol.
       
  1729 	    ]
       
  1730 	]
       
  1731     ] ifFalse:[
       
  1732 	currentSelector := selectorSymbol.
       
  1733 	currentMethod := actualClass compiledMethodAt:selectorSymbol.
       
  1734     ].
       
  1735 
       
  1736     methodCategoryListView notNil ifTrue:[
       
  1737 	currentMethod notNil ifTrue:[
       
  1738 	    (currentMethodCategory = currentMethod category) ifFalse:[
       
  1739 		currentMethodCategory := currentMethod category.
       
  1740 		methodCategoryListView selectElement:currentMethodCategory
       
  1741 	    ]
       
  1742 	]
       
  1743     ].
       
  1744 
       
  1745     self methodSelectionChanged
       
  1746 !
       
  1747 
       
  1748 listOfAllSelectorsInCategory:aCategory ofClass:aClass
       
  1749     "answer a list of all selectors in a given method category 
       
  1750      of the argument, aClass"
       
  1751 
       
  1752     |newList searchCategory selector|
       
  1753 
       
  1754     (aCategory = '* all *') ifTrue:[
       
  1755 	newList := aClass selectorArray asOrderedCollection
       
  1756     ] ifFalse:[
       
  1757 	(aCategory = '* no category *') ifTrue:[
       
  1758 	    searchCategory := nil
       
  1759 	] ifFalse:[
       
  1760 	    searchCategory := aCategory
       
  1761 	].
       
  1762 	newList := OrderedCollection new.
       
  1763 	aClass methodArray with:aClass selectorArray do:[:aMethod :selector |
       
  1764 	    |sel|
       
  1765 
       
  1766 	    (aMethod category = searchCategory) ifTrue:[
       
  1767 		aMethod isWrapped ifTrue:[
       
  1768 		    sel := selector , ' !!'
       
  1769 		] ifFalse:[
       
  1770 		    sel := selector
       
  1771 		].
       
  1772 
       
  1773 		"mhmh - can this happen ?"
       
  1774 "/                (newList includes:sel) ifFalse:[
       
  1775 		    newList add:sel
       
  1776 "/                ]
       
  1777 	    ]
       
  1778 	]
       
  1779     ].
       
  1780     (newList size == 0) ifTrue:[^ nil].
       
  1781     ^ newList sort
       
  1782 !
       
  1783 
       
  1784 template
       
  1785     "return a method definition template"
       
  1786 
       
  1787     ^ 
       
  1788 'message selector and argument names
       
  1789     "comment stating purpose of message"
       
  1790 
       
  1791 
       
  1792     |temporaries|
       
  1793     statements
       
  1794 
       
  1795 
       
  1796 "
       
  1797  change above template into real code.
       
  1798  Then ''accept'' either via the menu 
       
  1799  or via the keyboard (usually CMD-A).
       
  1800 
       
  1801  You do not need this template; you can also
       
  1802  select any existing methods code, change it,
       
  1803  and finally ''accept''.
       
  1804 "
       
  1805 '
       
  1806 !
       
  1807 
       
  1808 listOfAllSelectorsInCategory:aCategory inFullProtocolHierarchyOfClass:aClass
       
  1809     "answer a list of all selectors in a given method category 
       
  1810      of the argument, aClass and its superclasses.
       
  1811      Used with fullProtocol browsing."
       
  1812 
       
  1813     |newList thisList searchCategory selector|
       
  1814 
       
  1815     newList := Set new.
       
  1816     self classesInFullProtocolHierarchy:aClass do:[:c |
       
  1817 	(aCategory = '* all *') ifTrue:[
       
  1818 	    newList addAll:(c selectorArray)
       
  1819 	] ifFalse:[
       
  1820 	    (aCategory = '* no category *') ifTrue:[
       
  1821 		searchCategory := nil
       
  1822 	    ] ifFalse:[
       
  1823 		searchCategory := aCategory
       
  1824 	    ].
       
  1825 	    c methodArray with:c selectorArray do:[:aMethod :selector |
       
  1826 		(aMethod category = searchCategory) ifTrue:[
       
  1827 		    newList add:selector
       
  1828 		]
       
  1829 	    ]
       
  1830 	].
       
  1831     ].
       
  1832     (newList size == 0) ifTrue:[^ nil].
       
  1833     ^ newList asOrderedCollection sort
       
  1834 !
       
  1835 
       
  1836 checkMethodSelected
       
  1837     currentMethod isNil ifTrue:[
       
  1838 	self warn:'select a method first'.
       
  1839 	^ false
       
  1840     ].
       
  1841     ^ true
       
  1842 !
       
  1843 
       
  1844 switchToMethodNamed:matchString
       
  1845     |aSelector method cat index classToSearch selectors|
       
  1846 
       
  1847     currentClass notNil ifTrue:[
       
  1848 	showInstance ifTrue:[
       
  1849 	    classToSearch := currentClass
       
  1850 	] ifFalse:[
       
  1851 	    classToSearch := currentClass class
       
  1852 	].
       
  1853 	selectors := classToSearch selectorArray.
       
  1854 
       
  1855 	((matchString ~= '*') and:[matchString includesMatchCharacters]) ifTrue:[
       
  1856 	    index := selectors findFirst:[:element | matchString match:element]
       
  1857 	] ifFalse:[
       
  1858 	    index := selectors indexOf:matchString
       
  1859 	].
       
  1860 
       
  1861 	(index ~~ 0) ifTrue:[
       
  1862 	    aSelector := selectors at:index.
       
  1863 	    method := classToSearch methodArray at:index.
       
  1864 	    cat := method category.
       
  1865 	    cat isNil ifTrue:[cat := '* all *'].
       
  1866 	    methodCategoryListView selectElement:cat.
       
  1867 	    currentMethodCategory := cat.
       
  1868 	    self methodCategorySelectionChanged.
       
  1869 
       
  1870 	    currentMethod := classToSearch compiledMethodAt:aSelector.
       
  1871 	    currentMethod notNil ifTrue:[
       
  1872 		currentSelector := aSelector.
       
  1873 		methodListView selectElement:aSelector.
       
  1874 	    ].
       
  1875 	    self methodSelectionChanged
       
  1876 	]
       
  1877     ]
       
  1878 !
       
  1879 
       
  1880 switchToAnyMethodNamed:aString
       
  1881     |aSelector classToStartSearch aClass nm|
       
  1882 
       
  1883     aSelector := aString asSymbol.
       
  1884     currentClass isNil ifTrue:[
       
  1885 	currentClassHierarchy notNil ifTrue:[
       
  1886 	    classToStartSearch := currentClassHierarchy
       
  1887 	]
       
  1888     ] ifFalse:[
       
  1889 	classToStartSearch := currentClass 
       
  1890     ].
       
  1891     classToStartSearch notNil ifTrue:[
       
  1892 	showInstance ifFalse:[
       
  1893 	    classToStartSearch := classToStartSearch class
       
  1894 	].
       
  1895 	aClass := classToStartSearch whichClassImplements:aSelector.
       
  1896 	aClass notNil ifTrue:[
       
  1897 	    nm := aClass name.
       
  1898 	    showInstance ifFalse:[
       
  1899 		((nm ~= 'Metaclass') and:[nm endsWith:'class']) ifTrue:[
       
  1900 		    nm := nm copyTo:(nm size - 5)
       
  1901 		]
       
  1902 	    ].
       
  1903 	    self switchToClassNamed:nm.
       
  1904 	    self switchToMethodNamed:aString
       
  1905 	]
       
  1906     ]
       
  1907 ! !
       
  1908 
       
  1909 !SystemBrowser methodsFor:'misc'!
       
  1910 
       
  1911 updateCodeView
       
  1912     |code aStream|
       
  1913 
       
  1914     fullClass ifTrue:[
       
  1915 	currentClass notNil ifTrue:[
       
  1916 	    code := currentClass source.
       
  1917 	]
       
  1918     ] ifFalse:[
       
  1919 	currentMethod notNil ifTrue:[
       
  1920 	    (codeView acceptAction isNil
       
  1921 	    and:[actualClass notNil 
       
  1922 	    and:[currentMethodCategory notNil]]) ifTrue:[
       
  1923 		self setAcceptAndExplainActionsForMethod.
       
  1924 	    ].
       
  1925 
       
  1926 	    code := currentMethod source.
       
  1927 
       
  1928 	]
       
  1929     ].
       
  1930     codeView contents:code.
       
  1931     codeView modified:false.
       
  1932 
       
  1933     self normalLabel.
       
  1934 
       
  1935 
       
  1936 !
       
  1937 
       
  1938 instanceProtocol
       
  1939     "switch to instance protocol"
       
  1940 
       
  1941     showInstance ifFalse:[
       
  1942 	self checkSelectionChangeAllowed ifTrue:[
       
  1943 	    classToggle turnOff.
       
  1944 	    instanceToggle turnOn.
       
  1945 	    showInstance := true.
       
  1946 
       
  1947 	    (variableListView notNil
       
  1948 	    and:[variableListView hasSelection]) ifTrue:[
       
  1949 		self unhilightMethodCategories.
       
  1950 		self unhilightMethods.
       
  1951 		variableListView deselect
       
  1952 	    ].
       
  1953 
       
  1954 	    fullProtocol ifTrue:[
       
  1955 		actualClass := currentClass.
       
  1956 		self updateClassList.
       
  1957 		self updateMethodCategoryListWithScroll:false.
       
  1958 		self updateMethodListWithScroll:false.
       
  1959 		self updateVariableList.
       
  1960 		^ self
       
  1961 	    ].
       
  1962 	    currentClass notNil ifTrue:[
       
  1963 		self classSelectionChanged
       
  1964 	    ].
       
  1965 	    codeView modified:false.
       
  1966 	] ifFalse:[
       
  1967 	    instanceToggle turnOff.
       
  1968 	    classToggle turnOn
       
  1969 	]
       
  1970     ]
       
  1971 !
       
  1972 
       
  1973 classProtocol
       
  1974     "switch to class protocol"
       
  1975 
       
  1976     showInstance ifTrue:[
       
  1977 	self checkSelectionChangeAllowed ifTrue:[
       
  1978 	    instanceToggle turnOff.
       
  1979 	    classToggle turnOn.
       
  1980 	    showInstance := false.
       
  1981 
       
  1982 	    (variableListView notNil
       
  1983 	    and:[variableListView hasSelection]) ifTrue:[
       
  1984 		self unhilightMethodCategories.
       
  1985 		self unhilightMethods.
       
  1986 		variableListView deselect
       
  1987 	    ].
       
  1988 
       
  1989 	    fullProtocol ifTrue:[
       
  1990 		actualClass := currentClass class.
       
  1991 		self updateClassList.
       
  1992 		self updateMethodCategoryListWithScroll:false.
       
  1993 		self updateMethodListWithScroll:false.
       
  1994 		self updateVariableList.
       
  1995 		^ self
       
  1996 	    ].
       
  1997 	    currentClass notNil ifTrue:[
       
  1998 		self classSelectionChanged
       
  1999 	    ].
       
  2000 	    codeView modified:false.
       
  2001 	] ifFalse:[
       
  2002 	    instanceToggle turnOn.
       
  2003 	    classToggle turnOff
       
  2004 	]
       
  2005     ]
       
  2006 ! !
       
  2007 
       
  2008 !SystemBrowser methodsFor:'method category stuff'!
       
  2009 
       
  2010 updateMethodCategoryListWithScroll:scroll
       
  2011     |categories|
       
  2012 
       
  2013     methodCategoryListView notNil ifTrue:[
       
  2014 	fullProtocol ifTrue:[
       
  2015 	    currentClassHierarchy notNil ifTrue:[
       
  2016 		categories := self listOfAllMethodCategoriesInFullProtocolHierarchy:currentClassHierarchy
       
  2017 	    ]
       
  2018 	] ifFalse:[
       
  2019 	    currentClass notNil ifTrue:[
       
  2020 		categories := self listOfAllMethodCategoriesInClass:actualClass
       
  2021 	    ]
       
  2022 	].
       
  2023 	methodCategoryListView list = categories ifFalse:[
       
  2024 	    scroll ifTrue:[
       
  2025 		methodCategoryListView contents:categories
       
  2026 	    ] ifFalse:[
       
  2027 		methodCategoryListView setContents:categories
       
  2028 	    ].
       
  2029 	    currentMethodCategory notNil ifTrue:[
       
  2030 		methodCategoryListView selectElement:currentMethodCategory
       
  2031 	    ]
       
  2032 	]
       
  2033     ]
       
  2034 !
       
  2035 
       
  2036 listOfAllMethodCategoriesInClass:aClass
       
  2037     "answer a list of all method categories of the argument, aClass"
       
  2038 
       
  2039     |newList cat|
       
  2040 
       
  2041     newList := Text new.
       
  2042     aClass methodArray do:[:aMethod |
       
  2043 	cat := aMethod category.
       
  2044 	cat isNil ifTrue:[
       
  2045 	    cat := '* no category *'
       
  2046 	].
       
  2047 	(newList includes:cat) ifFalse:[newList add:cat]
       
  2048     ].
       
  2049     (newList size == 0) ifTrue:[^ nil].
       
  2050     newList add:'* all *'.
       
  2051     ^ newList sort
       
  2052 !
       
  2053 
       
  2054 methodCategorySelection:lineNr
       
  2055     "user clicked on a method category line - show selectors"
       
  2056 
       
  2057     |oldSelector|
       
  2058 
       
  2059     oldSelector := currentSelector.
       
  2060 
       
  2061     (fullProtocol not and:[currentClass isNil]) ifTrue:[^ self].
       
  2062 
       
  2063     currentMethodCategory := methodCategoryListView selectionValue.
       
  2064     self methodCategorySelectionChanged.
       
  2065 
       
  2066     "if there is only one method, show it right away"
       
  2067     methodListView list size == 1 ifTrue:[
       
  2068 	methodListView selection:1.
       
  2069 	self methodSelection:1
       
  2070     ] ifFalse:[
       
  2071 	oldSelector notNil ifTrue:[
       
  2072 	    methodListView selectElement:oldSelector.
       
  2073 	    methodListView selection notNil ifTrue:[
       
  2074 		self methodSelection:methodListView selection.
       
  2075 	    ]
       
  2076 	]
       
  2077     ]
       
  2078 
       
  2079 !
       
  2080 
       
  2081 updateMethodCategoryList
       
  2082     self updateMethodCategoryListWithScroll:true
       
  2083 !
       
  2084 
       
  2085 methodCategorySelectionChanged
       
  2086     "method category selection has changed - update dependant views"
       
  2087 
       
  2088     self withWaitCursorDo:[
       
  2089 	currentMethod := currentSelector := nil.
       
  2090 
       
  2091 	self updateMethodList.
       
  2092 	self updateCodeView.
       
  2093 
       
  2094 	currentMethodCategory notNil ifTrue:[
       
  2095 	    methodCategoryListView selectElement:currentMethodCategory
       
  2096 	].
       
  2097 
       
  2098 	self setAcceptAndExplainActionsForMethod.
       
  2099 	self hilightMethodsInMethodCategoryList:false inMethodList:true.
       
  2100     ]
       
  2101 !
       
  2102 
       
  2103 listOfAllMethodCategoriesInFullProtocolHierarchy:aClass
       
  2104     "answer a list of all method categories of the argument, aClass,
       
  2105      and all of its superclasses.
       
  2106      Used with fullProtocol browsing."
       
  2107 
       
  2108     |newList cat|
       
  2109 
       
  2110     newList := Text new.
       
  2111     self classesInFullProtocolHierarchy:aClass do:[:c |
       
  2112 	c methodArray do:[:aMethod |
       
  2113 	    cat := aMethod category.
       
  2114 	    cat isNil ifTrue:[
       
  2115 		cat := '* no category *'
       
  2116 	    ].
       
  2117 	    (newList includes:cat) ifFalse:[newList add:cat]
       
  2118 	]
       
  2119     ].
       
  2120     (newList size == 0) ifTrue:[^ nil].
       
  2121     newList add:'* all *'.
       
  2122     ^ newList sort
       
  2123 
       
  2124 !
       
  2125 
       
  2126 checkMethodCategorySelected
       
  2127     currentMethodCategory isNil ifTrue:[
       
  2128 	self warn:'select a method category first'.
       
  2129 	^ false
       
  2130     ].
       
  2131     ^ true
       
  2132 !
       
  2133 
       
  2134 whenMethodCategorySelected:aBlock
       
  2135     self checkMethodCategorySelected ifTrue:[
       
  2136 	self withWaitCursorDo:aBlock
       
  2137     ]
       
  2138 !
       
  2139 
       
  2140 copyMethodsFromClass:aClassName
       
  2141     |class box|
       
  2142 
       
  2143     currentClass notNil ifTrue:[
       
  2144 	Symbol hasInterned:aClassName ifTrue:[:sym |
       
  2145 	    (Smalltalk includesKey:sym) ifTrue:[
       
  2146 		class := Smalltalk at:sym
       
  2147 	    ].
       
  2148 	].
       
  2149 	class isBehavior ifFalse:[
       
  2150 	    self warn:'no class named %1' with:aClassName.
       
  2151 	    ^ self
       
  2152 	].
       
  2153 
       
  2154 	showInstance ifFalse:[
       
  2155 	    class := class class
       
  2156 	].
       
  2157 
       
  2158 	"show enterbox for category to copy from"
       
  2159 
       
  2160 	box := self enterBoxTitle:'name of category to copy from (matchpattern allowed, * for all):'
       
  2161 			   okText:'copy'.
       
  2162 	box action:[:aString | self copyMethodsFromClass:class category:aString].
       
  2163 	box showAtPointer.
       
  2164     ]
       
  2165 !
       
  2166 
       
  2167 copyMethodsFromClass:class category:category
       
  2168     |source|
       
  2169 
       
  2170     currentClass notNil ifTrue:[
       
  2171 "/        codeView abortAction:[^ self].
       
  2172 	Object abortSignal catch:[
       
  2173 	    class methodArray do:[:aMethod |
       
  2174 		(category match:aMethod category) ifTrue:[
       
  2175 		    source := aMethod source.
       
  2176 		    codeView contents:source.
       
  2177 		    codeView modified:false.
       
  2178 		    actualClass compiler compile:source 
       
  2179 					forClass:actualClass 
       
  2180 				      inCategory:aMethod category
       
  2181 				       notifying:codeView.
       
  2182 		    self updateMethodCategoryListWithScroll:false.
       
  2183 		    self updateMethodListWithScroll:false.
       
  2184 		]
       
  2185 	    ]
       
  2186 	]
       
  2187     ]
       
  2188 !
       
  2189 
       
  2190 newMethodCategory:aString
       
  2191     |categories|
       
  2192 
       
  2193     currentClass isNil ifTrue:[
       
  2194 	^ self warn:'select/create a class first'.
       
  2195     ].
       
  2196     categories := methodCategoryListView list.
       
  2197     categories isNil ifTrue:[categories := Text new].
       
  2198     (categories includes:aString) ifFalse:[
       
  2199 	categories add:aString.
       
  2200 	categories sort.
       
  2201 	methodCategoryListView contents:categories
       
  2202     ].
       
  2203     currentMethodCategory := aString.
       
  2204     self methodCategorySelectionChanged
   831 ! !
  2205 ! !
   832 
  2206 
   833 !SystemBrowser methodsFor:'initialize / release'!
  2207 !SystemBrowser methodsFor:'initialize / release'!
   834 
  2208 
   835 initialize
  2209 initialize
   838     self icon:(Form fromFile:(resources at:'ICON_FILE' default:'SBrowser.xbm')
  2212     self icon:(Form fromFile:(resources at:'ICON_FILE' default:'SBrowser.xbm')
   839 		  resolution:100).
  2213 		  resolution:100).
   840 
  2214 
   841     showInstance := true.
  2215     showInstance := true.
   842     fullClass := false.
  2216     fullClass := false.
       
  2217     fullProtocol := false.
   843     aspect := nil.
  2218     aspect := nil.
   844 
  2219 
   845     "inform me, when Smalltalk changes"
  2220     "inform me, when Smalltalk changes"
   846     Smalltalk addDependent:self
  2221     Smalltalk addDependent:self
       
  2222 !
       
  2223 
       
  2224 realize
       
  2225     |v checkBlock|
       
  2226 
       
  2227     super realize.
       
  2228 
       
  2229     checkBlock := [:lineNr | self checkSelectionChangeAllowed].
       
  2230 
       
  2231     v := classCategoryListView.
       
  2232     v notNil ifTrue:[
       
  2233 	v action:[:lineNr | self classCategorySelection:lineNr].
       
  2234 	v selectConditionBlock:checkBlock.
       
  2235 	v ignoreReselect:false.
       
  2236 	v contents:(self listOfAllClassCategories).
       
  2237 	self initializeClassCategoryMenu
       
  2238     ].
       
  2239 
       
  2240     v := classListView.
       
  2241     v notNil ifTrue:[
       
  2242 	v action:[:lineNr | self classSelection:lineNr].
       
  2243 	v selectConditionBlock:checkBlock.
       
  2244 	v ignoreReselect:false.
       
  2245 	self initializeClassMenu
       
  2246     ].
       
  2247 
       
  2248     v := methodCategoryListView.
       
  2249     v notNil ifTrue:[
       
  2250 	v action:[:lineNr | self methodCategorySelection:lineNr].
       
  2251 	v selectConditionBlock:checkBlock.
       
  2252 	v ignoreReselect:false.
       
  2253 	self initializeMethodCategoryMenu
       
  2254     ].
       
  2255 
       
  2256     v := methodListView.
       
  2257     v notNil ifTrue:[
       
  2258 	v action:[:lineNr | self methodSelection:lineNr].
       
  2259 	v selectConditionBlock:checkBlock.
       
  2260 	v ignoreReselect:false.
       
  2261 	self initializeMethodMenu
       
  2262     ].
       
  2263 
       
  2264     v := classMethodListView.
       
  2265     v notNil ifTrue:[
       
  2266 	v action:[:lineNr | self classMethodSelection:lineNr].
       
  2267 	v selectConditionBlock:checkBlock.
       
  2268 	v ignoreReselect:false.
       
  2269 	self initializeClassMethodMenu
       
  2270     ].
       
  2271 
       
  2272     v := variableListView.
       
  2273     v notNil ifTrue:[
       
  2274 	v action:[:lineNr | self variableSelection:lineNr].
       
  2275 	v ignoreReselect:false.
       
  2276 	v toggleSelect:true
       
  2277     ]
       
  2278 
       
  2279 !
       
  2280 
       
  2281 terminate
       
  2282     (self checkSelectionChangeAllowed) ifTrue:[
       
  2283 	super terminate
       
  2284     ]
   847 !
  2285 !
   848 
  2286 
   849 destroy
  2287 destroy
   850     "relese dependant - destroy popups"
  2288     "relese dependant - destroy popups"
   851 
  2289 
   855 	currentClass := nil
  2293 	currentClass := nil
   856     ].
  2294     ].
   857     super destroy
  2295     super destroy
   858 !
  2296 !
   859 
  2297 
   860 terminate
  2298 autoSearch:aString
   861     (self checkSelectionChangeAllowed) ifTrue:[
  2299     "used with class-method list browsing. If true,
   862 	super terminate
  2300      selecting an entry from the list will automatically
   863     ]
  2301      search for the searchstring in the codeView"
   864 !
  2302 
   865 
  2303     self setSearchPattern:aString.
   866 createTogglesIn:aFrame
  2304     autoSearch := aString
   867     "create and setup the class/instance toggles"
  2305 !
   868 
  2306 
   869     |halfSpacing h|
  2307 title:someString
   870 
  2308     myLabel := someString.
   871     instanceToggle := Toggle label:(resources at:'instance') in:aFrame.
  2309     self label:someString.
   872     h := instanceToggle height.
  2310 
   873     instanceToggle origin:(0.0 @ 1.0) corner:(0.5 @ 1.0).
  2311 ! !
   874     instanceToggle topInset:(h negated).
  2312 
   875 
  2313 !SystemBrowser methodsFor:'initialize subviews'!
   876     instanceToggle turnOn.
       
   877     instanceToggle pressAction:[self instanceProtocol].
       
   878     instanceToggle releaseAction:[self classProtocol].
       
   879 
       
   880     classToggle := Toggle label:(resources at:'class') in:aFrame.
       
   881     h := classToggle height.
       
   882     classToggle origin:(0.5 @ 1.0) corner:(1.0 @ 1.0).
       
   883     classToggle topInset:(h negated).
       
   884 
       
   885     classToggle turnOff.
       
   886     classToggle pressAction:[self classProtocol].
       
   887     classToggle releaseAction:[self instanceProtocol].
       
   888 
       
   889      StyleSheet is3D ifTrue:[
       
   890 	instanceToggle leftInset:(ViewSpacing // 2).
       
   891 	classToggle leftInset:(ViewSpacing // 2).
       
   892 	instanceToggle rightInset:ViewSpacing - (ViewSpacing // 2).
       
   893 	classToggle rightInset:ViewSpacing - (ViewSpacing // 2).
       
   894     ].
       
   895 !
       
   896 
  2314 
   897 createClassListViewIn:frame
  2315 createClassListViewIn:frame
   898     "setup the classlist subview, with its toggles"
  2316     "setup the classlist subview, with its toggles"
   899 
  2317 
   900     |v panel oldStyle|
  2318     |v panel oldStyle|
   926 			      - instanceToggle borderWidth
  2344 			      - instanceToggle borderWidth
   927 			      + v borderWidth)]
  2345 			      + v borderWidth)]
   928 			in:frame.
  2346 			in:frame.
   929 
  2347 
   930 	v := ScrollableView for:SelectionInListView in:panel.
  2348 	v := ScrollableView for:SelectionInListView in:panel.
   931 	v origin:(0.0 @ 0.0) corner:(1.0 @ 0.5).
  2349 	v origin:(0.0 @ 0.0) corner:(1.0 @ 0.7).
   932 	classListView := v scrolledView.
  2350 	classListView := v scrolledView.
   933 
  2351 
   934 
  2352 
   935 	v := ScrollableView for:SelectionInListView in:panel.
  2353 	v := ScrollableView for:SelectionInListView in:panel.
   936 	v origin:(0.0 @ 0.5)
  2354 	v origin:(0.0 @ 0.7)
   937 	  corner:(1.0 @ 1.0).
  2355 	  corner:(1.0 @ 1.0).
   938 
  2356 
   939 	variableListView := v scrolledView
  2357 	variableListView := v scrolledView
   940     ]
  2358     ]
       
  2359 !
       
  2360 
       
  2361 createCodeViewIn:aView at:relY
       
  2362     "setup the code view"
       
  2363     |v|
       
  2364 
       
  2365     v := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:aView.
       
  2366     v origin:(0.0 @ relY) corner:(1.0 @ 1.0).
       
  2367     codeView := v scrolledView
       
  2368 !
       
  2369 
       
  2370 createTogglesIn:aFrame
       
  2371     "create and setup the class/instance toggles"
       
  2372 
       
  2373     |halfSpacing h classAction instanceAction|
       
  2374 
       
  2375     classAction := [self classProtocol].
       
  2376     instanceAction := [self instanceProtocol].
       
  2377 
       
  2378     instanceToggle := Toggle label:(resources at:'instance') in:aFrame.
       
  2379     h := instanceToggle height.
       
  2380     instanceToggle origin:(0.0 @ 1.0) corner:(0.5 @ 1.0).
       
  2381     instanceToggle topInset:(h negated).
       
  2382 
       
  2383     instanceToggle turnOn.
       
  2384     instanceToggle pressAction:instanceAction.
       
  2385     instanceToggle releaseAction:classAction.
       
  2386 
       
  2387     classToggle := Toggle label:(resources at:'class') in:aFrame.
       
  2388     h := classToggle height.
       
  2389     classToggle origin:(0.5 @ 1.0) corner:(1.0 @ 1.0).
       
  2390     classToggle topInset:(h negated).
       
  2391 
       
  2392     classToggle turnOff.
       
  2393     classToggle pressAction:classAction.
       
  2394     classToggle releaseAction:instanceAction.
       
  2395 
       
  2396      StyleSheet is3D ifTrue:[
       
  2397 	instanceToggle leftInset:(ViewSpacing // 2).
       
  2398 	classToggle leftInset:(ViewSpacing // 2).
       
  2399 	instanceToggle rightInset:ViewSpacing - (ViewSpacing // 2).
       
  2400 	classToggle rightInset:ViewSpacing - (ViewSpacing // 2).
       
  2401     ].
   941 !
  2402 !
   942 
  2403 
   943 createCodeViewIn:aView
  2404 createCodeViewIn:aView
   944     "setup the code view"
  2405     "setup the code view"
   945     |v|
  2406 
   946 
  2407     ^ self createCodeViewIn:aView at:0.25
   947     v := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:aView.
  2408 !
   948     v origin:(0.0 @ 0.25) corner:(1.0 @ 1.0).
  2409 
   949     codeView := v scrolledView
  2410 setupForList:aList
   950 !
  2411     "setup subviews to browse methods from a list"
   951 
  2412 
   952 setupActions
  2413     |vpanel v|
   953 "/    |v|
  2414 
   954 
  2415     vpanel := VariableVerticalPanel
   955 "/    v := classCategoryListView.
  2416 			origin:(0.0 @ 0.0)
   956 "/    v notNil ifTrue:[
  2417 			corner:(1.0 @ 1.0)
   957 "/        v action:[:lineNr | self classCategorySelection:lineNr].
  2418 			    in:self.
   958 "/        v selectConditionBlock:[self checkSelectionChangeAllowed].
  2419 
   959 "/        v ignoreReselect:false.
  2420     v := ScrollableView for:SelectionInListView in:vpanel.
   960 "/    ].
  2421     v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25).
   961 "/    v := classListView.
  2422     classMethodListView := v scrolledView.
   962 "/    v notNil ifTrue:[
  2423     classMethodListView contents:aList.
   963 "/        v action:[:lineNr | self classSelection:lineNr].
  2424 
   964 "/        v selectConditionBlock:[self checkSelectionChangeAllowed].
  2425     self createCodeViewIn:vpanel.
   965 "/        v ignoreReselect:false.
  2426     self updateCodeView
   966 "/    ].
       
   967 "/    v := methodCategoryListView.
       
   968 "/    v notNil ifTrue:[
       
   969 "/        v action:[:lineNr | self methodCategorySelection:lineNr].
       
   970 "/        v selectConditionBlock:[self checkSelectionChangeAllowed].
       
   971 "/        v ignoreReselect:false.
       
   972 "/    ].
       
   973 "/    v := methodListView.
       
   974 "/    v notNil ifTrue:[
       
   975 "/        v action:[:lineNr | self methodSelection:lineNr].
       
   976 "/        v selectConditionBlock:[self checkSelectionChangeAllowed].
       
   977 "/        v ignoreReselect:false.
       
   978 "/    ].
       
   979 "/    v := classMethodListView.
       
   980 "/    v notNil ifTrue:[
       
   981 "/        v action:[:lineNr | self listSelection:lineNr].
       
   982 "/        v selectConditionBlock:[self checkSelectionChangeAllowed].
       
   983 "/        v ignoreReselect:false.
       
   984 "/    ]
       
   985 !
  2427 !
   986 
  2428 
   987 setupForAll
  2429 setupForAll
   988     "create subviews for a full browser"
  2430     "create subviews for a full browser"
   989 
  2431 
   996     v := HVScrollableView for:SelectionInListView
  2438     v := HVScrollableView for:SelectionInListView
   997 			  miniScrollerH:true miniScrollerV:false
  2439 			  miniScrollerH:true miniScrollerV:false
   998 			  in:hpanel.
  2440 			  in:hpanel.
   999     v origin:(0.0 @ 0.0) corner:(0.25 @ 1.0).
  2441     v origin:(0.0 @ 0.0) corner:(0.25 @ 1.0).
  1000     classCategoryListView := v scrolledView.
  2442     classCategoryListView := v scrolledView.
  1001 "/    classCategoryListView contents:(self listOfAllClassCategories).
       
  1002 
  2443 
  1003     frame := View origin:(0.25 @ 0.0) corner:(0.5 @ 1.0) in:hpanel.
  2444     frame := View origin:(0.25 @ 0.0) corner:(0.5 @ 1.0) in:hpanel.
  1004     self createClassListViewIn:frame.
  2445     self createClassListViewIn:frame.
  1005 
  2446 
  1006     v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel.
  2447     v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel.
  1009 
  2450 
  1010     v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel.
  2451     v := HVScrollableView for:SelectionInListView miniScrollerH:true miniScrollerV:false in:hpanel.
  1011     v origin:(0.75 @ 0.0) corner:(1.0 @ 1.0).
  2452     v origin:(0.75 @ 0.0) corner:(1.0 @ 1.0).
  1012     methodListView := v scrolledView.
  2453     methodListView := v scrolledView.
  1013 
  2454 
  1014 "/    self setupActions.
       
  1015     self createCodeViewIn:vpanel
  2455     self createCodeViewIn:vpanel
       
  2456 !
       
  2457 
       
  2458 setupForClassHierarchy:aClass
       
  2459     "setup subviews to browse a class hierarchy"
       
  2460 
       
  2461     |vpanel hpanel frame v|
       
  2462 
       
  2463     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0)
       
  2464 				    corner:(1.0 @ 1.0)
       
  2465 					in:self.
       
  2466 
       
  2467     "
       
  2468      notice: we use a different ratio here
       
  2469     "
       
  2470     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel.
       
  2471     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  2472 
       
  2473     self createClassListViewIn:frame.
       
  2474 
       
  2475     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2476     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  2477     methodCategoryListView := v scrolledView.
       
  2478 
       
  2479     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2480     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  2481     methodListView := v scrolledView.
       
  2482 
       
  2483     self createCodeViewIn:vpanel at:0.4.
       
  2484 
       
  2485     currentClassHierarchy := aClass.
       
  2486     self updateClassList.
       
  2487     self updateMethodCategoryList.
       
  2488     self updateMethodList.
       
  2489     self updateCodeView
  1016 !
  2490 !
  1017 
  2491 
  1018 setupForFullClass
  2492 setupForFullClass
  1019     "setup subviews to browse a class as full text"
  2493     "setup subviews to browse a class as full text"
  1020 
  2494 
  1033 
  2507 
  1034     v := ScrollableView for:SelectionInListView in:hpanel.
  2508     v := ScrollableView for:SelectionInListView in:hpanel.
  1035     v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0).
  2509     v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0).
  1036     classListView := v scrolledView.
  2510     classListView := v scrolledView.
  1037 
  2511 
  1038 "/    self setupActions.
       
  1039     self createCodeViewIn:vpanel.
  2512     self createCodeViewIn:vpanel.
  1040 
  2513 
  1041     fullClass := true.
  2514     fullClass := true.
  1042     self updateCodeView
       
  1043 !
       
  1044 
       
  1045 setupForClassCategory:aClassCategory
       
  1046     "setup subviews to browse a class category"
       
  1047 
       
  1048     |vpanel hpanel frame v|
       
  1049 
       
  1050     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) 
       
  1051 				    corner:(1.0 @ 1.0)
       
  1052 					in:self.
       
  1053 
       
  1054     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel.
       
  1055     frame  := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  1056 
       
  1057     self createClassListViewIn:frame.
       
  1058 
       
  1059     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1060     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  1061     methodCategoryListView := v scrolledView.
       
  1062 
       
  1063     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1064     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  1065     methodListView := v scrolledView.
       
  1066 
       
  1067 "/    self setupActions.
       
  1068     self createCodeViewIn:vpanel.
       
  1069 
       
  1070     currentClassCategory := aClassCategory.
       
  1071     self updateClassList.
       
  1072     self updateMethodCategoryList.
       
  1073     self updateMethodList.
       
  1074     self updateCodeView
       
  1075 !
       
  1076 
       
  1077 setupForClassList:aList
       
  1078     "setup subviews to browse classes from a list"
       
  1079 
       
  1080     |vpanel hpanel frame l v|
       
  1081 
       
  1082     vpanel := VariableVerticalPanel 
       
  1083 		 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:self.
       
  1084 
       
  1085     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel.
       
  1086     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  1087 
       
  1088     self createClassListViewIn:frame.
       
  1089 
       
  1090     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1091     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  1092     methodCategoryListView := v scrolledView.
       
  1093 
       
  1094     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1095     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  1096     methodListView := v scrolledView.
       
  1097 
       
  1098 "/    self setupActions.
       
  1099     self createCodeViewIn:vpanel.
       
  1100 
       
  1101     l := aList collect:[:entry | entry name].
       
  1102     classListView list:(l sort).
       
  1103 
       
  1104     self updateMethodCategoryList.
       
  1105     self updateMethodList.
       
  1106     self updateCodeView
       
  1107 !
       
  1108 
       
  1109 setupForClassHierarchy:aClass
       
  1110     "setup subviews to browse a class hierarchy"
       
  1111 
       
  1112     |vpanel hpanel frame v|
       
  1113 
       
  1114     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0)
       
  1115 				    corner:(1.0 @ 1.0)
       
  1116 					in:self.
       
  1117 
       
  1118     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel.
       
  1119     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  1120 
       
  1121     self createClassListViewIn:frame.
       
  1122 
       
  1123     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1124     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  1125     methodCategoryListView := v scrolledView.
       
  1126 
       
  1127     v := ScrollableView for:SelectionInListView in:hpanel.
       
  1128     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  1129     methodListView := v scrolledView.
       
  1130 
       
  1131 "/    self setupActions.
       
  1132     self createCodeViewIn:vpanel.
       
  1133 
       
  1134     currentClassHierarchy := aClass.
       
  1135     self updateClassList.
       
  1136     self updateMethodCategoryList.
       
  1137     self updateMethodList.
       
  1138     self updateCodeView
  2515     self updateCodeView
  1139 !
  2516 !
  1140 
  2517 
  1141 setupForClass:aClass
  2518 setupForClass:aClass
  1142     "create subviews for browsing a single class"
  2519     "create subviews for browsing a single class"
  1165 
  2542 
  1166     v := ScrollableView for:SelectionInListView in:hpanel.
  2543     v := ScrollableView for:SelectionInListView in:hpanel.
  1167     v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0).
  2544     v origin:(0.5 @ 0.0) corner:(1.0 @ 1.0).
  1168     methodListView := v scrolledView.
  2545     methodListView := v scrolledView.
  1169 
  2546 
  1170 "/    self setupActions.
       
  1171     self createCodeViewIn:vpanel.
  2547     self createCodeViewIn:vpanel.
  1172 
  2548 
  1173     self switchToClass:aClass.
  2549     self switchToClass:aClass.
  1174     actualClass := aClass.
  2550     actualClass := aClass.
  1175     self updateMethodCategoryList.
  2551     self updateMethodCategoryList.
  1176     self updateMethodList.
  2552     self updateMethodList.
  1177     self updateCodeView
  2553     self updateCodeView
  1178 !
  2554 !
  1179 
  2555 
       
  2556 setupForClassCategory:aClassCategory
       
  2557     "setup subviews to browse a class category"
       
  2558 
       
  2559     |vpanel hpanel frame v|
       
  2560 
       
  2561     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0) 
       
  2562 				    corner:(1.0 @ 1.0)
       
  2563 					in:self.
       
  2564 
       
  2565     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel.
       
  2566     frame  := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  2567 
       
  2568     self createClassListViewIn:frame.
       
  2569 
       
  2570     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2571     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  2572     methodCategoryListView := v scrolledView.
       
  2573 
       
  2574     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2575     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  2576     methodListView := v scrolledView.
       
  2577 
       
  2578     self createCodeViewIn:vpanel.
       
  2579 
       
  2580     currentClassCategory := aClassCategory.
       
  2581     self updateClassList.
       
  2582     self updateMethodCategoryList.
       
  2583     self updateMethodList.
       
  2584     self updateCodeView
       
  2585 !
       
  2586 
       
  2587 setupForClass:aClass selector:selector
       
  2588     "setup subviews to browse a single method"
       
  2589 
       
  2590     |v|
       
  2591 
       
  2592     v := ScrollableView for:CodeView in:self.
       
  2593     v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
       
  2594     codeView := v scrolledView.
       
  2595 
       
  2596     currentClassCategory := aClass category.
       
  2597     self switchToClass:aClass.
       
  2598     actualClass := aClass.
       
  2599     currentSelector := selector.
       
  2600     currentMethod := currentClass compiledMethodAt:selector.
       
  2601     currentMethodCategory := currentMethod category.
       
  2602     self updateCodeView
       
  2603 !
       
  2604 
       
  2605 setupForClassList:aList
       
  2606     "setup subviews to browse classes from a list"
       
  2607 
       
  2608     |vpanel hpanel frame l v|
       
  2609 
       
  2610     vpanel := VariableVerticalPanel 
       
  2611 		 origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:self.
       
  2612 
       
  2613     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.25) in:vpanel.
       
  2614     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  2615 
       
  2616     self createClassListViewIn:frame.
       
  2617 
       
  2618     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2619     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  2620     methodCategoryListView := v scrolledView.
       
  2621 
       
  2622     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2623     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  2624     methodListView := v scrolledView.
       
  2625 
       
  2626     self createCodeViewIn:vpanel.
       
  2627 
       
  2628     l := aList collect:[:entry | entry name].
       
  2629     classListView list:(l sort).
       
  2630 
       
  2631     self updateMethodCategoryList.
       
  2632     self updateMethodList.
       
  2633     self updateCodeView
       
  2634 !
       
  2635 
  1180 setupForClass:aClass methodCategory:aMethodCategory
  2636 setupForClass:aClass methodCategory:aMethodCategory
  1181     "setup subviews to browse a method category"
  2637     "setup subviews to browse a method category"
  1182 
  2638 
  1183     |vpanel v|
  2639     |vpanel v|
  1184 
  2640 
  1188 
  2644 
  1189     v := ScrollableView for:SelectionInListView in:vpanel.
  2645     v := ScrollableView for:SelectionInListView in:vpanel.
  1190     v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25).
  2646     v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25).
  1191     methodListView := v scrolledView.
  2647     methodListView := v scrolledView.
  1192 
  2648 
  1193 "/    self setupActions.
       
  1194     self createCodeViewIn:vpanel.
  2649     self createCodeViewIn:vpanel.
  1195 
  2650 
  1196     currentClassCategory := aClass category.
  2651     currentClassCategory := aClass category.
  1197     self switchToClass:aClass.
  2652     self switchToClass:aClass.
  1198     actualClass := aClass.
  2653     actualClass := aClass.
  1199     currentMethodCategory := aMethodCategory.
  2654     currentMethodCategory := aMethodCategory.
  1200     self updateMethodList.
  2655     self updateMethodList.
  1201     self updateCodeView
  2656     self updateCodeView
  1202 !
  2657 !
  1203 
  2658 
  1204 setupForClass:aClass selector:selector
  2659 setupForFullClassProtocol:aClass
  1205     "setup subviews to browse a single method"
  2660     "setup subviews to browse a classes full protocol"
  1206 
  2661 
  1207     |v|
  2662     |vpanel hpanel frame v|
  1208 
  2663 
  1209     v := ScrollableView for:CodeView in:self.
  2664     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0)
  1210     v origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
  2665 				    corner:(1.0 @ 1.0)
  1211     codeView := v scrolledView.
  2666 					in:self.
  1212 
  2667 
  1213     currentClassCategory := aClass category.
  2668     "
  1214     self switchToClass:aClass.
  2669      notice: we use a different ratio here
  1215     actualClass := aClass.
  2670     "
  1216     currentMethod := currentClass compiledMethodAt:selector.
  2671     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel.
  1217     currentMethodCategory := currentMethod category.
  2672     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
  1218     self updateCodeView
  2673 
  1219 !
  2674     self createClassListViewIn:frame.
  1220 
  2675     classListView multipleSelectOk:true.
  1221 setupForList:aList
  2676     classListView toggleSelect:true.
  1222     "setup subviews to browse methods from a list"
  2677     classListView strikeOut:true.
  1223 
  2678 
  1224     |vpanel v|
  2679     v := ScrollableView for:SelectionInListView in:hpanel.
  1225 
  2680     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
  1226     vpanel := VariableVerticalPanel
  2681     methodCategoryListView := v scrolledView.
  1227 			origin:(0.0 @ 0.0)
  2682 
  1228 			corner:(1.0 @ 1.0)
  2683     v := ScrollableView for:SelectionInListView in:hpanel.
  1229 			    in:self.
  2684     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
  1230 
  2685     methodListView := v scrolledView.
  1231     v := ScrollableView for:SelectionInListView in:vpanel.
  2686 
  1232     v origin:(0.0 @ 0.0) corner:(1.0 @ 0.25).
  2687     self createCodeViewIn:vpanel at:0.4.
  1233     classMethodListView := v scrolledView.
  2688 
  1234     classMethodListView contents:aList.
  2689     currentClassHierarchy := actualClass := currentClass := aClass.
       
  2690     fullProtocol := true.
       
  2691 
       
  2692     self updateClassList.
       
  2693     self updateMethodCategoryList.
       
  2694     self updateMethodList.
       
  2695     self updateCodeView.
       
  2696     self updateVariableList.
       
  2697 
       
  2698 !
       
  2699 
       
  2700 setupForFullClassHierarchy:aClass
       
  2701     "setup subviews to browse a class hierarchy"
       
  2702 
       
  2703     |vpanel hpanel frame v|
       
  2704 
       
  2705     vpanel := VariableVerticalPanel origin:(0.0 @ 0.0)
       
  2706 				    corner:(1.0 @ 1.0)
       
  2707 					in:self.
       
  2708 
       
  2709     hpanel := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.4) in:vpanel.
       
  2710     frame := View origin:(0.0 @ 0.0) corner:(0.33 @ 1.0) in:hpanel.
       
  2711 
       
  2712     self createClassListViewIn:frame.
       
  2713     classListView multipleSelectOk:true.
       
  2714     classListView toggleSelect:true.
       
  2715     classListView strikeOut:true.
       
  2716 
       
  2717     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2718     v origin:(0.33 @ 0.0) corner:(0.66 @ 1.0).
       
  2719     methodCategoryListView := v scrolledView.
       
  2720 
       
  2721     v := ScrollableView for:SelectionInListView in:hpanel.
       
  2722     v origin:(0.66 @ 0.0) corner:(1.0 @ 1.0).
       
  2723     methodListView := v scrolledView.
  1235 
  2724 
  1236 "/    self setupActions.
  2725 "/    self setupActions.
  1237     self createCodeViewIn:vpanel.
  2726     self createCodeViewIn:vpanel at:0.4.
  1238 
  2727 
  1239     self updateCodeView
  2728     currentClassHierarchy := actualClass := aClass.
       
  2729     fullProtocol := true.
       
  2730 
       
  2731     self updateClassList.
       
  2732     self updateMethodCategoryList.
       
  2733     self updateMethodList.
       
  2734     self updateCodeView.
       
  2735     self updateVariableList.
       
  2736 
  1240 ! !
  2737 ! !
  1241 
  2738 
  1242 !SystemBrowser methodsFor:'realization'!
  2739 !SystemBrowser methodsFor:'unused'!
  1243 
  2740 
  1244 realize
  2741 listOfAllSelectorsInCategory:aCategory inHierarchyOfClass:aClass
  1245     |v checkBlock|
  2742     "answer a list of all selectors in a given method category 
  1246 
  2743      of the argument, aClass and its superclasses"
  1247     super realize.
  2744 
  1248 
  2745     |newList thisList searchCategory selector|
  1249     checkBlock := [:lineNr | self checkSelectionChangeAllowed].
  2746 
  1250 
  2747     newList := Set new.
  1251     v := classCategoryListView.
  2748     self classesInHierarchy:aClass do:[:c |
  1252     v notNil ifTrue:[
  2749 	(aCategory = '* all *') ifTrue:[
  1253 	v action:[:lineNr | self classCategorySelection:lineNr].
  2750 	    newList addAll:(c selectorArray)
  1254 	v selectConditionBlock:checkBlock.
  2751 	] ifFalse:[
  1255 	v ignoreReselect:false.
  2752 	    (aCategory = '* no category *') ifTrue:[
  1256 	v contents:(self listOfAllClassCategories).
  2753 		searchCategory := nil
  1257 	self initializeClassCategoryMenu
  2754 	    ] ifFalse:[
  1258     ].
  2755 		searchCategory := aCategory
  1259 
  2756 	    ].
  1260     v := classListView.
  2757 	    c methodArray with:c selectorArray do:[:aMethod :selector |
  1261     v notNil ifTrue:[
  2758 		(aMethod category = searchCategory) ifTrue:[
  1262 	v action:[:lineNr | self classSelection:lineNr].
  2759 		    newList add:selector
  1263 	v selectConditionBlock:checkBlock.
  2760 		]
  1264 	v ignoreReselect:false.
  2761 	    ]
  1265 	self initializeClassMenu
  2762 	].
  1266     ].
  2763     ].
  1267 
  2764     (newList size == 0) ifTrue:[^ nil].
  1268     v := methodCategoryListView.
  2765     ^ newList asOrderedCollection sort
  1269     v notNil ifTrue:[
  2766 !
  1270 	v action:[:lineNr | self methodCategorySelection:lineNr].
  2767 
  1271 	v selectConditionBlock:checkBlock.
  2768 listOfAllMethodCategoriesInHierarchy:aClass
  1272 	v ignoreReselect:false.
  2769     "answer a list of all method categories of the argument, aClass,
  1273 	self initializeMethodCategoryMenu
  2770      and all of its superclasses"
  1274     ].
  2771 
  1275 
  2772     |newList cat|
  1276     v := methodListView.
  2773 
  1277     v notNil ifTrue:[
  2774     newList := Text new.
  1278 	v action:[:lineNr | self methodSelection:lineNr].
  2775     self classesInHierarchy:aClass do:[:c |
  1279 	v selectConditionBlock:checkBlock.
  2776 	c methodArray do:[:aMethod |
  1280 	v ignoreReselect:false.
  2777 	    cat := aMethod category.
  1281 	self initializeMethodMenu
  2778 	    cat isNil ifTrue:[
  1282     ].
  2779 		cat := '* no category *'
  1283 
  2780 	    ].
  1284     v := classMethodListView.
  2781 	    (newList includes:cat) ifFalse:[newList add:cat]
  1285     v notNil ifTrue:[
  2782 	]
  1286 	v action:[:lineNr | self listSelection:lineNr].
  2783     ].
  1287 	v selectConditionBlock:checkBlock.
  2784     (newList size == 0) ifTrue:[^ nil].
  1288 	v ignoreReselect:false.
  2785     newList add:'* all *'.
  1289 	self initializeClassMethodMenu
  2786     ^ newList sort
  1290     ]
  2787 
  1291 ! !
  2788 ! !
  1292 
  2789 
  1293 !SystemBrowser methodsFor:'private'!
  2790 !SystemBrowser methodsFor:'class stuff'!
  1294 
       
  1295 checkSelectionChangeAllowed
       
  1296     "return true, if selection change is ok;
       
  1297      its not ok, if code has been changed.
       
  1298      in this case, return the result of a user query"
       
  1299 
       
  1300     |box|
       
  1301 
       
  1302     codeView modified ifFalse:[
       
  1303 	^ true
       
  1304     ].
       
  1305     box := YesNoBox 
       
  1306 	       title:(resources at:'contents in codeview has not been accepted.\\Modifications will be lost when continuing.') withCRs
       
  1307 	       yesText:(resources at:'continue')
       
  1308 	       noText:(resources at:'abort').
       
  1309     ^ box confirm
       
  1310 !
       
  1311 
  2791 
  1312 switchToClass:newClass
  2792 switchToClass:newClass
       
  2793     fullProtocol ifTrue:[^ self].
  1313     currentClass notNil ifTrue:[
  2794     currentClass notNil ifTrue:[
  1314 	currentClass removeDependent:self
  2795 	currentClass removeDependent:self
  1315     ].
  2796     ].
  1316     currentClass := newClass.
  2797     currentClass := newClass.
  1317     currentClass notNil ifTrue:[
  2798     currentClass notNil ifTrue:[
  1318 	currentClass addDependent:self.
  2799 	currentClass addDependent:self.
  1319     ].
  2800     ].
  1320     self normalLabel
  2801     self normalLabel
  1321 !
  2802 !
  1322 
  2803 
  1323 showExplanation:someText
  2804 classSelectionChanged
  1324     "show explanation from Parser"
  2805     |oldMethodCategory oldMethod oldSelector|
  1325 
  2806 
  1326     self notify:someText
  2807     self withWaitCursorDo:[
  1327 !
  2808 	oldMethodCategory := currentMethodCategory.
  1328 
  2809 	oldMethod := currentMethod.
  1329 normalLabel
  2810 	oldSelector := currentSelector.
  1330     "set the normal (inactive) window- and icon labels"
  2811 
  1331 
  2812 	showInstance ifTrue:[
  1332     currentClass notNil ifTrue:[
  2813 	    actualClass := currentClass
  1333 	self label:'System Browser: ', currentClass name.
       
  1334 	self iconLabel:currentClass name
       
  1335     ] ifFalse:[
       
  1336 	self label:'System Browser'.
       
  1337 	self iconLabel:'System Browser'.
       
  1338     ]
       
  1339 !
       
  1340 
       
  1341 setSearchPattern:aString
       
  1342     codeView setSearchPattern:aString
       
  1343 !
       
  1344 
       
  1345 selectorToSearchFor
       
  1346     "look in codeView and methodListView for a search-string when searching for selectors"
       
  1347 
       
  1348     |sel t|
       
  1349 
       
  1350     sel := codeView selection.
       
  1351     sel notNil ifTrue:[
       
  1352 	sel := sel asString.
       
  1353 	t := Parser selectorInExpression:sel.
       
  1354 	t notNil ifTrue:[
       
  1355 	    sel := t
       
  1356 	].
       
  1357 	sel := sel withoutSpaces
       
  1358     ] ifFalse:[
       
  1359 	methodListView notNil ifTrue:[
       
  1360 	    sel := methodListView selectionValue
       
  1361 	] ifFalse:[
  2814 	] ifFalse:[
  1362 	    classMethodListView notNil ifTrue:[
  2815 	    actualClass := currentClass class
  1363 		sel := classMethodListView selectionValue.
  2816 	].
  1364 		sel notNil ifTrue:[
  2817 	currentMethodCategory := nil.
  1365 		    sel := self selectorFromClassMethodString:sel
  2818 	currentMethod := nil.
  1366 		]
  2819 	currentSelector := nil.
       
  2820 
       
  2821 	self updateVariableList.
       
  2822 	self updateMethodCategoryList.
       
  2823 
       
  2824 	oldMethodCategory notNil ifTrue:[
       
  2825 	    methodCategoryListView selectElement:oldMethodCategory.
       
  2826 	    methodCategoryListView selection notNil ifTrue:[
       
  2827 		currentMethodCategory := oldMethodCategory.
       
  2828 		self methodCategorySelectionChanged
  1367 	    ]
  2829 	    ]
  1368 	].
  2830 	].
  1369 	sel notNil ifTrue:[
  2831 	self updateMethodList.
  1370 	    sel := sel withoutSpaces
  2832 	self updateCodeView.
       
  2833 
       
  2834 	fullClass ifTrue:[
       
  2835 	    codeView acceptAction:[:theCode |
       
  2836 		codeView cursor:Cursor execute.
       
  2837 		Object abortSignal catch:[
       
  2838 		    self compileCode:theCode asString.
       
  2839 		    codeView modified:false.
       
  2840 		].
       
  2841 		codeView cursor:Cursor normal.
       
  2842 	    ].
  1371 	] ifFalse:[
  2843 	] ifFalse:[
  1372 	    sel := ''
  2844 	    self classDefinition.
  1373 	]
  2845 	    codeView acceptAction:[:theCode |
  1374     ].
  2846 		codeView cursor:Cursor execute.
  1375     ^ sel
  2847 		Object abortSignal catch:[
  1376 !
  2848 		    (Compiler evaluate:theCode asString notifying:codeView)
  1377 
  2849 		    isBehavior ifTrue:[
  1378 stringToSearchFor
  2850 			self classCategoryUpdate.
  1379     "look in codeView and methodListView for a search-string when searching for classes/names"
  2851 			self updateClassListWithScroll:false.
  1380 
  2852 			codeView modified:false.
  1381     |sel|
  2853 		    ].
  1382 
  2854 		].
  1383     sel := codeView selection.
  2855 		codeView cursor:Cursor normal.
  1384     sel notNil ifTrue:[
  2856 	    ].
  1385 	sel := sel asString withoutSpaces
  2857 	].
  1386     ] ifFalse:[
  2858 	codeView explainAction:nil.
  1387 	sel isNil ifTrue:[
  2859 
  1388 	    currentClass notNil ifTrue:[
  2860 	classCategoryListView notNil ifTrue:[
  1389 		sel := currentClass name
  2861 	    (currentClassCategory = currentClass category) ifFalse:[
       
  2862 		currentClassCategory := currentClass category.
       
  2863 		classCategoryListView selectElement:currentClassCategory
  1390 	    ]
  2864 	    ]
  1391 	].
  2865 	].
  1392 	sel notNil ifTrue:[
  2866 
  1393 	    sel := sel withoutSpaces
  2867 	"set self for doits. This allows accessing the current class
       
  2868 	 as self, and access to the class variables by name.
       
  2869 	"
       
  2870 	codeView doItAction:[:theCode |
       
  2871 	    |compiler|
       
  2872 
       
  2873 	    currentClass isNil ifTrue:[
       
  2874 		compiler := Compiler
       
  2875 	    ] ifFalse:[
       
  2876 		compiler := currentClass compiler
       
  2877 	    ].
       
  2878 	    compiler 
       
  2879 		evaluate:theCode 
       
  2880 		in:nil 
       
  2881 		receiver:currentClass 
       
  2882 		notifying:codeView 
       
  2883 		logged:false
       
  2884 		ifFail:nil 
       
  2885 	].
       
  2886     ]
       
  2887 !
       
  2888 
       
  2889 updateClassListWithScroll:scroll
       
  2890     |classes oldClassName|
       
  2891 
       
  2892     classListView notNil ifTrue:[
       
  2893 	"
       
  2894 	 refetch in case we are not up to date
       
  2895 	"
       
  2896 	(currentClass notNil and:[fullProtocol not]) ifTrue:[
       
  2897 	    oldClassName := currentClass name.
       
  2898 	    currentClass := Smalltalk at:(oldClassName asSymbol).
       
  2899 	].
       
  2900 
       
  2901 	currentClassCategory notNil ifTrue:[
       
  2902 	    classes := self listOfAllClassesInCategory:currentClassCategory
  1394 	] ifFalse:[
  2903 	] ifFalse:[
  1395 	    sel := ''
  2904 	    currentClassHierarchy notNil ifTrue:[
  1396 	]
  2905 		classes := self listOfClassHierarchyOf:currentClassHierarchy
  1397     ].
  2906 	    ]
  1398     ^ sel
  2907 	].
  1399 !
  2908 
  1400 
  2909 	classListView list = classes ifFalse:[
  1401 findClassOfVariable:aVariableName accessWith:aSelector
  2910 	    scroll ifTrue:[
  1402     "this method returns the class, in which a variable
  2911 		classListView contents:classes
  1403      is defined; 
  2912 	    ] ifFalse:[
  1404      needs either #instVarNames or #classVarNames as aSelector."
  2913 		classListView setContents:classes
  1405 
  2914 	    ].
  1406     |cls homeClass|
  2915 	    oldClassName notNil ifTrue:[
  1407 
  2916 		classListView setContents:classes.
  1408     "
  2917 		classListView selectElement:oldClassName
  1409      first, find the class, where the variable is declared
  2918 	    ] ifFalse:[
  1410     "
  2919 		variableListView notNil ifTrue:[variableListView contents:nil]
  1411     cls := currentClass.
  2920 	    ]
  1412     [cls notNil] whileTrue:[
  2921 	].
  1413 	((cls perform:aSelector) includes:aVariableName) ifTrue:[
  2922 	scroll ifTrue:[
  1414 	    homeClass := cls.
  2923 	    fullProtocol ifTrue:[
  1415 	    cls := nil.
  2924 		classListView scrollToBottom
  1416 	] ifFalse:[
  2925 	    ]
  1417 	    cls := cls superclass
  2926 	]
  1418 	]
  2927     ]
  1419     ].
  2928 !
  1420     homeClass isNil ifTrue:[
  2929 
  1421 	"nope, must be one below ... (could optimize a bit, by searching down
  2930 classSelection:lineNr
  1422 	 for the declaring class ...
  2931     "user clicked on a class line - show method categories"
  1423 	"
  2932 
  1424 	homeClass := currentClass
  2933     |classSymbol cls oldSelector|
  1425     ] ifFalse:[
  2934 
  1426 	Transcript showCr:'starting search in ' , homeClass name.
  2935     (currentClassHierarchy notNil
  1427     ].
  2936      and:[fullProtocol]) ifTrue:[
  1428     ^ homeClass
  2937 	oldSelector := currentSelector.
  1429 !
  2938 
  1430 
  2939 	self updateMethodCategoryListWithScroll:false.
  1431 listBoxTitle:title okText:okText list:aList
  2940 	self updateMethodListWithScroll:false.
  1432     "convenient method: setup a listBox & return it"
  2941 	self updateVariableList.
  1433 
  2942 	^ self
  1434     |box|
  2943     ].
  1435 
  2944 
  1436     box := ListSelectionBox new.
  2945     cls := Smalltalk classNamed:classListView selectionValue withoutSpaces.
  1437     box okText:(resources string:okText).
  2946 "
  1438     box title:(resources string:title).
  2947     classSymbol := classListView selectionValue withoutSpaces asSymbol.
  1439     box list:aList.
  2948     (Smalltalk includesKey:classSymbol) ifTrue:[
  1440     ^ box
  2949 	cls := Smalltalk at:classSymbol
  1441 !
  2950     ].
  1442 
  2951 "
  1443 enterBoxTitle:title okText:okText
  2952     cls notNil ifTrue:[
  1444     "convenient method: setup enterBox"
  2953 	self switchToClass:cls.
  1445 
  2954 	self classSelectionChanged
  1446     |box|
  2955     ]
  1447 
       
  1448     box := EnterBox new.
       
  1449     box title:(resources string:title) okText:(resources string:okText).
       
  1450     ^ box
       
  1451 !
       
  1452 
       
  1453 askBoxTitle:title okText:okText initialText:initialText action:aBlock
       
  1454     "convenient method: setup enterBox, and open it"
       
  1455 
       
  1456     |box|
       
  1457 
       
  1458     box := EnterBox new.
       
  1459     box title:(resources string:title) okText:(resources string:okText).
       
  1460     box initialText:initialText.
       
  1461     box action:[:aString | self withWaitCursorDo:aBlock value:aString].
       
  1462     box showAtPointer
       
  1463 !
       
  1464 
       
  1465 enterBoxForSearchSelectorTitle:title
       
  1466     "convenient method: setup enterBox with text from codeView or selected
       
  1467      method for browsing based on a selector"
       
  1468 
       
  1469     |box|
       
  1470 
       
  1471     box := self enterBoxTitle:title okText:'search'.
       
  1472     box initialText:(self selectorToSearchFor).
       
  1473     ^ box
       
  1474 !
       
  1475 
       
  1476 askAndBrowseSelectorTitle:title action:aBlock
       
  1477     "convenient method: setup enterBox with text from codeView or selected
       
  1478      method for browsing based on a selector. Set action and launch box"
       
  1479 
       
  1480     |box|
       
  1481 
       
  1482     box := self enterBoxTitle:title okText:'browse'.
       
  1483     box initialText:(self selectorToSearchFor).
       
  1484     box action:[:aString | self withCursor:(Cursor questionMark) do:[aBlock value:aString]].
       
  1485     box showAtPointer
       
  1486 !
       
  1487 
       
  1488 enterBoxForBrowseTitle:title action:aBlock
       
  1489     "convenient method: setup enterBox with text from codeView or selected
       
  1490      method for method browsing based on className/variable"
       
  1491 
       
  1492     |box|
       
  1493 
       
  1494     box := self enterBoxTitle:title okText:'browse'.
       
  1495     box initialText:(self stringToSearchFor).
       
  1496     box action:[:aString | self withWaitCursorDo:[aBlock value:aString]].
       
  1497     box showAtPointer
       
  1498 !
       
  1499 
       
  1500 enterBoxForCodeSelectionTitle:title okText:okText
       
  1501     "convenient method: setup enterBox with text from codeview"
       
  1502 
       
  1503     |sel box|
       
  1504 
       
  1505     box := self enterBoxTitle:(resources string:title) okText:(resources string:okText).
       
  1506     sel := codeView selection.
       
  1507     sel notNil ifTrue:[
       
  1508 	box initialText:(sel asString withoutSeparators)
       
  1509     ].
       
  1510     ^ box
       
  1511 !
       
  1512 
       
  1513 askAndBrowseMethodCategory:title action:aBlock
       
  1514     "convenient method: setup enterBox with initial being current method category"
       
  1515 
       
  1516     |sel box|
       
  1517 
       
  1518     box := self enterBoxTitle:title okText:'browse'.
       
  1519     sel := codeView selection.
       
  1520     sel isNil ifTrue:[
       
  1521 	currentMethodCategory notNil ifTrue:[
       
  1522 	    sel := currentMethodCategory
       
  1523 	]
       
  1524     ].
       
  1525     sel notNil ifTrue:[
       
  1526 	box initialText:(sel asString withoutSpaces)
       
  1527     ].
       
  1528     box action:[:aString | self withWaitCursorDo:[aBlock value:aString]].
       
  1529     box showAtPointer
       
  1530 !
       
  1531 
       
  1532 listOfAllClassCategories
       
  1533     "return a list of all class categories"
       
  1534 
       
  1535     |newList cat|
       
  1536 
       
  1537     newList := Text with:'* all *' with:'* hierarchy *'.
       
  1538     Smalltalk allBehaviorsDo:[:aClass |
       
  1539 	cat := aClass category.
       
  1540 	cat isNil ifTrue:[
       
  1541 	    cat := '* no category *'
       
  1542 	].
       
  1543 	newList indexOf:cat ifAbsent:[newList add:cat]
       
  1544     ].
       
  1545     newList sort.
       
  1546     ^ newList
       
  1547 !
       
  1548 
       
  1549 listOfClassHierarchyOf:aClass
       
  1550     "return a hierarchy class-list"
       
  1551 
       
  1552     ^ (aClass allSuperclasses reverse , 
       
  1553        (Array with:aClass),
       
  1554        aClass allSubclassesInOrder) collect:[:c | c name]
       
  1555 
       
  1556 "
       
  1557     |newList theClass|
       
  1558 
       
  1559     theClass := aClass.
       
  1560     newList := Text with:theClass name.
       
  1561     [theClass ~~ Object] whileTrue:[
       
  1562 	theClass := theClass superclass.
       
  1563 	newList add:theClass name
       
  1564     ].
       
  1565     newList reverse.
       
  1566     ^ newList
       
  1567 "
       
  1568 !
  2956 !
  1569 
  2957 
  1570 listOfAllClassesInCategory:aCategory
  2958 listOfAllClassesInCategory:aCategory
  1571     "return a list of all classes in a given category"
  2959     "return a list of all classes in a given category"
  1572 
  2960 
  1607     ].
  2995     ].
  1608     (newList size == 0) ifTrue:[^ nil].
  2996     (newList size == 0) ifTrue:[^ nil].
  1609     ^ newList sort
  2997     ^ newList sort
  1610 !
  2998 !
  1611 
  2999 
  1612 classHierarchyDo:aBlock
  3000 doClassMenu:aBlock
  1613     "eavluate the 2-arg block for every class,
  3001     "a helper - check if class is selected and evaluate aBlock
  1614      starting at Object; passing class and nesting level to the block."
  3002      while showing waitCursor"
  1615 
  3003 
  1616     |classes s classDict l|
  3004     self checkClassSelected ifTrue:[
  1617 
  3005 	self withWaitCursorDo:aBlock
  1618     classes := Smalltalk allClasses.
  3006     ]
  1619     classDict := IdentityDictionary new:classes size.
  3007 !
  1620     classes do:[:aClass |
  3008 
  1621 	s := aClass superclass.
  3009 checkClassSelected
  1622 	s notNil ifTrue:[
  3010     "warn and return false, if no class is selected"
  1623 	    l := classDict at:s ifAbsent:[nil].
  3011 
  1624 	    l isNil ifTrue:[
  3012     currentClass isNil ifTrue:[
  1625 		l := OrderedCollection new:5.
  3013 	self warn:'select a class first'.
  1626 		classDict at:s put:l
  3014 	^ false
  1627 	    ].
  3015     ].
  1628 	    l add:aClass
  3016     ^ true
  1629 	]
  3017 !
  1630     ].
  3018 
  1631     self classHierarchyOf:Object level:0 do:aBlock using:classDict
  3019 updateClassList
  1632 !
  3020     self updateClassListWithScroll:true
  1633 
  3021 !
  1634 classHierarchyOf:aClass level:level do:aBlock using:aDictionary
  3022 
  1635     "evaluate the 2-arg block for every subclass of aClass,
  3023 listOfClassHierarchyOf:aClass
  1636      passing class and nesting level to the block."
  3024     "return a hierarchy class-list"
  1637 
  3025 
  1638     |names subclasses|
  3026     |classes|
  1639 
  3027 
  1640     aBlock value:aClass value:level.
  3028     classes := aClass allSuperclasses reverse , (Array with:aClass).
  1641     subclasses := aDictionary at:aClass ifAbsent:[nil].
  3029     fullProtocol ifFalse:[
  1642     (subclasses size == 0) ifFalse:[
  3030 	classes := classes , aClass allSubclassesInOrder
  1643 	names := subclasses collect:[:class | class name].
  3031     ].
  1644 	names sortWith:subclasses.
  3032     ^ classes collect:[:c | c name]
  1645 	subclasses do:[:aSubClass |
  3033 
  1646 	    self classHierarchyOf:aSubClass level:(level + 1) do:aBlock using:aDictionary
       
  1647 	]
       
  1648     ]
       
  1649 !
       
  1650 
       
  1651 listOfAllMethodCategoriesInClass:aClass
       
  1652     "answer a list of all method categories of the argument, aClass"
       
  1653 
       
  1654     |newList cat|
       
  1655 
       
  1656     newList := Text new.
       
  1657     aClass methodArray do:[:aMethod |
       
  1658 	cat := aMethod category.
       
  1659 	cat isNil ifTrue:[
       
  1660 	    cat := '* no category *'
       
  1661 	].
       
  1662 	(newList includes:cat) ifFalse:[newList add:cat]
       
  1663     ].
       
  1664     (newList size == 0) ifTrue:[^ nil].
       
  1665     newList add:'* all *'.
       
  1666     ^ newList sort
       
  1667 !
       
  1668 
       
  1669 listOfAllSelectorsInCategory:aCategory ofClass:aClass
       
  1670     "answer a list of all selectors in a given method category 
       
  1671      of the argument, aClass"
       
  1672 
       
  1673     |newList searchCategory selector|
       
  1674 
       
  1675     (aCategory = '* all *') ifTrue:[
       
  1676 	newList := aClass selectorArray asText
       
  1677     ] ifFalse:[
       
  1678 	(aCategory = '* no category *') ifTrue:[
       
  1679 	    searchCategory := nil
       
  1680 	] ifFalse:[
       
  1681 	    searchCategory := aCategory
       
  1682 	].
       
  1683 	newList := Text new.
       
  1684 	aClass methodArray do:[:aMethod |
       
  1685 	    (aMethod category = searchCategory) ifTrue:[
       
  1686 		selector := aClass selectorForMethod:aMethod.
       
  1687 		selector notNil ifTrue:[
       
  1688 		    aMethod isWrapped ifTrue:[
       
  1689 			selector := selector , ' !!'
       
  1690 		    ].
       
  1691 		    (newList includes:selector) ifFalse:[
       
  1692 			newList add:selector
       
  1693 		    ]
       
  1694 		]
       
  1695 	    ]
       
  1696 	]
       
  1697     ].
       
  1698     (newList size == 0) ifTrue:[^ nil].
       
  1699     ^ newList sort
       
  1700 !
  3034 !
  1701 
  3035 
  1702 templateFor:className in:cat
  3036 templateFor:className in:cat
  1703     "return a class definition template - be smart in what is offered initially"
  3037     "return a class definition template - be smart in what is offered initially"
  1704 
  3038 
  1715 	instanceVariableNames: '''' 
  3049 	instanceVariableNames: '''' 
  1716 	classVariableNames: ''''    
  3050 	classVariableNames: ''''    
  1717 	poolDictionaries: ''''
  3051 	poolDictionaries: ''''
  1718 	category: '''.
  3052 	category: '''.
  1719 
  3053 
  1720 	cat notNil ifTrue:[
  3054     cat notNil ifTrue:[
  1721 	    aString := aString , cat
  3055 	aString := aString , cat
  1722 	].
  3056     ].
  1723 	aString := aString , ''''.
  3057     aString := aString , '''
  1724 	^ aString
  3058 
  1725 !
  3059 
  1726 
  3060 
  1727 template
  3061 
  1728     "return a method definition template"
  3062 
  1729 
  3063 "
  1730     ^ 
  3064  Replace ''' , className , ''', ''', name , ''' and
  1731 'message selector and argument names
  3065  the empty string arguments by true values.
  1732     "comment stating purpose of message"
  3066 
  1733 
  3067  Install (or change) the class by ''accepting'',
  1734 
  3068  either via the menu or the keyboard (usually CMD-A).
  1735     |temporaries|
  3069 
  1736     statements
  3070  To be nice to others (and yourself later), do not forget to
  1737 '
  3071  add some documentation; either under the classes documentation
  1738 !
  3072  protocol, or as a class comment.
  1739 
  3073 "
  1740 compileCode:someCode
  3074 '.
  1741     (ReadStream on:someCode) fileIn
  3075     ^ aString
       
  3076 !
       
  3077 
       
  3078 classClassDefinitionTemplateFor:name in:cat
       
  3079     "common helper for newClass and newSubclass
       
  3080      - show a template to define class name in category cat.
       
  3081      Also, set acceptaction to install the class."
       
  3082 
       
  3083     currentMethodCategory := nil.
       
  3084     currentMethod := currentSelector := nil.
       
  3085 
       
  3086     classListView deselect.
       
  3087 
       
  3088     fullClass ifFalse:[
       
  3089 	methodCategoryListView contents:nil.
       
  3090 	methodListView contents:nil
       
  3091     ].
       
  3092 
       
  3093     codeView contents:(self templateFor:name in:cat).
       
  3094     codeView modified:false.
       
  3095 
       
  3096     codeView acceptAction:[:theCode |
       
  3097 	codeView cursor:Cursor execute.
       
  3098 	Object abortSignal catch:[
       
  3099 	    |cls|
       
  3100 
       
  3101 	    cls := (Compiler evaluate:theCode asString notifying:codeView).
       
  3102 	    cls isBehavior ifTrue:[
       
  3103 		codeView modified:false.
       
  3104 		self classCategoryUpdate.
       
  3105 		self updateClassListWithScroll:false.
       
  3106 		self switchToClassNamed:(cls name).
       
  3107 	    ]
       
  3108 	].
       
  3109 	codeView cursor:(Cursor normal).
       
  3110     ].
       
  3111     codeView explainAction:nil.
       
  3112     self switchToClass:nil
       
  3113 !
       
  3114 
       
  3115 renameCurrentClassTo:aString
       
  3116     "helper - do the rename"
       
  3117 
       
  3118     self doClassMenu:[
       
  3119 	|oldName oldSym newSym|
       
  3120 
       
  3121 	oldName := currentClass name.
       
  3122 	oldSym := oldName asSymbol.
       
  3123 "
       
  3124 	currentClass setName:aString.
       
  3125 	newSym := aString asSymbol.
       
  3126 	Smalltalk at:oldSym put:nil.
       
  3127 	Smalltalk removeKey:oldSym.            
       
  3128 	Smalltalk at:newSym put:currentClass.
       
  3129 "
       
  3130 "
       
  3131 	currentClass renameTo:aString.
       
  3132 "
       
  3133 	Smalltalk renameClass:currentClass to:aString.
       
  3134 
       
  3135 	self updateClassList.
       
  3136 	self updateMethodCategoryListWithScroll:false.
       
  3137 	self updateMethodListWithScroll:false.
       
  3138 	self withWaitCursorDo:[
       
  3139 	    Transcript showCr:('searching for users of ' , oldSym); endEntry.
       
  3140 	    self class browseReferendsOf:oldSym warnIfNone:false
       
  3141 	]
       
  3142     ]
       
  3143 !
       
  3144 
       
  3145 switchToClassNamed:aString
       
  3146     |classSymbol theClass newCat|
       
  3147 
       
  3148     aString knownAsSymbol ifFalse:[^ self].
       
  3149 
       
  3150     classSymbol := aString asSymbol.
       
  3151     theClass := Smalltalk at:classSymbol.
       
  3152     theClass isBehavior ifTrue:[
       
  3153 	classCategoryListView notNil ifTrue:[
       
  3154 	    currentClassHierarchy isNil ifTrue:[
       
  3155 		((newCat := theClass category) ~= currentClassCategory) ifTrue:[
       
  3156 		    currentClassCategory := newCat.
       
  3157 		    newCat isNil ifTrue:[
       
  3158 			classCategoryListView selectElement:'* no category *'
       
  3159 		    ] ifFalse:[
       
  3160 			classCategoryListView selectElement:newCat.
       
  3161 		    ].
       
  3162 		    "/ classCategoryListView makeSelectionVisible.
       
  3163 		]
       
  3164 	    ]
       
  3165 	].
       
  3166 	self updateClassList.
       
  3167 	self switchToClass:theClass.
       
  3168 	classListView selectElement:aString.
       
  3169 	self classSelectionChanged
       
  3170     ]
       
  3171 !
       
  3172 
       
  3173 switchToClassNameMatching:aMatchString
       
  3174     |classNames thisName box|
       
  3175 
       
  3176     classNames := OrderedCollection new.
       
  3177     Smalltalk allBehaviorsDo:[:aClass |
       
  3178 	thisName := aClass name.
       
  3179 	(aMatchString match:thisName) ifTrue:[
       
  3180 	    classNames add:thisName
       
  3181 	]
       
  3182     ].
       
  3183     (classNames size == 0) ifTrue:[^ nil].
       
  3184     (classNames size == 1) ifTrue:[
       
  3185 	^ self switchToClassNamed:(classNames at:1)
       
  3186     ].
       
  3187 
       
  3188     box := self listBoxTitle:'select class to switch to:'
       
  3189 		      okText:'ok'
       
  3190 			list:classNames sort.
       
  3191     box action:[:aString | self switchToClassNamed:aString].
       
  3192     box showAtPointer
  1742 ! !
  3193 ! !
  1743 
  3194 
  1744 !SystemBrowser methodsFor:'user interaction'!
  3195 !SystemBrowser methodsFor:'variable stuff'!
  1745 
  3196 
  1746 instanceProtocol
  3197 updateVariableList
  1747     showInstance ifFalse:[
  3198     |l subList flags last nameAccessSelector class oldSelection|
  1748 	self checkSelectionChangeAllowed ifTrue:[
  3199 
  1749 	    classToggle turnOff.
  3200     variableListView isNil ifTrue:[^ self].
  1750 	    instanceToggle turnOn.
  3201 
  1751 	    showInstance := true.
  3202     oldSelection := variableListView selectionValue.
  1752 	    currentClass notNil ifTrue:[
  3203 
  1753 		self classSelectionChanged
  3204     l := OrderedCollection new.
       
  3205     "
       
  3206      show classVars, if classProtocol is shown (instead of classInstance vars)
       
  3207     "
       
  3208     showInstance ifTrue:[
       
  3209 	nameAccessSelector := #instVarNames
       
  3210     ] ifFalse:[
       
  3211 	nameAccessSelector := #classVarNames
       
  3212     ].
       
  3213 
       
  3214     class := currentClass notNil ifTrue:[currentClass] ifFalse:[actualClass].
       
  3215     class isNil ifTrue:[class := currentClassHierarchy].
       
  3216     class withAllSuperclasses do:[:aClass |
       
  3217 	|ignore|
       
  3218 
       
  3219 	ignore := fullProtocol 
       
  3220 		  and:[classListView valueIsInSelection:(aClass name asString)].
       
  3221 	ignore ifFalse:[
       
  3222 	    subList := aClass perform:nameAccessSelector.
       
  3223 	    subList size ~~ 0 ifTrue:[
       
  3224 		l := l , (subList asOrderedCollection reverse).
       
  3225 		l := l , (OrderedCollection with:'---- ' , aClass name , ' ---------').
       
  3226 	    ]
       
  3227 	]
       
  3228     ].
       
  3229     l reverse.
       
  3230     variableListView setAttributes:nil.
       
  3231     variableListView list:l.
       
  3232     l keysAndValuesDo:[:index :entry |
       
  3233 	(entry startsWith:'---') ifTrue:[
       
  3234 	    variableListView attributeAt:index put:#disabled.
       
  3235 	    last := index
       
  3236 	]
       
  3237     ].
       
  3238     last notNil ifTrue:[variableListView scrollToLine:last].
       
  3239 
       
  3240     oldSelection notNil ifTrue:[
       
  3241 	variableListView selectElement:oldSelection
       
  3242     ]
       
  3243 !
       
  3244 
       
  3245 unhilightMethods
       
  3246     "unhighlight items in method list"
       
  3247 
       
  3248     variableListView isNil ifTrue:[^ self].
       
  3249 
       
  3250     methodListView notNil ifTrue:[
       
  3251 	1 to:methodListView list size do:[:entry |
       
  3252 	     methodListView attributeAt:entry put:nil.
       
  3253 	].
       
  3254     ].
       
  3255 
       
  3256 
       
  3257 !
       
  3258 
       
  3259 hilightMethodsInMethodCategoryList:inCat inMethodList:inMethods 
       
  3260     "search for methods  which access the selected
       
  3261      variable, and highlight them"
       
  3262 
       
  3263     |name idx redefinedSelectors|
       
  3264 
       
  3265     variableListView isNil ifTrue:[^ self].
       
  3266 
       
  3267     inCat ifTrue:[self unhilightMethodCategories].
       
  3268     inMethods ifTrue:[self unhilightMethods].
       
  3269 
       
  3270     actualClass isNil ifTrue:[^ self].
       
  3271     (methodCategoryListView isNil 
       
  3272     and:[methodListView isNil]) ifTrue:[^ self].
       
  3273 
       
  3274     name := variableListView selectionValue.
       
  3275     name isNil ifTrue:[^ self].
       
  3276 
       
  3277     self withCursor:(Cursor questionMark) do:[
       
  3278 	|classes filter any|
       
  3279 
       
  3280 	classes := Array with:currentClass.
       
  3281 	currentClassHierarchy notNil ifTrue:[
       
  3282 	    fullProtocol ifTrue:[
  1754 	    ].
  3283 	    ].
  1755 	    codeView modified:false.
  3284 	    classes := classes , currentClass allSuperclasses.
       
  3285 	    redefinedSelectors := IdentitySet new.
       
  3286 	].
       
  3287 	showInstance ifTrue:[
       
  3288 	    filter := self class filterToSearchInstRefsTo:name modificationsOnly:false 
  1756 	] ifFalse:[
  3289 	] ifFalse:[
  1757 	    instanceToggle turnOff.
  3290 	    filter := self class filterToSearchClassRefsTo:name modificationsOnly:false 
  1758 	    classToggle turnOn
  3291 	].
  1759 	]
  3292 
  1760     ]
  3293 	any := false.
  1761 !
  3294 	"
  1762 
  3295 	 highlight the method that ref this variable
  1763 classProtocol
  3296 	"
  1764     showInstance ifTrue:[
  3297 	classes do:[:someClass |
  1765 	self checkSelectionChangeAllowed ifTrue:[
  3298 	    someClass methodArray with:someClass selectorArray 
  1766 	    instanceToggle turnOff.
  3299 	    do:[:method :selector |
  1767 	    classToggle turnOn.
  3300 
  1768 	    showInstance := false.
  3301 		(inCat
  1769 	    currentClass notNil ifTrue:[
  3302 		or:[methodListView list notNil
  1770 		self classSelectionChanged
  3303 		    and:[methodListView list includes:selector]])
       
  3304 		ifTrue:[
       
  3305 		    (redefinedSelectors isNil
       
  3306 		    or:[(redefinedSelectors includes:selector) not])
       
  3307 		   ifTrue:[
       
  3308 		       (filter value:someClass value:method value:selector) ifTrue:[
       
  3309 			   |idx cat|
       
  3310 
       
  3311 			   (inCat
       
  3312 			   and:[methodCategoryListView notNil 
       
  3313 			   and:[methodCategoryListView list notNil]]) ifTrue:[
       
  3314 			       cat := method category.
       
  3315 			       "
       
  3316 				highlight the methodCategory
       
  3317 			       "
       
  3318 			       idx := methodCategoryListView list indexOf:cat.
       
  3319 			       idx ~~ 0 ifTrue:[
       
  3320 				   methodCategoryListView attributeAt:idx put:#bold.
       
  3321 			       ].
       
  3322 			   ].
       
  3323 
       
  3324 			   (inMethods
       
  3325 			   and:[methodListView notNil 
       
  3326 			   and:[methodListView list notNil]]) ifTrue:[
       
  3327 			       "
       
  3328 				highlight the method
       
  3329 			       "
       
  3330 			       idx := methodListView list indexOf:selector.
       
  3331 			       idx ~~ 0 ifTrue:[
       
  3332 				   methodListView attributeAt:idx put:#bold.
       
  3333 			       ].
       
  3334 			       any := true
       
  3335 			   ].
       
  3336 		       ].
       
  3337 		       redefinedSelectors notNil ifTrue:[
       
  3338 			   redefinedSelectors add:selector
       
  3339 		       ]
       
  3340 		    ]
       
  3341 		]
       
  3342 	    ]
       
  3343 	].
       
  3344 	any ifTrue:[
       
  3345 	    self setSearchPattern:name
       
  3346 	]
       
  3347     ]
       
  3348 
       
  3349 
       
  3350 !
       
  3351 
       
  3352 hilightMethodsInMethodCategoryList
       
  3353     "search for methods  which access the selected
       
  3354      variable, and highlight them"
       
  3355 
       
  3356     self hilightMethodsInMethodCategoryList:true inMethodList:false
       
  3357 
       
  3358 
       
  3359 
       
  3360 !
       
  3361 
       
  3362 unhilightMethodCategories
       
  3363     "unhighlight items in method list"
       
  3364 
       
  3365     variableListView isNil ifTrue:[^ self].
       
  3366 
       
  3367     methodCategoryListView notNil ifTrue:[
       
  3368 	1 to:methodCategoryListView list size do:[:entry |
       
  3369 	    methodCategoryListView attributeAt:entry put:nil.
       
  3370 	]
       
  3371     ].
       
  3372 
       
  3373 
       
  3374 !
       
  3375 
       
  3376 hilightMethodsInMethodList
       
  3377     "search for methods  which access the selected
       
  3378      variable, and highlight them"
       
  3379 
       
  3380     self hilightMethodsInMethodCategoryList:false inMethodList:true 
       
  3381 
       
  3382 
       
  3383 
       
  3384 ! !
       
  3385 
       
  3386 !SystemBrowser methodsFor:'class list menu'!
       
  3387 
       
  3388 classDefinition
       
  3389     "show class definition in codeView and setup accept-action for
       
  3390      a class-definition change.
       
  3391      Extract documentation either from a documentation method or
       
  3392      from the comment - not a biggy, but beginners will like
       
  3393      it when exploring the system."
       
  3394 
       
  3395     self doClassMenu:[
       
  3396 	|m s aStream isComment|
       
  3397 
       
  3398 	aStream := WriteStream on:(String new:200).
       
  3399 	currentClass fileOutDefinitionOn:aStream.
       
  3400 
       
  3401 	currentClass isLoaded ifTrue:[
       
  3402 	    "
       
  3403 	     add documentation as a comment, if there is any
       
  3404 	    "
       
  3405 	    m := currentClass class compiledMethodAt:#documentation.
       
  3406 	    m notNil ifTrue:[
       
  3407 		s := m comment.
       
  3408 		isComment := false.
       
  3409 	    ] ifFalse:[
       
  3410 		"try comment"
       
  3411 		s := currentClass comment.
       
  3412 		s notNil ifTrue:[
       
  3413 		    isComment := true
       
  3414 		]
  1771 	    ].
  3415 	    ].
  1772 	    codeView modified:false.
  3416 	].
       
  3417 	s notNil ifTrue:[
       
  3418 	    aStream cr.
       
  3419 	    aStream cr.
       
  3420 	    aStream cr.
       
  3421 	    aStream cr.
       
  3422 	    aStream cr.
       
  3423 	    aStream nextPut:$" ; cr; nextPutAll:' Documentation:'; cr.
       
  3424 	    aStream cr.
       
  3425 	    aStream nextPutAll:s.    
       
  3426 	    aStream cr; cr.
       
  3427 	    aStream nextPutAll:' Notice: '; cr.
       
  3428 	    aStream nextPutAll:'   the above string has been extracted from the classes '.
       
  3429 	    aStream nextPutAll:(isComment ifTrue:['comment.'] ifFalse:['documentation method.']).
       
  3430 	    aStream cr.
       
  3431 	    aStream nextPutAll:'   It will not preserved when accepting a new class definition.'; cr.
       
  3432 	    aStream nextPut:$".
       
  3433 	].
       
  3434 
       
  3435 	codeView contents:(aStream contents).
       
  3436 	codeView modified:false.
       
  3437 	codeView acceptAction:[:theCode |
       
  3438 	    codeView cursor:Cursor execute.
       
  3439 	    Object abortSignal catch:[
       
  3440 		(Compiler evaluate:theCode asString notifying:codeView)
       
  3441 		isBehavior ifTrue:[
       
  3442 		    codeView modified:false.
       
  3443 		    self classCategoryUpdate.
       
  3444 		    self updateClassListWithScroll:false.
       
  3445 		]
       
  3446 	    ].
       
  3447 	    codeView cursor:Cursor normal.
       
  3448 	].
       
  3449 	codeView explainAction:nil.
       
  3450 
       
  3451 	methodListView notNil ifTrue:[
       
  3452 	    methodListView deselect
       
  3453 	].
       
  3454 	aspect := #definition.
       
  3455 	self normalLabel
       
  3456     ]
       
  3457 !
       
  3458 
       
  3459 initializeClassMenu
       
  3460     |labels menu|
       
  3461 
       
  3462     labels := resources array:#(
       
  3463 					'fileOut'
       
  3464 					'printOut'
       
  3465 					'printOut protocol'
       
  3466 				      " 'printOut full protocol' "
       
  3467 					'-'
       
  3468 					'SPAWN_CLASS' 
       
  3469 					'spawn full protocol' 
       
  3470 					'spawn hierarchy' 
       
  3471 					'spawn subclasses' 
       
  3472 					'-'
       
  3473 					'hierarchy' 
       
  3474 					'definition' 
       
  3475 					'comment' 
       
  3476 					'class instvars' 
       
  3477 				      " 'protocols' "
       
  3478 					'-'
       
  3479 "/                                        'variable search'
       
  3480 					'class refs'
       
  3481 					'-'
       
  3482 					'new class'
       
  3483 					'new subclass'
       
  3484 					'rename ...'
       
  3485 					'remove').
       
  3486 
       
  3487     menu := PopUpMenu labels:labels
       
  3488 		   selectors:#(classFileOut
       
  3489 			       classPrintOut
       
  3490 			       classPrintOutProtocol
       
  3491 			     " classPrintOutFullProtocol "
       
  3492 			       nil
       
  3493 			       classSpawn
       
  3494 			       classSpawnFullProtocol
       
  3495 			       classSpawnHierarchy
       
  3496 			       classSpawnSubclasses
       
  3497 			       nil
       
  3498 			       classHierarchy
       
  3499 			       classDefinition
       
  3500 			       classComment
       
  3501 			       classClassInstVars
       
  3502 			     "  classProtocols "
       
  3503 			       nil
       
  3504 "/                               variables
       
  3505 			       classRefs
       
  3506 			       nil
       
  3507 			       classNewClass
       
  3508 			       classNewSubclass
       
  3509 			       classRename
       
  3510 			       classRemove)
       
  3511 		    receiver:self
       
  3512 			 for:classListView.
       
  3513 
       
  3514     fullProtocol ifFalse:[
       
  3515 	classListView middleButtonMenu:menu. 
       
  3516     ].
       
  3517 
       
  3518     self initializeVariableListMenu.
       
  3519 
       
  3520 !
       
  3521 
       
  3522 classFileOut
       
  3523     "fileOut the current class.
       
  3524      Catch errors (sure, you like to know if it failed) and
       
  3525      warn if any)"
       
  3526 
       
  3527     self doClassMenu:[
       
  3528 	self busyLabel:'saving %1' with:currentClass name.
       
  3529 	Class fileOutErrorSignal handle:[:ex |
       
  3530 	    self warn:'cannot create: %1' with:ex parameter.
       
  3531 	    ex return.
       
  3532 	] do:[
       
  3533 	    currentClass fileOut.
       
  3534 	].
       
  3535 	self normalLabel.
       
  3536     ]
       
  3537 !
       
  3538 
       
  3539 doClassMenuWithSelection:aBlock
       
  3540     "a helper - if there is a selection, which represents a classes name,
       
  3541      evaluate aBlock, passing that class and optional selector as arguments.
       
  3542      Otherwise, check if a class is selected and evaluate aBlock with the
       
  3543      current class."
       
  3544 
       
  3545     |string words clsName cls sel isMeta w|
       
  3546 
       
  3547     string := codeView selection.
       
  3548     string notNil ifTrue:[
       
  3549 	self extractClassAndSelectorFromSelectionInto:[:c :s :m |
       
  3550 	    clsName := c.
       
  3551 	    sel := s.
       
  3552 	    isMeta := m.
       
  3553 	].
       
  3554 	clsName isNil ifTrue:[
       
  3555 	    string := string asString withoutSeparators.
       
  3556 	    words := string asCollectionOfWords.
       
  3557 	    words notNil ifTrue:[
       
  3558 		clsName := words first.
       
  3559 		(clsName endsWith:'class') ifTrue:[
       
  3560 		    isMeta := true.
       
  3561 		    clsName := clsName copyTo:(clsName size - 5)
       
  3562 		] ifFalse:[
       
  3563 		    isMeta := false
       
  3564 		].
       
  3565 		sel := Parser selectorInExpression:string.
       
  3566 	    ]
       
  3567 	].
       
  3568 	clsName notNil ifTrue:[
       
  3569 	    (cls := Smalltalk classNamed:clsName) notNil ifTrue:[
       
  3570 		isMeta ifTrue:[
       
  3571 		    cls := cls class
       
  3572 		].
       
  3573 		self withWaitCursorDo:[
       
  3574 		    aBlock value:cls value:sel.
       
  3575 		].
       
  3576 		^ self
       
  3577 	    ] ifFalse:[
       
  3578 		self warn:'no class named: %1 - spawning current' with:clsName
       
  3579 	    ]
       
  3580 	].
       
  3581     ].
       
  3582 
       
  3583     classMethodListView notNil ifTrue:[
       
  3584 	sel := classMethodListView selectionValue.
       
  3585 	sel notNil ifTrue:[
       
  3586 	    sel := self selectorFromClassMethodString:sel
       
  3587 	]
       
  3588     ].
       
  3589     self doClassMenu:[aBlock value:currentClass value:sel]
       
  3590 !
       
  3591 
       
  3592 classSpawn
       
  3593     "create a new SystemBrowser browsing current class,
       
  3594      or if there is a selection, spawn a browser on the selected class
       
  3595      even a class/selector pair can be specified."
       
  3596 
       
  3597     |browser|
       
  3598 
       
  3599     self doClassMenuWithSelection:[:cls :sel |
       
  3600 	cls isMeta ifTrue:[
       
  3601 	    Smalltalk allBehaviorsDo:[:aClass |
       
  3602 		aClass class == cls ifTrue:[
       
  3603 		    browser := self class browseClass:aClass.
       
  3604 		    browser classProtocol.
       
  3605 		    sel notNil ifTrue:[
       
  3606 			browser switchToMethodNamed:sel
       
  3607 		    ].
       
  3608 		    ^ self
       
  3609 		].
       
  3610 	    ].
       
  3611 	    self warn:'oops, no class for this metaclass'.
       
  3612 	    ^ self
       
  3613 	].
       
  3614 	browser := self class browseClass:cls. 
       
  3615 	cls hasMethods ifFalse:[
       
  3616 	    browser classProtocol.
       
  3617 	].
       
  3618 	sel notNil ifTrue:[
       
  3619 	    browser switchToMethodNamed:sel
       
  3620 	].
       
  3621     ]
       
  3622 
       
  3623     "
       
  3624      select 'Smalltalk allClassesDo:' and use spawn from the class menu
       
  3625      select 'Smalltalk'               and use spawn from the class menu
       
  3626     "
       
  3627 !
       
  3628 
       
  3629 classSpawnHierarchy
       
  3630     "create a new HierarchyBrowser browsing current class"
       
  3631 
       
  3632     self doClassMenuWithSelection:[:cls :sel |
       
  3633 	self class browseClassHierarchy:cls 
       
  3634     ]
       
  3635 !
       
  3636 
       
  3637 classSpawnSubclasses
       
  3638     "create a new browser browsing current class's subclasses"
       
  3639 
       
  3640     |subs|
       
  3641 
       
  3642     self doClassMenuWithSelection:[:cls :sel |
       
  3643 	subs := cls allSubclasses.
       
  3644 	(subs notNil and:[subs size ~~ 0]) ifTrue:[
       
  3645 	    self class browseClasses:subs title:('subclasses of ' , cls name)
       
  3646 	]
       
  3647     ]
       
  3648 !
       
  3649 
       
  3650 classPrintOutFullProtocol
       
  3651     |printStream|
       
  3652 
       
  3653     self doClassMenu:[
       
  3654 	printStream := Printer new.
       
  3655 	currentClass printOutFullProtocolOn:printStream.
       
  3656 	printStream close
       
  3657     ]
       
  3658 !
       
  3659 
       
  3660 classPrintOutProtocol
       
  3661     |printStream|
       
  3662 
       
  3663     self doClassMenu:[
       
  3664 	printStream := Printer new.
       
  3665 	currentClass printOutProtocolOn:printStream.
       
  3666 	printStream close
       
  3667     ]
       
  3668 !
       
  3669 
       
  3670 classPrintOut
       
  3671     |printStream|
       
  3672 
       
  3673     self doClassMenu:[
       
  3674 	printStream := Printer new.
       
  3675 	currentClass printOutOn:printStream.
       
  3676 	printStream close
       
  3677     ]
       
  3678 !
       
  3679 
       
  3680 classHierarchy
       
  3681     "show current classes hierarchy in codeView"
       
  3682 
       
  3683     |aStream|
       
  3684 
       
  3685     self doClassMenu:[
       
  3686 	aStream := WriteStream on:(String new:200).
       
  3687 	actualClass printHierarchyOn:aStream.
       
  3688 	codeView contents:(aStream contents).
       
  3689 	codeView modified:false.
       
  3690 	codeView acceptAction:nil.
       
  3691 	codeView explainAction:nil.
       
  3692 	methodListView notNil ifTrue:[
       
  3693 	    methodListView deselect
       
  3694 	].
       
  3695 	aspect := #hierarchy. 
       
  3696 	self normalLabel
       
  3697     ]
       
  3698 !
       
  3699 
       
  3700 classNewClass
       
  3701     "create a class-definition prototype in codeview"
       
  3702 
       
  3703     |nm|
       
  3704 
       
  3705     currentClass notNil ifTrue:[
       
  3706 	nm := currentClass superclass name 
       
  3707     ] ifFalse:[
       
  3708 	nm := 'Object'
       
  3709     ].
       
  3710     self classClassDefinitionTemplateFor:nm in:currentClassCategory.
       
  3711     aspect := nil.
       
  3712 !
       
  3713 
       
  3714 classClassInstVars
       
  3715     "show class instance variables in codeView and setup accept-action
       
  3716      for a class-instvar-definition change"
       
  3717 
       
  3718     |s|
       
  3719 
       
  3720     self doClassMenu:[
       
  3721 	s := WriteStream on:(String new).
       
  3722 	currentClass fileOutClassInstVarDefinitionOn:s.
       
  3723 	codeView contents:(s contents).
       
  3724 	codeView modified:false.
       
  3725 	codeView acceptAction:[:theCode |
       
  3726 	    codeView cursor:Cursor execute.
       
  3727 	    Object abortSignal catch:[
       
  3728 		Compiler evaluate:theCode asString notifying:codeView.
       
  3729 		codeView modified:false.
       
  3730 		self updateClassList.
       
  3731 	    ].
       
  3732 	    codeView cursor:Cursor normal.
       
  3733 	].
       
  3734 	codeView explainAction:nil.
       
  3735 	methodListView notNil ifTrue:[
       
  3736 	    methodListView deselect
       
  3737 	].
       
  3738 	aspect := #classInstVars.
       
  3739 	self normalLabel
       
  3740     ]
       
  3741 !
       
  3742 
       
  3743 classSpawnFullProtocol
       
  3744     "create a new browser, browsing current classes full protocol"
       
  3745 
       
  3746     self doClassMenuWithSelection:[:cls :sel |
       
  3747 	self class browseFullClassProtocol:cls 
       
  3748     ]
       
  3749 !
       
  3750 
       
  3751 classProtocols
       
  3752      ^ self
       
  3753 !
       
  3754 
       
  3755 classRemove
       
  3756     "user requested remove of current class and all subclasses -
       
  3757      count subclasses and let user confirm removal."
       
  3758 
       
  3759     |count t box|
       
  3760 
       
  3761     currentClass notNil ifTrue:[
       
  3762 	count := currentClass allSubclasses size.
       
  3763 	t := 'remove ' , currentClass name.
       
  3764 	count ~~ 0 ifTrue:[
       
  3765 	   t := t , '\(with ' , count printString , ' subclass'.
       
  3766 	   count ~~ 1 ifTrue:[
       
  3767 		t := t , 'es'
       
  3768 	   ].
       
  3769 	   t := (t , ')') withCRs
       
  3770 	].
       
  3771 	box := YesNoBox 
       
  3772 		   title:t
       
  3773 		   yesText:(resources at:'remove')
       
  3774 		   noText:(resources at:'abort').
       
  3775 	box confirm ifTrue:[
       
  3776 	    "after querying user - do really remove current class
       
  3777 	     and all subclasses
       
  3778 	    "
       
  3779 	    self doClassMenu:[
       
  3780 		"
       
  3781 		 query ?
       
  3782 		"
       
  3783 		currentClass allSubclassesDo:[:aSubClass |
       
  3784 		    (CheckForInstancesWhenRemovingClasses not
       
  3785 		    or:[aSubClass hasInstances not
       
  3786 		    or:[self confirm:(aSubClass name , ' has instances - remove anyway ?')]])
       
  3787 			ifTrue:[
       
  3788 			    Smalltalk removeClass:aSubClass
       
  3789 		    ]
       
  3790 		].
       
  3791 		(CheckForInstancesWhenRemovingClasses not
       
  3792 		or:[currentClass hasInstances not
       
  3793 		or:[self confirm:(currentClass name , ' has instances - remove anyway ?')]])
       
  3794 		    ifTrue:[
       
  3795 			Smalltalk removeClass:currentClass.
       
  3796 		].
       
  3797 
       
  3798 		self switchToClass:nil.
       
  3799 		Smalltalk changed.
       
  3800 		self updateClassList.
       
  3801 
       
  3802 		"if it was the last in its category, update class category list"
       
  3803 "
       
  3804 		classListView numberOfLines == 0 ifTrue:[
       
  3805 		    self updateClassCategoryListWithScroll:false
       
  3806 		].
       
  3807 "
       
  3808 		methodCategoryListView notNil ifTrue:[methodCategoryListView contents:nil].
       
  3809 		methodListView notNil ifTrue:[methodListView contents:nil].
       
  3810 		codeView contents:nil.
       
  3811 		codeView modified:false
       
  3812 	    ]
       
  3813 	]
       
  3814     ]
       
  3815 !
       
  3816 
       
  3817 classComment
       
  3818     "show the classes comment in the codeView.
       
  3819      Also, set acceptaction to change the comment."
       
  3820 
       
  3821     self doClassMenu:[
       
  3822 	codeView contents:(currentClass comment).
       
  3823 	codeView modified:false.
       
  3824 	codeView acceptAction:[:theCode |
       
  3825 	    Object abortSignal catch:[
       
  3826 		lockUpdates := true.
       
  3827 		currentClass comment:theCode asString.
       
  3828 		codeView modified:false.
       
  3829 	    ].
       
  3830 	    lockUpdates := false.
       
  3831 	].
       
  3832 	codeView explainAction:nil.
       
  3833 
       
  3834 	methodListView notNil ifTrue:[
       
  3835 	    methodListView deselect
       
  3836 	].
       
  3837 	aspect := #comment.
       
  3838 	self normalLabel
       
  3839     ]
       
  3840 !
       
  3841 
       
  3842 classRefs
       
  3843     self doClassMenu:[
       
  3844 	self withCursor:(Cursor questionMark) do:[
       
  3845 	    self class browseReferendsOf:currentClass name asSymbol
       
  3846 	]
       
  3847     ]
       
  3848 !
       
  3849 
       
  3850 classNewSubclass
       
  3851     "create a subclass-definition prototype in codeview"
       
  3852 
       
  3853     self doClassMenu:[
       
  3854 	self classClassDefinitionTemplateFor:(currentClass name) 
       
  3855 					  in:(currentClass category).
       
  3856 	aspect := nil
       
  3857     ]
       
  3858 !
       
  3859 
       
  3860 classUses
       
  3861     "a powerful tool, when trying to learn more about where
       
  3862      a class is used. This one searches all uses of a class,
       
  3863      and shows a list of uses - try it and like it"
       
  3864 
       
  3865     self doClassMenu:[
       
  3866 	self withCursor:(Cursor questionMark) do:[
       
  3867 	    self class browseUsesOf:currentClass
       
  3868 	]
       
  3869     ]
       
  3870 !
       
  3871 
       
  3872 classRename
       
  3873     "launch an enterBox for new name and query user"
       
  3874 
       
  3875     |box|
       
  3876 
       
  3877     self checkClassSelected ifFalse:[^ self].
       
  3878     box := self enterBoxTitle:(resources string:'rename %1 to:' with:currentClass name) okText:'rename'.
       
  3879     box initialText:(currentClass name).
       
  3880     box action:[:aString | self renameCurrentClassTo:aString].
       
  3881     box showAtPointer
       
  3882 !
       
  3883 
       
  3884 classSpawnFullHierarchy
       
  3885     "create a new HierarchyBrowser browsing current class"
       
  3886 
       
  3887     self doClassMenuWithSelection:[:cls :sel |
       
  3888 	self class browseFullClassHierarchy:cls 
       
  3889     ]
       
  3890 ! !
       
  3891 
       
  3892 !SystemBrowser methodsFor:'class category stuff'!
       
  3893 
       
  3894 checkClassCategorySelected
       
  3895     currentClassCategory isNil ifTrue:[
       
  3896 	self warn:'select a class category first'.
       
  3897 	^ false
       
  3898     ].
       
  3899     ^ true
       
  3900 !
       
  3901 
       
  3902 listOfAllClassCategories
       
  3903     "return a list of all class categories"
       
  3904 
       
  3905     |newList cat|
       
  3906 
       
  3907     newList := Text with:'* all *' with:'* hierarchy *'.
       
  3908     Smalltalk allBehaviorsDo:[:aClass |
       
  3909 	cat := aClass category.
       
  3910 	cat isNil ifTrue:[
       
  3911 	    cat := '* no category *'
       
  3912 	].
       
  3913 	newList indexOf:cat ifAbsent:[newList add:cat]
       
  3914     ].
       
  3915     newList sort.
       
  3916     ^ newList
       
  3917 !
       
  3918 
       
  3919 classCategorySelectionChanged
       
  3920     "class category has changed - update dependent views"
       
  3921 
       
  3922     self withWaitCursorDo:[
       
  3923 	self switchToClass:nil.
       
  3924 	actualClass := nil.
       
  3925 	currentMethodCategory := nil.
       
  3926 	currentMethod := currentSelector := nil.
       
  3927 
       
  3928 	self updateClassList.
       
  3929 	self updateMethodCategoryList.
       
  3930 	self updateMethodList.
       
  3931 	self updateCodeView.
       
  3932 
       
  3933 	codeView explainAction:nil.
       
  3934 	codeView acceptAction:nil
       
  3935     ]
       
  3936 !
       
  3937 
       
  3938 classCategorySelection:lineNr
       
  3939     "user clicked on a class category line - show classes.
       
  3940      If switching to hierarchy or all, keep current selections"
       
  3941 
       
  3942     |newCategory oldClass classIndex index|
       
  3943 
       
  3944     newCategory := classCategoryListView selectionValue.
       
  3945     (newCategory startsWith:'*') ifTrue:[
       
  3946 	"etiher all or hierarchy;
       
  3947 	 remember current selections and switch after showing class list"
       
  3948 	oldClass := currentClass
       
  3949     ].
       
  3950     currentClassCategory := newCategory.
       
  3951     oldClass isNil ifTrue:[
       
  3952 	self classCategorySelectionChanged
       
  3953     ] ifFalse:[
       
  3954 	self withWaitCursorDo:[
       
  3955 	    self updateClassList
       
  3956 	].
       
  3957 	"stupid - search for class name in (indented) list"
       
  3958 	index := 1.
       
  3959 	classListView list do:[:elem |
       
  3960 	    (elem endsWith:(oldClass name)) ifTrue:[
       
  3961 		classIndex := index
       
  3962 	    ].
       
  3963 	    index := index + 1
       
  3964 	].
       
  3965 	classIndex notNil ifTrue:[
       
  3966 	    classListView selection:classIndex.
       
  3967 	    self switchToClass:(Smalltalk at:(oldClass name asSymbol))
  1773 	] ifFalse:[
  3968 	] ifFalse:[
  1774 	    instanceToggle turnOn.
  3969 	    self normalLabel.
  1775 	    classToggle turnOff
       
  1776 	]
  3970 	]
  1777     ]
  3971     ]
  1778 !
  3972 !
  1779 
  3973 
  1780 updateClassCategoryListWithScroll:scroll
  3974 updateClassCategoryListWithScroll:scroll
  1786     oldClassCategory := currentClassCategory.
  3980     oldClassCategory := currentClassCategory.
  1787     oldClass := currentClass.
  3981     oldClass := currentClass.
  1788     oldMethodCategory := currentMethodCategory.
  3982     oldMethodCategory := currentMethodCategory.
  1789     oldMethod := currentMethod.
  3983     oldMethod := currentMethod.
  1790     oldMethod notNil ifTrue:[
  3984     oldMethod notNil ifTrue:[
  1791 	oldSelector := methodListView selectionValue
  3985 	oldSelector := currentSelector
  1792     ].
  3986     ].
  1793 
  3987 
  1794     classCategoryListView notNil ifTrue:[
  3988     classCategoryListView notNil ifTrue:[
  1795 	newCategoryList := self listOfAllClassCategories.
  3989 	newCategoryList := self listOfAllClassCategories.
  1796 	newCategoryList = classCategoryListView list ifFalse:[
  3990 	newCategoryList = classCategoryListView list ifFalse:[
  1826 
  4020 
  1827 updateClassCategoryList
  4021 updateClassCategoryList
  1828     self updateClassCategoryListWithScroll:true
  4022     self updateClassCategoryListWithScroll:true
  1829 !
  4023 !
  1830 
  4024 
  1831 updateClassListWithScroll:scroll
  4025 allClassesInCurrentCategoryInOrderDo:aBlock
  1832     |classes oldClassName|
  4026     "evaluate aBlock for all classes in the current class category;
  1833 
  4027      superclasses come first - then subclasses"
  1834     classListView notNil ifTrue:[
  4028 
  1835 	currentClass notNil ifTrue:[
  4029     |classes|
  1836 	    oldClassName := currentClass name.
  4030 
  1837 	    currentClass := Smalltalk at:(oldClassName asSymbol).
  4031     currentClassCategory notNil ifTrue:[
  1838 	].
  4032 	classes := OrderedCollection new.
  1839 
  4033 	Smalltalk allBehaviorsDo:[:aClass |
  1840 	currentClassCategory notNil ifTrue:[
  4034 	    aClass isMeta ifFalse:[
  1841 	    classes := self listOfAllClassesInCategory:currentClassCategory
  4035 		(aClass category = currentClassCategory) ifTrue:[
  1842 	] ifFalse:[
  4036 		    classes add:aClass
  1843 	    currentClassHierarchy notNil ifTrue:[
  4037 		]
  1844 		classes := self listOfClassHierarchyOf:currentClassHierarchy
       
  1845 	    ]
  4038 	    ]
  1846 	].
  4039 	].
  1847 
  4040 	classes topologicalSort:[:a :b | b isSubclassOf:a].
  1848 	classListView list = classes ifFalse:[
  4041 	classes do:aBlock
  1849 	    scroll ifTrue:[
  4042     ]
  1850 		classListView contents:classes
  4043 !
  1851 	    ] ifFalse:[
  4044 
  1852 		classListView setContents:classes
  4045 allClassesInCurrentCategoryDo:aBlock
  1853 	    ].
  4046     "evaluate aBlock for all classes in the current class category;
  1854 	    oldClassName notNil ifTrue:[
  4047      superclasses come first - then subclasses"
  1855 		classListView setContents:classes.
  4048 
  1856 		classListView selectElement:oldClassName
  4049     currentClassCategory notNil ifTrue:[
  1857 	    ] ifFalse:[
  4050 	Smalltalk allBehaviorsDo:[:aClass |
  1858 		variableListView notNil ifTrue:[variableListView contents:nil]
  4051 	    aClass isMeta ifFalse:[
       
  4052 		(aClass category = currentClassCategory) ifTrue:[
       
  4053 		    aBlock value:aClass
       
  4054 		]
  1859 	    ]
  4055 	    ]
  1860 	]
  4056 	].
  1861     ]
  4057     ]
  1862 !
  4058 !
  1863 
  4059 
  1864 updateClassList
  4060 renameCurrentClassCategoryTo:aString
  1865     self updateClassListWithScroll:true
  4061     "helper - do the rename"
  1866 !
  4062 
  1867 
  4063     |any categories|
  1868 updateVariableList
  4064 
  1869     |l subList flags last|
  4065     currentClassCategory notNil ifTrue:[
  1870 
  4066 	any := false.
  1871     variableListView isNil ifTrue:[^ self].
  4067 	Smalltalk allBehaviorsDo:[:aClass |
  1872 
  4068 	    aClass category = currentClassCategory ifTrue:[
  1873     l := OrderedCollection new.
  4069 		aClass category:aString.
  1874     actualClass withAllSuperclasses do:[:aClass |
  4070 		any := true
  1875 	subList := aClass instVarNames.
       
  1876 	subList size ~~ 0 ifTrue:[
       
  1877 	    l := l , (subList asOrderedCollection reverse).
       
  1878 	    l := l , (OrderedCollection with:'---- ' , aClass name , ' ---------').
       
  1879 	]
       
  1880     ].
       
  1881     l reverse.
       
  1882     variableListView attributes:nil.
       
  1883     variableListView list:l.
       
  1884     l keysAndValuesDo:[:index :entry |
       
  1885 	(entry startsWith:'---') ifTrue:[
       
  1886 	    variableListView attributeAt:index put:#halfIntensity.
       
  1887 	    last := index
       
  1888 	]
       
  1889     ].
       
  1890     last notNil ifTrue:[variableListView scrollToLine:last]
       
  1891 !
       
  1892 
       
  1893 updateMethodCategoryListWithScroll:scroll
       
  1894     |categories|
       
  1895 
       
  1896     methodCategoryListView notNil ifTrue:[
       
  1897 	currentClass notNil ifTrue:[
       
  1898 	    categories := self listOfAllMethodCategoriesInClass:actualClass
       
  1899 	].
       
  1900 	methodCategoryListView list = categories ifFalse:[
       
  1901 	    scroll ifTrue:[
       
  1902 		methodCategoryListView contents:categories
       
  1903 	    ] ifFalse:[
       
  1904 		methodCategoryListView setContents:categories
       
  1905 	    ].
       
  1906 	    currentMethodCategory notNil ifTrue:[
       
  1907 		methodCategoryListView selectElement:currentMethodCategory
       
  1908 	    ]
  4071 	    ]
  1909 	]
  4072 	].
  1910     ]
  4073 	any ifFalse:[
  1911 !
  4074 	    categories := classCategoryListView list.
  1912 
  4075 	    categories remove:currentClassCategory.
  1913 updateMethodCategoryList
  4076 	    categories add:aString.
  1914     self updateMethodCategoryListWithScroll:true
  4077 	    categories sort.
  1915 !
  4078 	    classCategoryListView setContents:categories.
  1916 
  4079 	    currentClassCategory := aString.
  1917 updateMethodListWithScroll:scroll
  4080 	    classCategoryListView selectElement:aString.
  1918     |selectors scr first last|
  4081 	] ifTrue:[
  1919 
  4082 	    currentClassCategory := aString.
  1920     methodListView notNil ifTrue:[
  4083 	    self updateClassCategoryList.
  1921 	currentMethodCategory notNil ifTrue:[
  4084 	    self updateClassListWithScroll:false
  1922 	    selectors := self listOfAllSelectorsInCategory:currentMethodCategory
  4085 	]
  1923 						   ofClass:actualClass
  4086     ]
  1924 	].
  4087 ! !
  1925 	scr := scroll.
  4088 
  1926 	first := methodListView firstLineShown.
  4089 !SystemBrowser methodsFor:'class-method stuff'!
  1927 	first ~~ 1 ifTrue:[
       
  1928 	    last := methodListView lastLineShown.
       
  1929 	    selectors size <= (last - first + 1) ifTrue:[
       
  1930 		scr := true
       
  1931 	    ]
       
  1932 	].
       
  1933 	methodListView list = selectors ifFalse:[
       
  1934 	    scr ifTrue:[
       
  1935 		methodListView contents:selectors
       
  1936 	    ] ifFalse:[
       
  1937 		methodListView setContents:selectors
       
  1938 	    ]
       
  1939 	].
       
  1940     ]
       
  1941 !
       
  1942 
       
  1943 updateMethodList
       
  1944     self updateMethodListWithScroll:true
       
  1945 !
       
  1946 
       
  1947 updateCodeView
       
  1948     |code aStream|
       
  1949 
       
  1950     fullClass ifTrue:[
       
  1951 	currentClass notNil ifTrue:[
       
  1952 " this is too slow for big classes ...
       
  1953 	    code := String new:1000.
       
  1954 	    aStream := WriteStream on:code.
       
  1955 	    currentClass fileOutOn:aStream
       
  1956 "
       
  1957 	    aStream := FileStream newFileNamed:'__temp'.
       
  1958 	    aStream isNil ifTrue:[
       
  1959 		self notify:'cannot create temporary file.'.
       
  1960 		codeView contents:nil.
       
  1961 		codeView modified:false.
       
  1962 		^ self
       
  1963 	    ].
       
  1964 	    currentClass fileOutOn:aStream.
       
  1965 	    aStream close.
       
  1966 	    aStream := FileStream oldFileNamed:'__temp'.
       
  1967 	    aStream isNil ifTrue:[
       
  1968 		self notify:'oops - cannot reopen temp file'.
       
  1969 		codeView contents:nil.
       
  1970 		codeView modified:false.
       
  1971 		^ self
       
  1972 	    ].
       
  1973 	    code := aStream contents.
       
  1974 	    aStream close.
       
  1975 	    OperatingSystem removeFile:'__temp'
       
  1976 	]
       
  1977     ] ifFalse:[
       
  1978 	currentMethod notNil ifTrue:[
       
  1979 	    code := currentMethod source
       
  1980 	]
       
  1981     ].
       
  1982     codeView contents:code.
       
  1983     codeView modified:false
       
  1984 !
       
  1985 
       
  1986 classSelectionChanged
       
  1987     |oldMethodCategory oldMethod|
       
  1988 
       
  1989     self withWaitCursorDo:[
       
  1990 	oldMethodCategory := currentMethodCategory.
       
  1991 	oldMethod := currentMethod.
       
  1992 
       
  1993 	showInstance ifTrue:[
       
  1994 	    actualClass := currentClass
       
  1995 	] ifFalse:[
       
  1996 	    actualClass := currentClass class
       
  1997 	].
       
  1998 	currentMethodCategory := nil.
       
  1999 	currentMethod := nil.
       
  2000 
       
  2001 	self updateVariableList.
       
  2002 	self updateMethodCategoryList.
       
  2003 	oldMethodCategory notNil ifTrue:[
       
  2004 	    methodCategoryListView selectElement:oldMethodCategory.
       
  2005 	    methodCategoryListView selection notNil ifTrue:[
       
  2006 		currentMethodCategory := oldMethodCategory.
       
  2007 		self methodCategorySelectionChanged
       
  2008 	    ]
       
  2009 	].
       
  2010 	self updateMethodList.
       
  2011 	self updateCodeView.
       
  2012 
       
  2013 	fullClass ifTrue:[
       
  2014 	    codeView acceptAction:[:theCode |
       
  2015 		codeView cursor:Cursor execute.
       
  2016 		Object abortSignal catch:[
       
  2017 		    self compileCode:theCode asString.
       
  2018 		    codeView modified:false.
       
  2019 		].
       
  2020 		codeView cursor:Cursor normal.
       
  2021 	    ].
       
  2022 	    codeView explainAction:nil
       
  2023 	] ifFalse:[
       
  2024 	    self classDefinition.
       
  2025 	    codeView acceptAction:[:theCode |
       
  2026 		codeView cursor:Cursor execute.
       
  2027 		Object abortSignal catch:[
       
  2028 		    (Compiler evaluate:theCode asString notifying:codeView)
       
  2029 		    isBehavior ifTrue:[
       
  2030 			self classCategoryUpdate.
       
  2031 			self updateClassListWithScroll:false.
       
  2032 			codeView modified:false.
       
  2033 		    ].
       
  2034 		].
       
  2035 		codeView cursor:Cursor normal.
       
  2036 	    ].
       
  2037 	    codeView explainAction:nil
       
  2038 	].
       
  2039 	classCategoryListView notNil ifTrue:[
       
  2040 	    (currentClassCategory = currentClass category) ifFalse:[
       
  2041 		currentClassCategory := currentClass category.
       
  2042 		classCategoryListView selectElement:currentClassCategory
       
  2043 	    ]
       
  2044 	].
       
  2045 
       
  2046 	"set self for doits. This allows accessing the current class
       
  2047 	 as self, and access to the class variables by name."
       
  2048 
       
  2049 	codeView doItAction:[:theCode |
       
  2050 	    |compiler|
       
  2051 
       
  2052 	    currentClass isNil ifTrue:[
       
  2053 		compiler := Compiler
       
  2054 	    ] ifFalse:[
       
  2055 		compiler := currentClass compiler
       
  2056 	    ].
       
  2057 	    compiler 
       
  2058 		evaluate:theCode 
       
  2059 		in:nil 
       
  2060 		receiver:currentClass 
       
  2061 		notifying:codeView 
       
  2062 		logged:false
       
  2063 		ifFail:nil 
       
  2064 	]
       
  2065     ]
       
  2066 !
       
  2067 
       
  2068 classCategorySelectionChanged
       
  2069     "class category has changed - update dependant views"
       
  2070 
       
  2071     self withWaitCursorDo:[
       
  2072 	self switchToClass:nil.
       
  2073 	actualClass := nil.
       
  2074 	currentMethodCategory := nil.
       
  2075 	currentMethod := nil.
       
  2076 
       
  2077 	self updateClassList.
       
  2078 	self updateMethodCategoryList.
       
  2079 	self updateMethodList.
       
  2080 	self updateCodeView.
       
  2081 
       
  2082 	codeView explainAction:nil.
       
  2083 	codeView acceptAction:nil
       
  2084     ]
       
  2085 !
       
  2086 
       
  2087 classCategorySelection:lineNr
       
  2088     "user clicked on a class category line - show classes.
       
  2089      If switching to hierarchy or all, keep current selections"
       
  2090 
       
  2091     |newCategory oldClass classIndex index|
       
  2092 
       
  2093     newCategory := classCategoryListView selectionValue.
       
  2094     (newCategory startsWith:'*') ifTrue:[
       
  2095 	"etiher all or hierarchy;
       
  2096 	 remember current selections and switch after showing class list"
       
  2097 	oldClass := currentClass
       
  2098     ].
       
  2099     currentClassCategory := newCategory.
       
  2100     oldClass isNil ifTrue:[
       
  2101 	self classCategorySelectionChanged
       
  2102     ] ifFalse:[
       
  2103 	self withWaitCursorDo:[
       
  2104 	    self updateClassList
       
  2105 	].
       
  2106 	"stupid - search for class name in (indented) list"
       
  2107 	index := 1.
       
  2108 	classListView list do:[:elem |
       
  2109 	    (elem endsWith:(oldClass name)) ifTrue:[
       
  2110 		classIndex := index
       
  2111 	    ].
       
  2112 	    index := index + 1
       
  2113 	].
       
  2114 	classIndex notNil ifTrue:[
       
  2115 	    classListView selection:classIndex.
       
  2116 	    self switchToClass:(Smalltalk at:(oldClass name asSymbol))
       
  2117 	] ifFalse:[
       
  2118 	    self normalLabel.
       
  2119 	]
       
  2120     ]
       
  2121 !
       
  2122 
       
  2123 classSelection:lineNr
       
  2124     "user clicked on a class line - show method categories"
       
  2125 
       
  2126     |classSymbol cls|
       
  2127 
       
  2128     classSymbol := classListView selectionValue withoutSpaces asSymbol.
       
  2129     (Smalltalk includesKey:classSymbol) ifTrue:[
       
  2130 	cls := Smalltalk at:classSymbol
       
  2131     ].
       
  2132     cls notNil ifTrue:[
       
  2133 	self switchToClass:cls.
       
  2134 	self classSelectionChanged
       
  2135     ]
       
  2136 !
       
  2137 
       
  2138 methodCategorySelectionChanged
       
  2139     "method category selection has changed - update dependant views"
       
  2140 
       
  2141     self withWaitCursorDo:[
       
  2142 	currentMethod := nil.
       
  2143 
       
  2144 	self updateMethodList.
       
  2145 	self updateCodeView.
       
  2146 
       
  2147 	currentMethodCategory notNil ifTrue:[
       
  2148 	    methodCategoryListView selectElement:currentMethodCategory
       
  2149 	].
       
  2150 
       
  2151 	codeView acceptAction:[:theCode |
       
  2152 	    codeView cursor:Cursor execute.
       
  2153 	    Object abortSignal catch:[
       
  2154 		actualClass compiler compile:theCode asString
       
  2155 				    forClass:actualClass
       
  2156 				  inCategory:currentMethodCategory
       
  2157 				   notifying:codeView.
       
  2158 		codeView modified:false.
       
  2159 		self updateMethodListWithScroll:false.
       
  2160 	    ].
       
  2161 	    codeView cursor:Cursor normal.
       
  2162 	].
       
  2163 	codeView explainAction:[:theCode :theSelection |
       
  2164 	    self showExplanation:(Explainer explain:theSelection 
       
  2165 						 in:theCode
       
  2166 					   forClass:actualClass)
       
  2167 	]
       
  2168     ]
       
  2169 !
       
  2170 
       
  2171 methodCategorySelection:lineNr
       
  2172     "user clicked on a method category line - show selectors"
       
  2173 
       
  2174     currentClass isNil ifTrue:[^ self].
       
  2175 
       
  2176     currentMethodCategory := methodCategoryListView selectionValue.
       
  2177     self methodCategorySelectionChanged
       
  2178 !
       
  2179 
       
  2180 methodSelectionChanged
       
  2181     "method selection has changed - update dependant views"
       
  2182 
       
  2183     self withWaitCursorDo:[
       
  2184 	self updateCodeView.
       
  2185 	codeView acceptAction:[:theCode |
       
  2186 	    codeView cursor:Cursor execute.
       
  2187 	    Object abortSignal catch:[
       
  2188 		actualClass compiler compile:theCode asString
       
  2189 				    forClass:actualClass
       
  2190 				    inCategory:currentMethodCategory
       
  2191 				     notifying:codeView.
       
  2192 		codeView modified:false.
       
  2193 		self updateMethodListWithScroll:false.
       
  2194 	    ].
       
  2195 	    codeView cursor:Cursor normal.
       
  2196 	].
       
  2197 	codeView explainAction:[:theCode :theSelection |
       
  2198 	    self showExplanation:(Explainer explain:theSelection 
       
  2199 						 in:theCode
       
  2200 					   forClass:actualClass)
       
  2201 	].
       
  2202 	methodListView notNil ifTrue:[
       
  2203 	    (currentMethod notNil and:[currentMethod isWrapped]) ifTrue:[
       
  2204 		self initializeMethodMenu2
       
  2205 	    ] ifFalse:[
       
  2206 		self initializeMethodMenu
       
  2207 	    ]
       
  2208 	]
       
  2209     ]
       
  2210 !
       
  2211 
       
  2212 methodSelection:lineNr
       
  2213     "user clicked on a method line - show code"
       
  2214 
       
  2215     |selectorString selectorSymbol|
       
  2216 
       
  2217     currentClass isNil ifTrue:[^ self].
       
  2218 
       
  2219     selectorString := methodListView selectionValue.
       
  2220     "
       
  2221      kludge: check if its a wrapped one
       
  2222     "
       
  2223     (selectorString endsWith:' !!') ifTrue:[
       
  2224 	selectorString := selectorString copyTo:(selectorString size - 2)
       
  2225     ].
       
  2226     selectorSymbol := selectorString asSymbol.
       
  2227     currentMethod := actualClass compiledMethodAt:selectorSymbol.
       
  2228 
       
  2229     methodCategoryListView notNil ifTrue:[
       
  2230 	currentMethod notNil ifTrue:[
       
  2231 	    (currentMethodCategory = currentMethod category) ifFalse:[
       
  2232 		currentMethodCategory := currentMethod category.
       
  2233 		methodCategoryListView selectElement:currentMethodCategory
       
  2234 	    ]
       
  2235 	]
       
  2236     ].
       
  2237 
       
  2238     self methodSelectionChanged
       
  2239 !
       
  2240 
  4090 
  2241 classFromClassMethodString:aString
  4091 classFromClassMethodString:aString
  2242     "helper for classMethod-list - extract class name from the string"
  4092     "helper for classMethod-list - extract class name from the string"
  2243 
  4093 
  2244     |pos|
  4094     |pos|
  2254 
  4104 
  2255     pos := aString indexOf:(Character space).
  4105     pos := aString indexOf:(Character space).
  2256     ^ aString copyFrom:(pos + 1)
  4106     ^ aString copyFrom:(pos + 1)
  2257 !
  4107 !
  2258 
  4108 
  2259 listSelection:lineNr
  4109 classMethodSelection:lineNr
  2260     "user clicked on a class/method line - show code"
  4110     "user clicked on a class/method line - show code"
  2261 
  4111 
  2262     |string classString selectorString|
  4112     |string classString selectorString|
  2263 
  4113 
  2264     string := classMethodListView selectionValue.
  4114     string := classMethodListView selectionValue.
  2274     ].
  4124     ].
  2275     currentClass isNil ifTrue:[
  4125     currentClass isNil ifTrue:[
  2276 	self warn:'oops class is gone'
  4126 	self warn:'oops class is gone'
  2277     ] ifFalse:[
  4127     ] ifFalse:[
  2278 	currentClassCategory := currentClass category.
  4128 	currentClassCategory := currentClass category.
  2279 	currentMethod := actualClass compiledMethodAt:(selectorString asSymbol).
  4129 	currentSelector := selectorString asSymbol.
       
  4130 	currentMethod := actualClass compiledMethodAt:currentSelector.
  2280 	currentMethodCategory := currentMethod category.
  4131 	currentMethodCategory := currentMethod category.
  2281 
  4132 
  2282 	self methodSelectionChanged
  4133 	self methodSelectionChanged
  2283     ]
  4134     ]
  2284 ! !
  4135 ! !
  2285 
  4136 
  2286 !SystemBrowser methodsFor:'class category menu'!
  4137 !SystemBrowser methodsFor:'class category list menu'!
  2287 
  4138 
  2288 initializeClassCategoryMenu
  4139 initializeClassCategoryMenu
  2289     |labels|
  4140     |labels|
  2290     
  4141     
  2291     labels := resources array:#(
  4142     labels := resources array:#(
  2326 					 classCategoryRemove)
  4177 					 classCategoryRemove)
  2327 			      receiver:self
  4178 			      receiver:self
  2328 				   for:classCategoryListView)
  4179 				   for:classCategoryListView)
  2329 !
  4180 !
  2330 
  4181 
  2331 allClassesInCurrentCategoryInOrderDo:aBlock
       
  2332     "evaluate aBlock for all classes in the current class category;
       
  2333      superclasses come first - then subclasses"
       
  2334 
       
  2335     |classes|
       
  2336 
       
  2337     currentClassCategory notNil ifTrue:[
       
  2338 	classes := OrderedCollection new.
       
  2339 	Smalltalk allClassesDo:[:aClass |
       
  2340 	    aClass isMeta ifFalse:[
       
  2341 		(aClass category = currentClassCategory) ifTrue:[
       
  2342 		    classes add:aClass
       
  2343 		]
       
  2344 	    ]
       
  2345 	].
       
  2346 	classes topologicalSort:[:a :b | b isSubclassOf:a].
       
  2347 	classes do:aBlock
       
  2348     ]
       
  2349 !
       
  2350 
       
  2351 allClassesInCurrentCategoryDo:aBlock
       
  2352     "evaluate aBlock for all classes in the current class category;
       
  2353      superclasses come first - then subclasses"
       
  2354 
       
  2355     currentClassCategory notNil ifTrue:[
       
  2356 	Smalltalk allClassesDo:[:aClass |
       
  2357 	    aClass isMeta ifFalse:[
       
  2358 		(aClass category = currentClassCategory) ifTrue:[
       
  2359 		    aBlock value:aClass
       
  2360 		]
       
  2361 	    ]
       
  2362 	].
       
  2363     ]
       
  2364 !
       
  2365 
       
  2366 classCategoryUpdate
  4182 classCategoryUpdate
  2367     "update class category list and dependants"
  4183     "update class category list and dependants"
  2368 
  4184 
  2369     |oldClassName oldMethodCategory|
  4185     |oldClassName oldMethodCategory|
  2370 
  4186 
  2413 	aClass printOutOn:printStream.
  4229 	aClass printOutOn:printStream.
  2414 	printStream close
  4230 	printStream close
  2415     ]
  4231     ]
  2416 !
  4232 !
  2417 
  4233 
       
  4234 classCategorySpawn
       
  4235     "create a new SystemBrowser browsing current classCategory"
       
  4236 
       
  4237     currentClassCategory notNil ifTrue:[
       
  4238 	self withWaitCursorDo:[
       
  4239 	    self class browseClassCategory:currentClassCategory
       
  4240 	]
       
  4241     ]
       
  4242 !
       
  4243 
  2418 classCategoryFileOut
  4244 classCategoryFileOut
  2419     "create a file 'categoryName' consisting of all classes in current category"
  4245     "create a file 'categoryName' consisting of all classes in current category"
  2420 
  4246 
  2421     |aStream fileName|
  4247     |aStream fileName|
  2422 
  4248 
  2440     aStream := FileStream newFileNamed:fileName.
  4266     aStream := FileStream newFileNamed:fileName.
  2441     aStream isNil ifTrue:[
  4267     aStream isNil ifTrue:[
  2442 	^ self warn:'cannot create: %1' with:fileName
  4268 	^ self warn:'cannot create: %1' with:fileName
  2443     ].
  4269     ].
  2444     self withWaitCursorDo:[
  4270     self withWaitCursorDo:[
  2445 	self label:('System Browser writing: ' , fileName).
  4271 	self busyLabel:'writing: %1' with:fileName.
  2446 	self allClassesInCurrentCategoryInOrderDo:[:aClass |
  4272 	self allClassesInCurrentCategoryInOrderDo:[:aClass |
  2447 	    aClass fileOutOn:aStream.
  4273 	    aClass fileOutOn:aStream.
  2448 	].
  4274 	].
  2449 	aStream close.
  4275 	aStream close.
  2450 	self normalLabel.
  4276 	self normalLabel.
       
  4277     ]
       
  4278 !
       
  4279 
       
  4280 classCategorySpawnFullClass
       
  4281     "create a new SystemBrowser browsing full class"
       
  4282 
       
  4283     |newBrowser|
       
  4284 
       
  4285     self withWaitCursorDo:[
       
  4286 	newBrowser := self class browseFullClasses
       
  4287 " "
       
  4288 	.
       
  4289 	currentClass notNil ifTrue:[
       
  4290 	    newBrowser switchToClassNamed:(currentClass name)
       
  4291 	]
       
  4292 " "
  2451     ]
  4293     ]
  2452 !
  4294 !
  2453 
  4295 
  2454 classCategoryFileOutEach
  4296 classCategoryFileOutEach
  2455     self withWaitCursorDo:[
  4297     self withWaitCursorDo:[
  2456 	self allClassesInCurrentCategoryDo:[:aClass |
  4298 	self allClassesInCurrentCategoryDo:[:aClass |
  2457 	    self label:('System Browser saving: ' , aClass name).
  4299 	    self busyLabel:'saving: ' with:aClass name.
  2458 	    Class fileOutErrorSignal handle:[:ex |
  4300 	    Class fileOutErrorSignal handle:[:ex |
  2459 		self warn:'cannot create: %1' with:ex parameter.
  4301 		self warn:'cannot create: %1' with:ex parameter.
  2460 		ex return.
  4302 		ex return.
  2461 	    ] do:[
  4303 	    ] do:[
  2462 		aClass fileOut
  4304 		aClass fileOut
  2464 	].
  4306 	].
  2465 	self normalLabel.
  4307 	self normalLabel.
  2466     ]
  4308     ]
  2467 !
  4309 !
  2468 
  4310 
  2469 classCategorySpawn
       
  2470     "create a new SystemBrowser browsing current classCategory"
       
  2471 
       
  2472     currentClassCategory notNil ifTrue:[
       
  2473 	self withWaitCursorDo:[
       
  2474 	    self class browseClassCategory:currentClassCategory
       
  2475 	]
       
  2476     ]
       
  2477 !
       
  2478 
       
  2479 classCategorySpawnFullClass
       
  2480     "create a new SystemBrowser browsing full class"
       
  2481 
       
  2482     |newBrowser|
       
  2483 
       
  2484     self withWaitCursorDo:[
       
  2485 	newBrowser := self class browseFullClasses
       
  2486 "
       
  2487 	.
       
  2488 	currentClass notNil ifTrue:[
       
  2489 	    newBrowser switchToClassNamed:(currentClass name)
       
  2490 	]
       
  2491 "
       
  2492     ]
       
  2493 !
       
  2494 
       
  2495 classCategoryNewCategory
  4311 classCategoryNewCategory
  2496     |box|
  4312     |box|
  2497 
  4313 
  2498     box := self enterBoxTitle:'name of new class category:' okText:'create'.
  4314     box := self enterBoxTitle:'name of new class category:' okText:'create'.
  2499     box action:[:aString |
  4315     box action:[:aString |
  2500 	|categories|
  4316 	|categories|
  2501 
  4317 
  2502 	categories := classCategoryListView list.
  4318 	currentClass notNil ifTrue:[
       
  4319 	    categories := OrderedCollection new.
       
  4320 	    currentClass withAllSuperclasses do:[:aClass |
       
  4321 		aClass methodArray do:[:aMethod |
       
  4322 		    (categories includes:aMethod category) ifFalse:[
       
  4323 			categories add:aMethod category
       
  4324 		    ]
       
  4325 		]
       
  4326 	    ].
       
  4327 	].
       
  4328 	categories isNil ifTrue:[
       
  4329 	    categories := classCategoryListView list.
       
  4330 	].
  2503 	(categories includes:aString) ifFalse:[
  4331 	(categories includes:aString) ifFalse:[
  2504 	    categories add:aString.
  4332 	    categories add:aString.
  2505 	    categories sort.
  4333 	    categories sort.
  2506 	    classCategoryListView setContents:categories.
  4334 	    classCategoryListView setContents:categories.
  2507 	    currentClassCategory := aString.
  4335 	    currentClassCategory := aString.
  2512 	]
  4340 	]
  2513     ].
  4341     ].
  2514     box showAtPointer
  4342     box showAtPointer
  2515 !
  4343 !
  2516 
  4344 
  2517 switchToClassNamed:aString
       
  2518     |classSymbol theClass|
       
  2519 
       
  2520     classSymbol := aString asSymbol.
       
  2521     theClass := Smalltalk at:classSymbol.
       
  2522     theClass isBehavior ifTrue:[
       
  2523 	classCategoryListView notNil ifTrue:[
       
  2524 	    currentClassHierarchy isNil ifTrue:[
       
  2525 		(theClass category ~~ currentClassCategory) ifTrue:[
       
  2526 		    currentClassCategory := theClass category.
       
  2527 		    currentClassCategory isNil ifTrue:[
       
  2528 			classCategoryListView selectElement:'* no category *'
       
  2529 		    ] ifFalse:[
       
  2530 			classCategoryListView selectElement:currentClassCategory
       
  2531 		    ].
       
  2532 		    self classCategorySelectionChanged
       
  2533 		]
       
  2534 	    ]
       
  2535 	].
       
  2536 	self switchToClass:theClass.
       
  2537 	classListView selectElement:aString.
       
  2538 	self classSelectionChanged
       
  2539     ]
       
  2540 !
       
  2541 
       
  2542 switchToClassNameMatching:aMatchString
       
  2543     |classNames thisName box|
       
  2544 
       
  2545     classNames := OrderedCollection new.
       
  2546     Smalltalk allBehaviorsDo:[:aClass |
       
  2547 	thisName := aClass name.
       
  2548 	(aMatchString match:thisName) ifTrue:[
       
  2549 	    classNames add:thisName
       
  2550 	]
       
  2551     ].
       
  2552     (classNames size == 0) ifTrue:[^ nil].
       
  2553     (classNames size == 1) ifTrue:[
       
  2554 	^ self switchToClassNamed:(classNames at:1)
       
  2555     ].
       
  2556 
       
  2557     box := self listBoxTitle:'select class to switch to:'
       
  2558 		      okText:'ok'
       
  2559 			list:classNames sort.
       
  2560     box action:[:aString | self switchToClassNamed:aString].
       
  2561     box showAtPointer
       
  2562 !
       
  2563 
       
  2564 classCategoryFindClass
  4345 classCategoryFindClass
  2565     |box|
  4346     |box|
  2566 
  4347 
  2567     box := self enterBoxForCodeSelectionTitle:'class to find:' okText:'find'.
  4348     box := self enterBoxForCodeSelectionTitle:'class to find:' okText:'find'.
  2568     box action:[:aString | self switchToClassNameMatching:aString].
  4349     box action:[:aString | self switchToClassNameMatching:aString].
  2569     box showAtPointer
  4350     box showAtPointer
  2570 !
       
  2571 
       
  2572 renameCurrentClassCategoryTo:aString
       
  2573     "helper - do the rename"
       
  2574 
       
  2575     |any categories|
       
  2576 
       
  2577     currentClassCategory notNil ifTrue:[
       
  2578 	any := false.
       
  2579 	Smalltalk allBehaviorsDo:[:aClass |
       
  2580 	    aClass category = currentClassCategory ifTrue:[
       
  2581 		aClass category:aString.
       
  2582 		any := true
       
  2583 	    ]
       
  2584 	].
       
  2585 	any ifFalse:[
       
  2586 	    categories := classCategoryListView list.
       
  2587 	    categories remove:currentClassCategory.
       
  2588 	    categories add:aString.
       
  2589 	    categories sort.
       
  2590 	    classCategoryListView setContents:categories.
       
  2591 	    currentClassCategory := aString.
       
  2592 	    classCategoryListView selectElement:aString.
       
  2593 	] ifTrue:[
       
  2594 	    currentClassCategory := aString.
       
  2595 	    self updateClassCategoryList.
       
  2596 	    self updateClassListWithScroll:false
       
  2597 	]
       
  2598     ]
       
  2599 !
  4351 !
  2600 
  4352 
  2601 classCategoryRename
  4353 classCategoryRename
  2602     "launch an enterBox to rename current class category"
  4354     "launch an enterBox to rename current class category"
  2603 
  4355 
  2666 	       noText:(resources at:'abort').
  4418 	       noText:(resources at:'abort').
  2667     box confirm ifTrue:[
  4419     box confirm ifTrue:[
  2668 	"after querying user - do really remove classes in list1 and list2"
  4420 	"after querying user - do really remove classes in list1 and list2"
  2669 
  4421 
  2670 	subclassesRemoved do:[:aClass |
  4422 	subclassesRemoved do:[:aClass |
  2671 	    Smalltalk removeClass:aClass
  4423 	    (CheckForInstancesWhenRemovingClasses not
       
  4424 	    or:[aClass hasInstances not
       
  4425 	    or:[self confirm:(aClass name , ' has instances - remove anyway ?')]])
       
  4426 		ifTrue:[   
       
  4427 		    Smalltalk removeClass:aClass
       
  4428 	    ]
  2672 	].
  4429 	].
  2673 	classesToRemove do:[:aClass |
  4430 	classesToRemove do:[:aClass |
  2674 	    Smalltalk removeClass:aClass
  4431 	    (CheckForInstancesWhenRemovingClasses not
       
  4432 	    or:[aClass hasInstances not
       
  4433 	    or:[self confirm:(aClass name , ' has instances - remove anyway ?')]])
       
  4434 		ifTrue:[   
       
  4435 		    Smalltalk removeClass:aClass
       
  4436 	    ].
  2675 	].
  4437 	].
  2676 	currentClassCategory := nil.
  4438 	currentClassCategory := nil.
  2677 	self switchToClass:nil.
  4439 	self switchToClass:nil.
  2678 	Smalltalk changed
  4440 	Smalltalk changed
  2679     ]
  4441     ]
  2680 ! !
  4442 ! !
  2681 
  4443 
  2682 !SystemBrowser methodsFor:'class menu'!
  4444 !SystemBrowser methodsFor:'method category list menu'!
  2683 
       
  2684 initializeClassMenu
       
  2685     |labels menu varMenu|
       
  2686 
       
  2687     labels := resources array:#(
       
  2688 					'fileOut'
       
  2689 					'printOut'
       
  2690 					'printOut protocol'
       
  2691 				      " 'printOut full protocol' "
       
  2692 					'-'
       
  2693 					'SPAWN_CLASS' 
       
  2694 					'spawn hierarchy' 
       
  2695 					'spawn subclasses' 
       
  2696 					'-'
       
  2697 					'hierarchy' 
       
  2698 					'definition' 
       
  2699 					'comment' 
       
  2700 					'class instvars' 
       
  2701 				      " 'protocols' "
       
  2702 					'-'
       
  2703 "/                                        'variable search'
       
  2704 					'class refs'
       
  2705 					'-'
       
  2706 					'new class'
       
  2707 					'new subclass'
       
  2708 					'rename ...'
       
  2709 					'remove').
       
  2710 
       
  2711     menu := PopUpMenu labels:labels
       
  2712 		   selectors:#(classFileOut
       
  2713 			       classPrintOut
       
  2714 			       classPrintOutProtocol
       
  2715 			     " classPrintOutFullProtocol "
       
  2716 			       nil
       
  2717 			       classSpawn
       
  2718 			       classSpawnHierarchy
       
  2719 			       classSpawnSubclasses
       
  2720 			       nil
       
  2721 			       classHierarchy
       
  2722 			       classDefinition
       
  2723 			       classComment
       
  2724 			       classClassInstVars
       
  2725 			     "  classProtocols "
       
  2726 			       nil
       
  2727 "/                               variables
       
  2728 			       classRefs
       
  2729 			       nil
       
  2730 			       classNewClass
       
  2731 			       classNewSubclass
       
  2732 			       classRename
       
  2733 			       classRemove)
       
  2734 		    receiver:self
       
  2735 			 for:classListView.
       
  2736 
       
  2737     classListView middleButtonMenu:menu. 
       
  2738 
       
  2739     varMenu := (PopUpMenu labels:(resources array:#(
       
  2740 					'instvar refs ...'
       
  2741 					'classvar refs ...'
       
  2742 					'all instvar refs ...'
       
  2743 					'all classvar refs ...'
       
  2744 					'-'
       
  2745 					'instvar mods ...'
       
  2746 					'classvar mods ...'
       
  2747 					'all instvar mods ...'
       
  2748 					'all classvar mods ...'
       
  2749 				     ))
       
  2750 			   selectors:#(
       
  2751 					classInstVarRefs
       
  2752 					classClassVarRefs
       
  2753 					classAllInstVarRefs
       
  2754 					classAllClassVarRefs
       
  2755 					nil
       
  2756 					classInstVarMods
       
  2757 					classClassVarMods
       
  2758 					classAllInstVarMods
       
  2759 					classAllClassVarMods
       
  2760 				     )
       
  2761 			   receiver:self
       
  2762 				for:self).
       
  2763 
       
  2764     variableListView isNil ifTrue:[
       
  2765 	menu addLabel:(resources string:'variable search')
       
  2766 	     selector:#variables
       
  2767 	     before:#classRefs.
       
  2768 	menu subMenuAt:#variables put:varMenu.
       
  2769     ] ifFalse:[
       
  2770 	variableListView middleButtonMenu:varMenu
       
  2771     ].
       
  2772 !
       
  2773 
       
  2774 checkClassCategorySelected
       
  2775     currentClassCategory isNil ifTrue:[
       
  2776 	self warn:'select a class category first'.
       
  2777 	^ false
       
  2778     ].
       
  2779     ^ true
       
  2780 !
       
  2781 
       
  2782 checkClassSelected
       
  2783     currentClass isNil ifTrue:[
       
  2784 	self warn:'select a class first'.
       
  2785 	^ false
       
  2786     ].
       
  2787     ^ true
       
  2788 !
       
  2789 
       
  2790 checkMethodCategorySelected
       
  2791     currentMethodCategory isNil ifTrue:[
       
  2792 	self warn:'select a method category first'.
       
  2793 	^ false
       
  2794     ].
       
  2795     ^ true
       
  2796 !
       
  2797 
       
  2798 whenMethodCategorySelected:aBlock
       
  2799     self checkMethodCategorySelected ifTrue:[
       
  2800 	self withWaitCursorDo:aBlock
       
  2801     ]
       
  2802 !
       
  2803 
       
  2804 checkMethodSelected
       
  2805     currentMethod isNil ifTrue:[
       
  2806 	self warn:'select a method first'.
       
  2807 	^ false
       
  2808     ].
       
  2809     ^ true
       
  2810 !
       
  2811 
       
  2812 doClassMenu:aBlock
       
  2813     "a helper - check if class is selected and evaluate aBlock
       
  2814      while showing waitCursor"
       
  2815 
       
  2816     self checkClassSelected ifTrue:[
       
  2817 	self withWaitCursorDo:aBlock
       
  2818     ]
       
  2819 !
       
  2820     
       
  2821 doClassMenuWithSelection:aBlock
       
  2822     "a helper - if there is a selection, which represents a classes name,
       
  2823      evaluate aBlock, passing that class and optional selector as arguments.
       
  2824      Otherwise, check if a class is selected and evaluate aBlock with the
       
  2825      current class."
       
  2826 
       
  2827     |string words clsName cls sel isMeta w|
       
  2828 
       
  2829     string := codeView selection.
       
  2830     string notNil ifTrue:[
       
  2831 	string := string asString withoutSeparators.
       
  2832 	words := string asCollectionOfWords.
       
  2833 	words notNil ifTrue:[
       
  2834 	    clsName := words first.
       
  2835 	    (clsName endsWith:'class') ifTrue:[
       
  2836 		isMeta := true.
       
  2837 		clsName := clsName copyTo:(clsName size - 5)
       
  2838 	    ] ifFalse:[
       
  2839 		isMeta := false
       
  2840 	    ].
       
  2841 	    (cls := Smalltalk classNamed:clsName) notNil ifTrue:[
       
  2842 		sel := Parser selectorInExpression:string.
       
  2843 		isMeta ifTrue:[
       
  2844 		    cls := cls class
       
  2845 		].
       
  2846 		self withWaitCursorDo:[
       
  2847 		    aBlock value:cls value:sel.
       
  2848 		].
       
  2849 		^ self
       
  2850 	    ] ifFalse:[
       
  2851 		self warn:'no class named: %1 - spawning current' with:clsName
       
  2852 	    ]
       
  2853 	].
       
  2854     ].
       
  2855 
       
  2856     self doClassMenu:[aBlock value:currentClass value:nil]
       
  2857 !
       
  2858 
       
  2859 classSpawn
       
  2860     "create a new SystemBrowser browsing current class,
       
  2861      or if there is a selection, spawn a browser on the selected class
       
  2862      even a class/selector pair can be specified."
       
  2863 
       
  2864     |browser|
       
  2865 
       
  2866     self doClassMenuWithSelection:[:cls :sel |
       
  2867 	cls isMeta ifTrue:[
       
  2868 	    Smalltalk allClassesDo:[:aClass |
       
  2869 		aClass class == cls ifTrue:[
       
  2870 		    browser := self class browseClass:aClass.
       
  2871 		    browser classProtocol.
       
  2872 		    sel notNil ifTrue:[
       
  2873 			browser switchToMethodNamed:sel
       
  2874 		    ].
       
  2875 		    ^ self
       
  2876 		].
       
  2877 	    ].
       
  2878 	    self warn:'oops, no class for this metaclass'.
       
  2879 	    ^ self
       
  2880 	].
       
  2881 	browser := self class browseClass:cls. 
       
  2882 	cls hasMethods ifFalse:[
       
  2883 	    browser classProtocol.
       
  2884 	].
       
  2885 	sel notNil ifTrue:[
       
  2886 	    browser switchToMethodNamed:sel
       
  2887 	].
       
  2888     ]
       
  2889 
       
  2890     "
       
  2891      select 'Smalltalk allClassesDo:' and use spawn from the class menu
       
  2892      select 'Smalltalk'               and use spawn from the class menu
       
  2893     "
       
  2894 !
       
  2895 
       
  2896 classSpawnHierarchy
       
  2897     "create a new HierarchyBrowser browsing current class"
       
  2898 
       
  2899     self doClassMenuWithSelection:[:cls :sel |
       
  2900 	self class browseClassHierarchy:cls 
       
  2901     ]
       
  2902 !
       
  2903 
       
  2904 classSpawnSubclasses
       
  2905     "create a new browser browsing current class's subclasses"
       
  2906 
       
  2907     |subs|
       
  2908 
       
  2909     self doClassMenuWithSelection:[:cls :sel |
       
  2910 	subs := cls allSubclasses.
       
  2911 	(subs notNil and:[subs size ~~ 0]) ifTrue:[
       
  2912 	    self class browseClasses:subs title:('subclasses of ' , cls name)
       
  2913 	]
       
  2914     ]
       
  2915 !
       
  2916 
       
  2917 classPrintOutFullProtocol
       
  2918     |printStream|
       
  2919 
       
  2920     self doClassMenu:[
       
  2921 	printStream := Printer new.
       
  2922 	currentClass printOutFullProtocolOn:printStream.
       
  2923 	printStream close
       
  2924     ]
       
  2925 !
       
  2926 
       
  2927 classPrintOutProtocol
       
  2928     |printStream|
       
  2929 
       
  2930     self doClassMenu:[
       
  2931 	printStream := Printer new.
       
  2932 	currentClass printOutProtocolOn:printStream.
       
  2933 	printStream close
       
  2934     ]
       
  2935 !
       
  2936 
       
  2937 classPrintOut
       
  2938     |printStream|
       
  2939 
       
  2940     self doClassMenu:[
       
  2941 	printStream := Printer new.
       
  2942 	currentClass printOutOn:printStream.
       
  2943 	printStream close
       
  2944     ]
       
  2945 !
       
  2946 
       
  2947 classFileOut
       
  2948     self doClassMenu:[
       
  2949 	self label:('System Browser saving: ' , currentClass name).
       
  2950 	Class fileOutErrorSignal handle:[:ex |
       
  2951 	    self warn:'cannot create: %1' with:ex parameter.
       
  2952 	    ex return.
       
  2953 	] do:[
       
  2954 	    currentClass fileOut.
       
  2955 	].
       
  2956 	self normalLabel.
       
  2957     ]
       
  2958 !
       
  2959 
       
  2960 classHierarchy
       
  2961     "show current classes hierarchy in codeView"
       
  2962 
       
  2963     |aStream|
       
  2964 
       
  2965     self doClassMenu:[
       
  2966 	aStream := WriteStream on:(String new:200).
       
  2967 	actualClass printHierarchyOn:aStream.
       
  2968 	codeView contents:(aStream contents).
       
  2969 	codeView modified:false.
       
  2970 	codeView acceptAction:nil.
       
  2971 	codeView explainAction:nil.
       
  2972 	methodListView notNil ifTrue:[
       
  2973 	    methodListView deselect
       
  2974 	].
       
  2975 	aspect := #hierarchy 
       
  2976     ]
       
  2977 !
       
  2978 
       
  2979 classDefinition
       
  2980     "show class definition in codeView and setup accept-action for
       
  2981      class-definition change"
       
  2982 
       
  2983     |aStream|
       
  2984 
       
  2985     self doClassMenu:[
       
  2986 	aStream := WriteStream on:(String new:200).
       
  2987 	currentClass fileOutDefinitionOn:aStream.
       
  2988 	codeView contents:(aStream contents).
       
  2989 	codeView modified:false.
       
  2990 	codeView acceptAction:[:theCode |
       
  2991 	    codeView cursor:Cursor execute.
       
  2992 	    Object abortSignal catch:[
       
  2993 		(Compiler evaluate:theCode asString notifying:codeView)
       
  2994 		isBehavior ifTrue:[
       
  2995 		    codeView modified:false.
       
  2996 		    self classCategoryUpdate.
       
  2997 		    self updateClassListWithScroll:false.
       
  2998 		]
       
  2999 	    ].
       
  3000 	    codeView cursor:Cursor normal.
       
  3001 	].
       
  3002 	codeView explainAction:nil.
       
  3003 	methodListView notNil ifTrue:[
       
  3004 	    methodListView deselect
       
  3005 	].
       
  3006 	aspect := #definition 
       
  3007     ]
       
  3008 !
       
  3009 
       
  3010 classClassInstVars
       
  3011     "show class instance variables in codeView and setup accept-action
       
  3012      for class-instvar-definition change"
       
  3013 
       
  3014     |s|
       
  3015 
       
  3016     self doClassMenu:[
       
  3017 	s := WriteStream on:(String new).
       
  3018 	currentClass fileOutClassInstVarDefinitionOn:s.
       
  3019 	codeView contents:(s contents).
       
  3020 	codeView modified:false.
       
  3021 	codeView acceptAction:[:theCode |
       
  3022 	    codeView cursor:Cursor execute.
       
  3023 	    Object abortSignal catch:[
       
  3024 		Compiler evaluate:theCode asString notifying:codeView.
       
  3025 		codeView modified:false.
       
  3026 		self updateClassList.
       
  3027 	    ].
       
  3028 	    codeView cursor:Cursor normal.
       
  3029 	].
       
  3030 	codeView explainAction:nil.
       
  3031 	methodListView notNil ifTrue:[
       
  3032 	    methodListView deselect
       
  3033 	]
       
  3034     ]
       
  3035 !
       
  3036 
       
  3037 classProtocols
       
  3038      ^ self
       
  3039 !
       
  3040 
       
  3041 classComment
       
  3042     "show the classes comment in the codeView"
       
  3043 
       
  3044     self doClassMenu:[
       
  3045 	codeView contents:(currentClass comment).
       
  3046 	codeView modified:false.
       
  3047 	codeView acceptAction:[:theCode |
       
  3048 	    Object abortSignal catch:[
       
  3049 		currentClass comment:theCode asString.
       
  3050 		codeView modified:false.
       
  3051 	    ]
       
  3052 	].
       
  3053 	codeView explainAction:nil.
       
  3054 	methodListView notNil ifTrue:[
       
  3055 	    methodListView deselect
       
  3056 	].
       
  3057 	aspect := #comment
       
  3058     ]
       
  3059 !
       
  3060 
       
  3061 classRefs
       
  3062     self doClassMenu:[
       
  3063 	self withCursor:(Cursor questionMark) do:[
       
  3064 	    self class browseReferendsOf:currentClass name asSymbol
       
  3065 	]
       
  3066     ]
       
  3067 !
       
  3068 
       
  3069 classClassDefinitionTemplateFor:name in:cat
       
  3070     "common helper for newClass and newSubclass
       
  3071      - show a template to define class name in category cat"
       
  3072 
       
  3073     currentMethodCategory := nil.
       
  3074     currentMethod := nil.
       
  3075 
       
  3076     classListView deselect.
       
  3077 
       
  3078     fullClass ifFalse:[
       
  3079 	methodCategoryListView contents:nil.
       
  3080 	methodListView contents:nil
       
  3081     ].
       
  3082 
       
  3083     codeView contents:(self templateFor:name in:cat).
       
  3084     codeView modified:false.
       
  3085 
       
  3086     codeView acceptAction:[:theCode |
       
  3087 	codeView cursor:Cursor execute.
       
  3088 	Object abortSignal catch:[
       
  3089 	    |cl|
       
  3090 
       
  3091 	    cl := (Compiler evaluate:theCode asString notifying:codeView).
       
  3092 	    cl isBehavior ifTrue:[
       
  3093 		codeView modified:false.
       
  3094 		self classCategoryUpdate.
       
  3095 		self updateClassListWithScroll:false.
       
  3096 		self switchToClassNamed:(cl name)
       
  3097 	    ]
       
  3098 	].
       
  3099 	codeView cursor:(Cursor normal).
       
  3100     ].
       
  3101     codeView explainAction:nil.
       
  3102     self switchToClass:nil
       
  3103 !
       
  3104 
       
  3105 classNewClass
       
  3106     "create a class-definition prototype in codeview"
       
  3107 
       
  3108     |nm|
       
  3109 
       
  3110     currentClass notNil ifTrue:[
       
  3111 	nm := currentClass superclass name 
       
  3112     ] ifFalse:[
       
  3113 	nm := 'Object'
       
  3114     ].
       
  3115     self classClassDefinitionTemplateFor:nm in:currentClassCategory.
       
  3116     aspect := nil 
       
  3117 !
       
  3118 
       
  3119 classNewSubclass
       
  3120     "create a subclass-definition prototype in codeview"
       
  3121 
       
  3122     self doClassMenu:[
       
  3123 	self classClassDefinitionTemplateFor:(currentClass name) 
       
  3124 					  in:(currentClass category).
       
  3125 	aspect := nil
       
  3126     ]
       
  3127 !
       
  3128 
       
  3129 renameCurrentClassTo:aString
       
  3130     "helper - do the rename"
       
  3131 
       
  3132     self doClassMenu:[
       
  3133 	|oldName oldSym newSym|
       
  3134 
       
  3135 	oldName := currentClass name.
       
  3136 	oldSym := oldName asSymbol.
       
  3137 "
       
  3138 	currentClass setName:aString.
       
  3139 	newSym := aString asSymbol.
       
  3140 	Smalltalk at:oldSym put:nil.
       
  3141 	Smalltalk removeKey:oldSym.            
       
  3142 	Smalltalk at:newSym put:currentClass.
       
  3143 "
       
  3144 "
       
  3145 	currentClass renameTo:aString.
       
  3146 "
       
  3147 	Smalltalk renameClass:currentClass to:aString.
       
  3148 
       
  3149 	self updateClassList.
       
  3150 	self updateMethodCategoryListWithScroll:false.
       
  3151 	self updateMethodListWithScroll:false.
       
  3152 	self withWaitCursorDo:[
       
  3153 	    Transcript showCr:('searching for users of ' , oldSym); endEntry.
       
  3154 	    self class browseReferendsOf:oldSym warnIfNone:false
       
  3155 	]
       
  3156     ]
       
  3157 !
       
  3158 
       
  3159 classRename
       
  3160     "launch an enterBox for new name and query user"
       
  3161 
       
  3162     |box|
       
  3163 
       
  3164     self checkClassSelected ifFalse:[^ self].
       
  3165     box := self enterBoxTitle:(resources string:'rename %1 to:' with:currentClass name) okText:'rename'.
       
  3166     box initialText:(currentClass name).
       
  3167     box action:[:aString | self renameCurrentClassTo:aString].
       
  3168     box showAtPointer
       
  3169 !
       
  3170 
       
  3171 classRemove
       
  3172     "user requested remove of current class and all subclasses -
       
  3173      count subclasses and let user confirm removal."
       
  3174 
       
  3175     |count t box|
       
  3176 
       
  3177     currentClass notNil ifTrue:[
       
  3178 	count := currentClass allSubclasses size.
       
  3179 	t := 'remove ' , currentClass name.
       
  3180 	count ~~ 0 ifTrue:[
       
  3181 	   t := t , '\(with ' , count printString , ' subclass'.
       
  3182 	   count ~~ 1 ifTrue:[
       
  3183 		t := t , 'es'
       
  3184 	   ].
       
  3185 	   t := (t , ')') withCRs
       
  3186 	].
       
  3187 	box := YesNoBox 
       
  3188 		   title:t
       
  3189 		   yesText:(resources at:'remove')
       
  3190 		   noText:(resources at:'abort').
       
  3191 	box confirm ifTrue:[
       
  3192 	    "after querying user - do really remove current class
       
  3193 	     and all subclasses
       
  3194 	    "
       
  3195 	    self doClassMenu:[
       
  3196 		currentClass allSubclassesDo:[:aSubClass |
       
  3197 		    Smalltalk removeClass:aSubClass
       
  3198 		].
       
  3199 		Smalltalk removeClass:currentClass.
       
  3200 
       
  3201 		self switchToClass:nil.
       
  3202 		Smalltalk changed.
       
  3203 		self updateClassList.
       
  3204 
       
  3205 		"if it was the last in its category, update class category list"
       
  3206 "
       
  3207 		classListView numberOfLines == 0 ifTrue:[
       
  3208 		    self updateClassCategoryListWithScroll:false
       
  3209 		].
       
  3210 "
       
  3211 		methodCategoryListView notNil ifTrue:[methodCategoryListView contents:nil].
       
  3212 		methodListView notNil ifTrue:[methodListView contents:nil].
       
  3213 		codeView contents:nil.
       
  3214 		codeView modified:false
       
  3215 	    ]
       
  3216 	]
       
  3217     ]
       
  3218 ! !
       
  3219 
       
  3220 !SystemBrowser methodsFor:'variables menu'!
       
  3221 
       
  3222 enterBoxForVariableSearch:title
       
  3223     |box sel|
       
  3224 
       
  3225     box := self enterBoxForCodeSelectionTitle:title okText:'browse'.
       
  3226     variableListView notNil ifTrue:[
       
  3227 	codeView hasSelection ifFalse:[
       
  3228 	    (sel := variableListView selectionValue) notNil ifTrue:[
       
  3229 		(sel startsWith:'---') ifFalse:[
       
  3230 		    box initialText:sel
       
  3231 		]
       
  3232 	    ]
       
  3233 	]
       
  3234     ].
       
  3235     ^ box
       
  3236 !
       
  3237 
       
  3238 classInstVarRefsOrModsTitle:title mods:mods
       
  3239     "show an enterbox for instvar to search for"
       
  3240 
       
  3241     self doClassMenu:[
       
  3242 	|box|
       
  3243 
       
  3244 	box := self enterBoxForVariableSearch:title.
       
  3245 	box action:[:aString | 
       
  3246 	    self withCursor:(Cursor questionMark) do:[
       
  3247 		self class browseInstRefsTo:aString
       
  3248 					 in:(Array with:currentClass)
       
  3249 			  modificationsOnly:mods 
       
  3250 	    ]
       
  3251 	].
       
  3252 	box showAtPointer
       
  3253     ]
       
  3254 !
       
  3255 
       
  3256 classInstVarRefs
       
  3257     "show an enterbox for instVar to search for"
       
  3258 
       
  3259     self classInstVarRefsOrModsTitle:'instance variable to browse references to:'
       
  3260 				mods:false
       
  3261 !
       
  3262 
       
  3263 classInstVarMods
       
  3264     "show an enterbox for instVar to search for"
       
  3265 
       
  3266     self classInstVarRefsOrModsTitle:'instance variable to browse modifications of:'
       
  3267 				mods:true 
       
  3268 !
       
  3269 
       
  3270 classClassVarRefsOrModsTitle:title mods:mods
       
  3271     "show an enterbox for classVar to search for"
       
  3272 
       
  3273     self doClassMenu:[
       
  3274 	|box|
       
  3275 
       
  3276 	box := self enterBoxForVariableSearch:title.
       
  3277 	box action:[:aString | 
       
  3278 	    self withCursor:(Cursor questionMark) do:[
       
  3279 		self class browseClassRefsTo:aString
       
  3280 					  in:(Array with:currentClass)
       
  3281 			   modificationsOnly:mods 
       
  3282 	    ]
       
  3283 	].
       
  3284 	box showAtPointer
       
  3285     ]
       
  3286 !
       
  3287 
       
  3288 classClassVarMods
       
  3289     "show an enterbox for classVar to search for"
       
  3290 
       
  3291     self classClassVarRefsOrModsTitle:'class variable to browse modifications of:'
       
  3292 				 mods:true
       
  3293 !
       
  3294 
       
  3295 classClassVarRefs
       
  3296     "show an enterbox for classVar to search for"
       
  3297 
       
  3298     self classClassVarRefsOrModsTitle:'class variable to browse references to:'
       
  3299 				 mods:false
       
  3300 !
       
  3301 
       
  3302 classAllClassOrInstVarRefsTitle:title access:access mods:modifications
       
  3303     "show an enterbox for instVar to search for"
       
  3304 
       
  3305     self doClassMenu:[
       
  3306 	|box|
       
  3307 
       
  3308 	box := self enterBoxForVariableSearch:title.
       
  3309 	box action:[:aVariableName | 
       
  3310 	    self withCursor:(Cursor questionMark) do:[
       
  3311 		|homeClass|
       
  3312 
       
  3313 		homeClass := self findClassOfVariable:aVariableName 
       
  3314 					   accessWith:access.
       
  3315 		(self class) browseInstRefsTo:aVariableName 
       
  3316 					under:homeClass 
       
  3317 			    modificationsOnly:modifications
       
  3318 	    ]
       
  3319 	].
       
  3320 	box showAtPointer
       
  3321     ]
       
  3322 !
       
  3323 
       
  3324 classAllInstVarRefs
       
  3325     "show an enterbox for instVar to search for"
       
  3326 
       
  3327     self classAllClassOrInstVarRefsTitle:'instance variable to browse references to:' 
       
  3328 				  access:#instVarNames
       
  3329 				  mods:false
       
  3330 !
       
  3331 
       
  3332 classAllClassVarRefs
       
  3333     "show an enterbox for classVar to search for"
       
  3334 
       
  3335     self classAllClassOrInstVarRefsTitle:'class variable to browse references to:' 
       
  3336 				  access:#classVarNames
       
  3337 				  mods:false
       
  3338 !
       
  3339 
       
  3340 classAllInstVarMods
       
  3341     "show an enterbox for instVar to search for"
       
  3342 
       
  3343     self classAllClassOrInstVarRefsTitle:'instance variable to browse modifications of:' 
       
  3344 				  access:#instVarNames
       
  3345 				  mods:true
       
  3346 !
       
  3347 
       
  3348 classAllClassVarMods
       
  3349     "show an enterbox for classVar to search for"
       
  3350 
       
  3351     self classAllClassOrInstVarRefsTitle:'class variable to browse modifications of:' 
       
  3352 				  access:#classVarNames
       
  3353 				  mods:true
       
  3354 ! !
       
  3355 
       
  3356 !SystemBrowser methodsFor:'method category menu'!
       
  3357 
  4445 
  3358 initializeMethodCategoryMenu
  4446 initializeMethodCategoryMenu
  3359     |labels|
  4447     |labels|
  3360 
  4448 
  3361     labels := resources array:#(
  4449     labels := resources array:#(
  3396 					 methodCategoryRemove)
  4484 					 methodCategoryRemove)
  3397 			      receiver:self
  4485 			      receiver:self
  3398 				   for:methodCategoryListView)
  4486 				   for:methodCategoryListView)
  3399 !
  4487 !
  3400 
  4488 
  3401 switchToMethodNamed:matchString
  4489 methodCategoryFindAnyMethod
  3402     |aSelector method cat index classToSearch selectors|
  4490     |box|
  3403 
  4491 
  3404     currentClass notNil ifTrue:[
  4492     box := self enterBoxForSearchSelectorTitle:'method selector to search for:'.
  3405 	showInstance ifTrue:[
  4493     box action:[:aString | self switchToAnyMethodNamed:aString].
  3406 	    classToSearch := currentClass
  4494     box showAtPointer
  3407 	] ifFalse:[
       
  3408 	    classToSearch := currentClass class
       
  3409 	].
       
  3410 	selectors := classToSearch selectorArray.
       
  3411 
       
  3412 	((matchString ~= '*') and:[matchString includesMatchCharacters]) ifTrue:[
       
  3413 	    index := selectors findFirst:[:element | matchString match:element]
       
  3414 	] ifFalse:[
       
  3415 	    index := selectors indexOf:matchString
       
  3416 	].
       
  3417 
       
  3418 	(index ~~ 0) ifTrue:[
       
  3419 	    aSelector := selectors at:index.
       
  3420 	    method := classToSearch methodArray at:index.
       
  3421 	    cat := method category.
       
  3422 	    cat isNil ifTrue:[cat := '* all *'].
       
  3423 	    methodCategoryListView selectElement:cat.
       
  3424 	    currentMethodCategory := cat.
       
  3425 	    self methodCategorySelectionChanged.
       
  3426 
       
  3427 	    currentMethod := classToSearch compiledMethodAt:aSelector.
       
  3428 	    methodListView selectElement:aSelector.
       
  3429 	    self methodSelectionChanged
       
  3430 	]
       
  3431     ]
       
  3432 !
       
  3433 
       
  3434 switchToAnyMethodNamed:aString
       
  3435     |aSelector classToStartSearch aClass nm|
       
  3436 
       
  3437     aSelector := aString asSymbol.
       
  3438     currentClass isNil ifTrue:[
       
  3439 	currentClassHierarchy notNil ifTrue:[
       
  3440 	    classToStartSearch := currentClassHierarchy
       
  3441 	]
       
  3442     ] ifFalse:[
       
  3443 	classToStartSearch := currentClass 
       
  3444     ].
       
  3445     classToStartSearch notNil ifTrue:[
       
  3446 	showInstance ifFalse:[
       
  3447 	    classToStartSearch := classToStartSearch class
       
  3448 	].
       
  3449 	aClass := classToStartSearch whichClassImplements:aSelector.
       
  3450 	aClass notNil ifTrue:[
       
  3451 	    nm := aClass name.
       
  3452 	    showInstance ifFalse:[
       
  3453 		((nm ~= 'Metaclass') and:[nm endsWith:'class']) ifTrue:[
       
  3454 		    nm := nm copyTo:(nm size - 5)
       
  3455 		]
       
  3456 	    ].
       
  3457 	    self switchToClassNamed:nm.
       
  3458 	    self switchToMethodNamed:aString
       
  3459 	]
       
  3460     ]
       
  3461 !
       
  3462 
       
  3463 copyMethodsFromClass:aClassName
       
  3464     |class box|
       
  3465 
       
  3466     currentClass notNil ifTrue:[
       
  3467 	Symbol hasInterned:aClassName ifTrue:[:sym |
       
  3468 	    (Smalltalk includesKey:sym) ifTrue:[
       
  3469 		class := Smalltalk at:sym
       
  3470 	    ].
       
  3471 	].
       
  3472 	class isBehavior ifFalse:[
       
  3473 	    self warn:'no class named %1' with:aClassName.
       
  3474 	    ^ self
       
  3475 	].
       
  3476 
       
  3477 	showInstance ifFalse:[
       
  3478 	    class := class class
       
  3479 	].
       
  3480 
       
  3481 	"show enterbox for category to copy from"
       
  3482 
       
  3483 	box := self enterBoxTitle:'name of category to copy from (matchpattern allowed, * for all):'
       
  3484 			   okText:'copy'.
       
  3485 	box action:[:aString | self copyMethodsFromClass:class category:aString].
       
  3486 	box showAtPointer.
       
  3487     ]
       
  3488 !
       
  3489 
       
  3490 copyMethodsFromClass:class category:category
       
  3491     |source|
       
  3492 
       
  3493     currentClass notNil ifTrue:[
       
  3494 "/        codeView abortAction:[^ self].
       
  3495 	Object abortSignal catch:[
       
  3496 	    class methodArray do:[:aMethod |
       
  3497 		(category match:aMethod category) ifTrue:[
       
  3498 		    source := aMethod source.
       
  3499 		    codeView contents:source.
       
  3500 		    codeView modified:false.
       
  3501 		    actualClass compiler compile:source 
       
  3502 					forClass:actualClass 
       
  3503 				      inCategory:aMethod category
       
  3504 				       notifying:codeView.
       
  3505 		    self updateMethodCategoryListWithScroll:false.
       
  3506 		    self updateMethodListWithScroll:false.
       
  3507 		]
       
  3508 	    ]
       
  3509 	]
       
  3510     ]
       
  3511 !
  4495 !
  3512 
  4496 
  3513 methodCategoryFindMethod
  4497 methodCategoryFindMethod
  3514     |box|
  4498     |box|
  3515 
  4499 
  3516     box := self enterBoxForSearchSelectorTitle:'method selector to search for:'.
  4500     box := self enterBoxForSearchSelectorTitle:'method selector to search for:'.
  3517     box action:[:aString | self switchToMethodNamed:aString].
  4501     box action:[:aString | self switchToMethodNamed:aString].
  3518     box showAtPointer
       
  3519 !
       
  3520 
       
  3521 methodCategoryFindAnyMethod
       
  3522     |box|
       
  3523 
       
  3524     box := self enterBoxForSearchSelectorTitle:'method selector to search for:'.
       
  3525     box action:[:aString | self switchToAnyMethodNamed:aString].
       
  3526     box showAtPointer
  4502     box showAtPointer
  3527 !
  4503 !
  3528 
  4504 
  3529 methodCategoryPrintOut
  4505 methodCategoryPrintOut
  3530     |printStream|
  4506     |printStream|
  3541     "fileOut all methods in the selected methodcategory of
  4517     "fileOut all methods in the selected methodcategory of
  3542      the current class"
  4518      the current class"
  3543 
  4519 
  3544     self checkClassSelected ifFalse:[^ self].
  4520     self checkClassSelected ifFalse:[^ self].
  3545     self whenMethodCategorySelected:[
  4521     self whenMethodCategorySelected:[
  3546 	self label:('System Browser saving: ' , currentClass name , '-' , currentMethodCategory).
  4522 	self busyLabel:'saving: %1' with:currentClass name , '-' , currentMethodCategory.
  3547 	Class fileOutErrorSignal handle:[:ex |
  4523 	Class fileOutErrorSignal handle:[:ex |
  3548 	    self warn:'cannot create: %1' with:ex parameter.
  4524 	    self warn:'cannot create: %1' with:ex parameter.
  3549 	    ex return.
  4525 	    ex return.
  3550 	] do:[
  4526 	] do:[
  3551 	    actualClass fileOutCategory:currentMethodCategory.
  4527 	    actualClass fileOutCategory:currentMethodCategory.
  3552 	].
  4528 	].
  3553 	self normalLabel.
  4529 	self normalLabel.
       
  4530     ]
       
  4531 !
       
  4532 
       
  4533 methodCategorySpawn
       
  4534     "create a new SystemBrowser browsing current method category"
       
  4535 
       
  4536     currentMethodCategory notNil ifTrue:[
       
  4537 	self withWaitCursorDo:[
       
  4538 	    self class browseClass:actualClass
       
  4539 		    methodCategory:currentMethodCategory
       
  4540 	]
  3554     ]
  4541     ]
  3555 !
  4542 !
  3556 
  4543 
  3557 methodCategoryFileOutAll
  4544 methodCategoryFileOutAll
  3558     "fileOut all methods in the selected methodcategory of
  4545     "fileOut all methods in the selected methodcategory of
  3579 	outStream := FileStream newFileNamed:fileName.
  4566 	outStream := FileStream newFileNamed:fileName.
  3580 	outStream isNil ifTrue:[
  4567 	outStream isNil ifTrue:[
  3581 	    ^ self warn:'cannot create: %1' with:fileName
  4568 	    ^ self warn:'cannot create: %1' with:fileName
  3582 	].
  4569 	].
  3583 
  4570 
  3584 	self label:('System Browser saving: ' , currentMethodCategory).
  4571 	self busyLabel:'saving: ' with:currentMethodCategory.
  3585 	Class fileOutErrorSignal handle:[:ex |
  4572 	Class fileOutErrorSignal handle:[:ex |
  3586 	    self warn:'cannot create: %1' with:ex parameter.
  4573 	    self warn:'cannot create: %1' with:ex parameter.
  3587 	    ex return
  4574 	    ex return
  3588 	] do:[
  4575 	] do:[
  3589 	    Smalltalk allClassesDo:[:class |
  4576 	    Smalltalk allBehaviorsDo:[:class |
  3590 		|hasMethodsInThisCategory|
  4577 		|hasMethodsInThisCategory|
  3591 
  4578 
  3592 		hasMethodsInThisCategory := false.
  4579 		hasMethodsInThisCategory := false.
  3593 		class methodArray do:[:method |
  4580 		class methodArray do:[:method |
  3594 		    method category = currentMethodCategory ifTrue:[
  4581 		    method category = currentMethodCategory ifTrue:[
  3614 	outStream close.
  4601 	outStream close.
  3615 	self normalLabel.
  4602 	self normalLabel.
  3616     ].
  4603     ].
  3617 !
  4604 !
  3618 
  4605 
  3619 methodCategorySpawn
       
  3620     "create a new SystemBrowser browsing current method category"
       
  3621 
       
  3622     currentMethodCategory notNil ifTrue:[
       
  3623 	self withWaitCursorDo:[
       
  3624 	    self class browseClass:actualClass
       
  3625 		    methodCategory:currentMethodCategory
       
  3626 	]
       
  3627     ]
       
  3628 !
       
  3629 
       
  3630 methodCategorySpawnCategory
       
  3631     "create a new SystemBrowser browsing all methods from all
       
  3632      classes with same category as current method category"
       
  3633 
       
  3634     self askAndBrowseMethodCategory:'category to browse methods:'
       
  3635 			     action:[:aString | 
       
  3636 					self class browseMethodCategory:aString
       
  3637 				    ]
       
  3638 !
       
  3639 
       
  3640 newMethodCategory:aString
       
  3641     |categories|
       
  3642 
       
  3643     currentClass isNil ifTrue:[
       
  3644 	^ self warn:'select/create a class first'.
       
  3645     ].
       
  3646     categories := methodCategoryListView list.
       
  3647     categories isNil ifTrue:[categories := Text new].
       
  3648     (categories includes:aString) ifFalse:[
       
  3649 	categories add:aString.
       
  3650 	categories sort.
       
  3651 	methodCategoryListView contents:categories
       
  3652     ].
       
  3653     currentMethodCategory := aString.
       
  3654     self methodCategorySelectionChanged
       
  3655 !
       
  3656 
       
  3657 methodCategoryNewCategory
  4606 methodCategoryNewCategory
  3658     "show the enter box to add a new method category"
  4607     "show the enter box to add a new method category.
       
  4608      Offer existing superclass categories in box to help avoiding
       
  4609      useless typing."
  3659 
  4610 
  3660     |someCategories existingCategories box|
  4611     |someCategories existingCategories box|
  3661 
  4612 
  3662     "a tiny little goody here ..."
  4613     actualClass notNil ifTrue:[
  3663     showInstance ifTrue:[
  4614 	someCategories := actualClass allCategories
  3664 	someCategories := #('accessing' 
       
  3665 			    'initialization'
       
  3666 			    'private' 
       
  3667 			    'printing & storing'
       
  3668 			    'queries'
       
  3669 			    'testing'
       
  3670 			   )
       
  3671     ] ifFalse:[
  4615     ] ifFalse:[
  3672 	someCategories := #(
  4616 	"
  3673 			    'documentation'
  4617 	 mhmh - offer some typical categories ...
  3674 			    'initialization'
  4618 	"
  3675 			    'instance creation'
  4619 	showInstance ifTrue:[
  3676 			   ).
  4620 	    someCategories := #('accessing' 
  3677     ].
  4621 				'initialization'
       
  4622 				'private' 
       
  4623 				'printing & storing'
       
  4624 				'queries'
       
  4625 				'testing'
       
  4626 			       )
       
  4627 	] ifFalse:[
       
  4628 	    someCategories := #(
       
  4629 				'documentation'
       
  4630 				'initialization'
       
  4631 				'instance creation'
       
  4632 			       ).
       
  4633 	].
       
  4634     ].
       
  4635     someCategories sort.
       
  4636 
       
  4637     "
       
  4638      remove existing categories
       
  4639     "
  3678     existingCategories := methodCategoryListView list.
  4640     existingCategories := methodCategoryListView list.
  3679     existingCategories notNil ifTrue:[
  4641     existingCategories notNil ifTrue:[
  3680 	someCategories := someCategories select:[:cat | (existingCategories includes:cat) not].
  4642 	someCategories := someCategories select:[:cat | (existingCategories includes:cat) not].
  3681     ].
  4643     ].
  3682 
  4644 
  3683     box := self listBoxTitle:'name of new method category:'
  4645     box := self listBoxTitle:'name of new method category:'
  3684 		      okText:'create'
  4646 		      okText:'create'
  3685 			list:someCategories.
  4647 			list:someCategories.
  3686     box action:[:aString | self newMethodCategory:aString].
  4648     box action:[:aString | self newMethodCategory:aString].
  3687     box showAtPointer
  4649     box showAtPointer
       
  4650 
       
  4651 
       
  4652 
       
  4653 !
       
  4654 
       
  4655 methodCategorySpawnCategory
       
  4656     "create a new SystemBrowser browsing all methods from all
       
  4657      classes with same category as current method category"
       
  4658 
       
  4659     self askAndBrowseMethodCategory:'category to browse methods:'
       
  4660 			     action:[:aString | 
       
  4661 					self class browseMethodCategory:aString
       
  4662 				    ]
  3688 !
  4663 !
  3689 
  4664 
  3690 methodCategoryCreateAccessMethods
  4665 methodCategoryCreateAccessMethods
  3691     "create access methods for all instvars"
  4666     "create access methods for all instvars"
  3692 
       
  3693     |source|
       
  3694 
  4667 
  3695     self checkClassSelected ifFalse:[^ self].
  4668     self checkClassSelected ifFalse:[^ self].
  3696 
  4669 
  3697     showInstance ifFalse:[
  4670     showInstance ifFalse:[
  3698 	self warn:'select instance - and try again'.
  4671 	self warn:'select instance - and try again'.
  3699 	^ self.
  4672 	^ self.
  3700     ].
  4673     ].
  3701 
  4674 
  3702     self withWaitCursorDo:[
  4675     self withWaitCursorDo:[
  3703 	currentClass instVarNames do:[:name |
  4676 	|nm names source|
       
  4677 
       
  4678 	(variableListView notNil
       
  4679 	and:[(nm := variableListView selectionValue) notNil]) ifTrue:[
       
  4680 	    names := Array with:nm
       
  4681 	] ifFalse:[
       
  4682 	    names := currentClass instVarNames 
       
  4683 	].
       
  4684 	names do:[:name |
  3704 	    "check, if method is not already present"
  4685 	    "check, if method is not already present"
  3705 	    (currentClass implements:(name asSymbol)) ifFalse:[
  4686 	    (currentClass implements:(name asSymbol)) ifFalse:[
  3706 		source := (name , '\    "return ' , name , '"\\    ^ ' , name) withCRs.
  4687 		source := (name , '\    "return ' , name , '"\\    ^ ' , name) withCRs.
  3707 		Compiler compile:source forClass:currentClass inCategory:'accessing'.
  4688 		Compiler compile:source forClass:currentClass inCategory:'accessing'.
  3708 	    ] ifTrue:[
  4689 	    ] ifTrue:[
  3750 		okText:(resources at:'rename').
  4731 		okText:(resources at:'rename').
  3751     box initialText:currentMethodCategory.
  4732     box initialText:currentMethodCategory.
  3752     box action:[:aString | 
  4733     box action:[:aString | 
  3753 	actualClass renameCategory:currentMethodCategory to:aString.
  4734 	actualClass renameCategory:currentMethodCategory to:aString.
  3754 	currentMethodCategory := aString.
  4735 	currentMethodCategory := aString.
  3755 	currentMethod := nil.
  4736 	currentMethod := currentSelector := nil.
  3756 	self updateMethodCategoryList.
  4737 	self updateMethodCategoryList.
  3757 	self updateMethodListWithScroll:false
  4738 	self updateMethodListWithScroll:false
  3758     ].
  4739     ].
  3759     box showAtPointer
  4740     box showAtPointer
  3760 !
  4741 !
  3771 		count := count + 1
  4752 		count := count + 1
  3772 	    ]
  4753 	    ]
  3773 	].
  4754 	].
  3774 	(count == 0) ifTrue:[
  4755 	(count == 0) ifTrue:[
  3775 	    currentMethodCategory := nil.
  4756 	    currentMethodCategory := nil.
  3776 	    currentMethod := nil.
  4757 	    currentMethod := currentSelector := nil.
  3777 	    self updateMethodCategoryListWithScroll:false.
  4758 	    self updateMethodCategoryListWithScroll:false.
  3778 	    self updateMethodList
  4759 	    self updateMethodList
  3779 	] ifFalse:[
  4760 	] ifFalse:[
  3780 	    (count == 1) ifTrue:[
  4761 	    (count == 1) ifTrue:[
  3781 		t := resources string:'remove %1 ?\(with 1 method)' with:currentMethodCategory
  4762 		t := resources string:'remove %1 ?\(with 1 method)' with:currentMethodCategory
  3795 			actualClass 
  4776 			actualClass 
  3796 			    removeSelector:(actualClass selectorForMethod:aMethod)
  4777 			    removeSelector:(actualClass selectorForMethod:aMethod)
  3797 		    ]
  4778 		    ]
  3798 		].
  4779 		].
  3799 		currentMethodCategory := nil.
  4780 		currentMethodCategory := nil.
  3800 		currentMethod := nil.
  4781 		currentMethod := currentSelector := nil.
  3801 		self updateMethodCategoryList.
  4782 		self updateMethodCategoryList.
  3802 		self updateMethodList
  4783 		self updateMethodList
  3803 	    ]
  4784 	    ]
  3804 	]
  4785 	]
  3805     ]
  4786     ]
  3806 ! !
  4787 ! !
  3807 
  4788 
  3808 !SystemBrowser methodsFor:'method menu'!
  4789 !SystemBrowser methodsFor:'method list menu'!
       
  4790 
       
  4791 methodMenu
       
  4792     "return a popupmenu as appropriate for the methodList"
       
  4793 
       
  4794     |labels selectors|
       
  4795 
       
  4796     (currentMethod notNil and:[currentMethod isWrapped]) ifTrue:[
       
  4797 	labels := #(
       
  4798 			'fileOut'
       
  4799 			'printOut'
       
  4800 			'-'
       
  4801 			'SPAWN_METHOD'
       
  4802 			'-'
       
  4803 			'senders ...'
       
  4804 			'implementors ...'
       
  4805 			'globals ...'
       
  4806 "
       
  4807 			'strings ...'
       
  4808 			'apropos ...'
       
  4809 "
       
  4810 			'-'
       
  4811 			'local senders ...'
       
  4812 			'local implementors ...'
       
  4813 "
       
  4814 			'local strings ...'
       
  4815 "
       
  4816 			'-'
       
  4817 			'remove break/trace' 
       
  4818 			'-'
       
  4819 			'new method' 
       
  4820 			'change category ...' 
       
  4821 			'remove'
       
  4822 		    ).
       
  4823 
       
  4824 	selectors := #(
       
  4825 			methodFileOut
       
  4826 			methodPrintOut
       
  4827 			nil
       
  4828 			methodSpawn
       
  4829 			nil
       
  4830 			methodSenders
       
  4831 			methodImplementors
       
  4832 			methodGlobalReferends
       
  4833 "
       
  4834 			methodStringSearch
       
  4835 			methodAproposSearch
       
  4836 "
       
  4837 			nil
       
  4838 			methodLocalSenders
       
  4839 			methodLocalImplementors
       
  4840 "
       
  4841 			methodLocalStringSearch
       
  4842 "
       
  4843 			nil
       
  4844 			methodRemoveBreakOrTrace
       
  4845 			nil
       
  4846 			methodNewMethod
       
  4847 			methodChangeCategory
       
  4848 			methodRemove
       
  4849 		      )
       
  4850     ] ifFalse:[
       
  4851 	labels := #(
       
  4852 			'fileOut'
       
  4853 			'printOut'
       
  4854 			'-'
       
  4855 			'SPAWN_METHOD'
       
  4856 			'-'
       
  4857 			'senders ...'
       
  4858 			'implementors ...'
       
  4859 			'globals ...'
       
  4860 "
       
  4861 			'strings ...'
       
  4862 			'apropos ...'
       
  4863 "
       
  4864 			'-'
       
  4865 			'local senders ...'
       
  4866 			'local implementors ...'
       
  4867 "
       
  4868 			'local strings ...'
       
  4869 "
       
  4870 			'-'
       
  4871 			'breakpoint' 
       
  4872 			'trace' 
       
  4873 			'trace sender' 
       
  4874 			'-'
       
  4875 			'new method' 
       
  4876 			'change category ...' 
       
  4877 			'remove'
       
  4878 		    ).
       
  4879 	selectors := #(
       
  4880 			methodFileOut
       
  4881 			methodPrintOut
       
  4882 			nil
       
  4883 			methodSpawn
       
  4884 			nil
       
  4885 			methodSenders
       
  4886 			methodImplementors
       
  4887 			methodGlobalReferends
       
  4888 "
       
  4889 			methodStringSearch
       
  4890 			methodAproposSearch
       
  4891 "
       
  4892 			nil
       
  4893 			methodLocalSenders
       
  4894 			methodLocalImplementors
       
  4895 "
       
  4896 			methodLocalStringSearch
       
  4897 "
       
  4898 			nil
       
  4899 			methodBreakPoint
       
  4900 			methodTrace
       
  4901 			methodTraceSender
       
  4902 			nil
       
  4903 			methodNewMethod
       
  4904 			methodChangeCategory
       
  4905 			methodRemove
       
  4906 		      )
       
  4907     ].
       
  4908 
       
  4909     ^ PopUpMenu
       
  4910 	 labels:(resources array:labels)
       
  4911 	 selectors:selectors
       
  4912 	 receiver:self
       
  4913 	 for:methodListView
       
  4914 !
  3809 
  4915 
  3810 initializeMethodMenu
  4916 initializeMethodMenu
  3811     |labels|
  4917     |labels|
       
  4918 
       
  4919 methodListView model:self.
       
  4920 methodListView menu:#methodMenu.
       
  4921 ^ self.
  3812 
  4922 
  3813     labels := resources array:#(
  4923     labels := resources array:#(
  3814 					 'fileOut'
  4924 					 'fileOut'
  3815 					 'printOut'
  4925 					 'printOut'
  3816 					 '-'
  4926 					 '-'
  3869 					 methodRemove)
  4979 					 methodRemove)
  3870 			      receiver:self
  4980 			      receiver:self
  3871 				   for:methodListView)
  4981 				   for:methodListView)
  3872 !
  4982 !
  3873 
  4983 
       
  4984 methodImplementors
       
  4985     "launch an enterBox for selector to search for"
       
  4986 
       
  4987     self askAndBrowseSelectorTitle:'selector to browse implementors of:'
       
  4988 			    action:[:aString | 
       
  4989 				       self class browseImplementorsOf:aString
       
  4990 				   ]
       
  4991 !
       
  4992 
       
  4993 methodSenders
       
  4994     "launch an enterBox for selector to search for"
       
  4995 
       
  4996     self askAndBrowseSelectorTitle:'selector to browse senders of:'
       
  4997 			    action:[:aString | 
       
  4998 				       self class browseAllCallsOn:aString
       
  4999 				   ]
       
  5000 !
       
  5001 
       
  5002 methodRemove
       
  5003     "remove the current method"
       
  5004 
       
  5005     self checkMethodSelected ifFalse:[^ self].
       
  5006     actualClass removeSelector:(actualClass selectorForMethod:currentMethod).
       
  5007     currentMethod := currentSelector := nil.
       
  5008     self updateMethodListWithScroll:false
       
  5009 !
       
  5010 
  3874 initializeMethodMenu2
  5011 initializeMethodMenu2
  3875     |labels|
  5012     |labels|
  3876 
  5013 
  3877     methodListView isNil ifTrue:[^ self].
  5014     methodListView isNil ifTrue:[^ self].
       
  5015 ^self.
  3878     labels := resources array:#(
  5016     labels := resources array:#(
  3879 					 'fileOut'
  5017 					 'fileOut'
  3880 					 'printOut'
  5018 					 'printOut'
  3881 					 '-'
  5019 					 '-'
  3882 					 'SPAWN_METHOD'
  5020 					 'SPAWN_METHOD'
  3930 					 methodRemove)
  5068 					 methodRemove)
  3931 			      receiver:self
  5069 			      receiver:self
  3932 				   for:methodListView)
  5070 				   for:methodListView)
  3933 !
  5071 !
  3934 
  5072 
       
  5073 methodLocalSenders
       
  5074     "launch an enterBox for selector to search for in current class & subclasses"
       
  5075 
       
  5076     self checkClassSelected ifFalse:[^ self].
       
  5077     self askAndBrowseSelectorTitle:'selector to browse local senderss of:'
       
  5078 			    action:[:aString | 
       
  5079 				       self class browseCallsOn:aString under:currentClass
       
  5080 				   ]
       
  5081 !
       
  5082 
  3935 methodPrintOut
  5083 methodPrintOut
  3936     "print out the current method"
  5084     "print out the current method"
  3937 
  5085 
  3938     |printStream|
  5086     |printStream|
  3939 
  5087 
  3940     self checkMethodSelected ifFalse:[^ self].
  5088     self checkMethodSelected ifFalse:[^ self].
  3941 
  5089 
  3942     printStream := Printer new.
  5090     printStream := Printer new.
  3943     actualClass printOutSource:currentMethod source on:printStream.
  5091     actualClass printOutSource:(currentMethod source) on:printStream.
  3944     printStream close
  5092     printStream close
       
  5093 !
       
  5094 
       
  5095 methodLocalImplementors
       
  5096     "launch an enterBox for selector to search for"
       
  5097 
       
  5098     self checkClassSelected ifFalse:[^ self].
       
  5099     self askAndBrowseSelectorTitle:'selector to browse local implementors of:'
       
  5100 			    action:[:aString | 
       
  5101 				       self class browseImplementorsOf:aString under:currentClass
       
  5102 				   ]
       
  5103 !
       
  5104 
       
  5105 methodGlobalReferends
       
  5106     "launch an enterBox for global symbol to search for"
       
  5107 
       
  5108     self enterBoxForBrowseTitle:'global variable to browse users of:'
       
  5109 			 action:[:aString | 
       
  5110 				    self class browseReferendsOf:aString asSymbol
       
  5111 				]
       
  5112 !
       
  5113 
       
  5114 methodSpawn
       
  5115     "create a new SystemBrowser browsing current method,
       
  5116      or if the current selection is of the form 'class>>selector', spawan
       
  5117      a browser on that method."
       
  5118 
       
  5119     |s sel selSymbol clsName clsSymbol cls meta isMeta w sep|
       
  5120 
       
  5121     classMethodListView notNil ifTrue:[
       
  5122 	s := classMethodListView selectionValue.
       
  5123 	clsName := self classFromClassMethodString:s.
       
  5124 	sel := self selectorFromClassMethodString:s.
       
  5125 	isMeta := false
       
  5126     ].
       
  5127 
       
  5128     self extractClassAndSelectorFromSelectionInto:[:c :s :m |
       
  5129 	clsName := c.
       
  5130 	sel := s.
       
  5131 	isMeta := m
       
  5132     ].
       
  5133 
       
  5134     (sel notNil and:[clsName notNil]) ifTrue:[
       
  5135 	(clsName knownAsSymbol and:[sel knownAsSymbol]) ifTrue:[
       
  5136 	    clsSymbol := clsName asSymbol.
       
  5137 	    (Smalltalk includesKey:clsSymbol) ifTrue:[
       
  5138 		cls := Smalltalk at:clsSymbol.
       
  5139 		isMeta ifTrue:[
       
  5140 		    cls := cls class
       
  5141 		].
       
  5142 		cls isBehavior ifFalse:[
       
  5143 		    cls := cls class
       
  5144 		].
       
  5145 		cls isBehavior ifTrue:[
       
  5146 		    selSymbol := sel asSymbol.
       
  5147 		    self withWaitCursorDo:[
       
  5148 			(cls implements:selSymbol) ifFalse:[
       
  5149 			    cls := cls class.
       
  5150 			].
       
  5151 			(cls implements:selSymbol) ifTrue:[
       
  5152 			    self class browseClass:cls selector:selSymbol.
       
  5153 			    ^ self
       
  5154 			].
       
  5155 			w := ' does not implement #' , sel
       
  5156 		    ]
       
  5157 		] ifFalse:[
       
  5158 		    w := ' is not a class'
       
  5159 		]
       
  5160 	    ] ifFalse:[
       
  5161 		w := ' is unknown'
       
  5162 	    ]
       
  5163 	] ifFalse:[
       
  5164 	    w := ' and/or ' , sel , ' are unknown'
       
  5165 	].
       
  5166 	self warn:(clsName , w).
       
  5167 	^ self
       
  5168     ].
       
  5169 
       
  5170     self checkMethodSelected ifFalse:[
       
  5171 	self warn:'select a method first'.
       
  5172 	^ self
       
  5173     ].
       
  5174 
       
  5175     self withWaitCursorDo:[
       
  5176 	w := currentMethod who.
       
  5177 	self class browseClass:(w at:1) selector:(w at:2)
       
  5178     ]
  3945 !
  5179 !
  3946 
  5180 
  3947 methodFileOut
  5181 methodFileOut
  3948     "file out the current method"
  5182     "file out the current method"
  3949 
  5183 
  3950     self checkMethodSelected ifFalse:[^ self].
  5184     self checkMethodSelected ifFalse:[^ self].
  3951 
  5185 
  3952     self label:'System Browser saving'.
  5186     self busyLabel:'saving:' with:currentSelector.
  3953     Class fileOutErrorSignal handle:[:ex |
  5187     Class fileOutErrorSignal handle:[:ex |
  3954 	self warn:'cannot create: %1' with:ex parameter.
  5188 	self warn:'cannot create: %1' with:ex parameter.
  3955 	ex return
  5189 	ex return
  3956     ] do:[
  5190     ] do:[
  3957 	actualClass fileOutMethod:currentMethod.
  5191 	actualClass fileOutMethod:currentMethod.
  3958     ].
  5192     ].
  3959     self normalLabel.
  5193     self normalLabel.
  3960 !
  5194 !
  3961 
  5195 
  3962 methodImplementors
  5196 methodChangeCategory
  3963     "launch an enterBox for selector to search for"
  5197     "move the current method into another category -
  3964 
  5198      nothing done here, but a query for the new category.
  3965     self askAndBrowseSelectorTitle:'selector to browse implementors of:'
  5199      Remember the last category, to allow faster category change of a group of methods."
  3966 			    action:[:aString | 
  5200 
  3967 				       self class browseImplementorsOf:aString
  5201     |box txt|
  3968 				   ]
  5202 
  3969 !
  5203     self checkMethodSelected ifFalse:[^ self].
  3970 
  5204 
  3971 methodLocalImplementors
  5205     actualClass isNil ifTrue:[
  3972     "launch an enterBox for selector to search for"
  5206 	box := self enterBoxTitle:'' okText:'change'.
  3973 
  5207     ] ifFalse:[
  3974     self checkClassSelected ifFalse:[^ self].
  5208 	|someCategories|
  3975     self askAndBrowseSelectorTitle:'selector to browse local implementors of:'
  5209 
  3976 			    action:[:aString | 
  5210 	someCategories := actualClass categories sort.
  3977 				       self class browseImplementorsOf:aString under:currentClass
  5211 	box := self listBoxTitle:'' okText:'change' list:someCategories.
  3978 				   ]
  5212     ].
  3979 !
  5213     box title:('change category from ''' , currentMethod category , ''' to:').
  3980 
  5214     lastMethodCategory isNil ifTrue:[
  3981 methodSenders
  5215 	txt := currentMethod category.
  3982     "launch an enterBox for selector to search for"
  5216     ] ifFalse:[
  3983 
  5217 	txt := lastMethodCategory
  3984     self askAndBrowseSelectorTitle:'selector to browse senders of:'
  5218     ].
  3985 			    action:[:aString | 
  5219     box initialText:txt.
  3986 				       self class browseAllCallsOn:aString
  5220     box action:[:aString |
  3987 				   ]
  5221 		    lastMethodCategory := aString.
  3988 !
  5222 
  3989 
  5223 		    currentMethod category:aString asSymbol.
  3990 methodLocalSenders
  5224 		    currentClass changed.
  3991     "launch an enterBox for selector to search for in current class & subclasses"
  5225 		    currentMethod changed:#category.
  3992 
  5226 		    currentClass addChangeRecordForMethodCategory:currentMethod category:aString.
  3993     self checkClassSelected ifFalse:[^ self].
  5227 		    self updateMethodCategoryListWithScroll:false.
  3994     self askAndBrowseSelectorTitle:'selector to browse local senderss of:'
  5228 		    self updateMethodListWithScroll:false
  3995 			    action:[:aString | 
  5229 	       ].
  3996 				       self class browseCallsOn:aString under:currentClass
  5230     box showAtPointer
  3997 				   ]
       
  3998 !
       
  3999 
       
  4000 methodGlobalReferends
       
  4001     "launch an enterBox for global symbol to search for"
       
  4002 
       
  4003     self enterBoxForBrowseTitle:'global variable to browse users of:'
       
  4004 			 action:[:aString | 
       
  4005 				    self class browseReferendsOf:aString asSymbol
       
  4006 				]
       
  4007 !
  5231 !
  4008 
  5232 
  4009 methodStringSearch
  5233 methodStringSearch
  4010     "launch an enterBox for (sub)-string to search for"
  5234     "launch an enterBox for (sub)-string to search for"
  4011 
  5235 
  4032 			    action:[:aString | 
  5256 			    action:[:aString | 
  4033 				       self class aproposSearch:aString
  5257 				       self class aproposSearch:aString
  4034 				   ]
  5258 				   ]
  4035 !
  5259 !
  4036 
  5260 
  4037 methodSpawn
       
  4038     "create a new SystemBrowser browsing current method,
       
  4039      or if the current selection is of the form 'class>>selector', spwan
       
  4040      a browser on that method."
       
  4041 
       
  4042     |s sel selSymbol clsName clsSymbol cls meta browseMeta w sep|
       
  4043 
       
  4044     sel := codeView selection.
       
  4045     sel notNil ifTrue:[
       
  4046 	sel := sel asString withoutSeparators.
       
  4047 	('*>>*' match:sel) ifTrue:[
       
  4048 	    sep := $>
       
  4049 	] ifFalse:[
       
  4050 	    ('* *' match:sel) ifTrue:[
       
  4051 		sep := Character space
       
  4052 	    ]
       
  4053 	].
       
  4054 	sep notNil ifTrue:[
       
  4055 	    "
       
  4056 	     extract class/sel from selection
       
  4057 	    "
       
  4058 	    s := ReadStream on:sel.
       
  4059 	    clsName := s upTo:sep.
       
  4060 	    [s peek == sep] whileTrue:[s next].
       
  4061 	    sel := s upToEnd.
       
  4062 
       
  4063 	    (clsName endsWith:'class') ifTrue:[
       
  4064 		browseMeta := true.
       
  4065 		clsName := clsName copyTo:(clsName size - 5)
       
  4066 	    ] ifFalse:[
       
  4067 		browseMeta := false
       
  4068 	    ].
       
  4069 	    (clsName knownAsSymbol and:[sel knownAsSymbol]) ifTrue:[
       
  4070 		clsSymbol := clsName asSymbol.
       
  4071 		(Smalltalk includesKey:clsSymbol) ifTrue:[
       
  4072 		    cls := Smalltalk at:clsSymbol.
       
  4073 		    browseMeta ifTrue:[
       
  4074 			cls := cls class
       
  4075 		    ].
       
  4076 		    cls isBehavior ifFalse:[
       
  4077 			cls := cls class
       
  4078 		    ].
       
  4079 		    cls isBehavior ifTrue:[
       
  4080 			selSymbol := sel asSymbol.
       
  4081 			self withWaitCursorDo:[
       
  4082 			    (cls implements:selSymbol) ifTrue:[
       
  4083 				self class browseClass:cls selector:selSymbol.
       
  4084 				^ self
       
  4085 			    ] ifFalse:[
       
  4086 				meta := cls class.
       
  4087 				(meta implements:selSymbol) ifTrue:[
       
  4088 				    self class browseClass:meta selector:selSymbol.
       
  4089 				    ^ self
       
  4090 				].
       
  4091 				w := ' does not implement #' , sel
       
  4092 			    ]
       
  4093 			]
       
  4094 		    ] ifFalse:[
       
  4095 			w := ' is not a class'
       
  4096 		    ]
       
  4097 		] ifFalse:[
       
  4098 		    w := ' is unknown'
       
  4099 		]
       
  4100 	    ] ifFalse:[
       
  4101 		w := ' and/or ' , sel , ' is unknown'
       
  4102 	    ].
       
  4103 	    self warn:(clsName , w).
       
  4104 	    ^ self
       
  4105 	].
       
  4106     ].
       
  4107 
       
  4108     self checkMethodSelected ifFalse:[^ self].
       
  4109     self withWaitCursorDo:[
       
  4110 	self class browseClass:actualClass
       
  4111 		      selector:(actualClass selectorForMethod:currentMethod)
       
  4112     ]
       
  4113 !
       
  4114 
       
  4115 methodNewMethod
  5261 methodNewMethod
  4116     "prepare for definition of a new method - put a template into
  5262     "prepare for definition of a new method - put a template into
  4117      code view and define accept-action to compile it"
  5263      code view and define accept-action to compile it"
  4118 
  5264 
  4119     currentClass isNil ifTrue:[
  5265     currentClass isNil ifTrue:[
  4121     ].
  5267     ].
  4122     currentMethodCategory isNil ifTrue:[
  5268     currentMethodCategory isNil ifTrue:[
  4123 	^ self warn:'select/create a method category first'.
  5269 	^ self warn:'select/create a method category first'.
  4124     ].
  5270     ].
  4125 
  5271 
  4126     currentMethod := nil.
  5272     currentMethod := currentSelector := nil.
  4127 
  5273 
  4128     methodListView deselect.
  5274     methodListView deselect.
  4129     codeView contents:(self template).
  5275     codeView contents:(self template).
  4130     codeView modified:false.
  5276     codeView modified:false.
  4131 
  5277 
  4132     codeView acceptAction:[:theCode |
  5278     self setAcceptAndExplainActionsForMethod.
  4133 	codeView cursor:Cursor execute.
  5279 !
  4134 	Object abortSignal catch:[
  5280 
  4135 	    actualClass compiler compile:theCode asString
  5281 methodTrace
  4136 				forClass:actualClass
  5282     "turn on tracing of the current method"
  4137 			      inCategory:currentMethodCategory
  5283 
  4138 			       notifying:codeView.
  5284     |sel|
  4139 	    codeView modified:false.
  5285 
  4140 	    self updateMethodListWithScroll:false.
  5286 currentClass notNil ifTrue:[
  4141 	].
  5287    currentSelector notNil ifTrue:[
  4142 	codeView cursor:Cursor normal.
  5288       currentMethod := actualClass compiledMethodAt:currentSelector
  4143     ].
  5289    ]
  4144     codeView explainAction:[:theCode :theSelection |
  5290 ].
  4145 	self showExplanation:(Explainer explain:theSelection 
  5291 
  4146 					     in:theCode
  5292     (currentMethod notNil and:[currentMethod isWrapped not])
  4147 				       forClass:actualClass)
  5293     ifTrue:[
  4148     ]
  5294 	currentMethod := MessageTracer traceMethod:currentMethod.
  4149 !
  5295 	sel := methodListView selection.
  4150 
  5296 	self updateMethodListWithScroll:false.
  4151 methodRemove
  5297 	methodListView selection:sel.
  4152     "remove the current method"
  5298 	currentClass changed:#methodDictionary with:currentSelector.
  4153 
  5299     ]
  4154     self checkMethodSelected ifFalse:[^ self].
       
  4155     actualClass removeSelector:(actualClass selectorForMethod:currentMethod).
       
  4156     self updateMethodListWithScroll:false
       
  4157 !
       
  4158 
       
  4159 methodChangeCategory
       
  4160     "move the current method into another category -
       
  4161      nothing done here, but a query for the new category.
       
  4162      Remember the last category, to allow faster category change of a group of methods."
       
  4163 
       
  4164     |box txt|
       
  4165 
       
  4166     self checkMethodSelected ifFalse:[^ self].
       
  4167 
       
  4168     box := self enterBoxTitle:('change category from ' , currentMethod category , ' to:') 
       
  4169 		okText:'change'.
       
  4170     lastMethodCategory isNil ifTrue:[
       
  4171 	txt := currentMethod category.
       
  4172     ] ifFalse:[
       
  4173 	txt := lastMethodCategory
       
  4174     ].
       
  4175     box initialText:txt.
       
  4176     box action:[:aString | 
       
  4177 		    lastMethodCategory := aString.
       
  4178 
       
  4179 		    currentMethod category:aString asSymbol.
       
  4180 		    currentClass changed.
       
  4181 		    self updateMethodCategoryListWithScroll:false.
       
  4182 		    self updateMethodListWithScroll:false
       
  4183 	       ].
       
  4184     box showAtPointer
       
  4185 !
  5300 !
  4186 
  5301 
  4187 methodRemoveBreakOrTrace
  5302 methodRemoveBreakOrTrace
  4188     "turn off tracing of the current method"
  5303     "turn off tracing of the current method"
  4189 
  5304 
  4190     |sel|
  5305     |sel|
  4191 
  5306 
  4192     currentMethod notNil ifTrue:[
  5307     (currentMethod notNil and:[currentMethod isWrapped])
  4193 	currentMethod isWrapped ifTrue:[
  5308     ifTrue:[
  4194 	    currentMethod := MessageTracer unwrapMethod:currentMethod.
  5309 	currentMethod := MessageTracer unwrapMethod:currentMethod.
  4195 	    sel := methodListView selection.
  5310 	sel := methodListView selection.
  4196 	    self updateMethodListWithScroll:false.
  5311 	self updateMethodListWithScroll:false.
  4197 	    methodListView selection:sel.
  5312 	methodListView selection:sel.
  4198 	    self initializeMethodMenu
  5313 	currentClass changed:#methodDictionary with:currentSelector.
  4199 	].
       
  4200     ]
  5314     ]
  4201 !
  5315 !
  4202 
  5316 
  4203 methodBreakPoint
  5317 methodBreakPoint
  4204     "set a breakpoint on the current method"
  5318     "set a breakpoint on the current method"
  4214 	    methodListView selection:sel
  5328 	    methodListView selection:sel
  4215 	].
  5329 	].
  4216     ]
  5330     ]
  4217 !
  5331 !
  4218 
  5332 
  4219 methodTrace
       
  4220     "turn on tracing of the current method"
       
  4221 
       
  4222     |sel|
       
  4223 
       
  4224     currentMethod notNil ifTrue:[
       
  4225 	currentMethod isWrapped ifFalse:[
       
  4226 	    currentMethod := MessageTracer traceMethod:currentMethod.
       
  4227 	    self initializeMethodMenu2.
       
  4228 	    sel := methodListView selection.
       
  4229 	    self updateMethodListWithScroll:false.
       
  4230 	    methodListView selection:sel
       
  4231 	].
       
  4232     ]
       
  4233 !
       
  4234 
       
  4235 methodTraceSender
  5333 methodTraceSender
  4236     "turn on tracing of the current method"
  5334     "turn on tracing of the current method"
  4237 
  5335 
  4238     |sel|
  5336     |sel|
  4239 
  5337 
  4240     currentMethod notNil ifTrue:[
  5338     (currentMethod notNil and:[currentMethod isWrapped not])
  4241 	currentMethod isWrapped ifFalse:[
  5339     ifTrue:[
  4242 	    currentMethod := MessageTracer traceMethodSender:currentMethod.
  5340 	currentMethod := MessageTracer traceMethodSender:currentMethod.
  4243 	    self initializeMethodMenu2.
  5341 	sel := methodListView selection.
  4244 	    sel := methodListView selection.
  5342 	self updateMethodListWithScroll:false.
  4245 	    self updateMethodListWithScroll:false.
  5343 	methodListView selection:sel.
  4246 	    methodListView selection:sel
  5344 	currentClass changed:#methodDictionary with:currentSelector.
  4247 	].
  5345     ]
  4248     ]
  5346 !
       
  5347 
       
  5348 methodMenuForWrappedMethod
       
  5349     |labels|
       
  5350 
       
  5351     labels := resources array:#(
       
  5352 					 'fileOut'
       
  5353 					 'printOut'
       
  5354 					 '-'
       
  5355 					 'SPAWN_METHOD'
       
  5356 					 '-'
       
  5357 					 'senders ...'
       
  5358 					 'implementors ...'
       
  5359 					 'globals ...'
       
  5360 "
       
  5361 					 'strings ...'
       
  5362 					 'apropos ...'
       
  5363 "
       
  5364 					 '-'
       
  5365 					 'local senders ...'
       
  5366 					 'local implementors ...'
       
  5367 "
       
  5368 					 'local strings ...'
       
  5369 "
       
  5370 					 '-'
       
  5371 					 'remove break/trace' 
       
  5372 					 '-'
       
  5373 					 'new method' 
       
  5374 					 'change category ...' 
       
  5375 					 'remove').
       
  5376 
       
  5377     ^ PopUpMenu
       
  5378 				labels:labels
       
  5379 			     selectors:#(methodFileOut
       
  5380 					 methodPrintOut
       
  5381 					 nil
       
  5382 					 methodSpawn
       
  5383 					 nil
       
  5384 					 methodSenders
       
  5385 					 methodImplementors
       
  5386 					 methodGlobalReferends
       
  5387 "
       
  5388 					 methodStringSearch
       
  5389 					 methodAproposSearch
       
  5390 "
       
  5391 					 nil
       
  5392 					 methodLocalSenders
       
  5393 					 methodLocalImplementors
       
  5394 "
       
  5395 					 methodLocalStringSearch
       
  5396 "
       
  5397 					 nil
       
  5398 					 methodRemoveBreakOrTrace
       
  5399 					 nil
       
  5400 					 methodNewMethod
       
  5401 					 methodChangeCategory
       
  5402 					 methodRemove)
       
  5403 			      receiver:self
       
  5404 				   for:methodListView
  4249 ! !
  5405 ! !
  4250 
  5406 
  4251 !SystemBrowser methodsFor:'class-method menu'!
  5407 !SystemBrowser methodsFor:'variable list menu'!
       
  5408 
       
  5409 initializeVariableListMenu
       
  5410     |varMenu|
       
  5411 
       
  5412     varMenu := (PopUpMenu labels:(resources array:#(
       
  5413 					'instvar refs ...'
       
  5414 					'classvar refs ...'
       
  5415 					'all instvar refs ...'
       
  5416 					'all classvar refs ...'
       
  5417 					'-'
       
  5418 					'instvar mods ...'
       
  5419 					'classvar mods ...'
       
  5420 					'all instvar mods ...'
       
  5421 					'all classvar mods ...'
       
  5422 				     ))
       
  5423 			   selectors:#(
       
  5424 					instVarRefs
       
  5425 					classVarRefs
       
  5426 					allInstVarRefs
       
  5427 					allClassVarRefs
       
  5428 					nil
       
  5429 					instVarMods
       
  5430 					classVarMods
       
  5431 					allInstVarMods
       
  5432 					allClassVarMods
       
  5433 				     )
       
  5434 			   receiver:self
       
  5435 				for:self).
       
  5436 
       
  5437     variableListView isNil ifTrue:[
       
  5438 	classListView notNil ifTrue:[
       
  5439 	    |menu|
       
  5440 
       
  5441 	    menu := classListView middleButtonMenu.
       
  5442 	    menu addLabel:(resources string:'variable search')
       
  5443 		 selector:#variables
       
  5444 		 before:#classRefs.
       
  5445 	    menu subMenuAt:#variables put:varMenu.
       
  5446 	]
       
  5447     ] ifFalse:[
       
  5448 	variableListView middleButtonMenu:varMenu
       
  5449     ]
       
  5450 
       
  5451 !
       
  5452 
       
  5453 variableSelection:lineNr
       
  5454     "variable selection changed"
       
  5455 
       
  5456     |name idx|
       
  5457 
       
  5458     name := variableListView selectionValue.
       
  5459     name isNil ifTrue:[
       
  5460 	self unhilightMethodCategories.
       
  5461 	self unhilightMethods.
       
  5462 	self autoSearch:nil.
       
  5463 	^ self
       
  5464     ].
       
  5465 
       
  5466     "
       
  5467      first, check if the selected variable is really the one 
       
  5468      we get - reselect if its hidden (for example, a class variable
       
  5469      with the same name could be defined in a subclass)
       
  5470     "
       
  5471     idx := variableListView list findLast:[:entry | entry = name].
       
  5472     idx ~~ lineNr ifTrue:[
       
  5473 	"select it - user will see whats going on"
       
  5474 	variableListView selection:idx
       
  5475     ].
       
  5476 
       
  5477     "search for methods in the current category, which access the selected
       
  5478      variable, and highlight them"
       
  5479 
       
  5480     self hilightMethodsInMethodCategoryList:true inMethodList:true.
       
  5481     self autoSearch:name.
       
  5482 
       
  5483 
       
  5484 !
       
  5485 
       
  5486 enterBoxForVariableSearch:title
       
  5487     |box sel|
       
  5488 
       
  5489     box := self enterBoxForCodeSelectionTitle:title okText:'browse'.
       
  5490     variableListView notNil ifTrue:[
       
  5491 	codeView hasSelection ifFalse:[
       
  5492 	    (sel := variableListView selectionValue) notNil ifTrue:[
       
  5493 		(sel startsWith:'---') ifFalse:[
       
  5494 		    box initialText:sel
       
  5495 		]
       
  5496 	    ]
       
  5497 	]
       
  5498     ].
       
  5499     ^ box
       
  5500 !
       
  5501 
       
  5502 allClassOrInstVarRefsTitle:title access:access mods:modifications
       
  5503     "show an enterbox for instVar to search for"
       
  5504 
       
  5505     self doClassMenu:[
       
  5506 	|box|
       
  5507 
       
  5508 	box := self enterBoxForVariableSearch:title.
       
  5509 	box action:[:aVariableName | 
       
  5510 	    self withCursor:(Cursor questionMark) do:[
       
  5511 		|homeClass|
       
  5512 
       
  5513 		homeClass := self findClassOfVariable:aVariableName 
       
  5514 					   accessWith:access.
       
  5515 		(self class) browseInstRefsTo:aVariableName 
       
  5516 					under:homeClass 
       
  5517 			    modificationsOnly:modifications
       
  5518 	    ]
       
  5519 	].
       
  5520 	box showAtPointer
       
  5521     ]
       
  5522 !
       
  5523 
       
  5524 instVarRefsOrModsTitle:title mods:mods
       
  5525     "show an enterbox for instvar to search for"
       
  5526 
       
  5527     self doClassMenu:[
       
  5528 	|box|
       
  5529 
       
  5530 	box := self enterBoxForVariableSearch:title.
       
  5531 	box action:[:aString | 
       
  5532 	    self withCursor:(Cursor questionMark) do:[
       
  5533 		self class browseInstRefsTo:aString
       
  5534 					 in:(Array with:currentClass)
       
  5535 			  modificationsOnly:mods 
       
  5536 	    ]
       
  5537 	].
       
  5538 	box showAtPointer
       
  5539     ]
       
  5540 !
       
  5541 
       
  5542 allClassVarMods
       
  5543     "show an enterbox for classVar to search for"
       
  5544 
       
  5545     self allClassOrInstVarRefsTitle:'class variable to browse modifications of:' 
       
  5546 				  access:#classVarNames
       
  5547 				  mods:true
       
  5548 !
       
  5549 
       
  5550 instVarMods
       
  5551     "show an enterbox for instVar to search for"
       
  5552 
       
  5553     self instVarRefsOrModsTitle:'instance variable to browse modifications of:'
       
  5554 				mods:true 
       
  5555 !
       
  5556 
       
  5557 instVarRefs
       
  5558     "show an enterbox for instVar to search for"
       
  5559 
       
  5560     self instVarRefsOrModsTitle:'instance variable to browse references to:'
       
  5561 			   mods:false
       
  5562 !
       
  5563 
       
  5564 classVarRefsOrModsTitle:title mods:mods
       
  5565     "show an enterbox for classVar to search for"
       
  5566 
       
  5567     self doClassMenu:[
       
  5568 	|box|
       
  5569 
       
  5570 	box := self enterBoxForVariableSearch:title.
       
  5571 	box action:[:aString | 
       
  5572 	    self withCursor:(Cursor questionMark) do:[
       
  5573 		self class browseClassRefsTo:aString
       
  5574 					  in:(Array with:currentClass)
       
  5575 			   modificationsOnly:mods 
       
  5576 	    ]
       
  5577 	].
       
  5578 	box showAtPointer
       
  5579     ]
       
  5580 !
       
  5581 
       
  5582 allInstVarRefs
       
  5583     "show an enterbox for instVar to search for"
       
  5584 
       
  5585     self allClassOrInstVarRefsTitle:'instance variable to browse references to:' 
       
  5586 				  access:#instVarNames
       
  5587 				  mods:false
       
  5588 !
       
  5589 
       
  5590 classVarRefs
       
  5591     "show an enterbox for classVar to search for"
       
  5592 
       
  5593     self classVarRefsOrModsTitle:'class variable to browse references to:'
       
  5594 				 mods:false
       
  5595 !
       
  5596 
       
  5597 classVarMods
       
  5598     "show an enterbox for classVar to search for"
       
  5599 
       
  5600     self classVarRefsOrModsTitle:'class variable to browse modifications of:'
       
  5601 				 mods:true
       
  5602 !
       
  5603 
       
  5604 allInstVarMods
       
  5605     "show an enterbox for instVar to search for"
       
  5606 
       
  5607     self allClassOrInstVarRefsTitle:'instance variable to browse modifications of:' 
       
  5608 				  access:#instVarNames
       
  5609 				  mods:true
       
  5610 !
       
  5611 
       
  5612 allClassVarRefs
       
  5613     "show an enterbox for classVar to search for"
       
  5614 
       
  5615     self allClassOrInstVarRefsTitle:'class variable to browse references to:' 
       
  5616 				  access:#classVarNames
       
  5617 				  mods:false
       
  5618 ! !
       
  5619 
       
  5620 !SystemBrowser methodsFor:'class-method list menu'!
  4252 
  5621 
  4253 initializeClassMethodMenu
  5622 initializeClassMethodMenu
  4254     |labels|
  5623     |labels|
  4255 
  5624 
  4256     labels := resources array:#(
  5625     labels := resources array:#(
  4327 	    ^ self warn:'cannot create: %1' with:fileName
  5696 	    ^ self warn:'cannot create: %1' with:fileName
  4328 	].
  5697 	].
  4329 	self withWaitCursorDo:[
  5698 	self withWaitCursorDo:[
  4330 	    list := classMethodListView list.
  5699 	    list := classMethodListView list.
  4331 	    list do:[:line |
  5700 	    list do:[:line |
  4332 		self label:('System Browser writing: ' , line).
  5701 		self busyLabel:'writing: ' with:line.
  4333 
  5702 
  4334 		classString := self classFromClassMethodString:line.
  5703 		classString := self classFromClassMethodString:line.
  4335 		selectorString := self selectorFromClassMethodString:line.
  5704 		selectorString := self selectorFromClassMethodString:line.
  4336 
  5705 
  4337 		((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[
  5706 		((classString ~= 'Metaclass') and:[classString endsWith:'class']) ifTrue:[
  4352 			box yesText:'continue' noText:'abort'.
  5721 			box yesText:'continue' noText:'abort'.
  4353 			(box confirm:('fileOut error: ' , ex errorString ,
  5722 			(box confirm:('fileOut error: ' , ex errorString ,
  4354 					       '\\continue anyway ?') withCRs) ifTrue:[
  5723 					       '\\continue anyway ?') withCRs) ifTrue:[
  4355 			    ex proceed
  5724 			    ex proceed
  4356 			].
  5725 			].
  4357 			self label:'System Browser'.
  5726 			self normalLabel.
  4358 			^ self
  5727 			^ self
  4359 		    ] do:[
  5728 		    ] do:[
  4360 			cls fileOutMethod:mth on:outStream.
  5729 			cls fileOutMethod:mth on:outStream.
  4361 		    ]    
  5730 		    ]    
  4362 		]
  5731 		]
  4365 	    self normalLabel.
  5734 	    self normalLabel.
  4366 	]
  5735 	]
  4367     ]
  5736     ]
  4368 ! !
  5737 ! !
  4369 
  5738 
  4370 !SystemBrowser methodsFor:'dependencies'!
  5739 SystemBrowser initialize!
  4371 
       
  4372 update
       
  4373     "handle changes from other browsers"
       
  4374 
       
  4375     |oldClassCategory oldClassName oldMethodCategory oldMethod oldSelector|
       
  4376 
       
  4377 self updateClassCategoryListWithScroll:false.
       
  4378 "
       
  4379 self updateClassListWithScroll:false.
       
  4380 "
       
  4381 ^ self.
       
  4382 
       
  4383     oldClassCategory := currentClassCategory.
       
  4384     currentClass notNil ifTrue:[
       
  4385 	oldClassName := currentClass name
       
  4386     ].
       
  4387     oldMethodCategory := currentMethodCategory.
       
  4388     oldMethod := currentMethod.
       
  4389     methodListView notNil ifTrue:[
       
  4390 	oldMethod notNil ifTrue:[
       
  4391 	    oldSelector := methodListView selectionValue
       
  4392 	]
       
  4393     ].
       
  4394 
       
  4395     classCategoryListView notNil ifTrue:[
       
  4396 	classCategoryListView setContents:(self listOfAllClassCategories).
       
  4397 	oldClassCategory notNil ifTrue:[
       
  4398 	    classCategoryListView selectElement:oldClassCategory
       
  4399 	].
       
  4400 	classCategoryListView selection isNil ifTrue:[
       
  4401 	    currentClassCategory := nil.
       
  4402 	    self switchToClass:nil.
       
  4403 	    oldClassName := nil
       
  4404 	]
       
  4405     ].
       
  4406     classListView notNil ifTrue:[
       
  4407 	self updateClassListWithScroll:false.
       
  4408 	oldClassName notNil ifTrue:[
       
  4409 	      classListView selectElement:oldClassName
       
  4410 	].
       
  4411 	classListView selection isNil ifTrue:[
       
  4412 	    self switchToClass:nil.
       
  4413 	    currentMethodCategory := nil.
       
  4414 	    oldMethodCategory := nil
       
  4415 	]
       
  4416     ].
       
  4417     methodCategoryListView notNil ifTrue:[
       
  4418 	self updateMethodCategoryListWithScroll:false.
       
  4419 	oldMethodCategory notNil ifTrue:[
       
  4420 	    methodCategoryListView selectElement:oldMethodCategory
       
  4421 	].
       
  4422 	methodCategoryListView selection isNil ifTrue:[
       
  4423 	    currentMethodCategory := nil.
       
  4424 	    currentMethod := nil.
       
  4425 	    oldSelector := nil
       
  4426 	]
       
  4427     ].
       
  4428     methodListView notNil ifTrue:[
       
  4429 	self updateMethodListWithScroll:false.
       
  4430 	oldSelector notNil ifTrue:[
       
  4431 	    methodListView selectElement:oldSelector
       
  4432 	].
       
  4433 	methodListView selection isNil ifTrue:[
       
  4434 	    currentMethod := nil
       
  4435 	]
       
  4436     ].
       
  4437     self updateCodeView
       
  4438 !
       
  4439 
       
  4440 update:something with:someArgument from:changedObject
       
  4441     (changedObject == Smalltalk) ifTrue:[self update. ^ self].
       
  4442     changedObject isBehavior ifTrue:[
       
  4443 	(currentClass notNil and:[changedObject name = currentClass name]) ifTrue:[
       
  4444 	    currentClass := Smalltalk at:(currentClass name asSymbol).
       
  4445 	    showInstance ifTrue:[
       
  4446 		actualClass := currentClass
       
  4447 	    ] ifFalse:[
       
  4448 		actualClass := currentClass class
       
  4449 	    ].
       
  4450 	    self updateMethodCategoryListWithScroll:false.
       
  4451 	    "dont update codeView ...."
       
  4452 	    "self update"
       
  4453 	    ^ self
       
  4454 	]
       
  4455     ]
       
  4456 ! !