do not allow copy of password-characters out of an editfield.
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libwidg' }"
TextCollector subclass:#Workspace
instanceVariableNames:'doItAction codeStartPosition errorFgColor errorBgColor
commentStrings'
classVariableNames:'DefaultErrorForegroundColor DefaultErrorBackgroundColor
WorkspaceVariables'
poolDictionaries:''
category:'Interface-Smalltalk'
!
!Workspace class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
a view for editable text which can evaluate expressions.
I.e. its basically a view for editable text, with added
'doIt', 'printIt' and 'inspectIt' functions on the popup-menu.
The action to be performed on doIt is defined by a block,
which can be defined by the owner of this view.
(thus you can put a workspace into more complex widgets, and
control what should happen on 'doIt').
A useful default action is automatically defined, which simply
evaluates the selection as a smalltalk expression.
(but, a lisp or prolog workspace would define its own action,
to call for another compiler/interpreter ...)
Caveat:
in this version, Workspace does not yet support doIt in MVC setups.
For now, simulate this by setting the doItAction, to notify the
model manually about the doIt.
[instance variables:]
doItAction <Block> block to evaluate for doIt
errorFgColor <Color> fg-Color to be used when highlighting errors
errorBgColor <Color> bg-Color to be used when highlighting errors
codeStartPosition private temporary
[styleSheet values:]
codeErrorSelectionForegroundColor fg color to highlight errors
(default: selection fg)
codeErrorSelectionBackgroundColor bg color to highlight errors
(default: selection bg)
[start with:]
Workspace open
[see also:]
Workspace EditTextView
Parser ByteCodeCompiler
[author:]
Claus Gittinger
"
! !
!Workspace class methodsFor:'defaults'!
defaultLabel
"my default window label"
^ 'Workspace'
"Created: / 16.5.1998 / 16:53:37 / cg"
!
updateStyleCache
"extract values from the styleSheet and cache them in class variables"
<resource: #style (#'codeErrorSelection.foregroundColor'
#'codeErrorSelection.backgroundColor')>
DefaultErrorForegroundColor := StyleSheet colorAt:'codeErrorSelection.foregroundColor'.
DefaultErrorBackgroundColor := StyleSheet colorAt:'codeErrorSelection.backgroundColor'.
"Modified: 20.10.1997 / 14:06:18 / cg"
! !
!Workspace class methodsFor:'getting a System Workspace'!
open
"launch a new workspace"
|scr topView workspace f|
topView := StandardSystemView
label:(self classResources string:(self defaultLabel))
" minExtent:(100 @ 100)".
scr := HVScrollableView for:self in:topView.
scr origin:(0.0 @ 0.0) corner:(1.0 @ 1.0).
workspace := scr scrolledView.
"/ adjust topViews extent according to my font
f := workspace font.
topView extent:((f widthOf:'x') * 40) @ (f height * 10).
topView open.
^ workspace
"
Workspace open
"
"Modified: / 16.5.1998 / 16:53:53 / cg"
!
openForRemote:hostName
"launch a new workspace to evaluate expression on some remote machine.
Entered expressions are sent over to some partner machine, evaluated there,
and the result is shown here.
This requires the RemoteObjects package to be loaded."
|server remoteCompiler workspace|
RemoteObjectServer isNil ifTrue:[
self warn:'no remoteObjectServer available'.
^ nil
].
server := RemoteObjectServer on:hostName.
remoteCompiler := server get:#Compiler.
workspace := self open.
workspace topView
label:(self classResources string:'Remote Workspace {%1}' with:hostName).
workspace doItAction:
[:theCode |
remoteCompiler
evaluate:theCode
in:nil
receiver:nil
notifying:workspace
logged:true
ifFail:nil
]
"
Workspace openForRemote:'andi'
"
"Modified: / 16.5.1998 / 16:57:38 / cg"
! !
!Workspace class methodsFor:'queries'!
isVisualStartable
"returns whether this application class can be started via #open
(i.e. via a double click on the class in the browser)"
^ self == Workspace
"Created: / 16.5.1998 / 16:59:00 / cg"
"Modified: / 16.5.1998 / 16:59:39 / cg"
! !
!Workspace class methodsFor:'workspace variables'!
addWorkspaceVariable:name
"create a new workspace variable"
|holder|
WorkspaceVariables isNil ifTrue:[
WorkspaceVariables := Dictionary new.
].
WorkspaceVariables at:name put:(holder := ValueHolder new).
^ holder
!
removeAllWorkspaceVariables
"delete all workspace variables"
WorkspaceVariables := nil
!
removeWorkspaceVariable:name
"delete a workspace variable"
WorkspaceVariables notNil ifTrue:[
WorkspaceVariables removeKey:name ifAbsent:nil.
WorkspaceVariables isEmpty ifTrue:[
WorkspaceVariables := nil
]
].
!
workspaceVariableAt:name
"retrieve a workspace variable (actually, a holder onto it)"
WorkspaceVariables isNil ifTrue:[^ nil].
^ WorkspaceVariables at:name ifAbsent:nil.
!
workspaceVariables
"retrieve the collection of workspace variables"
^ WorkspaceVariables
! !
!Workspace methodsFor:'accessing'!
commentStrings:anArrayOfCommentStrings
"define the comment strings"
commentStrings := anArrayOfCommentStrings
"Created: / 9.11.1997 / 01:05:25 / cg"
!
doItAction
"return the action to be performed when 'doIt' is selected"
^ doItAction
!
doItAction:aOneArgBlock
"define the action to be performed when 'doIt' is selected.
The block will be evaluated, passing the selection as a String argument.
A default doItAction is set for you in the initialize method."
doItAction := aOneArgBlock
"Modified: 27.2.1996 / 15:31:37 / cg"
! !
!Workspace methodsFor:'compiler interface'!
compilerClass
^ Compiler
!
currentSourceCode
"special interface to compiler - called by parser
to get the updated source code after a corrected error"
^ self contents
!
wantChangeLog
"sent by the compiler to ask if a changeLog entry should
be written. Return true here."
^ true
! !
!Workspace methodsFor:'compiler interface - error handling'!
correctableError:aString position:relPos to:relEndPos from:aCompiler
"compiler notifies us of a correctable error;
hilight the error (relPos to relEndPos) and show a Box asking for continue/correct/abort;
this method should return true to the compiler if user wants the error
to be corrected; false otherwise"
|action|
self highlightingErrorPosition:relPos to:relEndPos do:[
action := OptionBox
request:aString
label:'Error'
form:(WarningBox iconBitmap)
buttonLabels:#('cancel' 'declare as...' 'correct...' 'continue')
values:#(#abort #declare #correct #continue)
default:#continue.
].
action == #declare ifTrue:[
^ action
].
action == #abort ifTrue:[
Object abortSignal raise.
^ false
].
^ action == #correct
"Modified: 20.2.1996 / 20:48:52 / cg"
!
correctableSelectorWarning:aString position:relPos to:relEndPos from:aCompiler
"compiler notifies us of a correctable selector warning;
hilight the error (relPos to relEndPos) and show a Box asking for continue/correct/abort;
this method should return true to the compiler if user wants the error
to be corrected; false otherwise"
|action|
self highlightingErrorPosition:relPos to:relEndPos do:[
action := OptionBox
request:aString
label:'Warning'
form:(WarningBox iconBitmap)
buttonLabels:#('cancel' 'correct...' 'generate' 'continue')
values:#(#abort #correct #generate #continue)
default:#continue.
].
action == #generate ifTrue:[
^ action
].
action == #abort ifTrue:[
Object abortSignal raise.
^ false
].
^ action == #correct
"Modified: / 19.1.2000 / 16:26:39 / cg"
"Created: / 19.1.2000 / 16:27:28 / cg"
!
error:aString position:relPos to:relEndPos asWarning:asWarning
"obsolete - no longer invoked"
^ self error:aString position:relPos to:relEndPos from:nil asWarning:asWarning
!
error:aString position:relPos to:relEndPos from:aCompiler
"compiler notifies us of an error; hilight the error (relPos to relEndPos)
and show a Box asking for continue/abort."
^ self error:aString position:relPos to:relEndPos from:aCompiler asWarning:false
!
error:aString position:relPos to:relEndPos from:aCompiler asWarning:asWarning
"compiler notifies us of an error; hilight the error (relPos to relEndPos)
and show a Box asking for continue/abort."
|answer|
self highlightingErrorPosition:relPos to:relEndPos do:[
|box lbl|
WarningSignal isHandled ifTrue:[
WarningSignal raiseErrorString:aString.
^ false
].
"
ask if we should abort or continue
"
box := YesNoBox title:aString
yesText:(resources string:'continue')
noText:(resources string:'abort').
lbl := aCompiler isNil ifTrue:['Compiler'] ifFalse:[aCompiler class name].
asWarning ifTrue:[
lbl := lbl , ' warning'
] ifFalse:[
lbl := lbl , ' error'.
].
box label:lbl.
box form:(WarningBox iconBitmap).
answer := box confirm.
box destroy.
].
"
do the abort if we have to
"
answer ifFalse:[
Object abortSignal raise.
].
^ false
"Created: 24.11.1995 / 22:56:34 / cg"
"Modified: 7.1.1997 / 23:00:45 / cg"
!
highlightingErrorPosition:relPos to:relEndPos do:aBlock
"evaluate aBlock while some selection is shown highlighted with error colors."
|absPosition fg bg|
"
change color of selection & hide cursor
"
fg := selectionFgColor.
bg := selectionBgColor.
selectionBgColor := errorBgColor.
selectionFgColor := errorFgColor.
self hideCursor.
"
select the text - relEndPos may be nil in which case the whole line is selected
we have to adjust the positions given by the compiler, since they
are relative to the texts start (the compiler did stream-read the code).
"
codeStartPosition isNil ifTrue:[codeStartPosition := 1].
absPosition := codeStartPosition + relPos - 1.
relEndPos isNil ifTrue:[
self selectLineWhereCharacterPosition:absPosition
] ifFalse:[
self selectFromCharacterPosition:absPosition to:(codeStartPosition + relEndPos - 1)
].
self makeSelectionVisible.
device flush.
aBlock valueNowOrOnUnwindDo:[
"
undo selection color change and show cursor again
"
selectionFgColor := fg.
selectionBgColor := bg.
self showCursor.
].
!
warning:aString position:relPos to:relEndPos from:aCompiler
"compiler notifies us of a warning - same behavior as error"
self error:aString position:relPos to:relEndPos from:aCompiler asWarning:true
! !
!Workspace methodsFor:'editing'!
commentFrom:line1 to:line2
"convenient function to comment out a block.
All lines from line1 to line2 get an end-of-line comment
in the first col
(if no eol comment is available, a bracketing comment is used)."
|eolComment opening closing|
eolComment := commentStrings at:1.
eolComment isNil ifTrue:[
opening := (commentStrings at:2) at:1.
closing := (commentStrings at:2) at:2.
(opening isNil or:[closing isNil]) ifTrue:[^ self].
].
line1 to:line2 do:[:lineNr |
|l|
l := self listAt:lineNr.
l isNil ifTrue:[l := ''].
eolComment notNil ifTrue:[
l := eolComment , l
] ifFalse:[
l := opening , l , closing
].
self at:lineNr basicPut:l
].
self textChanged.
"Modified: / 7.1.1997 / 20:15:06 / cg"
"Created: / 9.11.1997 / 01:05:35 / cg"
!
commentSelection
"convenient function to comment out a block.
All lines from line1 to line2 get an end-of-line comment
in the first col."
|e commentPair opening closing|
(self checkModificationsAllowed) ifFalse:[ ^ self].
selectionStartLine notNil ifTrue:[
(selectionStartCol == 1 and:[selectionEndCol == 0]) ifTrue:[
self commentFrom:selectionStartLine to:selectionEndLine-1
] ifFalse:[
commentPair := commentStrings at:2.
opening := commentPair at:1.
closing := commentPair at:2.
(opening isNil or:[closing isNil]) ifTrue:[^ self].
e := selectionEndCol.
self insertString:closing atLine:selectionEndLine col:e+1.
self insertString:opening atLine:selectionStartLine col:selectionStartCol.
selectionStartLine == selectionEndLine ifTrue:[e := e + opening size].
self selectFromLine:selectionStartLine col:selectionStartCol
toLine:selectionEndLine col:e+closing size.
]
]
"Created: / 9.11.1997 / 01:05:40 / cg"
"Modified: / 5.4.1998 / 16:52:23 / cg"
!
uncommentFrom:line1 to:line2
"convenient function to comment out a block.
All lines from line1 to line2 get an end-of-line comment
in the first col.
(if no eol comment is available, a bracketing comment is removed)"
|eolComment opening closing rest|
eolComment := commentStrings at:1.
eolComment isNil ifTrue:[
opening := (commentStrings at:2) at:1.
closing := (commentStrings at:2) at:2.
(opening isNil or:[closing isNil]) ifTrue:[^ self].
] ifFalse:[
rest := eolComment size + 1.
].
line1 to:line2 do:[:lineNr |
|l|
l := self listAt:lineNr.
l notNil ifTrue:[
eolComment notNil ifTrue:[
(l startsWith:eolComment) ifTrue:[
l := l copyFrom:rest
]
] ifFalse:[
((l startsWith:opening)
and:[l endsWith:closing]) ifTrue:[
l := l copyFrom:opening size + 1.
l := l copyWithoutLast:closing size.
]
].
self at:lineNr basicPut:l
]
].
self textChanged.
"Modified: / 7.1.1997 / 20:17:44 / cg"
"Created: / 9.11.1997 / 01:05:43 / cg"
!
uncommentSelection
"convenient function to comment out a block.
All lines from line1 to line2 get an end-of-line comment
in the first col."
|e commentPair opening closing sz1 sz2|
selectionStartLine notNil ifTrue:[
(selectionStartCol == 1 and:[selectionEndCol == 0]) ifTrue:[
self uncommentFrom:selectionStartLine to:selectionEndLine-1
] ifFalse:[
commentPair := commentStrings at:2.
opening := commentPair at:1.
closing := commentPair at:2.
(opening isNil or:[closing isNil]) ifTrue:[^ self].
sz1 := opening size.
sz2 := closing size.
((self
stringAtLine:selectionStartLine
from:selectionStartCol
to:selectionStartCol+sz1 - 1) = opening
and:[(self
stringAtLine:selectionEndLine
from:selectionEndCol - sz2 + 1
to:selectionEndCol) = closing ]) ifTrue:[
self deleteCharsAtLine:selectionEndLine fromCol:selectionEndCol-sz2+1 toCol:selectionEndCol.
self deleteCharsAtLine:selectionStartLine fromCol:selectionStartCol toCol:selectionStartCol+sz1-1.
e := selectionEndCol - sz2.
selectionStartLine == selectionEndLine ifTrue:[e := e - sz1].
self selectFromLine:selectionStartLine col:selectionStartCol
toLine:selectionEndLine col:e.
]
]
]
"Modified: / 7.1.1997 / 20:13:32 / cg"
"Created: / 9.11.1997 / 01:05:46 / cg"
! !
!Workspace methodsFor:'events'!
keyPress:key x:x y:y
<resource: #keyboard (#DoIt #InspectIt #PrintIt #BrowseIt #'CmdF*' #'CtrlF*')>
|cmd fKey|
(key == #DoIt) ifTrue:[^ self doIt].
(key == #InspectIt) ifTrue:[^ self inspectIt].
(key == #PrintIt) ifTrue:[^ self printIt].
(key == #BrowseIt) ifTrue:[^ self browseIt].
"
Ctrl-Fn or Cmd-Fn evaluates a key-sequence (n = 0..99)
(I added Ctrl-Fn, because some windowmanagers already use cmd-fn)
see TextView>>keyPress:x:y:
"
key isSymbol ifTrue:[
(key startsWith:'CmdF') ifTrue:[
fKey := key copyFrom:4
] ifFalse:[
(key startsWith:'CtrlF') ifTrue:[
fKey := key copyFrom:5
]
].
].
fKey notNil ifTrue:[
fKey := fKey asSymbol.
cmd := UserPreferences current functionKeySequences at:fKey ifAbsent:nil.
cmd notNil ifTrue:[
AbortSignal "ErrorSignal" handle:[:ex |
self warn:'error occurred in keyboard macro'.
ex return.
] do:[
Parser evaluate:cmd asString
receiver:self
notifying:nil
compile:false.
].
^ self
]
].
super keyPress:key x:x y:y
"
example uses of function keys:
to set tab-distance to 4-cols,
select the following:
self setTab4
then, press shift-F2 to define the sequence;
press cmd-F2 to execute it
voila: you have set 4-tabs.
(some window managers (MWM, 4DWM have cmd-Fn redefined; use Ctrl-Fn then).
to switch back, perform the same procedure with:
self setTab8
Within the expression, 'self' is bound to the view. Thus, you can do
all kinds of fancy things.
For example:
if you like a browser to come up on the selection when pressing Cmd-F3:
select:
|sel|
sel := self selection asString withoutSeparators.
(Smalltalk includesKey:sel asSymbol) ifTrue:[
(Smalltalk at:sel asSymbol) isClass ifTrue:[
SystemBrowser browseClass:(Smalltalk at:sel asSymbol)
]
]
then, press shift-F3 to define the command.
press cmd-F3 to execute it (select some classname before).
(notice: on the Indy, Cmd-F3 is already used by the window manager)
if you like a file-include command on Cmd-F4:
select:
|sel|
sel := self selection.
sel notNil ifTrue:[
sel := sel asString withoutSeparators.
s := FileStream readonlyFileNamed:sel.
s notNil ifTrue:[
self paste:(s contents asString).
s close
]
]
this will paste the contents of the file at the current cusor position.
(select above expression, press Shift-F4,
then select any filename and press Cmd-F4)
try it here: /etc/passwd
"
"Modified: 9.1.1997 / 12:18:30 / cg"
! !
!Workspace methodsFor:'executing'!
do:code withValueDo:aBlock
"helper for doIt, printIt and inspectIt.
Evaluate the selection and, if all went well, evaluate the argument,
aBlock with the value.
Most work is in preparing for proper cleanup in case of abort
or other exception while the evaluation is performed.
(restore cursor, selectionColors etc.)"
|selLine selCol endLine endCol cLine cCol cleanUp|
code notNil ifTrue:[
codeStartPosition := self characterPositionOfSelection.
"
remember selection for later - if there is an error,
the notification method will highlight it.
thus destroying the current selection
"
selLine := selectionStartLine.
selCol := selectionStartCol.
endLine := selectionEndLine.
endCol := selectionEndCol.
cCol := cursorCol.
cLine := cursorLine.
"
cleanup: restore previous selection and cursor positions
"
cleanUp := [
self selectFromLine:selLine col:selCol toLine:endLine col:endCol.
cLine notNil ifTrue:[
self cursorLine:cLine col:cCol
].
].
"
perform the action.
Be careful to release the reference to the value;
otherwise, we could keep lots of garbage from being freed
until the view gets closed
"
self topView withExecuteCursorDo:[
[
AbortSignal handle:[:ex |
ex return
] do:[
|value|
doItAction notNil ifTrue:[
value := doItAction value:(code asString).
cleanUp value. cleanUp := nil.
aBlock value:value.
]
]
] valueNowOrOnUnwindDo:[
cleanUp notNil ifTrue:[
cleanUp value. cleanUp := nil
].
]
].
]
"Modified: / 11.1.1997 / 20:56:30 / cg"
"Modified: / 22.4.1998 / 21:56:13 / ca"
"Created: / 22.4.1998 / 21:57:05 / ca"
! !
!Workspace methodsFor:'initialize / release'!
initStyle
"setup viewStyle specifics"
super initStyle.
errorFgColor := DefaultErrorForegroundColor.
errorFgColor isNil ifTrue:[errorFgColor := selectionFgColor].
errorBgColor := DefaultErrorBackgroundColor.
errorBgColor isNil ifTrue:[
device hasColors ifTrue:[
errorBgColor := Color red
] ifFalse:[
errorBgColor := selectionBgColor
]
].
"Modified: 22.1.1997 / 11:58:00 / cg"
!
initialize
super initialize.
showMatchingParenthesis := true.
commentStrings := #(
'"/'
('"' '"')
).
self initializeDoITAction.
"Modified: / 9.11.1997 / 01:10:18 / cg"
!
initializeDoITAction
"set up the block to be evaluated for doIts.
This is done here in a separate method to allow easier
redefinition in subclasses"
doItAction := [:theCode |
self compilerClass
evaluate:theCode
in:nil
receiver:nil
notifying:self
logged:true
ifFail:nil
].
! !
!Workspace methodsFor:'menu & menu actions'!
browseClass
"user selected 'browseClass' from menu; evaluate the code
and open a browser on the resulting class (if it evaluates to one)"
^ self
do:(self selection)
withValueDo:[:result | result isBehavior ifTrue:[
SystemBrowser openInClass:result selector:nil
] ifFalse:[
self warn:'Selection does not evaluate to a class'
]
].
!
browseIt
"evaluate the code and open a browser on the resulting class (if it evaluates to one),
or the class of the resulting object (if it does not evaluate to a class)"
^ self
do:(self selection)
withValueDo:[:result | result isBehavior ifTrue:[
SystemBrowser openInClass:result selector:nil
] ifFalse:[
SystemBrowser openInClass:(result class) selector:nil
]
].
!
browseItsClass
"user selected 'browseItsClass' from menu; evaluate the code
and open a browser on the results class"
^ self
do:(self selection)
withValueDo:[:result | SystemBrowser openInClass:result class selector:nil]
!
doIt
"user selected 'doIt' from menu; show a wait-cursor, evaluate the code
and finally restore cursor; return result of evaluation"
^ self
do:(self selection)
withValueDo:[:result | ]
"Modified: / 16.5.1998 / 16:45:01 / cg"
!
editMenu
"return my popUpMenu; thats the superclasses menu
PLUS st-evaluation items: doIt, printIt and inspectIt."
<resource: #keyboard (#DoIt #PrintIt #InspectIt)>
<resource: #programMenu>
|m idx sensor s|
m := super editMenu.
((sensor := self sensor) notNil and:[sensor ctrlDown]) ifTrue:[
m addLabels:(resources array:#('-' 'commentIt' 'uncommentIt' '-' 'browse' '-' 'timeIt' 'spyOnIt'))
selectors:#(nil commentSelection uncommentSelection nil browseIt nil timeIt spyOnIt)
accelerators:#(nil CommentSelection UncommentSelection nil nil nil nil nil nil)
after:#again.
self hasSelection ifFalse:[
m disableAll:#(browseIt commentSelection uncommentSelection timeIt spyOnIt)
"/ ] ifTrue:[
"/ s := self selectionAsString.
"/ (s knownAsSymbol
"/ and:[(Smalltalk includesKey:(s := s asSymbol))
"/ and:[(Smalltalk at:s) isBehavior]])
"/ ifFalse:[
"/ m disableAll:#(browseClass).
"/ ]
].
^ m
].
"
workspaces support #doIt, #printIt and #inspectIt
add them after paste.
"
idx := m indexOf:#paste.
idx == 0 ifTrue:[idx := m indexOf:#pasteOrReplace].
idx ~~ 0 ifTrue:[
m addLabels:(resources array:#('-' 'doIt' 'printIt' 'inspectIt'))
selectors:#(nil doIt printIt inspectIt)
accelerators:#(nil #DoIt #PrintIt #InspectIt)
after:idx.
].
self hasSelection ifFalse:[
m disableAll:#(printIt doIt inspectIt)
].
^ m.
"Modified: / 22.4.1998 / 21:49:06 / ca"
"Modified: / 7.5.1998 / 02:47:00 / cg"
!
inspectIt
"user selected 'inspectIt' from menu; use doIt to evaluate the code
and start an inspector on the result"
^ self
do:(self selection)
withValueDo:[:result | result inspect]
"Modified: / 16.5.1998 / 16:44:56 / cg"
!
printIt
"user selected 'printIt' from menu; use doIt to evaluate the code
and insert result of evaluation into my text.
If the text is readOnly, do nothing."
self isReadOnly ifTrue:[
self beep
] ifFalse:[
self
do:(self selection)
withValueDo:[:result |
self cursorLine:selectionEndLine col:(selectionEndCol + 1).
self insertSelectedStringAtCursor:(result displayString "printString")
]
]
"Modified: / 16.5.1998 / 16:44:44 / cg"
!
spyOnIt
"user selected 'spyOnIt' from menu; show a wait-cursor, evaluate the code
and finally restore cursor; return result of evaluation"
|code|
code := 'MessageTally spyOn:[' , self selection asString string, ']'.
self do:code withValueDo:[:result | ]
"Modified: / 22.4.1998 / 22:03:53 / ca"
!
timeIt
"user selected 'timeIt' from menu; show a wait-cursor, evaluate the code
and finally restore cursor; return result of evaluation"
|code|
code := '|t| t := Time millisecondsToRun:[' , self selection asString string, '].
Transcript showCR:''execution time: '' , t printString , '' ms''.'.
self do:code withValueDo:[:result | ]
"Modified: / 22.4.1998 / 22:03:51 / ca"
! !
!Workspace class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libwidg/Workspace.st,v 1.82 2001-01-11 11:17:38 cg Exp $'
! !