"======================================================================
|
|   Smalltalk GUI debugger window
|
|   $Revision: 1.7.5$
|   $Date: 2000/05/28 16:56:52$
|   $Author: pb$
|
 ======================================================================"


"======================================================================
|
| Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
| Written by Brad Diller.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 2, or (at your option) any later version.
| 
| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
| FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
| details.
| 
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
|
 ======================================================================
"

GuiData subclass: #ContextInspector
     instanceVariableNames: 'contextHolder theClass theSelector'
     classVariableNames: ''
     poolDictionaries: ''
     category: 'Graphics-Browser'
! 

!ContextInspector class methodsFor: 'instance creation'!

new: contextBrowser
    ^self new init: contextBrowser
! !

!ContextInspector methodsFor: 'private'!


init: contextBrowser
    | topView toplevel container text lowerpane pane list context llpane lrpane textView|
    contextHolder := contextBrowser.
    context := contextHolder currentContext.

    theSelector := context home selector.
    theClass := context methodClass.
    theSelector isNil ifTrue: ['Unable to inspect method context' printNl. ^self].

    topView := ((BrowserShell new: 'Context Inspector' ) data: self).
    toplevel := topView blox.
    toplevel width: 500 height: 350.

    pane := Form new: 'panes' in: topView.
    topView addChildView: pane.
    
    pane addChildView: ((textView := PCode new: pane)
    data: self;
    stateChange: #text;
    handleUserChange: #compile:from:;
    textMsg: #text;
    yourself).
    textView menuInit: ((PopupMenu new: textView label: '') selectors: 
   #(('Cut' gstCut) ('Copy' gstCopy) ('Paste' gstPaste) 
    () ('Clear' gstClear) () ('Line...' line)  ('Find...' find) ()
    ('Do it' eval) ('Print it' evalAndPrintResult) ('Inspect' evalAndInspectResult) 
    () ('Accept' compileIt)
    ('Cancel' revert) () ('Close' close))
		receiver: textView
		argument: nil).
    text := textView blox.
    text width: 500; height: 175.
    
    lowerpane := Form new: 'panes' in: pane.
    pane addChildView: lowerpane.

    lowerpane blox height: 175.
    lowerpane blox posVert: (textView blox).
    
    llpane := Form new: 'panes' in: lowerpane.
    llpane blox width: 250 height: 175.
    lowerpane addChildView: llpane.

    contextHolder currentContext receiver inspect: llpane.

    lrpane := Form new: 'panes' in: lowerpane.
    lowerpane addChildView: lrpane.
    lrpane blox width: 250 height: 175.
    lrpane blox posHoriz: llpane blox.

    StackInspector new openOn: (contextHolder currentContext) in: lrpane.
    lrpane blox posHoriz: (llpane blox).

    self changeState: #text.
    Primitive updateViews.
    topView display.
! !

!ContextInspector methodsFor: 'text pane'!

text
"Return source code for the selected method"
    theSelector printNl.
    theClass printNl.
    theSelector notNil 
	ifTrue: [^theClass -> (theClass sourceCodeAt: theSelector) ].
    ^''.
!

compile: aString from: aView
"Compile aString derived from text in text view for the selected selector"
    theSelector notNil  
	ifTrue: [ theClass compile: aString classified: 
		      ((theClass compiledMethodAt: theSelector) methodCategory) 
			   ifError: [:fname :lineNo :errorString |
								  aView displayError: errorString at: lineNo.
								  ^nil]]
! !



GenericInspector subclass:  #StackInspector
	instanceVariableNames: 'vars'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Graphics-Browser'
!

!StackInspector methodsFor: 'private'!

currentVariableValue
    "Return value at currently selected key"
    | variable |
    currentVariable == 0 ifTrue: [ ^nil].
    currentVariable == 1 ifTrue: [ ^theObject ].
    variable := vars at: currentVariable - 1.
    ^variable key at: variable value
!

currentVariable: obj
    | variable |
    currentVariable < 2	ifTrue: [ ^self ].
    variable := vars at: currentVariable - 1.
    ^variable key at: variable value put: obj
!

setInstanceVars: anObject
    theObject := anObject.
    vars := OrderedCollection new.
    instVars add: #thisContext.
    self setVariablesIn: anObject
!

setVariablesIn: context
    | prefix numVars prefixSize |
    numVars := context numArgs + context numTemps.
    context home == context
	ifTrue: [ prefixSize := -2. ]
	ifFalse: [
	    prefixSize := self setVariablesIn: context outerContext.
	].

    numVars > 0 ifTrue: [ prefixSize := prefixSize + 2 ].
    prefix := String new: (prefixSize max: 0) withAll: $-.
    1 to: numVars do: [ :i |
	instVars add: prefix, instVars size printString.
	vars add: context -> i
    ].
    ^prefixSize
! !

!ContextPart methodsFor: 'debugging' !

inspect: pane
"Open an Inspector window on self"
    ContextInspector new openOn: self in: pane
! !
