Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.771.mcz
==================== Summary ====================
Name: Tools-eem.771
Author: eem
Time: 31 October 2017, 10:29:35.046372 am
UUID: 42f7dc0f-720f-4d34-8871-9dc9b59c4135
Ancestors: Tools-tpr.770
Beef up thorough selector discovery in methods with pragmas so that any arguments to the pragma are also considered. e.g. when browsing implementors in something like
notifyInformeeOfChange
"If there is a changeInformee, notify her that I have changed value"
<hasLiteralTest: #isChangeSelector:>
"To find this method as sender of all changeSelectors"
changeInformee ifNotNil: [changeInformee perform: changeSelector]
we want #isChangeSelector: included, not just #hasLiteralTest:
=============== Diff against Tools-tpr.770 ===============
Item was changed:
----- Method: StringHolder>>withSelectorAndMessagesIn:evaluate: (in category '*Tools') -----
withSelectorAndMessagesIn: aCompiledMethod evaluate: aBlock
"Allow the user to choose one selector, chosen from the currently selected message's selector, as well as those of all messages sent by it, and evaluate aBlock on behalf of chosen selector. If there is only one possible choice, simply make it; if there are multiple choices, put up a menu, and evaluate aBlock on behalf of the the chosen selector, doing nothing if the user declines to choose any"
| selectorOrNil messages |
selectorOrNil := aCompiledMethod selector.
+ messages := aCompiledMethod messages.
+ SystemNavigation thoroughSenders ifTrue:
+ [| litGetter |
+ litGetter := [:l|
+ (l isSymbol and: [l size > 0 and: [l first isLowercase]]) ifTrue:
+ [messages add: l].
+ l isArray ifTrue:
+ [l do: litGetter]].
+ aCompiledMethod allLiterals do: litGetter.
+ aCompiledMethod pragmas do:
+ [:pragma|
+ litGetter
+ value: pragma keyword;
+ value: pragma arguments]].
+ messages remove: selectorOrNil ifAbsent: ["do nothing"].
+ messages ifEmpty: "If only one item, there is no choice"
+ [^selectorOrNil ifNotNil: [aBlock value: selectorOrNil]].
- messages := SystemNavigation thoroughSenders
- ifTrue: [
- | litGetter |
- litGetter := [:set :l|
- (l isSymbol and: [l size > 0 and: [l first isLowercase]]) ifTrue:
- [set add: l].
- l isArray ifTrue:
- [l inject: set into: litGetter].
- set].
- aCompiledMethod allLiterals,
- (aCompiledMethod pragmas collect: [:pragma| pragma keyword])
- inject: aCompiledMethod messages into: litGetter]
- ifFalse: [aCompiledMethod messages].
- messages remove: selectorOrNil ifAbsent: [ "do nothing" ].
- messages ifEmpty: [ "If only one item, there is no choice"
- ^selectorOrNil ifNotNil: [ aBlock value: selectorOrNil ] ].
self systemNavigation
showMenuOf: messages
withFirstItem: selectorOrNil
ifChosenDo: aBlock!
tim Rowledge uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-tpr.770.mcz
==================== Summary ====================
Name: Tools-tpr.770
Author: tpr
Time: 28 October 2017, 1:20:10.016299 pm
UUID: 70254f01-f4e8-47ae-8907-de13158e10f4
Ancestors: Tools-tpr.769
Add FileChooserDialog and FileSaverDialog; these are experimental modal dialogs intended as replacements for FileList2>modalFileSelector, FileChooser, StandardFileMenu and several other ugly horrors.
=============== Diff against Tools-tpr.769 ===============
Item was changed:
SystemOrganization addCategory: #'Tools-ArchiveViewer'!
SystemOrganization addCategory: #'Tools-Base'!
SystemOrganization addCategory: #'Tools-Browser'!
SystemOrganization addCategory: #'Tools-Changes'!
SystemOrganization addCategory: #'Tools-Debugger'!
SystemOrganization addCategory: #'Tools-Explorer'!
SystemOrganization addCategory: #'Tools-File Contents Browser'!
SystemOrganization addCategory: #'Tools-FileList'!
SystemOrganization addCategory: #'Tools-Inspector'!
SystemOrganization addCategory: #'Tools-Menus'!
SystemOrganization addCategory: #'Tools-MethodFinder'!
SystemOrganization addCategory: #'Tools-Process Browser'!
+ SystemOrganization addCategory: #'Tools-FileDialogs'!
Item was added:
+ Model subclass: #FileAbstractSelectionDialog
+ instanceVariableNames: 'pattern directory directoryCache list listIndex fileName finalChoice'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tools-FileDialogs'!
+
+ !FileAbstractSelectionDialog commentStamp: 'tpr 10/28/2017 12:55' prior: 0!
+ FileAbstractSelectionDialog is the abstract superclass for the file chooser & saver modal dialogs.
+
+ The UI provides a text input field, a directory tree widget and a list of files within any chosen directory, and buttons to accept the selected file name/path or cancel the operation. See subclass comments and class side methods for specific usage examples.
+
+ Instance Variables
+ directory: <FileDirectory> used for the currently selected directory
+ directoryCache: <WeakIdentityKeyDictionary> used to cache a boolean to help us more quickly populate the directory tree widget when revisiting a directory
+ fileName: <String|nil> the name of the currently selected file, if any
+ finalChoice: <String|nil> pathname of the finally chosen file, returned as the result of accepting; nil is returned otherwise
+ list: <Array> the list of String of filenames (and date/size) that match the current pattern
+ listIndex: <Integer> list index of the currently selected file
+ pattern: <String> the pattern is held as a string with three simple tokens;
+ a) a ; or LF or CR splits the string into separate patterns and filenames matching any of them will be included in list
+ b) a * matches any number of characters
+ c) a # matches one character
+ The usage of pattern (see entriesMatching:, updateFileList , listForPatterns:) definitely needs improving.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog class>>open (in category 'instance creation') -----
+ open
+ "open a modal dialog to choose or save a file. Start the dialog with the default directory selected"
+
+ ^self openOn: FileDirectory default
+
+ !
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>acceptFileName (in category 'initialize-release') -----
+ acceptFileName
+
+ finalChoice := fileName.
+ self changed: #close!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buildDirectoryTreeWith: (in category 'toolbuilder') -----
+ buildDirectoryTreeWith: builder
+ | treeSpec |
+ treeSpec := builder pluggableTreeSpec new.
+ treeSpec
+ model: self ;
+ roots: #rootDirectoryList ;
+ hasChildren: #hasMoreDirectories: ;
+ getChildren: #subDirectoriesOf: ;
+ getSelectedPath: #selectedPath ;
+ setSelected: #setDirectoryTo: ;
+ getSelected: #directory;
+ label: #directoryNameOf: ;
+ menu: nil ;
+ autoDeselect: false.
+ ^ treeSpec!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buildFileListWith: (in category 'toolbuilder') -----
+ buildFileListWith: builder
+ | listSpec |
+ listSpec := builder pluggableListSpec new.
+ listSpec
+ model: self ;
+ list: #fileList ;
+ getIndex: #fileListIndex ;
+ setIndex: #fileListIndex: ;
+ menu: nil ;
+ keyPress: nil ;
+ frame:
+ (self
+ frameOffsetFromTop:0
+ fromLeft: 0
+ width: 1
+ bottomFraction: 1) .
+ ^listSpec!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buildTextInputWith: (in category 'toolbuilder') -----
+ buildTextInputWith: builder
+ | textSpec |
+ textSpec := builder pluggableInputFieldSpec new.
+ textSpec
+ model: self;
+ font: self textViewFont;
+ getText: #inputText;
+ setText: #inputText:.
+ ^textSpec
+ !
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buildWindowWith: (in category 'toolbuilder') -----
+ buildWindowWith: builder
+ "Since a file chooser is a modal dialog we over-ride the normal window build to use a dialog as the top component"
+
+ | windowSpec |
+ windowSpec := builder pluggableDialogSpec new.
+ windowSpec model: self;
+ label: #windowTitle;
+ extent: self initialExtent;
+ children: OrderedCollection new;
+ buttons: OrderedCollection new.
+ ^windowSpec!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buildWith: (in category 'toolbuilder') -----
+ buildWith: builder
+ "assemble the spec for the common chooser/saver dialog UI"
+ "ToolBuilder open: FileChooserDialog"
+ "ToolBuilder open: FileSaverDialog"
+ | windowSpec window |
+ windowSpec := self buildWindowWith: builder specs: {
+ (self topConstantHeightFrame: self textViewHeight
+ fromLeft: 0
+ width: 1) -> [self buildTextInputWith: builder].
+ (self frameOffsetFromTop: self textViewHeight
+ fromLeft: 0.25
+ width: 0.75
+ offsetFromBottom: self buttonHeight) -> [self buildFileListWith: builder].
+ (self frameOffsetFromTop: self textViewHeight
+ fromLeft: 0
+ width: 0.25
+ offsetFromBottom: self buttonHeight) -> [self buildDirectoryTreeWith: builder].
+ }.
+ windowSpec buttons add:( builder pluggableButtonSpec new
+ model: self;
+ label: 'Accept';
+ action: #acceptFileName).
+ windowSpec buttons add:( builder pluggableButtonSpec new
+ model: self;
+ label: 'Cancel';
+ action: #cancelFileChooser).
+ window := builder build: windowSpec.
+ self changed: #selectedPath.
+ ^window
+ !
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>buttonHeight (in category 'ui details') -----
+ buttonHeight
+
+ ^ Preferences standardButtonFont height * 2!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>cancelFileChooser (in category 'initialize-release') -----
+ cancelFileChooser
+
+ fileName := nil.
+ self changed: #close.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>directory (in category 'directory tree') -----
+ directory
+
+ ^ directory!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>directory: (in category 'directory tree') -----
+ directory: aFileDirectory
+ "Set the path of the directory to be displayed."
+ self okToChange ifFalse: [ ^ self ].
+ self modelSleep.
+ directory := aFileDirectory.
+ self modelWakeUp.
+ self changed: #directory.
+ self pattern: pattern!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>directoryNameOf: (in category 'directory tree') -----
+ directoryNameOf: aDirectory
+ "Return a name for the selected directory in the tree view"
+
+ ^aDirectory localName!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>entriesMatching: (in category 'file list') -----
+ entriesMatching: patternString
+ "Answer a list of directory entries which match the patternString.
+ The patternString may consist of multiple patterns separated by ';'.
+ Each pattern can include a '*' or '#' as wildcards - see String>>match:"
+
+ | entries patterns |
+ entries := directory entries reject:[:e| Smalltalk isMorphic and: [e isDirectory]].
+ patterns := patternString findTokens: ';'.
+ (patterns anySatisfy: [:each | each = '*'])
+ ifTrue: [^ entries].
+ ^ entries select: [:entry | patterns anySatisfy: [:each | each match: entry name]]!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>fileList (in category 'file list') -----
+ fileList
+ "return the list of files in the currently selected directory"
+
+ ^list!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>fileListIndex (in category 'file list') -----
+ fileListIndex
+ "return the index in the list of files for the currently selected filey"
+
+ ^listIndex!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>fileNameFormattedFrom:sizePad: (in category 'path and pattern') -----
+ fileNameFormattedFrom: entry sizePad: sizePad
+ "entry is a 5-element array of the form:
+ (name creationTime modificationTime dirFlag fileSize)"
+ | sizeStr nameStr dateStr |
+ nameStr := entry isDirectory
+ ifTrue: [entry name , self folderString]
+ ifFalse: [entry name].
+ dateStr := ((Date fromSeconds: entry modificationTime )
+ printFormat: #(3 2 1 $. 1 1 2)) , ' ' ,
+ (String streamContents: [:s |
+ (Time fromSeconds: entry modificationTime \\ 86400)
+ print24: true on: s]).
+ sizeStr := entry fileSize asStringWithCommas.
+ ^ nameStr , ' (' , dateStr , ' ' , sizeStr , ')'
+ !
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>fileNameFromFormattedItem: (in category 'file list') -----
+ fileNameFromFormattedItem: item
+ "Extract fileName and folderString from a formatted fileList item string"
+
+ | from to |
+ from := item lastIndexOf: $(.
+ to := item lastIndexOf: $).
+ ^ (from * to = 0
+ ifTrue: [item]
+ ifFalse: [item copyReplaceFrom: from to: to with: '']) withBlanksTrimmed!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>finalChoice (in category 'initialize-release') -----
+ finalChoice
+ "return the chosen directory/filename that was saved by an accept click or nil; client must check for validity"
+
+ ^self directory fullNameFor: finalChoice!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>frameOffsetFromTop:fromLeft:width:bottomFraction: (in category 'ui details') -----
+ frameOffsetFromTop: height fromLeft: leftFraction width: widthFraction bottomFraction: bottomFraction
+ "return a layout frame that starts at the fixed upper offset and goes down to the bottomFraction, and runs widthFraction from the leftFraction"
+
+ ^LayoutFrame new
+ topFraction: 0 offset: height;
+ leftFraction: leftFraction offset: 0;
+ rightFraction: (leftFraction + widthFraction) offset: 0;
+ bottomFraction: bottomFraction offset: 0;
+ yourself.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>frameOffsetFromTop:fromLeft:width:offsetFromBottom: (in category 'ui details') -----
+ frameOffsetFromTop: height fromLeft: leftFraction width: widthFraction offsetFromBottom: bottomOffset
+ "return a layout frame that starts at the fixed upper offset and goes down to the bottom - the offsetn, and runs widthFraction from the leftFraction"
+
+ ^LayoutFrame new
+ topFraction: 0 offset: height;
+ leftFraction: leftFraction offset: 0;
+ rightFraction: (leftFraction + widthFraction) offset: 0;
+ bottomFraction: 1 offset: bottomOffset negated;
+ yourself.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>hasMoreDirectories: (in category 'directory tree') -----
+ hasMoreDirectories: aDirectory
+ ^directoryCache at: aDirectory ifAbsentPut:[
+ [aDirectory directoryNames notEmpty] on: Error do:[:ex| true].
+ ].!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>initialize (in category 'initialize-release') -----
+ initialize
+ super initialize.
+ directoryCache := WeakIdentityKeyDictionary new.
+ self directory: FileDirectory default!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>listForPatterns: (in category 'path and pattern') -----
+ listForPatterns: anArray
+ "return a list of those file names which match any of the patterns in the array."
+
+ | sizePad newList |
+ newList := Set new.
+ anArray do: [ :pat | newList addAll: (self entriesMatching: pat) ].
+ sizePad := (newList inject: 0 into: [:mx :entry | mx max: entry fileSize])
+ asStringWithCommas size.
+ newList := newList collect: [ :e | self fileNameFormattedFrom: e sizePad: sizePad ].
+
+ ^ newList asArray!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>pattern: (in category 'path and pattern') -----
+ pattern: textOrStringOrNil
+
+ textOrStringOrNil
+ ifNil: [pattern := '*']
+ ifNotNil: [pattern := textOrStringOrNil asString].
+ pattern isEmpty ifTrue: [pattern := '*'].
+ self updateFileList.
+ ^ true
+ !
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>rootDirectoryList (in category 'directory tree') -----
+ rootDirectoryList
+ | dirList dir |
+ dir := FileDirectory on: ''.
+ dirList := dir directoryNames collect:[:each| dir directoryNamed: each]..
+ dirList isEmpty ifTrue:[dirList := Array with: FileDirectory default].
+ ^dirList!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>selectedPath (in category 'path and pattern') -----
+ selectedPath
+ | top here |
+ top := FileDirectory root.
+ here := directory.
+ ^(Array streamContents:[:s| | next |
+ s nextPut: here.
+ [next := here containingDirectory.
+ top pathName = next pathName] whileFalse:[
+ s nextPut: next.
+ here := next.
+ ]]) reversed.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>setDirectoryTo: (in category 'directory tree') -----
+ setDirectoryTo: dir
+ "Set the current directory shown in the FileList.
+ Does not allow setting the directory to nil since this blows up in various places."
+ dir ifNil:[^self].
+ self directory: dir.
+ self changed: #fileList.
+ self changed: #inputText.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>subDirectoriesOf: (in category 'directory tree') -----
+ subDirectoriesOf: aDirectory
+ ^aDirectory directoryNames collect:[:each| aDirectory directoryNamed: each].!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>textViewFont (in category 'ui details') -----
+ textViewFont
+
+ ^ Preferences standardDefaultTextFont!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>textViewHeight (in category 'ui details') -----
+ textViewHeight
+ " Take a whole font line and 50 % for space "
+ ^ (self textViewFont height * 1.5) ceiling!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>topConstantHeightFrame:fromLeft:width: (in category 'ui details') -----
+ topConstantHeightFrame: height fromLeft: leftFraction width: widthFraction
+ "return a layout to make a fixed height frame that starts at the top of its parent and runs widthFraction from the leftFraction."
+
+ ^LayoutFrame new
+ topFraction: 0 offset: 0;
+ leftFraction: leftFraction offset: 0;
+ rightFraction: (leftFraction + widthFraction) offset: 0;
+ bottomFraction: 0 offset: height;
+ yourself.!
Item was added:
+ ----- Method: FileAbstractSelectionDialog>>updateFileList (in category 'file list') -----
+ updateFileList
+ "Update my files list with file names in the current directory
+ that match the pattern.
+ The pattern string may have embedded newlines or semicolons; these separate different patterns."
+ | patterns |
+ patterns := OrderedCollection new.
+ Cursor wait showWhile: [
+ (pattern findTokens: (String with: Character cr with: Character lf with: $;))
+ do: [ :each |
+ (each includes: $*) | (each includes: $#)
+ ifTrue: [ patterns add: each]
+ ifFalse: [each isEmpty
+ ifTrue: [ patterns add: '*']
+ ifFalse: [ patterns add: '*' , each , '*']]].
+
+ list := self listForPatterns: patterns.
+ listIndex := 0.
+ fileName := nil.
+ self changed: #fileList]!
Item was added:
+ FileAbstractSelectionDialog subclass: #FileChooserDialog
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tools-FileDialogs'!
+
+ !FileChooserDialog commentStamp: 'tpr 10/28/2017 12:57' prior: 0!
+ A FileChooserDialog is a modal dialog to allow choosing a file. The full file name is returned, or nil if no selection was made.
+ Users can enter a pattern in the text input field that will be read as a directory path and an optional pattern (see comments about pattern in my superclass) to define the files in the file list.
+
+ Normal usage would be
+ myFilename := FileChooserDialog openOn: myApplicationDefaultDirectory pattern: '*.myapp'
+ to find a file with a name matching *.myapp and with the directory initial choice set to myApplicationDefaultDirectory. It would be quite possible to choose a file from any other directory and with any other pattern match if the user wishes, so the file name must be carefully checked.
+
+ Simpler usage might be
+ myFilename := FileChooserDialog open
+ or
+ myFilename := FileChoosverDialog openOn: FileDirectory default
+ - see the class side methods for details. See my parent class for most implementation details!
Item was added:
+ ----- Method: FileChooserDialog class>>openOn: (in category 'instance creation') -----
+ openOn: aDirectory
+ "open a modal dialog to choose a file. Start the dialog with aDirectory selected and files matching the default 'everything' pattern"
+
+ ^self openOn: aDirectory pattern: nil
+
+ !
Item was added:
+ ----- Method: FileChooserDialog class>>openOn:pattern: (in category 'instance creation') -----
+ openOn: aDirectory pattern: aPatternString
+ "open a modal dialog to choose a file. Start the dialog with aDirectory selected and files matching the pattern"
+
+ ^self new openOn: aDirectory pattern: aPatternString
+
+ !
Item was added:
+ ----- Method: FileChooserDialog>>fileListIndex: (in category 'file list') -----
+ fileListIndex: anInteger
+ "We've selected the file at the given index,so find the file name."
+
+ self okToChange ifFalse: [^ self].
+ listIndex := anInteger.
+ listIndex = 0
+ ifTrue: [fileName := nil]
+ ifFalse:
+ [fileName := self fileNameFromFormattedItem: (list at: anInteger)]. "open the file selected"
+
+ self
+ changed: #fileListIndex!
Item was added:
+ ----- Method: FileChooserDialog>>inputText (in category 'path and pattern') -----
+ inputText
+ "Answers path and pattern together"
+ ^directory fullName, directory slash, pattern!
Item was added:
+ ----- Method: FileChooserDialog>>inputText: (in category 'path and pattern') -----
+ inputText: stringOrText
+ "both path and pattern are in the text, so split them apart"
+ | base pat aString |
+ aString := stringOrText asString.
+ base := aString copyUpToLast: directory pathNameDelimiter.
+ pat := aString copyAfterLast: directory pathNameDelimiter.
+ self changed: #inputText. "avoid asking if it's okToChange"
+ pattern := pat.
+ self directory: (FileDirectory on: base).
+ self changed: #inputText.
+ self changed: #selectedPath.!
Item was added:
+ ----- Method: FileChooserDialog>>openOn:pattern: (in category 'initialize-release') -----
+ openOn: aDirectory pattern: aPatternString
+ "open a modal dialog to choose a file from aDirectory as filtered by aPattern"
+
+ directory := aDirectory.
+ pattern := aPatternString.
+
+ ToolBuilder open: self.
+ ^self finalChoice!
Item was added:
+ ----- Method: FileChooserDialog>>windowTitle (in category 'ui details') -----
+ windowTitle
+ "return the window label; would be some application dependent string but I suspect we will want to make the outer morph a dialogue box with no label anyway"
+
+ ^'File Chooser'!
Item was added:
+ FileAbstractSelectionDialog subclass: #FileSaverDialog
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tools-FileDialogs'!
+
+ !FileSaverDialog commentStamp: 'tpr 10/28/2017 12:58' prior: 0!
+ A FileSaverDialog is a modal dialog for choosing a file name to use for saving a file.
+ Users can enter a filename in the text input view that will
+ a) if it exists in the current directry listing, be selected
+ b) over ride any filenames in the current directry, providing a way to specify a completely new file.
+ This will not affect the selected directory path.
+
+ Normal usage would be
+ myFilename := FileSaverDialog openOn: myApplicationDefaultDirectory initialFilename: 'foo.myapp'
+ to find a file with a name matching foo.myapp and with the directory initial choice set to myApplicationDefaultDirectory. It would be quite possible to choose a file from any other directory and with any other name if the user wishes, so the file name must be carefully checked.
+
+ Simpler usage might be
+ myFilename := FileSaverDialog open
+ or
+ myFilename := FileSaverDialog openOn: FileDirectory default
+ - see the class side methods for details. See my parent class for most implementation details!
Item was added:
+ ----- Method: FileSaverDialog class>>openOn: (in category 'instance creation') -----
+ openOn: aDirectory
+ "open a modal dialog to save a file. Start the dialog with aDirectory selected and no suggested file name"
+
+ ^self new openOn: aDirectory initialFilename: nil
+
+ !
Item was added:
+ ----- Method: FileSaverDialog>>fileListIndex: (in category 'file list') -----
+ fileListIndex: anInteger
+ "We've selected the file at the given index,so find the file name."
+
+ self okToChange ifFalse: [^ self].
+ listIndex := anInteger.
+ listIndex = 0
+ ifTrue: [fileName := nil]
+ ifFalse:
+ [fileName := self fileNameFromFormattedItem: (list at: anInteger)]. "open the file selected"
+
+ self
+ changed: #fileListIndex;
+ changed: #inputText!
Item was added:
+ ----- Method: FileSaverDialog>>inputText (in category 'filename') -----
+ inputText
+ "return the filename to appear in the text field"
+
+ ^fileName ifNil:['Enter a filename here']!
Item was added:
+ ----- Method: FileSaverDialog>>inputText: (in category 'filename') -----
+ inputText: aText
+ "user has entered a potential filename in the text field. If it is a file in the currect list, highlight it"
+
+ fileName := aText asString.
+ listIndex := list findFirst:[: nm| (self fileNameFromFormattedItem: nm) = fileName].
+ listIndex = 0 ifFalse:
+ [fileName := self fileNameFromFormattedItem: (list at: listIndex)].
+
+ self
+ changed: #fileListIndex;
+ changed: #inputFilename!
Item was added:
+ ----- Method: FileSaverDialog>>openOn:initialFilename: (in category 'initialize-release') -----
+ openOn: aDirectory initialFilename: aFilename
+ "open a modal dialog to choose a file name to save to aDirectory"
+
+ directory := aDirectory.
+ fileName := aFilename.
+
+ ToolBuilder open: self.
+ ^self finalChoice!
Item was added:
+ ----- Method: FileSaverDialog>>selectedPath (in category 'path and pattern') -----
+ selectedPath
+ | top here |
+ top := FileDirectory root.
+ here := directory.
+ ^(Array streamContents:[:s| | next |
+ s nextPut: here.
+ [next := here containingDirectory.
+ top pathName = next pathName] whileFalse:[
+ s nextPut: next.
+ here := next.
+ ]]) reversed.!
Item was added:
+ ----- Method: FileSaverDialog>>windowTitle (in category 'ui details') -----
+ windowTitle
+ "return the window label; would be some application dependent string but I suspect we will want to make the outer morph a dialogue box with no label anyway"
+
+ ^'FileSaver'!
tim Rowledge uploaded a new version of 51Deprecated to project The Trunk:
http://source.squeak.org/trunk/51Deprecated-tpr.49.mcz
==================== Summary ====================
Name: 51Deprecated-tpr.49
Author: tpr
Time: 28 October 2017, 11:03:55.208019 am
UUID: 140ed91b-1f30-4f04-bb81-368e58ef4772
Ancestors: 51Deprecated-mt.48
deprecate #labelString in favour of #windowTitle
=============== Diff against 51Deprecated-mt.48 ===============
Item was added:
+ ----- Method: StringHolder>>labelString (in category '*51Deprecated') -----
+ labelString
+ ^self windowTitle!
tim Rowledge uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-tpr.769.mcz
==================== Summary ====================
Name: Tools-tpr.769
Author: tpr
Time: 22 October 2017, 3:53:05.953495 pm
UUID: 0879078d-c9fe-4863-814e-dd459c06d9ea
Ancestors: Tools-dtl.768
Changes to clean up creation and construction of Browsers.
All Browsers can now be made with
ToolBuilder open: BrowserClassOfMyChoice
except for FileContentsBrowser, which requires setup that doesn't really work as a default thing.
=============== Diff against Tools-dtl.768 ===============
Item was changed:
----- Method: Browser class>>fullOnClass: (in category 'instance creation') -----
fullOnClass: aClass
"Open a new full browser set to class."
+ "Browser fullOnClass: Browser"
+ ^ self new
- ^ self
- openBrowserView: (self new
setClass: aClass;
+ buildAndOpenFullBrowser!
- openEditString: nil)
- label: nil!
Item was changed:
----- Method: Browser class>>fullOnClass:category: (in category 'instance creation') -----
fullOnClass: aClass category: category
+ "Open a new full browser set to class and message category."
+ "Browser fullOnClass: Browser category: 'controls' "
+ ^ self new
- ^ self
- openBrowserView: (self new
setClass: aClass;
selectMessageCategoryNamed: category;
+ buildAndOpenFullBrowser!
- openEditString: nil)
- label: nil!
Item was changed:
----- Method: Browser class>>fullOnClass:selector: (in category 'instance creation') -----
fullOnClass: aClass selector: aSelector
+ "Open a new full browser set to the class and selector."
+ "Browser fullOnClass: Browser selector: #defaultWindowColor"
- "Open a new full browser set to class."
+ ^ self new
- ^ self
- openBrowserView: (self new
setClass: aClass selector: aSelector;
+ buildAndOpenFullBrowser!
- openEditString: nil)
- label: nil!
Item was changed:
----- Method: Browser class>>newOnCategory: (in category 'instance creation') -----
newOnCategory: aCategory
+ "Open a new browser on this category"
- "Browse the system category of the given name. 7/13/96 sw"
+ "Browser newOnCategory: 'Tools-Browser'"
- "Browser newOnCategory: 'Interface-Browser'"
+ ^self newOnCategory: aCategory label: 'Classes in category ', aCategory
- | newBrowser newCat |
- newBrowser := self new..
- newCat := aCategory asSymbol.
- (newBrowser systemCategoryList includes: newCat)
- ifTrue: [ newBrowser selectSystemCategory: newCat ]
- ifFalse: [ ^ self inform: 'No such category' ].
-
- ^ self
- openBrowserView: (newBrowser openSystemCatEditString: nil)
- label: 'Classes in category ', aCategory
!
Item was added:
+ ----- Method: Browser class>>newOnCategory:editString:label: (in category 'instance creation') -----
+ newOnCategory: aCategory editString: aString label: aLabel
+ "Open a new browser on this category (testing first for existence) with aString pre-selected in the code pane.
+ We have to be a bit sneaky to do the string insertion since it cannot be handled until after the actual browser is built and opened"
+
+ "Browser newOnCategory: 'Tools-Browser' editString: 'test string edit setup' label: 'Testing category browser with set edit string'"
+
+ | newBrowser |
+ newBrowser := self newOnCategory: aCategory label: aLabel.
+ aString ifNotNil:[newBrowser changed: #editString with: aString].
+ ^ newBrowser
+
+ !
Item was added:
+ ----- Method: Browser class>>newOnCategory:label: (in category 'instance creation') -----
+ newOnCategory: aCategory label: aLabel
+ "Open a new browser on this category (testing first for existence)."
+
+ "Browser newOnCategory: 'Tools-Browser' label: 'Testing category browser'"
+
+ | newBrowser newCat |
+ newBrowser := self new.
+ newCat := aCategory asSymbol.
+ (newBrowser systemCategoryList includes: newCat)
+ ifTrue: [ newBrowser selectSystemCategory: newCat ]
+ ifFalse: [ ^ self inform: 'No such category' ].
+
+ newBrowser buildAndOpenCategoryBrowserLabel: aLabel.
+ ^ newBrowser
+
+ !
Item was added:
+ ----- Method: Browser class>>newOnClass:editString:label: (in category 'instance creation') -----
+ newOnClass: aClass editString: aString label: aLabel
+ "Open a new class browser on this class with aString pre-selected in the code pane.
+ We have to be a bit sneaky to do the string insertion since it cannot be handled until after the actual browser is built and opened"
+ "Browser newOnClass: Browser editString: 'test string edit setup' label: 'Testing category browser with set edit string'"
+ | newBrowser|
+
+ newBrowser := self newOnClass: aClass label: aLabel.
+ newBrowser editSelection: #newMessage.
+ aString ifNotNil:[newBrowser changed: #editString with: aString].
+ ^ newBrowser
+ !
Item was changed:
----- Method: Browser class>>newOnClass:label: (in category 'instance creation') -----
newOnClass: aClass label: aLabel
+ "Open a new class browser on this class and set the label."
+ "Browser newOnClass: Browser label: 'A specific label that I want'"
- "Open a new class browser on this class."
| newBrowser |
newBrowser := self new.
newBrowser setClass: aClass.
+ ^ newBrowser buildAndOpenClassBrowserLabel: aLabel
- ^ self
- openBrowserView: (newBrowser openOnClassWithEditString: nil)
- label: aLabel
!
Item was added:
+ ----- Method: Browser class>>newOnClass:messageCategory: (in category 'instance creation') -----
+ newOnClass: aClass messageCategory: aCategory
+
+ ^ self newOnClass: aClass messageCategory: aCategory editString: nil label: 'Message Category Browser (' , aClass name, ')'.!
Item was added:
+ ----- Method: Browser class>>newOnClass:messageCategory:editString:label: (in category 'instance creation') -----
+ newOnClass: aClass messageCategory: aCategory editString: aString label: aLabel
+ "Open a new message protocol browser on this class & protocol with aString pre-selected in the code pane.
+ We have to be a bit sneaky to do the string insertion since it cannot be handled until after the actual browser is built and opened"
+
+ ^self newOnClass: aClass messageCategory: aCategory selector: nil editString: aString label: aLabel!
Item was added:
+ ----- Method: Browser class>>newOnClass:messageCategory:selector:editString:label: (in category 'instance creation') -----
+ newOnClass: aClass messageCategory: aCategory selector: aSelector editString: aString label: aLabel
+ "Open a new message protocol browser on this class & protocol with aString pre-selected in the code pane.
+ We have to be a bit sneaky to do the string insertion since it cannot be handled until after the actual browser is built and opened"
+ "Browser newOnClass: Browser messageCategory: 'controls' selector: #decorateButtons editString: 'test string edit setup' label: 'Testing class browser with set edit string'"
+ | newBrowser|
+
+ newBrowser := self new.
+ "setting up a new browser for a specific class, category and selector requires this order of messages
+ since the #selectMessageCategoryNamed: carefully nils the chosen selector; thus we can't use
+ the more obvious seeming #setClass:selector: method"
+ newBrowser setClass: aClass;
+ selectMessageCategoryNamed: aCategory;
+ selectMessageNamed: aSelector.
+
+ newBrowser buildAndOpenMessageCategoryBrowserLabel: 'Message Category Browser (' , aClass name, ')'.
+ aString ifNotNil:[newBrowser changed: #editString with: aString].
+ ^newBrowser!
Item was changed:
----- Method: Browser class>>newOnClass:selector: (in category 'instance creation') -----
newOnClass: aClass selector: aSymbol
"Open a new class browser on this class."
+ "Browser newOnClass: Browser selector: #decorateButtons"
| newBrowser |
newBrowser := self new.
newBrowser setClass: aClass selector: aSymbol.
+ ^ newBrowser buildAndOpenClassBrowserLabel: 'Class Browser: ', aClass name
- ^ self
- openBrowserView: (newBrowser openOnClassWithEditString: nil)
- label: 'Class Browser: ', aClass name
!
Item was removed:
- ----- Method: Browser class>>newOnMessageCategory:inClass: (in category 'instance creation') -----
- newOnMessageCategory: aCategory inClass: aClass
-
- ^ self
- openBrowserView: (self new
- setClass: aClass;
- selectMessageCategoryNamed: aCategory;
- openMessageCatEditString: nil)
- label: 'Message Category Browser (' , aClass name, ')'.!
Item was changed:
----- Method: Browser class>>openBrowser (in category 'instance creation') -----
openBrowser
+ "Open a standard system browser with the generic category/class/protocol/message lists"
+ "Browser openBrowser"
- "Create and schedule a BrowserView with default browser label. The
- view consists of five subviews, starting with the list view of system
- categories of SystemOrganization. The initial text view part is empty."
+ ^ self new buildAndOpenFullBrowser
- | br |
- br := self new.
- ^ self
- openBrowserView: (br openEditString: nil)
- label: br defaultBrowserTitle.
!
Item was removed:
- ----- Method: Browser class>>openBrowserView:label: (in category 'instance creation') -----
- openBrowserView: aBrowserView label: aString
- "Schedule aBrowserView, labelling the view aString."
-
- (aBrowserView isKindOf: ToolBuilderSpec)
- ifTrue:[
- (self canUseMultiWindowBrowsers
- and: [self useMultiWindowBrowsers])
- ifTrue: [aBrowserView multiWindowStyle: #labelButton].
- aString
- ifNil: [ToolBuilder open: aBrowserView]
- ifNotNil: [ToolBuilder open: aBrowserView label: aString]]
- ifFalse:[
- aBrowserView isMorph
- ifTrue: [
- aString ifNotNil: [aBrowserView setLabel: aString].
- aBrowserView openInWorld]
- ifFalse: [
- aString ifNotNil: [aBrowserView label: aString].
- aBrowserView minimumSize: 300 @ 200.
- aBrowserView subViews do: [:each | each controller].
- aBrowserView controller open]].
-
- ^ aBrowserView model
- !
Item was changed:
----- Method: Browser class>>prototypicalToolWindow (in category 'instance creation') -----
prototypicalToolWindow
"Answer an example of myself seen in a tool window, for the benefit of parts-launching tools"
+ ^ ToolBuilder default build: self !
- | aWindow |
- aWindow := self new openEditString: nil.
- ^ ToolBuilder build: aWindow!
Item was changed:
----- Method: Browser>>browseAllClasses (in category 'system category functions') -----
browseAllClasses
"Create and schedule a new browser on all classes alphabetically."
+
+ ^ClassListBrowser newOnAllClasses!
- | newBrowser |
- newBrowser := HierarchyBrowser new initAlphabeticListing.
- self class openBrowserView: (newBrowser openSystemCatEditString: nil)
- label: 'All Classes Alphabetically'!
Item was added:
+ ----- Method: Browser>>buildAndOpenCategoryBrowser (in category 'toolbuilder') -----
+ buildAndOpenCategoryBrowser
+ "assemble the spec for a system category browser, build it and open it - use the default label"
+
+ ^self buildAndOpenCategoryBrowserLabel: nil
+ !
Item was added:
+ ----- Method: Browser>>buildAndOpenCategoryBrowserLabel: (in category 'toolbuilder') -----
+ buildAndOpenCategoryBrowserLabel: aLabelString
+ "assemble the spec for a system category browser, build it and open it"
+
+ | builder windowSpec |
+ builder := ToolBuilder default.
+
+ windowSpec := self buildCategoryBrowserWith: builder.
+ aLabelString ifNotNil:[:str| windowSpec label: str].
+
+ builder open: windowSpec.
+
+ ^self
+ !
Item was added:
+ ----- Method: Browser>>buildAndOpenClassBrowserLabel: (in category 'toolbuilder') -----
+ buildAndOpenClassBrowserLabel: aLabelString
+ "assemble the spec for a class browser, build it and open it"
+
+ | builder max windowSpec catPaneHeight|
+ builder := ToolBuilder default.
+ catPaneHeight := Preferences standardListFont height + 5 "top margin/border" + 5 "bottom margin/border".
+ max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
+
+ windowSpec :=self buildWindowWith: builder specs: {
+ (self topConstantHeightFrame: self buttonHeight fromLeft: 0 width: 0.5) -> [self buildClassListSingletonWith: builder].
+ (self frameOffsetFromTop: self buttonHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildMessageCategoryListWith: builder].
+ (self topConstantHeightFrame: self buttonHeight fromLeft: 0.5 width: 0.5) -> [self buildSwitchesWith: builder].
+ (self frameOffsetFromTop: self buttonHeight fromLeft: 0.5 width: 0.5 bottomFraction: max) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+ windowSpec label: aLabelString.
+
+ builder open: windowSpec.
+
+ ^self
+ !
Item was added:
+ ----- Method: Browser>>buildAndOpenFullBrowser (in category 'toolbuilder') -----
+ buildAndOpenFullBrowser
+ "assemble the spec for a full system browser, build it and open it"
+
+ | builder windowSpec |
+ builder := ToolBuilder default.
+
+ "the build-but-don't-open phase is factored out to support the prototypicalToolWindow facility"
+ windowSpec := self buildDefaultBrowserWith: builder.
+ builder open: windowSpec.
+
+ ^self
+ !
Item was added:
+ ----- Method: Browser>>buildAndOpenMessageCategoryBrowserLabel: (in category 'toolbuilder') -----
+ buildAndOpenMessageCategoryBrowserLabel: aLabelString
+ "assemble the spec for a messasge category browser, build it and open it"
+
+ | builder max windowSpec|
+ builder := ToolBuilder default.
+ max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
+
+ windowSpec :=self buildWindowWith: builder specs: {
+ (0@0 corner: 1.0(a)0.08) -> [self buildMessageListCatSingletonWith: builder].
+ (0.0(a)0.08 corner: 1.0@max) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+ windowSpec label: aLabelString.
+
+ builder open: windowSpec.
+
+ ^self
+ !
Item was added:
+ ----- Method: Browser>>buildCategoryBrowserWith: (in category 'toolbuilder') -----
+ buildCategoryBrowserWith: builder
+ "assemble the spec for a system category browser, build it and return it"
+
+ | max windowSpec catPaneHeight|
+ catPaneHeight := Preferences standardListFont height + 5 "top margin/border" + 5 "bottom margin/border".
+ max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
+
+ windowSpec := self buildWindowWith: builder specs: {
+ (LayoutFrame fractions: (0@0 corner: 1.0@0) offsets: (0@0 corner: 0@catPaneHeight)) -> [self buildSystemCatListSingletonWith: builder].
+ ((self classListFrame: max fromTop: 0 fromLeft: 0 width: 0.333)
+ topOffset: catPaneHeight) -> [self buildClassListWith: builder].
+ (self switchesFrame: max fromLeft: 0 width: 0.333) -> [self buildSwitchesWith: builder].
+ (LayoutFrame fractions: (0.333@0 corner: 0.666@max) offsets: (0@catPaneHeight corner: 0@0)) -> [self buildMessageCategoryListWith: builder].
+ (LayoutFrame fractions: (0.666@0 corner: 1@max) offsets: (0@catPaneHeight corner: 0@0)) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+
+ ^builder build: windowSpec
+ !
Item was added:
+ ----- Method: Browser>>buildDefaultBrowserWith: (in category 'toolbuilder') -----
+ buildDefaultBrowserWith: builder
+ "assemble the spec for a full system browser, build it and return the built but not opened morph"
+ "this build-but-don't-open phase is factored out to support the prototypicalToolWindow facility"
+
+ | max windowSpec |
+ max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5].
+
+ windowSpec := self buildWindowWith: builder specs: {
+ (0@0 corner: 0.25@max) -> [self buildSystemCategoryListWith: builder].
+ (self classListFrame: max) -> [self buildClassListWith: builder].
+ (self switchesFrame: max) -> [self buildSwitchesWith: builder].
+ (0.5@0 corner: 0.75@max) -> [self buildMessageCategoryListWith: builder].
+ (0.75@0 corner: 1@max) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+
+ ^builder build: windowSpec!
Item was changed:
----- Method: Browser>>buildMessageCategoryBrowserEditString: (in category 'message category functions') -----
buildMessageCategoryBrowserEditString: aString
+ "Create and schedule a new class browser for the current selection,
+ with initial textual contents set to aString. This is used specifically in
+ spawning where a class is established but a method-category is not."
+ ^ self hasMessageCategorySelected ifTrue: [Browser
+ newOnClass: self selectedClassOrMetaClass
+ messageCategory: self selectedMessageCategoryName
+ selector: self selectedMessageName
+ editString: aString
+ label: 'Message category Browser: ' , self selectedClassOrMetaClass name , self categoryOfCurrentMethod]!
- "Create and schedule a message category browser for the currently
- selected message category. The initial text view contains the characters
- in aString."
-
- ^ self hasMessageCategorySelected ifTrue: [
- (self class
- newOnMessageCategory: self selectedMessageCategoryName
- inClass: self selectedClassOrMetaClass)
- "Select my message."
- selectMessageNamed: self selectedMessageName;
- yourself]!
Item was changed:
----- Method: Browser>>buildSystemCategoryBrowser (in category 'system category functions') -----
buildSystemCategoryBrowser
+ "Open a new system category browser on the selelcted category, if there is one"
- "Create and schedule a new system category browser."
+ self hasSystemCategorySelected
+ ifTrue:
+ [self class newOnCategory: self selectedSystemCategory]!
- self buildSystemCategoryBrowserEditString: nil!
Item was changed:
----- Method: Browser>>buildSystemCategoryBrowserEditString: (in category 'system category functions') -----
buildSystemCategoryBrowserEditString: aString
+ "Open a new system category browser on the selelcted category, if
+ there is one"
- "Create and schedule a new system category browser with initial textual
- contents set to aString."
-
- | newBrowser |
self hasSystemCategorySelected
+ ifTrue: [self class
+ newOnCategory: self selectedSystemCategory
+ editString: aString
+ label: 'Classes in category ' , self selectedSystemCategory]!
- ifTrue:
- [newBrowser := self class new.
- newBrowser selectSystemCategory: self selectedSystemCategory.
- newBrowser setClass: self selectedClassOrMetaClass selector: self selectedMessageName.
- self class openBrowserView: (newBrowser openSystemCatEditString: aString)
- label: 'Classes in category ', newBrowser selectedSystemCategory]!
Item was changed:
----- Method: Browser>>buildWith: (in category 'toolbuilder') -----
buildWith: builder
"Create the ui for the browser"
+ "Browser is a bit of an oddity in the ToolBuilder>build: world since the class provides several dfferent UIs rather than the one-per-class idiom of ToolBuilder. Here we are building the full browser version"
+
+ ^self buildDefaultBrowserWith: builder !
- | windowSpec max |
- max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5].
- windowSpec := self buildWindowWith: builder specs: {
- (0@0 corner: 0.25@max) -> [self buildSystemCategoryListWith: builder].
- (self classListFrame: max fromLeft: 0.25 width: 0.25) -> [self buildClassListWith: builder].
- (self switchesFrame: max fromLeft: 0.25 width: 0.25) -> [self buildSwitchesWith: builder].
- (0.5@0 corner: 0.75@max) -> [self buildMessageCategoryListWith: builder].
- (0.75@0 corner: 1@max) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }.
- ^builder build: windowSpec!
Item was removed:
- ----- Method: Browser>>openEditString: (in category 'initialize-release') -----
- openEditString: aString
- "Create a pluggable version of all the views for a Browser, including views and controllers."
- "Example:
- Browser fullOnClass: Browser.
- "
- | builder max |
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5].
- ^self buildWindowWith: builder specs: {
- (0@0 corner: 0.25@max) -> [self buildSystemCategoryListWith: builder].
- (self classListFrame: max) -> [self buildClassListWith: builder].
- (self switchesFrame: max) -> [self buildSwitchesWith: builder].
- (0.5@0 corner: 0.75@max) -> [self buildMessageCategoryListWith: builder].
- (0.75@0 corner: 1@max) -> [self buildMessageListWith: builder].
- "(0@max corner: 1(a)0.5) -> [self buildOptionalButtonsWith: builder]."
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }!
Item was removed:
- ----- Method: Browser>>openMessageCatEditString: (in category 'initialize-release') -----
- openMessageCatEditString: aString
- "Create a pluggable version of the views for a Browser that just shows one message category."
- "Example:
- Preferences browseThemes.
- "
- | builder max |
- aString ifNotNil:[
- "Note: The views aren't actually built yet after we've called buildWindowWith:.
- Since we can't send changed: #editString before the views have been built
- we just shoot the #changed: message into the #future. This is the easiest
- way to solve this issue locally."
- self future changed: #editString with: aString].
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
- ^self buildWindowWith: builder specs: {
- (0@0 corner: 1.0(a)0.08) -> [self buildMessageListCatSingletonWith: builder].
- (0.0(a)0.08 corner: 1.0@max) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }.!
Item was removed:
- ----- Method: Browser>>openOnClassWithEditString: (in category 'initialize-release') -----
- openOnClassWithEditString: aString
- "Create a pluggable version of all the views for a Browser, including views and controllers."
- "Example:
- Browser newOnClass: Browser.
- "
- | builder max |
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
- ^self buildWindowWith: builder specs: {
- (self topConstantHeightFrame: self buttonHeight fromLeft: 0 width: 0.5) -> [self buildClassListSingletonWith: builder].
- (self frameOffsetFromTop: self buttonHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildMessageCategoryListWith: builder].
- (self topConstantHeightFrame: self buttonHeight fromLeft: 0.5 width: 0.5) -> [self buildSwitchesWith: builder].
- (self frameOffsetFromTop: self buttonHeight fromLeft: 0.5 width: 0.5 bottomFraction: max) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }
- !
Item was removed:
- ----- Method: Browser>>openSystemCatEditString: (in category 'initialize-release') -----
- openSystemCatEditString: aString
- "Create a pluggable version of all the views for a Browser, including views and controllers. The top list view is of the currently selected system class category--a single item list."
- "Example:
- Browser new browseAllClasses.
- "
- | builder catPaneHeight max |
- catPaneHeight := Preferences standardListFont height + 5 "top margin/border" + 5 "bottom margin/border".
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
- ^self buildWindowWith: builder specs: {
- (LayoutFrame fractions: (0@0 corner: 1.0@0) offsets: (0@0 corner: 0@catPaneHeight)) -> [self buildSystemCatListSingletonWith: builder].
- ((self classListFrame: max fromTop: 0 fromLeft: 0 width: 0.333)
- topOffset: catPaneHeight) -> [self buildClassListWith: builder].
- (self switchesFrame: max fromLeft: 0 width: 0.333) -> [self buildSwitchesWith: builder].
- (LayoutFrame fractions: (0.333@0 corner: 0.666@max) offsets: (0@catPaneHeight corner: 0@0)) -> [self buildMessageCategoryListWith: builder].
- (LayoutFrame fractions: (0.666@0 corner: 1@max) offsets: (0@catPaneHeight corner: 0@0)) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }!
Item was added:
+ ----- Method: Browser>>setMultiWindowFor: (in category 'toolbuilder') -----
+ setMultiWindowFor: windowSpec
+ "set the multi-window style for the windowSpec according to both the users preference and the browser's ability"
+ (self class canUseMultiWindowBrowsers and: [self class useMultiWindowBrowsers])
+ ifTrue: [windowSpec multiWindowStyle: #labelButton].
+
+ !
Item was changed:
----- Method: Browser>>setSelector: (in category 'initialize-release') -----
setSelector: aSymbol
+ "Make the receiver point at the given selector, in the currently chosen class. If the selector is found in the class organization we also set the message category to suit"
- "Make the receiver point at the given selector, in the currently chosen class"
| aClass |
aSymbol ifNil: [^ self].
(aClass := self selectedClassOrMetaClass) ifNil: [^ self].
(aClass organization categoryOfElement: aSymbol)
ifNil: [^ self]
ifNotNil: [:category |
self
selectMessageCategoryNamed: category;
selectMessageNamed: aSymbol].!
Item was changed:
----- Method: Browser>>spawn: (in category 'accessing') -----
spawn: aString
"Create and schedule a fresh browser and place aString in its code pane. This method is called when the user issues the #spawn command (cmd-o) in any code pane. Whatever text was in the original code pane comes in to this method as the aString argument; the changes in the original code pane have already been cancelled by the time this method is called, so aString is the only copy of what the user had in his code pane."
self selectedClassOrMetaClass ifNotNil: [^ super spawn: aString].
self hasSystemCategorySelected ifTrue:
+ ["Open a browser with the initial codepane string set"
- ["This choice is slightly useless but is the historical implementation"
^ self buildSystemCategoryBrowserEditString: aString].
^ super spawn: aString
"This bail-out at least saves the text being spawned, which would otherwise be lost"!
Item was changed:
HierarchyBrowser subclass: #ClassListBrowser
instanceVariableNames: 'defaultTitle'
classVariableNames: ''
poolDictionaries: ''
category: 'Tools-Browser'!
+ !ClassListBrowser commentStamp: 'tpr 10/15/2017 16:46' prior: 0!
- !ClassListBrowser commentStamp: '<historical>' prior: 0!
A ClassListBrowser displays the code for an arbitrary list of classes.
ClassListBrowser example1. "all classes that have the string 'Pluggable' in their names"
ClassListBrowser example2. "all classes whose names start with the letter S"
ClassListBrowser example3. "all variable classes"
ClassListBrowser example4. "all classes with more than 100 methods"
ClassListBrowser example5. "all classes that lack class comments"
ClassListBrowser example6. "all classes that have class instance variables"
+ ClassListBrowser newOnClassesNamed: #(Browser Boolean) label: 'Browser and Boolean!!'.
+ ClassListBrowser newOnAllClasses "all classes listed alphabetically"
- ClassListBrowser new initForClassesNamed: #(Browser Boolean) title: 'Browser and Boolean!!'.
!
Item was changed:
----- Method: ClassListBrowser class>>browseClassesSatisfying:title: (in category 'instance creation') -----
browseClassesSatisfying: classBlock title: aTitle
"Put up a ClassListBrowser showing all classes that satisfy the classBlock."
+ self newOnClassesNamed:
+ (self systemNavigation allClasses select: [:c | (classBlock value: c) == true]
+ thenCollect: [:c | c name])
+ label: aTitle!
- self new
- initForClassesNamed:
- (self systemNavigation allClasses select:
- [:c | (classBlock value: c) == true]
- thenCollect:
- [:c | c name])
- title:
- aTitle!
Item was changed:
----- Method: ClassListBrowser class>>example2 (in category 'examples') -----
example2
"Put up a ClassListBrowser that shows all classes whose names start with
the letter S"
+ self newOnClassesNamed: (self systemNavigation allClasses
- self new
- initForClassesNamed: (self systemNavigation allClasses
collect: [:c | c name]
thenSelect: [:aName | aName first == $S])
+ label: 'All classes starting with S'
- title: 'All classes starting with S'
"ClassListBrowser example2"!
Item was added:
+ ----- Method: ClassListBrowser class>>newOnAllClasses (in category 'instance creation') -----
+ newOnAllClasses
+ "Open a browser on all the classes in the system, listed alphabetically"
+ "NB - what meaning does 'all classes' have in an environment that is not the root?
+ - what might alphabetic ordering need to do for non-latin languages?"
+ "ClassListBrowser newOnAllClasses"
+
+ | newBrowser |
+
+ newBrowser := self new.
+ ^ newBrowser buildAndOpenBrowserLabel: 'All Classes Alphabetically'
+ !
Item was added:
+ ----- Method: ClassListBrowser class>>newOnClassesNamed:label: (in category 'instance creation') -----
+ newOnClassesNamed: aListOfClassNames label: aString
+ "Open a browser on all the classes in the list, set the label to aString since we may need to specify to the user what the list includes"
+ "ClassListBrowser newOnClassesNamed: #(Browser Boolean) label: 'Browser and Boolean!!'."
+ | newBrowser |
+
+ newBrowser := self new.
+ newBrowser initForClassesNamed: aListOfClassNames.
+ ^ newBrowser buildAndOpenBrowserLabel: aString
+ !
Item was added:
+ ----- Method: ClassListBrowser>>defaultBrowserTitle (in category 'initialization') -----
+ defaultBrowserTitle
+ ^ 'Class List Browser' !
Item was added:
+ ----- Method: ClassListBrowser>>initAlphabeticListing (in category 'initialization') -----
+ initAlphabeticListing
+ | tab stab index |
+ self systemOrganizer: SystemOrganization.
+ metaClassIndicated := false.
+ classDisplayList := Smalltalk classNames.!
Item was added:
+ ----- Method: ClassListBrowser>>initForClassesNamed: (in category 'initialization') -----
+ initForClassesNamed: nameList
+ "Initialize the receiver for the class-name-list"
+
+ self systemOrganizer: SystemOrganization.
+ metaClassIndicated := false.
+ classDisplayList := nameList copy!
Item was removed:
- ----- Method: ClassListBrowser>>initForClassesNamed:title: (in category 'initialization') -----
- initForClassesNamed: nameList title: aTitle
- "Initialize the receiver for the class-name-list and title provided"
-
- self systemOrganizer: SystemOrganization.
- metaClassIndicated := false.
- defaultTitle := aTitle.
- classDisplayList := nameList copy.
- self class openBrowserView: (self openSystemCatEditString: nil)
- label: aTitle
-
- "ClassListBrowser new initForClassesNamed: #(Browser CategoryViewer) title: 'Frogs'"!
Item was added:
+ ----- Method: ClassListBrowser>>setupIfNotInitialisedYet (in category 'toolbuilder') -----
+ setupIfNotInitialisedYet
+ "ClassListBrowser needs some initialisation to work in the ToolBuilder>build: world since there has to be a list of classes ready to be listed. As a default we use the full list of classes in the system"
+
+ classDisplayList ifNil:[self initAlphabeticListing]!
Item was changed:
----- Method: CodeHolder>>buildClassBrowserEditString: (in category 'construction') -----
buildClassBrowserEditString: aString
"Create and schedule a new class browser for the current selection, with initial textual contents set to aString. This is used specifically in spawning where a class is established but a method-category is not."
+ ^Browser newOnClass: self selectedClassOrMetaClass editString: aString label: 'Class Browser: ', self selectedClassOrMetaClass name
- | newBrowser |
- newBrowser := Browser new.
- newBrowser setClass: self selectedClassOrMetaClass selector: nil.
- newBrowser editSelection: #newMessage.
- Browser openBrowserView: (newBrowser openOnClassWithEditString: aString)
- label: 'Class Browser: ', self selectedClassOrMetaClass name
!
Item was added:
+ ----- Method: CodeHolder>>buildMessageBrowserEditString: (in category 'construction') -----
+ buildMessageBrowserEditString: aString
+ "Create and schedule a new message browser for the current selection,
+ with initial textual contents set to aString."
+ ^ Browser
+ newOnClass: self selectedClassOrMetaClass
+ messageCategory: self categoryOfCurrentMethod
+ selector: self selectedMessageName
+ editString: aString
+ label: 'Message Browser: ' , self selectedClassOrMetaClass name , self categoryOfCurrentMethod!
Item was added:
+ ----- Method: CodeHolder>>buildMessageCategoryBrowserForClass:selector:editString: (in category 'construction') -----
+ buildMessageCategoryBrowserForClass: aClass selector: aSelectorOrNil editString: aString
+ "Create and schedule a new class browser for the current selection,
+ with initial textual contents set to aString. This is used specifically in
+ spawning where a class is established but a method-category is not."
+ ^ Browser
+ newOnClass: aClass
+ messageCategory: self categoryOfCurrentMethod
+ selector: aSelectorOrNil
+ editString: aString
+ label: 'Message category Browser: ' , self selectedClassOrMetaClass name , self categoryOfCurrentMethod!
Item was changed:
----- Method: CodeHolder>>spawn: (in category 'commands') -----
spawn: aString
"Create and schedule a spawned message category browser for the currently selected message category. The initial text view contains the characters in aString. In the spawned browser, preselect the current selector (if any) as the going-in assumption, though upon acceptance this will often change"
+ | aCategory aClass |
- | newBrowser aCategory aClass |
(aClass := self selectedClassOrMetaClass) isNil ifTrue:
[^ aString isEmptyOrNil ifFalse: [(Workspace new contents: aString) openLabel: 'spawned workspace']].
(aCategory := self categoryOfCurrentMethod)
ifNil:
[self buildClassBrowserEditString: aString]
ifNotNil:
+ [self buildMessageCategoryBrowserForClass: aClass selector: self selectedMessageName editString: aString ]!
- [newBrowser := Browser new setClass: aClass selector: self selectedMessageName.
- self suggestCategoryToSpawnedBrowser: newBrowser.
- ^ Browser openBrowserView: (newBrowser openMessageCatEditString: aString)
- label: 'category "', aCategory, '" in ',
- newBrowser selectedClassOrMetaClassName]!
Item was changed:
----- Method: CodeHolder>>spawnToClass: (in category 'commands') -----
spawnToClass: aClass
"Used to copy down code from a superclass to a subclass in one easy step, if you know what you're doing. Spawns a new message-category browser for the indicated class, populating it with the source code seen in the current tool."
+ self categoryOfCurrentMethod
- | aCategory newBrowser org |
- (aCategory := self categoryOfCurrentMethod)
ifNil:
[self buildClassBrowserEditString: self contents]
ifNotNil:
+ [self buildMessageCategoryBrowserForClass: aClass selector: nil editString: self contents]!
- [((org := aClass organization) categories includes: aCategory)
- ifFalse: [org addCategory: aCategory].
- newBrowser := Browser new setClass: aClass selector: nil.
- newBrowser selectMessageCategoryNamed: aCategory.
- Browser openBrowserView: (newBrowser openMessageCatEditString: self contents)
- label: 'category "', aCategory, '" in ',
- newBrowser selectedClassOrMetaClassName]!
Item was changed:
----- Method: FileContentsBrowser class>>browseFiles: (in category 'instance creation') -----
browseFiles: fileList
+ "Open a browser on the packages found within the files in the list; we expect the list to contain acceptable filename strings.
+ If there is more than one package found the browser will be a full system browser, otherwise it will be a category browser"
-
| browser |
Cursor wait showWhile: [ | organizer packageDict |
packageDict := Dictionary new.
organizer := SystemOrganizer defaultList: Array new.
fileList do: [:fileName | | package |
package := FilePackage fromFileNamed: fileName.
packageDict
at: package packageName
put: package.
organizer
classifyAll: package classes keys
under: package packageName].
(browser := self systemOrganizer: organizer)
packages: packageDict].
+ ^ browser buildAndOpenBrowser
- self
- openBrowserView: browser createViews
- label: 'File Contents Browser'.
!
Item was changed:
----- Method: FileContentsBrowser class>>browseStream: (in category 'instance creation') -----
browseStream: aStream
+
+ aStream setConverterForCode.
- aStream setConverterForCode.
self browseStream: aStream named: aStream name!
Item was changed:
----- Method: FileContentsBrowser class>>browseStream:named: (in category 'instance creation') -----
browseStream: aStream named: aString
+ "Read an already opened file stream into a browser"
-
| browser |
Cursor wait showWhile: [ | package packageDict organizer |
packageDict := Dictionary new.
browser := self new.
organizer := SystemOrganizer defaultList: Array new.
package := (FilePackage new fullName: aString; fileInFrom: aStream).
packageDict
at: package packageName
put: package.
organizer
classifyAll: package classes keys
under: package packageName.
(browser := self systemOrganizer: organizer)
packages: packageDict].
+ ^ browser buildAndOpenBrowser
- self
- openBrowserView: browser createViews
- label: 'File Contents Browser'.
!
Item was added:
+ ----- Method: FileContentsBrowser>>buildAndOpenBrowser (in category 'toolbuilder') -----
+ buildAndOpenBrowser
+ "assemble the spec for a file contents browser, build it and open it"
+ "The browser may have either the full 4-pane layout or the simpler 3-pane version, depending on whether we have 1 or more packages to look at"
+
+ contentsSymbol := self defaultDiffsSymbol. "#showDiffs or #prettyDiffs"
+
+ ^ self packages size = 1
+ ifTrue:[
+ self systemCategoryListIndex: 1.
+ self buildAndOpenCategoryBrowser]
+ ifFalse: [self buildAndOpenFullBrowser]!
Item was changed:
----- Method: FileContentsBrowser>>buildWith: (in category 'toolbuilder') -----
buildWith: builder
+ "Depending upon whether we have a single package or multiple packages, we use different window specs. "
+ self packages ifNil:[^self error: self class name, ' cannot be built without any packages; see class instance creation methods' ].
^ self packages size = 1
ifTrue:[
+ self systemCategoryListIndex: 1;
+ buildCategoryBrowserWith: builder]
- self systemCategoryListIndex: 1.
- self openSystemCatEditString: '']
ifFalse: [super buildWith: builder]!
Item was removed:
- ----- Method: FileContentsBrowser>>createViews (in category 'creation') -----
- createViews
- "Create a pluggable version of all the views for a Browser, including views and controllers."
- contentsSymbol := self defaultDiffsSymbol. "#showDiffs or #prettyDiffs"
- ^self buildWith: ToolBuilder default!
Item was changed:
+ ----- Method: FileContentsBrowser>>defaultBrowserTitle (in category 'toolbuilder') -----
- ----- Method: FileContentsBrowser>>defaultBrowserTitle (in category 'initialize-release') -----
defaultBrowserTitle
+ ^ 'File Contents Browser' !
- ^ 'File Contents Browser'!
Item was added:
+ ----- Method: HierarchyBrowser class>>openBrowser (in category 'instance creation') -----
+ openBrowser
+ "Open a default hierarchy browser on Object - ie the entire class tree, so it may take a moment - with class/protocol/message lists"
+ "HierarchyBrowser openBrowser"
+ | newBrowser |
+ newBrowser := self new initHierarchyForClass: Object.
+ ^ newBrowser buildAndOpenBrowserLabel: nil
+ !
Item was removed:
- ----- Method: HierarchyBrowser>>assureSelectionsShow (in category 'class list') -----
- assureSelectionsShow
- "This is a workaround for the fact that a hierarchy browser, when launched, often does not show the selected class"
-
- | saveMsgName saveCatName |
- saveCatName := self selectedMessageCategoryName.
- saveMsgName := self selectedMessageName.
- self selectClassNamed: selectedClassName.
- self selectMessageCategoryNamed: saveCatName.
- self selectMessageNamed: saveMsgName!
Item was added:
+ ----- Method: HierarchyBrowser>>buildAndOpenBrowserLabel: (in category 'toolbuilder') -----
+ buildAndOpenBrowserLabel: aLabelString
+ "assemble the spec for a class list/hierarchy browser, build it and open it"
+
+ | builder windowSpec |
+ builder := ToolBuilder default.
+
+ windowSpec := self buildDefaultBrowserWith: builder.
+ aLabelString ifNotNil:[:str| windowSpec label: str].
+
+ builder open: windowSpec.
+
+ ^self
+ !
Item was changed:
----- Method: HierarchyBrowser>>buildClassBrowserEditString: (in category 'menu messages') -----
buildClassBrowserEditString: aString
+ "Open a hierarchy browser on the currently selected class; the string has to be ignored in this case"
- "Create and schedule a new class browser for the current selection, if one
- exists, with initial textual contents set to aString."
self spawnHierarchy!
Item was added:
+ ----- Method: HierarchyBrowser>>buildDefaultBrowserWith: (in category 'toolbuilder') -----
+ buildDefaultBrowserWith: builder
+ "assemble the spec for a hierarchical browser, build it and return the built but not opened morph"
+ "this build-but-don't-open phase is factored out to support the prototypicalToolWindow facility"
+
+ | max windowSpec |
+
+
+ self setupIfNotInitialisedYet.
+ max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
+
+ windowSpec := self buildWindowWith: builder specs: {
+ (self classListFrame: max fromTop: 0 fromLeft: 0 width: 0.333) -> [self buildClassListWith: builder].
+ (self switchesFrame: max fromLeft: 0 width: 0.333) -> [self buildSwitchesWith: builder].
+ (LayoutFrame fractions: (0.333@0 corner: 0.666@max) offsets: (0@0 corner: 0@0)) -> [self buildMessageCategoryListWith: builder].
+ (LayoutFrame fractions: (0.666@0 corner: 1@max) offsets: (0@0 corner: 0@0)) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+
+ ^builder build: windowSpec!
Item was removed:
- ----- Method: HierarchyBrowser>>buildWith: (in category 'toolbuilder') -----
- buildWith: builder
- ^builder build: (self openSystemCatEditString: '')!
Item was changed:
----- Method: HierarchyBrowser>>classList (in category 'class list') -----
classList
+ "each time we update the class list make sure to check that all the classes we think we should display are in fact in the environment"
classDisplayList := classDisplayList select: [:each | (self environment valueOf: each withBlanksTrimmed asSymbol) notNil].
^ classDisplayList!
Item was removed:
- ----- Method: HierarchyBrowser>>initAlphabeticListing (in category 'initialization') -----
- initAlphabeticListing
- | tab stab index |
- self systemOrganizer: SystemOrganization.
- metaClassIndicated := false.
- classDisplayList := Smalltalk classNames.!
Item was changed:
----- Method: HierarchyBrowser>>isHierarchy (in category 'multi-window support') -----
isHierarchy
+ "This almost certainly needs implementing in ClassListBrowser to return false"
^true!
Item was removed:
- ----- Method: HierarchyBrowser>>openEditString: (in category 'initialization') -----
- openEditString: aString
- "Create a pluggable version of all the views for a HierarchyBrowser, including views and controllers. The top list view is of the currently selected system class category--a single item list."
-
- ^ self openSystemCatEditString: aString!
Item was removed:
- ----- Method: HierarchyBrowser>>openSystemCatEditString: (in category 'toolbuilder') -----
- openSystemCatEditString: aString
- "Create a pluggable version of all the views for a Browser, including views and controllers. The top list view is of the currently selected system class category--a single item list."
- "Example:
- Browser new browseAllClasses.
- "
- | builder catPaneHeight max |
- catPaneHeight := Preferences standardListFont height + 5 "top margin/border" + 5 "bottom margin/border".
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.32] ifFalse:[0.4].
- ^self buildWindowWith: builder specs: {
- (self classListFrame: max fromTop: 0 fromLeft: 0 width: 0.333) -> [self buildClassListWith: builder].
- (self switchesFrame: max fromLeft: 0 width: 0.333) -> [self buildSwitchesWith: builder].
- (LayoutFrame fractions: (0.333@0 corner: 0.666@max) offsets: (0@0 corner: 0@0)) -> [self buildMessageCategoryListWith: builder].
- (LayoutFrame fractions: (0.666@0 corner: 1@max) offsets: (0@0 corner: 0@0)) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }!
Item was added:
+ ----- Method: HierarchyBrowser>>setupIfNotInitialisedYet (in category 'toolbuilder') -----
+ setupIfNotInitialisedYet
+ "HierarchyBrowser needs some initialisation to work in the ToolBuilder>build: world since there has to be a list of classes ready to be listed. As a default we use the full Object class tree"
+ classDisplayList ifNil:[ self initHierarchyForClass: Object]!
Item was changed:
----- Method: HierarchyBrowser>>systemCatSingletonKey:from: (in category 'menu messages') -----
systemCatSingletonKey: aChar from: aView
+ "This appears to be obsolete now that the hierarchybrowser has not category view"
^ self systemCatListKey: aChar from: aView!
Item was changed:
----- Method: HierarchyBrowser>>systemCatSingletonMenu: (in category 'menu messages') -----
systemCatSingletonMenu: aMenu
+ "This appears to be obsolete now that the hierarchybrowser has not category view"
-
^ aMenu labels:
'find class... (f)
browse
printOut
fileOut
update
rename...
remove'
lines: #(1 4)
selections:
#(findClass buildSystemCategoryBrowser
printOutSystemCategory fileOutSystemCategory updateSystemCategories
renameSystemCategory removeSystemCategory )
!
Item was removed:
- ----- Method: PackagePaneBrowser class>>prototypicalToolWindow (in category 'instance creation') -----
- prototypicalToolWindow
- "Answer an example of myself seen in a tool window, for the benefit of parts-launching tools"
-
- | aWindow |
- aWindow := self new openEditString: nil.
- ^ ToolBuilder build: aWindow!
Item was added:
+ ----- Method: PackagePaneBrowser>>buildDefaultBrowserWith: (in category 'toolbuilder') -----
+ buildDefaultBrowserWith: builder
+ "assemble the spec for a full 5-pane browser - package, category, class, protocol & message lists, build it and return the built but not opened morph.
+ the build-but-don't-open phase is factored out to support the prototypicalToolWindow facility"
+
+ "PackagePaneBrowser fullOnClass: Browser."
+
+ | max windowSpec |
+ max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5].
+ windowSpec := self buildWindowWith: builder specs: {
+ (0@0 corner: 0.15@max) -> [self buildPackageListWith: builder].
+ (0.15@0 corner: 0.35@max) -> [self buildSystemCategoryListWith: builder].
+ (self classListFrame: max fromLeft: 0.35 width: 0.25) -> [self buildClassListWith: builder].
+ (self switchesFrame: max fromLeft: 0.35 width: 0.25) -> [self buildSwitchesWith: builder].
+ (0.6@0 corner: 0.75@max) -> [self buildMessageCategoryListWith: builder].
+ (0.75@0 corner: 1@max) -> [self buildMessageListWith: builder].
+ (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
+ }.
+ self setMultiWindowFor:windowSpec.
+
+ ^builder build: windowSpec!
Item was changed:
+ ----- Method: PackagePaneBrowser>>buildPackageListWith: (in category 'toolbuilder') -----
- ----- Method: PackagePaneBrowser>>buildPackageListWith: (in category 'initialize-release') -----
buildPackageListWith: builder
| listSpec |
listSpec := builder pluggableListSpec new.
listSpec
model: self;
list: #packageList;
getIndex: #packageListIndex;
setIndex: #packageListIndex:;
menu: #packageMenu:;
keyPress: #packageListKey:from:.
^listSpec
!
Item was removed:
- ----- Method: PackagePaneBrowser>>openEditString: (in category 'initialize-release') -----
- openEditString: aString
- "Create a pluggable version of all the views for a Browser, including views and controllers."
- "Example:
- PackagePaneBrowser fullOnClass: Browser.
- "
- | builder max |
- builder := ToolBuilder default.
- max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5].
- ^self buildWindowWith: builder specs: {
- (0@0 corner: 0.15@max) -> [self buildPackageListWith: builder].
- (0.15@0 corner: 0.35@max) -> [self buildSystemCategoryListWith: builder].
- (self classListFrame: max fromLeft: 0.35 width: 0.25) -> [self buildClassListWith: builder].
- (self switchesFrame: max fromLeft: 0.35 width: 0.25) -> [self buildSwitchesWith: builder].
- (0.6@0 corner: 0.75@max) -> [self buildMessageCategoryListWith: builder].
- (0.75@0 corner: 1@max) -> [self buildMessageListWith: builder].
- (0@max corner: 1@1) -> [self buildCodePaneWith: builder].
- }!
Item was changed:
StringHolder subclass: #SelectorBrowser
instanceVariableNames: 'selectorIndex selectorList classListIndex classList'
classVariableNames: ''
poolDictionaries: ''
category: 'Tools-Browser'!
+
+ !SelectorBrowser commentStamp: 'tpr 10/15/2017 16:42' prior: 0!
+ A SelectorBrowser is more commonly referred to as the method finder; you can enter message names or more interestingly, example inputs and results to have the system try to find plausible methods that would satisfy the parameters. See SelectorBrowser>>#byExample for much more detail.!
Item was changed:
----- Method: StandardToolSet class>>browseMessageCategory:inClass: (in category 'browsing') -----
browseMessageCategory: aCategory inClass: aClass
"Open a message category browser."
^ SystemBrowser default
+ newOnClass: aClass messageCategory: aCategory!
- newOnMessageCategory: aCategory inClass: aClass.!
Item was changed:
----- Method: StandardToolSet class>>openClassListBrowser:title: (in category 'browsing') -----
openClassListBrowser: anArray title: aString
+ "Open a class list browser on the list of classes named"
+
+ ^ClassListBrowser newOnClassesNamed: anArray label: aString
- "Open a class list browser"
- ^ClassListBrowser new initForClassesNamed: anArray title: aString
!
David T. Lewis uploaded a new version of ReleaseBuilder to project The Trunk:
http://source.squeak.org/trunk/ReleaseBuilder-dtl.170.mcz
==================== Summary ====================
Name: ReleaseBuilder-dtl.170
Author: dtl
Time: 22 October 2017, 9:19:52.093743 pm
UUID: 31532d3c-8537-4e8e-b924-e27de683d339
Ancestors: ReleaseBuilder-mt.169
Do "MCMcmUpdater clearRegistry" to clear all but the current default updater
=============== Diff against ReleaseBuilder-mt.169 ===============
Item was changed:
----- Method: ReleaseBuilder class>>prepareSourceCode (in category 'preparing') -----
prepareSourceCode
"Update code. Remove foreign packages."
MCMcmUpdater defaultUpdateURL: self buildRepository description.
MCMcmUpdater updateMissingPackages: true.
MCMcmUpdater enableUpdatesForAllPackages.
TestCase new ensureInternetConnectionTo: self buildRepository description.
"Flush all caches. If a previous download failed this is often helpful"
MCFileBasedRepository flushAllCaches.
+ "Save the current default updater, clear the registry, and re-register the current updater"
+ MCMcmUpdater clearRegistry.
+
[MCMcmUpdater default doUpdate: false. "non-interactive"]
on: MCEmptyVersion do: [:warning | warning resume].
self
unloadForeignPackages;
checkForDirtyPackages;
loadWellKnownPackages;
checkForUndeclaredSymbols.
Compiler recompileAll.!