tim Rowledge uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-tpr.773.mcz ==================== Summary ==================== Name: Tools-tpr.773 Author: tpr Time: 13 November 2017, 11:51:08.236067 am UUID: 348383f7-66f6-41a4-8cc0-60df2edc835f Ancestors: Tools-tpr.772 Updates to add use of pattern for the saver dialog (not certain that is the right way to do it), to speed up making the file list, update class comments and make sure the initial file is selected where appropriate =============== Diff against Tools-tpr.772 =============== Item was changed: Model subclass: #FileAbstractSelectionDialog instanceVariableNames: 'pattern directory directoryCache message listIndex fileName finalChoice nameList sizeList dateList' classVariableNames: '' poolDictionaries: '' category: 'Tools-FileDialogs'! + !FileAbstractSelectionDialog commentStamp: 'tpr 11/13/2017 11:08' prior: 0! - !FileAbstractSelectionDialog commentStamp: 'tpr 11/9/2017 15:37' prior: 0! FileAbstractSelectionDialog is the abstract superclass for the file chooser & saver modal dialogs. + The UI provides a message to the user, 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. - 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 that may include * or # wildcasrds. See FileAbstractSelectionDialog>>#parsePatternString for details + message: <String> a message to the user to explain what is expected + nameList,DateList, sizeList: <Array> the list of file names matching the pattern and the appropriate date and size values, formatted for a PluggableMultiColumnListMorph! - pattern: <String> the pattern is held as a string that may include * or # wildcasrds. See FileAbstractSelectionDialog>>#parsePatternString for details! Item was changed: ----- Method: FileAbstractSelectionDialog>>entriesMatching: (in category 'file list') ----- + entriesMatching: patternList + "Answer a list of directory entries which match any of the patterns. + See #parsePatternString for the pattern rules" - 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 | + "This odd clause helps supports MVC projects; the file list & directory views are built from a list that includes directories. In Morphic we filter out the directories because they are entirely handled by the direcctory tree morph" + entries := Smalltalk isMorphic + ifTrue:[directory fileEntries ] + ifFalse:[directory entries]. + + (patternList anySatisfy: [:each | each = '*']) - | entries patterns | - entries := directory entries reject:[:e| Smalltalk isMorphic and: [e isDirectory]]. - patterns := patternString findTokens: ';'. - (patterns anySatisfy: [:each | each = '*']) ifTrue: [^ entries]. + + ^ entries select: [:entry | patternList anySatisfy: [:each | each match: entry name]]! - ^ entries select: [:entry | patterns anySatisfy: [:each | each match: entry name]]! Item was changed: ----- Method: FileAbstractSelectionDialog>>listForPatterns: (in category 'path and pattern') ----- listForPatterns: arrayOfPatterns "return a list of those file names which match any of the patterns in the array." | newList | newList := Set new. + newList addAll: (self entriesMatching: arrayOfPatterns). - arrayOfPatterns do: [ :pat | newList addAll: (self entriesMatching: pat) ]. newList := newList sorted: [:a :b| a name <= b name]. nameList := newList collect:[:e| e name]. dateList := newList collect:[:e| ((Date fromSeconds: e modificationTime ) printFormat: #(3 2 1 $. 1 1 2)) , ' ' , (String streamContents: [:s | (Time fromSeconds: e modificationTime \\ 86400) print24: true on: s])]. sizeList := newList collect:[:e| e fileSize asStringWithCommas] ! Item was changed: FileAbstractSelectionDialog subclass: #FileChooserDialog instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Tools-FileDialogs'! + !FileChooserDialog commentStamp: 'tpr 11/13/2017 11:46' prior: 0! - !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' message: 'Choose the file to load' - 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:pattern:message: (in category 'instance creation') ----- + openOn: aDirectory pattern: aPatternString message: messageString + "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 message: messageString + + ! Item was changed: ----- 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" + ^self openOn: aDirectory pattern: aPatternString message: nil + ! - directory := aDirectory. - self pattern: aPatternString. - - ToolBuilder open: self. - ^self finalChoice! Item was added: + ----- Method: FileChooserDialog>>openOn:pattern:message: (in category 'initialize-release') ----- + openOn: aDirectory pattern: aPatternString message: messageString + "open a modal dialog to choose a file from aDirectory as filtered by aPattern" + + directory := aDirectory. + self pattern: aPatternString. + message := messageString. + + ToolBuilder open: self. + ^self finalChoice! Item was changed: ----- Method: FileList>>directoryNameOf: (in category 'directory tree') ----- directoryNameOf: aDirectory "Attempt to find the name of ServerDirectories when used." ^(aDirectory isRemoteDirectory and:[aDirectory isKindOf: ServerDirectory]) + ifTrue:[ServerDirectory servers keyAtIdentityValue: aDirectory ifAbsent:[aDirectory localName]] - ifTrue:[ServerDirectory servers keyAtIdentityValue: aDirectory] ifFalse:[aDirectory localName]! Item was changed: FileAbstractSelectionDialog subclass: #FileSaverDialog instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Tools-FileDialogs'! + !FileSaverDialog commentStamp: 'tpr 11/13/2017 11:49' prior: 0! - !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. The full set of options would invovle + myFilename := FileSaverDialog openOn: myApplicationDefaultDirectory initialFilename: 'foo.myapp' pattern: '*.mya' message: 'Save your myApp file to ... ' - 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:initialFilename:pattern: (in category 'instance creation') ----- + openOn: aDirectory initialFilename: aString pattern: patternString + "open a modal dialog to save a file. Start the dialog with aDirectory selected and the suggested file name. Visible filenames are limited by the pattern" + + ^self new openOn: aDirectory initialFilename: aString pattern: patternString + + ! Item was added: + ----- Method: FileSaverDialog class>>openOn:initialFilename:pattern:message: (in category 'instance creation') ----- + openOn: aDirectory initialFilename: aString pattern: patternString message: messageString + "open a modal dialog to save a file. Start the dialog with aDirectory selected and the suggested file name. Visible filenames are limited by the pattern. Use the messageString to explain what ther user needs to know" + + ^self new openOn: aDirectory initialFilename: aString pattern: patternString message: messageString + + ! Item was added: + ----- Method: FileSaverDialog>>buildWith: (in category 'toolbuilder') ----- + buildWith: builder + "assemble the spec for the common chooser/saver dialog UI" + + | window | + window := super buildWith: builder. + self inputText: fileName. + ^window + ! Item was changed: ----- Method: FileSaverDialog>>inputText: (in category 'filename') ----- + inputText: aText + "user has entered a potential filename in the text field. + Check it against the current pattern; if it is ok we can accept it and then if it is a file in + the current list, highlight it. + If it would not match the pattern, alert the user as best we can" + | candidate | + candidate := aText asString. + (self parsePatternString anySatisfy: [:p | p match: candidate]) + ifTrue: [fileName := candidate. + listIndex := nameList findFirst: [:nm | nm = fileName]. + self changed: #fileListIndex. + ^true] + ifFalse: [fileName := nil. + ^false]! - inputText: aText - "user has entered a potential filename in the text field. If it is a file in the current list, highlight it" - - fileName := aText asString. - listIndex := nameList findFirst:[: nm| nm = fileName]. - - self - changed: #fileListIndex; - changed: #inputText! Item was changed: ----- 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" + ^self openOn: aDirectory initialFilename: aFilename pattern: nil! - directory := aDirectory. - fileName := aFilename. - - ToolBuilder open: self. - ^self finalChoice! Item was added: + ----- Method: FileSaverDialog>>openOn:initialFilename:pattern: (in category 'initialize-release') ----- + openOn: aDirectory initialFilename: aFilename pattern: patternString + "open a modal dialog to choose a file name to save to aDirectory; limit visible files in the file list with the pattern" + + ^self openOn: aDirectory initialFilename: aFilename pattern: patternString message: nil + ! Item was added: + ----- Method: FileSaverDialog>>openOn:initialFilename:pattern:message: (in category 'initialize-release') ----- + openOn: aDirectory initialFilename: aFilename pattern: patternString message: messageString + "open a modal dialog to choose a file name to save to aDirectory; limit visible files in the file list with the pattern. Set the user message" + + directory := aDirectory. + fileName := aFilename. + message:= messageString. + self pattern: patternString. + + ToolBuilder open: self. + ^self finalChoice! |
2017-11-13 20:51 GMT+01:00 <[hidden email]>: tim Rowledge uploaded a new version of Tools to project The Trunk: Hi Tim, where this fileEntries message comes from? I see no implementor and no other senders in my trunk image... + ifFalse:[directory entries]. |
> On 15-11-2017, at 2:02 PM, Nicolas Cellier <[hidden email]> wrote: > > > Hi Tim, where this fileEntries message comes from? > I see no implementor and no other senders in my trunk image… Ah, right, well, umm… yes. I forgot to publish the other package. Mistakes were made and a full and frank transparent investigation will held and reported on in due course, for those with appropriate security clearances. It is the obvious (to me) method to return the actual entries for all the files in a directory rather than just the file names. I added a directoryEntries as well for symmetry. You should see Files-tpr.173 appearing very soon... tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim "How many Carlos Wus does it take to change a lightbulb?” "With an unlimited breeding licence, who needs lightbulbs?" |
Free forum by Nabble | Edit this page |