InspectorList.st
changeset 1213 6cf7a4c2dfce
parent 1212 a13dafe6f9fe
child 1214 02a032b1098c
equal deleted inserted replaced
1212:a13dafe6f9fe 1213:6cf7a4c2dfce
     1 "
       
     2  COPYRIGHT (c) 1997 by eXept Software AG
       
     3               All Rights Reserved
       
     4 
       
     5  This software is furnished under a license and may be used
       
     6  only in accordance with the terms of that license and with the
       
     7  inclusion of the above copyright notice.   This software may not
       
     8  be provided or otherwise made available to, or used by, any
       
     9  other person.  No title to or ownership of the software is
       
    10  hereby transferred.
       
    11 "
       
    12 
       
    13 
       
    14 "{ NameSpace: NewInspector }"
       
    15 
       
    16 Object subclass:#InspectorList
       
    17 	instanceVariableNames:'inspectedObject instanceNames instanceTypes selection'
       
    18 	classVariableNames:''
       
    19 	poolDictionaries:''
       
    20 	category:'Interface-Inspector'
       
    21 !
       
    22 
       
    23 !InspectorList class methodsFor:'documentation'!
       
    24 
       
    25 copyright
       
    26 "
       
    27  COPYRIGHT (c) 1997 by eXept Software AG
       
    28               All Rights Reserved
       
    29 
       
    30  This software is furnished under a license and may be used
       
    31  only in accordance with the terms of that license and with the
       
    32  inclusion of the above copyright notice.   This software may not
       
    33  be provided or otherwise made available to, or used by, any
       
    34  other person.  No title to or ownership of the software is
       
    35  hereby transferred.
       
    36 "
       
    37 
       
    38 ! !
       
    39 
       
    40 !InspectorList class methodsFor:'instance creation'!
       
    41 
       
    42 for:anObject
       
    43     "create a new list for an instance
       
    44     "
       
    45     ^ self new inspect:anObject
       
    46 
       
    47 
       
    48 !
       
    49 
       
    50 new
       
    51     "create a new instance and set the inspected object to nil
       
    52     "
       
    53     ^ self basicNew initialize.
       
    54 
       
    55 ! !
       
    56 
       
    57 !InspectorList class methodsFor:'helpers'!
       
    58 
       
    59 asString:aCollection
       
    60     "converts any collection to a string seperated by spaces. If
       
    61      the collection is empty or nil, nil is returned otherwise a
       
    62      string.
       
    63     "
       
    64     |string|
       
    65 
       
    66     aCollection isCollection ifTrue:[
       
    67         aCollection isString ifTrue:[
       
    68             string := aCollection
       
    69         ] ifFalse:[
       
    70             string := aCollection asStringWith:Character space
       
    71                                           from:1 to:(aCollection size)
       
    72                                   compressTabs:true 
       
    73                                          final:nil
       
    74         ].
       
    75         string := string withoutSeparators.
       
    76 
       
    77         string notEmpty ifTrue:[
       
    78             ^ string
       
    79         ]
       
    80     ].
       
    81     ^ nil
       
    82 
       
    83 
       
    84 ! !
       
    85 
       
    86 !InspectorList class methodsFor:'testing'!
       
    87 
       
    88 isDirectory:anInstance
       
    89     "returns true if the instance is a directory
       
    90     "
       
    91     |cls|
       
    92 
       
    93     anInstance notNil ifTrue:[
       
    94         cls := anInstance class.
       
    95 
       
    96         cls == Character  ifTrue:[ ^ false ].
       
    97         cls == Symbol     ifTrue:[ ^ false ].
       
    98         cls == String     ifTrue:[ ^ false ].
       
    99         cls == Float      ifTrue:[ ^ false ].
       
   100         cls == ShortFloat ifTrue:[ ^ false ].
       
   101 
       
   102         cls allInstVarNames notEmpty ifTrue:[
       
   103             ^ true
       
   104         ].
       
   105 
       
   106         anInstance isVariable ifTrue:[
       
   107             ^ true
       
   108         ].
       
   109     ].
       
   110     ^ false
       
   111 
       
   112     "Modified: / 4.2.1999 / 20:00:11 / cg"
       
   113 !
       
   114 
       
   115 isTraceable:anInstance
       
   116     "returns true if the instance could be traced or traped
       
   117     "
       
   118     |cls|
       
   119 
       
   120     anInstance notNil ifTrue:[
       
   121         cls := anInstance class.
       
   122 
       
   123       ^ (     cls ~~ True
       
   124          and:[cls ~~ False
       
   125          and:[cls ~~ SmallInteger]]
       
   126         )
       
   127     ].
       
   128     ^ false.
       
   129 
       
   130 ! !
       
   131 
       
   132 !InspectorList methodsFor:'accessing'!
       
   133 
       
   134 includesSelf:aBoolean
       
   135     "includes 'self' dependant on the boolean
       
   136     "
       
   137     (self includesSelf) ~~ aBoolean ifTrue:[
       
   138         aBoolean ifTrue:[
       
   139             instanceNames addFirst:'self'.
       
   140             instanceTypes addFirst:#self.
       
   141 
       
   142             selection notNil ifTrue:[selection := selection + 1]
       
   143                             ifFalse:[selection := 1]
       
   144 
       
   145         ] ifFalse:[
       
   146             instanceNames removeFirst.
       
   147             instanceTypes removeFirst.
       
   148 
       
   149             selection isNil ifFalse:[
       
   150                 (selection := selection - 1) == 0 ifTrue:[
       
   151                     selection := nil
       
   152                 ]
       
   153             ]
       
   154         ]
       
   155     ]
       
   156 
       
   157 
       
   158 !
       
   159 
       
   160 list
       
   161     "returns self
       
   162     "
       
   163     ^ self
       
   164 !
       
   165 
       
   166 size
       
   167     "returns size of list
       
   168     "
       
   169     ^ instanceNames size
       
   170 
       
   171 !
       
   172 
       
   173 update
       
   174     "update list contents
       
   175     "
       
   176     |start stop size|
       
   177 
       
   178     inspectedObject isVariable ifTrue:[
       
   179         start := instanceNames findFirst:[:el|(el at:1) isDigit].
       
   180         stop  := instanceTypes size.
       
   181 
       
   182         start == 0 ifTrue:[
       
   183             size := stop + 10.  "must be > 1: force a resize the first time"   
       
   184         ] ifFalse:[
       
   185             instanceTypes last ~~ #grow ifTrue:[size := stop]
       
   186                                        ifFalse:[size := stop-1].
       
   187 
       
   188             instanceTypes removeFromIndex:start toIndex:stop.
       
   189             instanceNames removeFromIndex:start toIndex:stop.
       
   190         ].
       
   191         self resizeTo:size.
       
   192     ]
       
   193 
       
   194     "Modified: / 4.2.1999 / 20:00:38 / cg"
       
   195 ! !
       
   196 
       
   197 !InspectorList methodsFor:'accessing contents'!
       
   198 
       
   199 inspectedObject
       
   200     "returns current inspected object
       
   201     "
       
   202     ^ inspectedObject
       
   203 
       
   204 
       
   205 !
       
   206 
       
   207 instanceNames
       
   208     "returns list of instance names
       
   209     "
       
   210     ^ instanceNames
       
   211 
       
   212 
       
   213 !
       
   214 
       
   215 instanceTypeAt:anIndex
       
   216     "returns type assigned to the list entry (#directory #normal #self #grow)
       
   217      In case of an invalid index nil is returned.
       
   218     "
       
   219     (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[^ instanceTypes at:anIndex]
       
   220                                                        ifTrue:[^ nil].
       
   221 
       
   222 
       
   223 !
       
   224 
       
   225 instanceTypes
       
   226     "returns list of types (#directory #normal #self #grow)
       
   227     "
       
   228     ^ instanceTypes
       
   229 
       
   230 
       
   231 !
       
   232 
       
   233 instanceVarAt:anIndex
       
   234     "returns the instnace variable assigned to the index or 
       
   235      nil in case of an invalid index.
       
   236     "
       
   237     |nm|
       
   238 
       
   239     (anIndex isNil or:[anIndex > instanceTypes size]) ifFalse:[
       
   240         nm := instanceNames at:anIndex.
       
   241 
       
   242         (nm at:1) isDigit ifFalse:[
       
   243             self includesSelf ifFalse:[
       
   244                 ^ inspectedObject instVarAt:anIndex
       
   245             ].
       
   246             anIndex == 1 ifFalse:[^ inspectedObject instVarAt:(anIndex-1)]
       
   247                           ifTrue:[^ inspectedObject]
       
   248         ].
       
   249       ^ inspectedObject basicAt:(Number readFrom:nm onError:0)
       
   250     ].
       
   251     ^ nil
       
   252 
       
   253 
       
   254 ! !
       
   255 
       
   256 !InspectorList methodsFor:'initialization'!
       
   257 
       
   258 initialize
       
   259     "initialize instance attributes
       
   260     "
       
   261     super initialize.
       
   262 
       
   263     instanceNames := OrderedCollection new.
       
   264     instanceTypes := OrderedCollection new.
       
   265 
       
   266 ! !
       
   267 
       
   268 !InspectorList methodsFor:'private'!
       
   269 
       
   270 resizeTo:aNumber
       
   271     "resize list to minimum aNumber
       
   272     "
       
   273     |lstVarId basicSize newLastId obj instSize|
       
   274 
       
   275     (inspectedObject isVariable and:[self class isDirectory:inspectedObject]) ifFalse:[
       
   276         ^ self
       
   277     ].
       
   278 
       
   279     instanceTypes size == 0 ifTrue:[
       
   280         lstVarId := 0
       
   281     ] ifFalse:[
       
   282         instSize := inspectedObject class instSize.
       
   283 
       
   284         instanceTypes first == #self ifTrue:[
       
   285             instSize := instSize + 1
       
   286         ].
       
   287         instanceTypes last == #grow ifTrue:[
       
   288             instanceNames removeLast.       " ..    "
       
   289             instanceTypes removeLast.       " #grow "
       
   290         ].
       
   291         lstVarId := instanceTypes size - instSize.
       
   292     ].
       
   293 
       
   294     (basicSize := inspectedObject basicSize) == lstVarId ifTrue:[
       
   295         ^ self
       
   296     ].
       
   297     newLastId := (1 bitShift:((aNumber-1) highBit)) max:128.
       
   298 
       
   299     (newLastId + 64) > basicSize ifTrue:[
       
   300         newLastId := basicSize
       
   301     ].
       
   302 
       
   303     [lstVarId ~~ newLastId] whileTrue:[
       
   304         lstVarId := lstVarId + 1.
       
   305         obj := inspectedObject basicAt:lstVarId.
       
   306 
       
   307         (self class isDirectory:obj) ifTrue:[instanceTypes add:#directory]
       
   308                                     ifFalse:[instanceTypes add:#normal].
       
   309 
       
   310         instanceNames add:(lstVarId printString, '   ', obj class name printString).
       
   311     ].
       
   312 
       
   313     lstVarId ~~ basicSize ifTrue:[
       
   314         instanceNames add:'..'.
       
   315         instanceTypes add:#grow
       
   316     ].
       
   317 ! !
       
   318 
       
   319 !InspectorList methodsFor:'selections'!
       
   320 
       
   321 selectedInstanceType
       
   322     "returns type assigned to the selected list entry (#directory #normal #self #grow).
       
   323      In case of no selection nil is returned.
       
   324     "
       
   325     ^ self instanceTypeAt:selection
       
   326 
       
   327 
       
   328 !
       
   329 
       
   330 selectedInstanceVar
       
   331     "returns current inspected instance variable or nil
       
   332     "
       
   333     ^ self instanceVarAt:selection
       
   334 
       
   335 
       
   336 !
       
   337 
       
   338 selection
       
   339     "returns current selection number or nil
       
   340     "
       
   341     ^ selection
       
   342 
       
   343 
       
   344 !
       
   345 
       
   346 setSelection:aNrOrNil
       
   347     "change current selection to a number or nil; may resize the lists
       
   348     "
       
   349     selection := aNrOrNil.
       
   350 
       
   351     (selection isNil or:[instanceTypes size > selection]) ifFalse:[
       
   352         self resizeTo:selection.
       
   353 
       
   354         selection > instanceTypes size ifTrue:[
       
   355             selection := nil
       
   356         ]
       
   357     ]    
       
   358 ! !
       
   359 
       
   360 !InspectorList methodsFor:'testing'!
       
   361 
       
   362 includesSelf
       
   363     "returns true if 'self' is included in the list
       
   364     "
       
   365     ^ (instanceTypes notEmpty and:[instanceTypes first == #self])
       
   366 
       
   367 
       
   368 !
       
   369 
       
   370 isEmpty
       
   371     "returns true if the list is empty
       
   372     "
       
   373     ^ instanceNames isEmpty
       
   374 
       
   375 !
       
   376 
       
   377 notEmpty
       
   378     "returns true if the list is not empty
       
   379     "
       
   380     ^ instanceNames notEmpty
       
   381 
       
   382 ! !
       
   383 
       
   384 !InspectorList methodsFor:'user interaction'!
       
   385 
       
   386 accept:aText notifying:aView
       
   387     "evaluating aText on the selected instance var; if an error occurs #Error
       
   388      is returned otherwise the inspected object instance. On success the list
       
   389      will be updated.
       
   390     "
       
   391     |text slNr value|
       
   392 
       
   393     selection notNil ifTrue:[
       
   394         text := self class asString:aText.
       
   395 
       
   396         text notNil ifTrue:[
       
   397             self includesSelf ifFalse:[slNr := selection]
       
   398                                ifTrue:[slNr := selection-1].
       
   399 
       
   400             value := inspectedObject class evaluatorClass 
       
   401                        evaluate:text
       
   402                        receiver:inspectedObject 
       
   403                       notifying:aView.
       
   404 
       
   405             slNr ~~ 0 ifTrue:[
       
   406                 (inspectedObject class isVariable) ifFalse:[
       
   407                     inspectedObject instVarAt:slNr put:value
       
   408                 ] ifTrue:[
       
   409                     slNr <= (inspectedObject class instSize) ifTrue:[
       
   410                         inspectedObject instVarAt:slNr put:value
       
   411                     ] ifFalse:[
       
   412                         slNr := slNr - inspectedObject class instSize.
       
   413                         inspectedObject basicAt:slNr put:value
       
   414                     ]
       
   415                 ]
       
   416             ].
       
   417             inspectedObject changed.
       
   418             self update.
       
   419           ^ inspectedObject
       
   420         ]
       
   421     ].
       
   422     ^ #Error
       
   423 !
       
   424 
       
   425 doIt:aCode notifying:aView
       
   426     "evaluating aCode on the selected instance var; if an error occurs #Error
       
   427      is returned otherwise the result returned from the evaluator. On success
       
   428      the list will be updated.
       
   429     "
       
   430     |successFg result evaluator selInstVar code|
       
   431 
       
   432     selInstVar := self selectedInstanceVar.
       
   433 
       
   434     selInstVar notNil ifTrue:[
       
   435         code := self class asString:aCode.
       
   436 
       
   437         code notNil ifTrue:[
       
   438             evaluator := selInstVar class evaluatorClass.
       
   439             successFg := true.
       
   440 
       
   441             evaluator notNil ifTrue:[
       
   442                 result := evaluator evaluate:code 
       
   443                                           in:nil 
       
   444                                     receiver:selInstVar 
       
   445                                    notifying:aView 
       
   446                                       logged:true 
       
   447                                       ifFail:[successFg := false].
       
   448 
       
   449                 successFg ifTrue:[
       
   450                     self update. 
       
   451                   ^ result 
       
   452                 ]
       
   453             ]
       
   454         ]
       
   455     ].
       
   456     ^ #Error.
       
   457 
       
   458 
       
   459 !
       
   460 
       
   461 inspect:anObject
       
   462     "inspect a new instance; update contents
       
   463     "
       
   464     |varNamesSize|
       
   465 
       
   466     selection := nil.
       
   467 
       
   468     anObject == inspectedObject ifFalse:[
       
   469         inspectedObject := anObject.
       
   470 
       
   471         (self class isDirectory:inspectedObject) ifFalse:[
       
   472             instanceNames := OrderedCollection new.
       
   473             instanceTypes := OrderedCollection new.
       
   474         ] ifTrue:[    
       
   475             instanceNames := inspectedObject class allInstVarNames.
       
   476             varNamesSize  := instanceNames size.
       
   477             instanceTypes := OrderedCollection new:varNamesSize.
       
   478 
       
   479             1 to:varNamesSize do:[:i|
       
   480                 (self class isDirectory:(inspectedObject instVarAt:i)) ifTrue:[
       
   481                     instanceTypes add:#directory
       
   482                 ] ifFalse:[
       
   483                     instanceTypes add:#normal
       
   484                 ]
       
   485             ].
       
   486         ]
       
   487     ].
       
   488     self update
       
   489 ! !
       
   490 
       
   491 !InspectorList class methodsFor:'documentation'!
       
   492 
       
   493 version
       
   494     ^ '$Header$'
       
   495 ! !