"{ Package: 'cvut:stx/goodies/libtool3' }"
"{ NameSpace: Tools }"
CodeView subclass:#NewSystemBrowserCodeView
instanceVariableNames:'browser parseTree selectedNode parsingProcess
parsingProcessRunning highlightEmphasis seqNum'
classVariableNames:''
poolDictionaries:''
category:'Interface-Browsers-New'
!
!NewSystemBrowserCodeView class methodsFor:'documentation'!
version_SVN
^ '$Header: /cvs/stx/stx/libtool/Tools__NewSystemBrowserCodeView.st,v 1.2 2009-09-28 09:08:21 fm Exp $'
! !
!NewSystemBrowserCodeView class methodsFor:'initialization'!
initialize
"
self initialize
"
Display keyboardMap
bindValue:#ImplementorsOfIt to:#Cmdm;
bindValue:#SendersOfIt to:#Cmdn;
bindValue:#GoBack to:#CmdBackSpace
"Created: / 25-12-2007 / 19:58:53 / janfrog"
"Modified: / 27-02-2008 / 12:16:10 / janfrog"
! !
!NewSystemBrowserCodeView class methodsFor:'menu specs'!
editMenuSpec
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:Tools::NewSystemBrowserCodeView andSelector:#editMenuSpec
(Menu new fromLiteralArrayEncoding:(Tools::NewSystemBrowserCodeView editMenuSpec)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Implementors'
itemValue: browseImplementorsOfIt
translateLabel: true
shortcutKey: ImplementorsOfIt
)
(MenuItem
label: 'Senders'
itemValue: browseSendersOfIt
translateLabel: true
shortcutKey: SendersOfIt
)
(MenuItem
label: 'Refactor'
translateLabel: true
isVisible: false
shortcutKey: Shift
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Accept'
itemValue: accept
translateLabel: true
shortcutKey: Accept
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Cut'
itemValue: cut
translateLabel: true
shortcutKey: Cut
)
(MenuItem
label: 'Copy'
itemValue: copySelection
translateLabel: true
shortcutKey: Copy
)
(MenuItem
label: 'Paste'
itemValue: pasteOrReplace
translateLabel: true
shortcutKey: Paste
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Undo'
itemValue: undo
translateLabel: true
shortcutKey: Undo
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Do it'
itemValue: doIt
translateLabel: true
shortcutKey: DoIt
)
(MenuItem
label: 'Print it'
itemValue: printIt
translateLabel: true
shortcutKey: PrintIt
)
(MenuItem
label: 'Inspect it'
itemValue: inspectIt
translateLabel: true
shortcutKey: InspectIt
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Special'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'Inspect RB Parse Tree'
itemValue: inspectParseTree
translateLabel: true
)
(MenuItem
label: 'Inspect selected selector'
itemValue: inspectSelectedSelector
translateLabel: true
)
)
nil
nil
)
)
(MenuItem
label: 'More'
nameKey: More
translateLabel: true
)
)
nil
nil
)
"Modified: / 18-10-2008 / 18:50:01 / Jan Vrany <vranyj1@fel.cvut.cz>"
! !
!NewSystemBrowserCodeView methodsFor:'accessing'!
browser
^ browser ? menuHolder
"Created: / 25-12-2007 / 10:20:01 / janfrog"
"Modified: / 26-12-2007 / 12:22:56 / janfrog"
!
browser:something
browser := something.
"Created: / 25-12-2007 / 10:20:01 / janfrog"
!
findNode
^selectedNode
ifNil:[self findNodeForInterval: self selectedInterval]
ifNotNil:[selectedNode]
"Created: / 18-02-2008 / 22:52:24 / janfrog"
"Modified: / 19-02-2008 / 09:35:11 / janfrog"
!
findNodeForInterval:anInterval
"
An empty interval check based on Claus suggestion
(email Fri, 10 Oct 2008 16:10:25 +0200)
"
anInterval isEmpty ifTrue:[^self].
^self findNodeIn: self parseTree forInterval: anInterval
"Created: / 19-02-2008 / 09:44:50 / janfrog"
"Modified: / 18-10-2008 / 16:47:53 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
findNodeIn:tree forInterval:interval
|node wouldReturn|
node := nil.
tree = #error ifTrue:[^nil].
tree nodesDo:[:each |
(each intersectsInterval:interval) ifTrue:[
(node isNil or:[node == each parent]) ifTrue:[
node := each
] ifFalse:[
(node parent notNil
and:[node parent isCascade and:[each parent isCascade]]) ifFalse:[^ nil]
]
] ifFalse:[
node notNil ifTrue:[
"/ already found one - beyond that one; leave
wouldReturn notNil ifTrue:[wouldReturn := node].
]
].
].
(wouldReturn notNil and:[wouldReturn ~~ node]) ifTrue:[self halt].
^ node
"Created: / 19-02-2008 / 09:40:24 / janfrog"
"Modified: / 21-02-2008 / 09:35:31 / janfrog"
!
selectedClass
^self browser theSingleSelectedClass
"Created: / 21-02-2008 / 09:26:55 / janfrog"
!
selectedNode
^ self findNode
"Created: / 21-02-2008 / 09:17:29 / janfrog"
!
selectedSelector
|selectedText|
^ (selectedText := self selectionAsString) isNilOrEmptyCollection
ifFalse:[ ^ (SystemBrowser extractSelectorFrom:selectedText) asSymbol ]
ifTrue:[
selectedNode ifNil:[ self highlightNodeAtCursor ].
(selectedNode notNil and:[ selectedNode isMessage ]) ifTrue:[
selectedNode selector
] ifFalse:[ nil ]
]
"Created: / 26-12-2007 / 11:12:26 / janfrog"
"Modified: / 19-02-2008 / 09:16:11 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'accessing-contents'!
list: anObject
super list: anObject.
self updateParseTree.
"Created: / 25-12-2007 / 10:05:17 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'change & update'!
updateParseTree
self startParsingProcess
"/Transcript showCR:'Updating parse tree'
"Created: / 25-12-2007 / 10:05:49 / janfrog"
"Modified: / 25-12-2007 / 21:29:28 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'event handling'!
buttonMotion:button x:x y:y
^ (button == 0 and:[ self sensor ctrlDown ])
ifTrue:[
self
highlightNodeAtX:x y:y;
redraw
]
ifFalse:[
super
buttonMotion:button
x:x
y:y
]
"Created: / 25-12-2007 / 21:53:50 / janfrog"
"Modified: / 19-02-2008 / 09:15:09 / janfrog"
!
buttonPress:button x:x y:y
|node|
(self sensor ctrlDown and:[ (node := self selectedNode) notNil ]) ifTrue:[
button = 1 ifTrue:[
^ self openMenu:(node redButtonMenuInCodeView:self)
].
button = #paste ifTrue:[
^ self openMenu:(node yellowButtonMenuInCodeView:self)
].
button = 2 ifTrue:[
^ self openMenu:(node blueButtonMenuInCodeView:self)
]
].
super
buttonPress:button
x:x
y:y
"Created: / 26-12-2007 / 11:39:50 / janfrog"
"Modified: / 21-02-2008 / 09:17:29 / janfrog"
!
handleNonCommandKey:keyArg
super handleNonCommandKey: keyArg.
self startParsingProcess.
"Created: / 18-02-2008 / 17:18:22 / janfrog"
!
keyPress:key x:x y:y
(x notNil and:[ y notNil ]) ifTrue:[
key = #'Control_L' ifTrue:[
self
highlightNodeAtX:x y:y;
redraw
].
"key = #Alt_L ifTrue: [self highlightParseTreeNodeAtX: x y: y; redraw]"
].
(#( #Tab #Return #BackSpace ) includes:key) ifTrue:[
self startParsingProcess
].
key == #GoBack ifTrue:[self goBack].
^ super
keyPress:key
x:x
y:y
"Created: / 25-12-2007 / 23:49:38 / janfrog"
"Modified: / 27-02-2008 / 12:18:56 / janfrog"
"Modified: / 12-03-2009 / 16:35:56 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
keyRelease: key x: x y: y
(key = #Control_L) ifTrue:
[ selectedNode := nil. self highlightClear; redraw ].
"(key = #Alt_L) ifTrue:
[ parseTreeNode := nil. self highlightClear; redraw ]."
^ super
keyRelease: key
x: x
y: y
"Created: / 25-12-2007 / 23:15:15 / janfrog"
"Modified: / 19-02-2008 / 09:16:11 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'menu'!
editMenu
| editMenu superEditMenu moreMenu moreMenuItem |
editMenu := self class editMenuSpec decodeAsLiteralArray.
superEditMenu := super editMenu.
moreMenu := superEditMenu subMenuAt: superEditMenu numberOfItems.
moreMenuItem := editMenu menuItemLabeled: 'More'.
moreMenuItem submenu: moreMenu asMenu.
editMenu findGuiResourcesIn: self.
^editMenu
"Created: / 25-12-2007 / 10:10:01 / janfrog"
"Modified: / 25-12-2007 / 19:50:53 / janfrog"
"Modified: / 18-10-2008 / 20:31:16 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
messageNodeContextMenu:messageNode
|menu|
menu := Menu new.
menu
addItem:((MenuItem new)
label:'Implementors';
shortcutKey:#ImplementorsOfIt;
submenuChannel:(Promise
value:[ self messageNodeImplementorsMenu:messageNode ]));
addItem:((MenuItem new)
label:'Senders';
shortcutKey:#SendersOfIt;
submenuChannel:(Promise value:[ self messageNodeSendersMenu:messageNode ])).
^ menu
"Created: / 18-02-2008 / 21:05:36 / janfrog"
!
messageNodeImplementorsMenu:messageNode
|implementors selector menu|
menu := Menu new.
implementors := self implementorsOf:(selector := messageNode selector).
implementors isNilOrEmptyCollection ifTrue:[
menu addItem:(MenuItem label:'No implementors found') disable
] ifFalse:[
menu addItem:(MenuItem
label:(selector storeString , (' (all implementors) ') asText allItalic)
value:[
self browseMethods:implementors
label:'Implementors of ' , selector storeString
]).
menu addSeparator.
implementors do:[:mth |
menu
addItem:(MenuItem label:(selector storeString
, (' in ' , mth containingClass name asText allBold))
value:[ self browseMethod:mth label: 'Implementor of ' , selector storeString ])
]
].
^ menu
"Created: / 18-02-2008 / 21:05:47 / janfrog"
"Modified: / 19-10-2008 / 08:16:50 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
messageNodeSendersMenu:messageNode
|implementors selector menu|
menu := Menu new.
implementors := self sendersOf:(selector := messageNode selector).
implementors isNilOrEmptyCollection ifTrue:[
menu addItem:(MenuItem label:'No senders found') disable
] ifFalse:[
menu addItem:(MenuItem
label:(selector storeString , (' (all senders)') asText allItalic)
value:[
self browseMethods:implementors
label:'Senders of ' , selector storeString
]).
menu addSeparator.
implementors do:[:mth |
menu
addItem:(MenuItem label:(mth selector storeString
, (' in ' , mth containingClass name asText allBold))
value:[ self browseMethod:mth label: 'Sender of ' , selector storeString ])
]
].
^ menu
"Created: / 18-02-2008 / 21:05:56 / janfrog"
"Modified: / 19-10-2008 / 08:17:00 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
openMenu: aMenuOrNil
aMenuOrNil ifNotNil:
[self highlightClear; redraw.
aMenuOrNil startUp].
"Created: / 18-02-2008 / 19:03:08 / janfrog"
!
variableNodeMenuContext:variableNode
| menu |
menu := Menu new.
menu
addItem:
(MenuItem new
label: 'Rename Local Variable';
value:[self refactorMenuRenameLocalVariable];
enabled:(self isLocalVariableNode: variableNode));
addItem:
(MenuItem new
label: 'Rename Instance Variable';
value:[self refactorMenuRenameInstanceVariable];
enabled:(self isInstanceVariableNode: variableNode)).
^menu
"Created: / 18-02-2008 / 21:10:46 / janfrog"
"Modified: / 21-02-2008 / 09:40:09 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'menu - actions'!
accept
super accept.
self startParsingProcess
"Created: / 26-12-2007 / 12:33:19 / janfrog"
!
browseImplementorsOfIt
| selector implementors |
selector := self selectedSelector.
implementors := self implementorsOf: selector.
self browseMethods: implementors label: 'Implementors of: ', selector storeString
"Created: / 26-12-2007 / 11:02:41 / janfrog"
!
browseMethod: method label: label
self browser ifNil: [^NewSystemBrowser openInMethod:method].
(UserPreferences current alwaysOpenNewTabWhenCtrlClick or:[self browser navigationState modified])
ifTrue:
[self browser
spawnMethodBrowserFor:(Array with: method)
in:#newBuffer
label:label]
ifFalse:
[self browser
switchToClass: method containingClass
selector: method selector].
"Modified: / 19-02-2008 / 10:15:17 / janfrog"
"Created: / 19-10-2008 / 08:16:17 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
browseMethods: methods label: label
methods size = 1 ifTrue:
[^self browseMethod: methods anyOne label: label].
self browser
ifNil: [NewSystemBrowser browseMethods: methods title: label]
ifNotNil:[self browser spawnMethodBrowserFor:methods in:#newBuffer label:label]
"Created: / 26-12-2007 / 11:32:04 / janfrog"
"Modified: / 19-10-2008 / 08:17:28 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
browseSendersOfIt
| selector implementors |
selector := self selectedSelector.
implementors := self sendersOf: selector.
self browseMethods: implementors label: 'Senders of: ', selector storeString
"Created: / 26-12-2007 / 11:35:43 / janfrog"
!
goBack
(self browser respondsTo: #goBack)
ifTrue:[self browser goBack]
"Created: / 27-02-2008 / 12:18:02 / janfrog"
!
inspectParseTree
^ self parseTree inspect
"Created: / 25-12-2007 / 21:36:09 / janfrog"
"Modified: / 19-02-2008 / 09:20:03 / janfrog"
!
inspectSelectedSelector
^self selectedSelector inspect
"Created: / 26-12-2007 / 11:16:48 / janfrog"
!
refactorMenuRenameInstanceVariable
self topView application codeMenuRenameTemporary
"Created: / 21-02-2008 / 09:15:08 / janfrog"
!
refactorMenuRenameLocalVariable
self browser codeMenuRenameTemporary
"Created: / 18-02-2008 / 21:21:26 / janfrog"
"Modified: / 19-02-2008 / 09:59:11 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'menu - double dispatch'!
blueButtonMenuForMessageNode:messageNode
^ self messageNodeContextMenu:messageNode
"Created: / 18-02-2008 / 19:12:56 / janfrog"
"Modified: / 18-02-2008 / 21:05:36 / janfrog"
!
blueButtonMenuForVariableNode: messageNode
^self variableNodeMenuContext:messageNode
"Created: / 18-02-2008 / 21:04:32 / janfrog"
!
redButtonMenuForMessageNode:messageNode
^ self messageNodeImplementorsMenu:messageNode
"Modified: / 18-02-2008 / 21:05:47 / janfrog"
!
yellowButtonMenuForMessageNode:messageNode
^ self messageNodeSendersMenu:messageNode
"Created: / 18-02-2008 / 19:08:50 / janfrog"
"Modified: / 18-02-2008 / 21:05:56 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'private'!
implementorsOf: selector
selector ifNil:[^#()].
^SystemBrowser
findImplementorsOf: selector
in: Smalltalk allClasses
ignoreCase: false
"Created: / 26-12-2007 / 11:37:11 / janfrog"
!
sendersOf: selector
^SystemBrowser
findSendersOf: selector
in: Smalltalk allClasses
ignoreCase: false
"Created: / 26-12-2007 / 11:37:22 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'private - highlighting'!
highlightClear
self list ifNil:[^self].
self list do:
[:line |
line isText ifTrue:
[ line emphasisAllRemove: self highlightEmphasis]]
"Created: / 25-12-2007 / 23:26:27 / janfrog"
"Modified: / 26-12-2007 / 12:28:05 / janfrog"
!
highlightEmphasis
^ highlightEmphasis ifNil:
[highlightEmphasis := Array
with:#underline
with:#bold
"with:#underlineColor -> Color blue"]
"Created: / 25-12-2007 / 22:57:23 / janfrog"
"Modified: / 26-12-2007 / 11:16:14 / janfrog"
!
highlightFrom: start to: end
"Remove underlined emphasis"
|startLine startCol endLine endCol|
startLine := self lineOfCharacterPosition:start.
startCol := start - (self characterPositionOfLine:startLine col:1) + 1.
endLine := self lineOfCharacterPosition:end.
endCol := end - (self characterPositionOfLine:endLine col:1) + 1.
self highlightFromLine: startLine col: startCol toLine: endLine col: endCol
"Created: / 25-12-2007 / 22:56:28 / janfrog"
!
highlightFromLine: startLine col: startCol toLine: endLine col: endCol
self list keysAndValuesDo:
[:lineNo :line|
|start end|
line isText ifTrue:
[line emphasisAllRemove: self highlightEmphasis.
self highlightLine: lineNo fromLine: startLine col: endLine toLine: startCol col: endCol.
self redrawLine: lineNo]].
"Created: / 25-12-2007 / 23:10:57 / janfrog"
!
highlightLine: lineNo fromLine: startLine col: endLine toLine: startCol col: endCol
| line start end |
(lineNo between:startLine and: endLine) ifFalse:[^self].
line := self listAt: lineNo.
start := lineNo = startLine
ifTrue:[startCol]
ifFalse:[line indexOfSeparator].
end := lineNo = endLine
ifTrue:[endCol]
ifFalse:[line size].
line emphasisFrom: start to: end add: self highlightEmphasis
"Created: / 25-12-2007 / 23:30:32 / janfrog"
!
highlightNode:node
selectedNode == node ifTrue:[^ self].
selectedNode := node.
selectedNode ifNil:[ ^ self highlightClear ].
selectedNode highlightInCodeView:self.
"Created: / 19-02-2008 / 09:14:38 / janfrog"
!
highlightNodeAtCursor
self highlightNodeAtLine:self cursorLine col:self cursorCol
"Created: / 19-02-2008 / 09:14:46 / janfrog"
!
highlightNodeAtLine:line col:col
|characterPosition node|
(self parseTree isNil or:[ self parseTree = #error ]) ifTrue:[
^ self
].
characterPosition := self characterPositionOfLine:line col:col.
node := self findNodeForInterval: (characterPosition to:characterPosition).
self highlightNode:node
"Created: / 19-02-2008 / 09:14:58 / janfrog"
!
highlightNodeAtX:x y:y
|visibleLine line col|
(self parseTree isNil or:[ self parseTree = #error ]) ifTrue:[
^ self
].
visibleLine := self visibleLineOfY:y.
col := self colOfX:x inVisibleLine:visibleLine.
line := self visibleLineToAbsoluteLine:visibleLine.
self highlightNodeAtLine:line col:col
"Created: / 19-02-2008 / 09:15:09 / janfrog"
!
highlightWithoutClearFrom: start to: end
"Remove underlined emphasis"
|startLine startCol endLine endCol|
startLine := self lineOfCharacterPosition:start.
startCol := start - (self characterPositionOfLine:startLine col:1) + 1.
endLine := self lineOfCharacterPosition:end.
endCol := end - (self characterPositionOfLine:endLine col:1) + 1.
self highlightWithoutClearFromLine: startLine col: startCol toLine: endLine col: endCol
"Created: / 25-12-2007 / 23:27:14 / janfrog"
!
highlightWithoutClearFromLine: startLine col: startCol toLine: endLine col: endCol
self list keysAndValuesDo:
[:lineNo :line|
|start end|
line isText ifTrue:
[self highlightLine: lineNo fromLine: startLine col: endLine toLine: startCol col: endCol]].
"Created: / 25-12-2007 / 23:35:07 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'private - highlighting - nodes'!
highlightLiteralNode: node
node value isSymbol ifTrue:
[self highlightFrom: node start to: node stop]
"Created: / 26-12-2007 / 10:19:08 / janfrog"
!
highlightMessageNode: node
self highlightClear.
node selectorParts do:
[:part|self highlightWithoutClearFrom: part start to: part stop]
"Created: / 25-12-2007 / 23:41:36 / janfrog"
!
highlightVariableNode: node
(#('self' 'super' 'here' 'thisContext') includes:node name) ifTrue:[^self].
^ self highlightFrom: node start to: node stop
"Created: / 25-12-2007 / 23:45:42 / janfrog"
"Modified: / 18-02-2008 / 20:51:51 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'private - parsing'!
parseTree
^ parseTree
"Created: / 19-02-2008 / 09:20:03 / janfrog"
"Modified: / 19-10-2008 / 07:36:36 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
parseTree:something
parseTree := something.
"Created: / 19-10-2008 / 07:39:15 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
parseTree:something sequenceNumber: givenSeqNum
givenSeqNum < seqNum ifFalse:
[parseTree := something].
"Created: / 12-03-2009 / 16:29:11 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
startParsingProcess
|prio contents|
seqNum := ((seqNum ? 0) + 1).
parsingProcess
ifNotNil:[
parsingProcessRunning ~~ true ifTrue:[
^ self
].
self stopParsingProcess
].
prio := Processor userBackgroundPriority - 1.
self shown ifFalse:[
prio := prio - 1 max:1
].
contents := self contents.
parsingProcess := [
[
| tree |
tree := ((contents isNilOrEmptyCollection)
ifTrue:[ nil ]
ifFalse:[ RBParser parseMethod:contents onError:[:err :pos | #error ] ]).
self sensor
pushUserEvent:#parseTree:sequenceNumber:
for: self
withArguments:
(Array with: tree with: seqNum)
] ensure:[
parsingProcessRunning := false.
parsingProcess := nil.
]
] forkAt:prio
"Modified: / 19-02-2008 / 09:22:57 / janfrog"
"Created: / 21-08-2009 / 15:40:06 / Jan Vrany <vranyj1@fel.cvut.cz>"
"Modified: / 22-08-2009 / 11:51:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
stopParsingProcess
|p|
(p := parsingProcess) notNil ifTrue:[
parsingProcess := nil.
p terminate.
"/ raise its prio to make it terminate quickly
p priority:(Processor userSchedulingPriority + 1)
]
"Created: / 25-12-2007 / 21:16:03 / janfrog"
! !
!NewSystemBrowserCodeView methodsFor:'private - testing'!
isInstanceVariableNode: node
node isVariable ifFalse:[^false].
^(self selectedClass allInstVarNames includes:(node name))
"Created: / 21-02-2008 / 09:39:10 / janfrog"
!
isLocalVariableNode: node
(self parseTree arguments includes: node) ifTrue:[^true].
(self parseTree body temporaries includes: node) ifTrue:[^true].
^false
"Created: / 21-02-2008 / 09:32:33 / janfrog"
! !
!NewSystemBrowserCodeView class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libtool/Tools__NewSystemBrowserCodeView.st,v 1.2 2009-09-28 09:08:21 fm Exp $'
! !
NewSystemBrowserCodeView initialize!