[squeak-dev] The Trunk: ToolBuilder-Morphic-cmm.209.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Mar 30 23:02:10 UTC 2018


Chris Muller uploaded a new version of ToolBuilder-Morphic to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Morphic-cmm.209.mcz

==================== Summary ====================

Name: ToolBuilder-Morphic-cmm.209
Author: cmm
Time: 30 March 2018, 6:01:58.101354 pm
UUID: da0cc990-c84a-49e8-ad16-99d84013a244
Ancestors: ToolBuilder-Morphic-tpr.208

Various fixes and improvements to Tim's cool new FileSaverDialog.  Restores the convenience of simply typing a name and pressing [Return], by opening with the filename field directly under the mouse, ready to type.  It is also once again not required to type the filename extension, the system will add it or prompt the user for it if there are multiple possibilities.  If an invalid filename is specified, the user is alerted appropriately, instead of silently not saving their file.

=============== Diff against ToolBuilder-Morphic-tpr.208 ===============

Item was changed:
  ----- Method: DialogWindow>>openAsTool (in category '*ToolBuilder-Morphic-opening') -----
  openAsTool
+ 	self flag: #dev.
+ 	"cm: The following line may no longer be necessary."
+ 	preferredPosition isMorph ifFalse: [ self moveToHand ].
+ 	^ self getUserResponse!
- 
- 	self flag: #fishy. "mt: Why does the dialog not return its Morphic form but data?"
- 	^ self
- 		moveToHand;
- 		getUserResponse!

Item was changed:
  Model subclass: #FileAbstractSelectionDialog
+ 	instanceVariableNames: 'patternList directory directoryCache message listIndex fileName finalChoice nameList sizeList dateList suffixList'
- 	instanceVariableNames: 'patternList directory directoryCache message listIndex fileName finalChoice nameList sizeList dateList'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'ToolBuilder-Morphic-Tools'!
  
  !FileAbstractSelectionDialog commentStamp: 'tpr 11/21/2017 18:18' 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.
  
  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
  	patternList:		<OrderedCollection of String> the patterns are held as a collection of string that may include * or # wildcards. 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!

Item was changed:
  ----- Method: FileAbstractSelectionDialog>>buildTextInputWith: (in category 'toolbuilder') -----
  buildTextInputWith: builder
  	| textSpec |
  	textSpec := builder pluggableInputFieldSpec new.
  	textSpec 
  		model: self;
+ 		name: #inputText ;
  		font: self textViewFont;
+ 		getText: #inputText;
+ 		setText: #selectFilename:;
+ 		selection: #contentsSelection.
- 		getText: #inputText; 
- 		setText: #inputText:.
  	^textSpec
  !

Item was changed:
  ----- Method: FileAbstractSelectionDialog>>initialize (in category 'initialize-release') -----
  initialize
  	super initialize.
  	directoryCache := WeakIdentityKeyDictionary new.
  	listIndex := 0.
+ 	patternList := self defaultPatternList.
+ 	suffixList := OrderedCollection new!
- 	patternList := self defaultPatternList!

Item was changed:
  ----- Method: FileAbstractSelectionDialog>>suffixList: (in category 'path and pattern') -----
+ suffixList: listOfStrings 
- suffixList: listOfStrings
  	"Make a pattern list from a one or more filename suffix strings in a list , i.e. #('jpg' 'mpeg') "
- 
  	listOfStrings isEmptyOrNil
+ 		ifTrue: [ patternList := self defaultPatternList ]
+ 		ifFalse:
+ 			[ patternList := OrderedCollection new.
+ 			listOfStrings do:
+ 				[ : each | each isEmptyOrNil ifFalse:
+ 					[ patternList add: '*.' , each.
+ 					suffixList add: each ] ] ]!
- 		ifTrue: [patternList := self defaultPatternList]
- 		ifFalse: [patternList := OrderedCollection new.
- 				listOfStrings do: [:each|
- 					each isEmptyOrNil ifFalse:[ patternList add: '*.',each] ] ]!

Item was changed:
  ----- Method: FileChooserDialog class>>openOn:suffixList:label: (in category 'instance creation') -----
