'From Squeak3.2gamma of 15 January 2002 [latest update: #4811] on 4 April 2002 at 6:25:25 pm'! "Change Set: BrowserPaneVars-sbw Date: 21 August 2001 Author: Stephan B. Wessels Updated 4-Apr-2002 (sbw). Fixed conflict introduced with change set 4808colorScrollBars-dew. Adds variables pane to several of the Browsers, similar to old Smalltalk/V browsers. Adds an instance variable to the Browser hierarchy: . The variables pane is controlled by Preferences in the 'browsing' category. Two options exist: #showVarsInBrowser - toggles if variables pane is included in the browsers or not #showInheritedVars - if the vars are enabled by the above option, this one controls if inherited variables are shown or not. This option can be disabled by a menu in the variables pane itself. The variables pane includes menu items for searching for accesses and references to a selected variable from the list too. This code was tested for the full system browser and the class hierarchy browser. It was verified to behave correctly both with the alternativeWindowLook or the standard look."! CodeHolder subclass: #Browser instanceVariableNames: 'systemOrganizer classOrganizer metaClassOrganizer systemCategoryListIndex classListIndex messageCategoryListIndex messageListIndex editSelection metaClassIndicated varsListIndex ' classVariableNames: 'RecentClasses ' poolDictionaries: '' category: 'Tools-Browser'! !Browser methodsFor: 'class list' stamp: 'sbw 8/21/2001 15:44'! classListIndex: anInteger "Set anInteger to be the index of the current class selection." | className | classListIndex _ anInteger. self setClassOrganizer. messageCategoryListIndex _ 1. messageListIndex _ 0. varsListIndex _ 0. self classCommentIndicated ifFalse: [editSelection _ anInteger = 0 ifTrue: [metaClassIndicated | (systemCategoryListIndex == 0) ifTrue: [#none] ifFalse: [#newClass]] ifFalse: [#editClass]]. contents _ nil. self selectedClass isNil ifFalse: [className _ self selectedClass name. (RecentClasses includes: className) ifTrue: [RecentClasses remove: className]. RecentClasses addFirst: className. RecentClasses size > 16 ifTrue: [RecentClasses removeLast]]. self changed: #classSelectionChanged. self changed: #classListIndex. self changed: #varsList. "update my selection" self changed: #messageCategoryList. self changed: #messageList. self changed: #relabel. self contentsChanged! ! !Browser methodsFor: 'copying' stamp: 'sbw 8/21/2001 15:37'! veryDeepInner: deepCopier "Copy all of my instance variables. Some need to be not copied at all, but shared. See DeepCopier class comment." super veryDeepInner: deepCopier. "systemOrganizer _ systemOrganizer. clone has the old value. we share it" "classOrganizer _ classOrganizer clone has the old value. we share it" "metaClassOrganizer _ metaClassOrganizer clone has the old value. we share it" systemCategoryListIndex _ systemCategoryListIndex veryDeepCopyWith: deepCopier. classListIndex _ classListIndex veryDeepCopyWith: deepCopier. messageCategoryListIndex _ messageCategoryListIndex veryDeepCopyWith: deepCopier. messageListIndex _ messageListIndex veryDeepCopyWith: deepCopier. editSelection _ editSelection veryDeepCopyWith: deepCopier. metaClassIndicated _ metaClassIndicated veryDeepCopyWith: deepCopier. varsListIndex _ varsListIndex veryDeepCopyWith: deepCopier. ! ! !Browser methodsFor: 'initialize-release' stamp: 'sbw 8/21/2001 16:29'! addMsgCatListPaneTo: window at: nominalFractions plus: verticalOffset | row innerFractions msgCatList varsPane divider dividerDelta | row _ AlignmentMorph newColumn hResizing: #spaceFill; vResizing: #spaceFill; layoutInset: 0; borderWidth: 1; layoutPolicy: ProportionalLayout new. innerFractions _ self showVarsInBrowser ifTrue: [0 @ 0 extent: 1 @ 0.5] ifFalse: [0 @ 0 extent: 1 @ 1]. msgCatList _ self buildMorphicMessageCatList. Preferences alternativeWindowLook ifTrue: [msgCatList borderWidth: 0] ifFalse: [msgCatList borderWidth: 1]. row addMorph: msgCatList fullFrame: (LayoutFrame fractions: innerFractions offsets: (0 @ 0 corner: 0 @ 0)). self showVarsInBrowser ifTrue: [varsPane _ self buildVarsListMorph. Preferences alternativeWindowLook ifTrue: [varsPane borderWidth: 0] ifFalse: [varsPane borderWidth: 1]. innerFractions _ 0 @ 0.5 extent: 1 @ 0.5. divider _ BorderedSubpaneDividerMorph forTopEdge. dividerDelta _ 0. Preferences alternativeWindowLook ifTrue: [divider extent: 4 @ 4; color: Color transparent; borderColor: #raised; borderWidth: 2. dividerDelta _ 3]. row addMorph: divider fullFrame: (LayoutFrame fractions: (0 @ 0.5 extent: 1 @ 0) offsets: (0 @ 0 corner: 0 @ dividerDelta)). row addMorph: varsPane fullFrame: (LayoutFrame fractions: innerFractions offsets: (0 @ dividerDelta corner: 0 @ 0))]. window addMorph: row fullFrame: (LayoutFrame fractions: nominalFractions offsets: (0 @ verticalOffset corner: 0 @ 0)). Preferences alternativeWindowLook ifTrue: [row borderWidth: 2] ifFalse: [row borderWidth: 0]. row on: #mouseEnter send: #paneTransition: to: window. row on: #mouseLeave send: #paneTransition: to: window! ! !Browser methodsFor: 'initialize-release' stamp: 'sbw 1/26/2001 19:10'! buildVarsListMorph ^ PluggableListMorph on: self list: #varsList selected: #varsListIndex changeSelected: #varsListIndex: menu: #varsListMenu:! ! !Browser methodsFor: 'initialize-release' stamp: 'sbw 1/26/2001 19:11'! buildVarsListView ^ PluggableListView on: self list: #varsList selected: #varsListIndex changeSelected: #varsListIndex: menu: #varsListMenu:! ! !Browser methodsFor: 'initialize-release' stamp: 'sbw 3/11/2002 12:50'! openAsMorphEditing: editString "Create a pluggable version of all the morphs for a Browser in Morphic" | window hSepFrac | hSepFrac _ 0.4. window _ (SystemWindow labelled: 'later') model: self. window addMorph: self buildMorphicSystemCatList frame: (0 @ 0 corner: 0.25 @ hSepFrac). self addClassAndSwitchesTo: window at: (0.25 @ 0 corner: 0.5 @ hSepFrac) plus: 0. self addMsgCatListPaneTo: window at: (0.5 @ 0 corner: 0.75 @ hSepFrac) plus: 0. window addMorph: self buildMorphicMessageList frame: (0.75 @ 0 extent: 0.25 @ hSepFrac). self addLowerPanesTo: window at: (0 @ hSepFrac corner: 1 @ 1) with: editString. window setUpdatablePanesFrom: #(#systemCategoryList #classList #messageCategoryList #messageList ). ^ window! ! !Browser methodsFor: 'initialize-release' stamp: 'sbw 4/4/2002 18:23'! openAsMorphSysCatEditing: editString "Create a pluggable version of all the views for a Browser, including views and controllers." | window hSepFrac switchHeight mySingletonList nextOffsets | window _ (SystemWindow labelled: 'later') model: self. hSepFrac _ 0.3. switchHeight _ 25. mySingletonList _ PluggableListMorph on: self list: #systemCategorySingleton selected: #indexIsOne changeSelected: #indexIsOne: menu: #systemCatSingletonMenu: keystroke: #systemCatSingletonKey:from:. mySingletonList enableDragNDrop: Preferences browseWithDragNDrop. mySingletonList hideScrollBarIndefinitely. window addMorph: mySingletonList fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 0.3333 @ 0) offsets: (0 @ 0 corner: 0 @ switchHeight)). self addClassAndSwitchesTo: window at: (0 @ 0 corner: 0.3333 @ hSepFrac) plus: switchHeight. nextOffsets _ 0 @ 0 corner: 0 @ 0. self addMsgCatListPaneTo: window at: (0.3333 @ 0 corner: 0.6666 @ hSepFrac) plus: 0. window addMorph: self buildMorphicMessageList fullFrame: (LayoutFrame fractions: (0.6666 @ 0 corner: 1 @ hSepFrac) offsets: nextOffsets). self addLowerPanesTo: window at: (0 @ hSepFrac corner: 1 @ 1) with: editString. window setUpdatablePanesFrom: #(#classList #messageCategoryList #messageList ). ^ window! ! !Browser methodsFor: 'metaclass' stamp: 'sbw 2/2/2001 14:41'! metaClassIndicated: trueOrFalse "Indicate whether browsing instance or class messages." metaClassIndicated _ trueOrFalse. self setClassOrganizer. systemCategoryListIndex > 0 ifTrue: [editSelection _ classListIndex = 0 ifTrue: [metaClassIndicated ifTrue: [#none] ifFalse: [#newClass]] ifFalse: [#editClass]]. messageCategoryListIndex _ 1. messageListIndex _ 0. varsListIndex _ 0. contents _ nil. self changed: #classSelectionChanged. self changed: #messageCategoryList. self changed: #varsList. self changed: #messageList. self changed: #contents. self decorateButtons! ! !Browser methodsFor: 'system category list' stamp: 'sbw 3/11/2002 13:12'! systemCategoryListIndex: anInteger "Set the selected system category index to be anInteger. Update all other selections to be deselected." systemCategoryListIndex _ anInteger. classListIndex _ 0. messageCategoryListIndex _ 0. messageListIndex _ 0. varsListIndex _ 0. editSelection _ anInteger = 0 ifTrue: [#none] ifFalse: [#newClass]. metaClassIndicated _ false. self setClassOrganizer. contents _ nil. self changed: #systemCategorySelectionChanged. self changed: #systemCategoryListIndex. "update my selection" self changed: #classList. self changed: #messageCategoryList. self changed: #varsList. self changed: #messageList. self changed: #relabel. self contentsChanged! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:04'! browseDefsForSelectedInstanceVar | varName cls | varName _ self selectedVarName. varName == nil ifTrue: [^ nil]. cls _ self selectedClassOrMetaClass. cls == nil ifTrue: [^ nil]. cls browseAllStoresInto: varName! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:04'! browseRefsForSelectedClassVar | varName cls | varName _ self selectedVarName. varName == nil ifTrue: [^ nil]. cls _ self selectedClass. cls == nil ifTrue: [^ nil]. cls _ cls classThatIncludesClassVar: varName. Smalltalk browseAllCallsOn: (cls classPool associationAt: varName)! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:03'! browseRefsForSelectedInstanceVar | varName cls | varName _ self selectedVarName. varName == nil ifTrue: [^ nil]. cls _ self selectedClassOrMetaClass. cls == nil ifTrue: [^ nil]. cls browseAllAccessesTo: varName! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:02'! selectedVarName | entry | varsListIndex = 0 ifTrue: [^ nil]. entry _ self varsList at: varsListIndex. entry isText ifTrue: [^ nil]. ^ entry! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 18:58'! showInheritedVars "Answers true/false if the vars list should show inherited values too." ^ Preferences valueOfFlag: #showInheritedVars! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 18:58'! showVarsInBrowser ^ Preferences valueOfFlag: #showVarsInBrowser! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:42'! showingInheritedVariablesString | string | string _ 'show inherited variables'. ^ self showInheritedVars ifTrue: ['' , string] ifFalse: ['' , string]! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:01'! toggleShowInheritedVars Preferences togglePreference: #showInheritedVars. self changed: #varsList! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:00'! variableListForClass: cls into: aCollection meta: meta | classVarList instVarList classNameString headerString | classVarList _ cls classVarNames. instVarList _ meta ifTrue: [OrderedCollection new] ifFalse: [cls instVarNames]. classNameString _ Text string: cls name emphasis: (Array with: TextEmphasis bold). classVarList isEmpty ifFalse: [headerString _ classNameString , (Text string: ' class variables' emphasis: (Array with: TextEmphasis italic)). aCollection add: headerString]. classVarList do: [:each | aCollection add: each]. instVarList isEmpty ifFalse: [headerString _ classNameString , (Text string: ' instance variables' emphasis: (Array with: TextEmphasis italic)). aCollection add: headerString]. instVarList do: [:each | aCollection add: each]. ^ aCollection! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:00'! varsList | variables cls meta | variables _ OrderedCollection new. cls _ self selectedClass. meta _ self metaClassIndicated. cls isNil ifFalse: [self showInheritedVars ifTrue: [cls withAllSuperclasses do: [:eachClass | self variableListForClass: eachClass into: variables meta: meta]] ifFalse: [self variableListForClass: cls into: variables meta: meta]]. ^ variables! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:00'! varsListIndex varsListIndex isNil ifTrue: [varsListIndex _ 0]. ^ varsListIndex! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 1/26/2001 19:00'! varsListIndex: anInteger varsListIndex _ anInteger. self changed: #varsListIndex! ! !Browser methodsFor: 'vars pane' stamp: 'sbw 8/21/2001 15:40'! varsListMenu: aMenu | selected | selected _ self selectedVarName. self metaClassIndicated ifFalse: [aMenu addUpdating: #showingInheritedVariablesString action: #toggleShowInheritedVars. aMenu addLine. aMenu add: 'inst var refs...' action: #browseInstVarRefs. aMenu add: 'inst var defs...' action: #browseInstVarDefs. (selected ~~ nil and: [(selected isKindOf: Symbol) not]) ifTrue: [aMenu addLine. aMenu add: 'refs to ' , selected action: #browseRefsForSelectedInstanceVar. aMenu add: 'defs for ' , selected action: #browseDefsForSelectedInstanceVar]]. aMenu addLine. aMenu add: 'class var refs...' action: #browseClassVarRefs. aMenu add: 'class vars' action: #browseClassVariables. (selected ~~ nil and: [selected isKindOf: Symbol]) ifTrue: [aMenu addLine. aMenu add: 'refs to ' , selected action: #browseRefsForSelectedClassVar]. ^ aMenu! ! !ClassDescription methodsFor: 'instance variables' stamp: 'sbw 1/27/2001 09:30'! classThatIncludesClassVar: classVarName | coll | coll _ self withAllSuperclasses select: [:class | class classVarNames includes: classVarName]. ^coll isEmpty ifTrue: [nil] ifFalse: [coll first] "Can only be one."! ! !PackagePaneBrowser methodsFor: 'initialize-release' stamp: 'sbw 8/21/2001 20:39'! openAsMorphEditing: editString "Create a pluggable version of all the views for a Browser, including views and controllers." "PackagePaneBrowser openBrowser" | listHeight window | listHeight _ 0.4. (window _ SystemWindow labelled: 'later') model: self. window addMorph: (PluggableListMorph on: self list: #packageList selected: #packageListIndex changeSelected: #packageListIndex: menu: #packageMenu: keystroke: #packageListKey:from:) frame: (0 @ 0 extent: 0.15 @ listHeight). window addMorph: self buildMorphicSystemCatList frame: (0.15 @ 0 extent: 0.2 @ listHeight). self addClassAndSwitchesTo: window at: (0.35 @ 0 extent: 0.25 @ listHeight) plus: 0. self addMsgCatListPaneTo: window at: (0.6 @ 0 extent: 0.15 @ listHeight) plus: 0. window addMorph: self buildMorphicMessageList frame: (0.75 @ 0 extent: 0.25 @ listHeight). self addLowerPanesTo: window at: (0 @ listHeight corner: 1 @ 1) with: editString. window setUpdatablePanesFrom: #(#packageList #systemCategoryList #classList #messageCategoryList #messageList ). ^ window! ! !Preferences class methodsFor: 'initialization' stamp: 'sbw 6/30/2001 13:53'! addPreferenceForInheritedVarsInBrowser self preferenceAt: #showInheritedVars ifAbsent: [self addPreference: #showInheritedVars category: #browsing default: false balloonHelp: 'If true, and if showVarsInBrowser is true then the variables shown will include those from inhertited classes. If false, then only those in the immediate class are shown.']! ! !Preferences class methodsFor: 'initialization' stamp: 'sbw 6/30/2001 13:55'! addPreferenceForShowVarsInBrowser self preferenceAt: #showVarsInBrowser ifAbsent: [self addPreference: #showVarsInBrowser category: #browsing default: true balloonHelp: 'If true, uses Steve''s browser extension to include the variables pane. If false, back to standard browser.']! ! !Preferences class methodsFor: 'initialization' stamp: 'sbw 6/30/2001 13:56'! addPreferencesForBrowserVarsPanes "Preferences addPreferencesForBrowserVarsPanes" self addPreferenceForShowVarsInBrowser; addPreferenceForInheritedVarsInBrowser! ! "Postscript: Create the entry in Preferences to control the vars panes in Browsers." Preferences addPreferencesForBrowserVarsPanes. !