+ openOn: aDirectory suffixList: aCollection label: labelString
+ 	"Open a modal dialog to choose a file. Start the dialog with aDirectory selected 	and files matching the file name suffixes in aCollection. Set the user message to labelString."
- openOn: aDirectory suffixList: patternList label: labelString
- 	"Open a modal dialog to choose a file. Start the dialog with aDirectory selected
- 	and files matching the file name suffixes in patternList. Set the user message
- 	to labelString."
  
  	"FileChooserDialog openOn: FileDirectory default suffixList: { 'changes' . 'image' } label: 'Do something with the selected files' "
  
  	^self new
  		directory: aDirectory;
+ 		suffixList: aCollection;
- 		suffixList: patternList;
  		message: labelString;
  		getUserResponse!

Item was changed:
  ----- Method: FileSaverDialog>>buildWith: (in category 'toolbuilder') -----
  buildWith: builder
  	"assemble the spec for the saver dialog UI and build the window"
  
  	| window windowSpec |
  	windowSpec := self buildWindowWith: builder specs: {
  		(self topConstantHeightFrame: self textViewHeight + self viewSpacing
  			fromLeft: 0
  			width: 1) -> [self buildTextInputWith: builder].
  		(self frameOffsetFromTop: self textViewHeight + self viewSpacing
  			fromLeft: 0.25
  			width: 0.75
  			offsetFromBottom: 0) -> [self buildFileListWith: builder].
  		(self frameOffsetFromTop: self textViewHeight + self viewSpacing
  			fromLeft: 0
  			width: 0.25
  			offsetFromBottom: 0) -> [self buildDirectoryTreeWith: builder].
  	}.
  	windowSpec buttons addAll: ( self buildButtonsWith: builder ).
  	window := builder build: windowSpec.
  	window addKeyboardCaptureFilter: self.
  	self changed: #selectedPath.
  	self inputText: fileName.
+ 	window positionOverWidgetNamed: #inputText.
  	^window
  !

Item was added:
+ ----- Method: FileSaverDialog>>contentsSelection (in category 'ui details') -----
+ contentsSelection
+ 	^ 1 to: 9999!

Item was changed:
  ----- Method: FileSaverDialog>>inputText: (in category 'filename') -----
  inputText: aText 
+ 	"Initialize the filename entry field to aString.  If a file with that name already exists, set up to highlight it."
+ 	fileName := aText asString.
+ 	self selectExistingFilename!
- 	"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.
- 	(patternList anySatisfy: [:p | p match: candidate])
- 		ifTrue: [fileName := candidate.
- 			listIndex := nameList findFirst: [:nm | nm = fileName].
- 			self changed: #fileListIndex.
- 				^true]
- 		ifFalse: [fileName := nil.
- 				self changed: #flash.
- 			^false]!

Item was added:
+ ----- Method: FileSaverDialog>>selectExistingFilename (in category 'private') -----
+ selectExistingFilename
+ 	"Answer whether an existing file in the list matches my proposed filename, selecting it if it does."
+ 	^ (patternList anySatisfy:
+ 		[ : each | (each
+ 			compare: fileName
+ 			caseSensitive: FileDirectory default isCaseSensitive) = 2 ])
+ 		and:
+ 			[ listIndex := nameList findFirst: [ : each | each = fileName ].
+ 			true ]!

Item was added:
+ ----- Method: FileSaverDialog>>selectFilename: (in category 'filename') -----
+ selectFilename: aText 
+ 	"The 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."
+ 	fileName := aText asString.
+ 	^ self selectExistingFilename
+ 		ifTrue:
+ 			[ self changed: #fileListIndex.
+ 			true ]
+ 		ifFalse:
+ 			[ suffixList size = 1
+ 				ifTrue:
+ 					[ fileName := fileName , '.' , suffixList first.
+ 					true ]
+ 				ifFalse:
+ 					[ suffixList
+ 						at:
+ 							(UIManager default
+ 								chooseFrom: suffixList
+ 								title: 'Please choose the type of file to save.')
+ 						ifPresent:
+ 							[ : choice | fileName := fileName , '.' , choice.
+ 							true ]
+ 						ifAbsent:
+ 							[ fileName := nil.
+ 							UIManager default inform: 'WARNING:  File not saved!!  A filename matching one of ' , patternList asArray asString , ' patterns is required.'.
+ 							false ] ] ]!



More information about the Squeak-dev mailing list