diff -r c643ead8ede7 -r 395b851346df FileSelectionBrowser.st --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FileSelectionBrowser.st Wed Dec 03 22:12:21 1997 +0100 @@ -0,0 +1,575 @@ +SelectionBrowser subclass:#FileSelectionBrowser + instanceVariableNames:'selectedFileFilter fileName readTask' + classVariableNames:'' + poolDictionaries:'' + category:'Interface-Advanced-Tools' +! + +Object subclass:#Row + instanceVariableNames:'fileName size iconKey group owner permissions baseName' + classVariableNames:'' + poolDictionaries:'' + privateIn:FileSelectionBrowser +! + + +!FileSelectionBrowser class methodsFor:'instance creation'! + +requestFileName + + ^self new title: 'Select a file'; open + +! + +requestFileName: aFileName fileFilters: fileFilters + + ^self new + fileName: aFileName; + listOfFileFilters: fileFilters; + open +! ! + +!FileSelectionBrowser class methodsFor:'accessing'! + +lastFileSelectionDirectory + "^ LastFileSelectionDirectory" + +! ! + +!FileSelectionBrowser class methodsFor:'interface specs'! + +windowSpec + "this window spec was automatically generated by the ST/X UIPainter" + + "do not manually edit this - the painter/builder may not be able to + handle the specification if its corrupted." + + " + UIPainter new openOnClass:FileSelectionBrowser andSelector:#windowSpec + FileSelectionBrowser new openInterface:#windowSpec + " + "FileSelectionBrowser open" + + + + ^ + + #(#FullSpec + #'window:' + #(#WindowSpec + #'name:' 'File Selection Browser' + #'layout:' #(#LayoutFrame 410 0 282 0 809 0 581 0) + #'label:' 'File Selection Browser' + #'min:' #(#Point 10 10) + #'max:' #(#Point 1152 900) + #'bounds:' #(#Rectangle 410 282 810 582) + #'usePreferredExtent:' false + ) + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#ViewSpec + #'name:' 'view' + #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -40 1.0) + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#VariableHorizontalPanelSpec + #'name:' 'panel' + #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 -1 1.0) + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#ViewSpec + #'name:' 'view1' + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#FileSelectionTreeSpec + #'name:' 'directoryTreeView' + #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #'model:' #selectionOfDirectory + #'hasHorizontalScrollBar:' true + #'hasVerticalScrollBar:' true + #'miniScrollerHorizontal:' true + #'showRoot:' false + #'showDirectoryIndicator:' true + #'valueChangeSelector:' #readDirectory + #'hierarchicalList:' #rootOfDirectory + #'itemClass:' 'Directory' + ) + ) + ) + #'level:' -1 + ) + #(#ViewSpec + #'name:' 'view2' + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#DataSetSpec + #'name:' 'filesDataSetView' + #'layout:' #(#LayoutFrame 0 0.0 24 0.0 0 1.0 -23 1.0) + #'model:' #selectionOfFile + #'hasHorizontalScrollBar:' true + #'hasVerticalScrollBar:' true + #'miniScrollerHorizontal:' true + #'dataList:' #listOfFiles + #'useIndex:' false + #'level:' 1 + #'doubleClickSelector:' #fileDoubleClicked + #'valueChangeSelector:' #fileSelected + #'verticalSpacing:' 1 + #'columns:' + #( + #(#DataSetColumnSpec + #'label:' '' + #'width:' 30 + #'printSelector:' #'iconOn:' + #'canSelect:' false + ) + #(#DataSetColumnSpec + #'label:' 'file name' + #'minWidth:' 100 + #'model:' #baseName + ) + #(#DataSetColumnSpec + #'label:' 'size' + #'width:' 50 + #'model:' #size + #'canSelect:' false + ) + #(#DataSetColumnSpec + #'label:' 'permissions' + #'width:' 85 + #'model:' #permissions + #'canSelect:' false + ) + #(#DataSetColumnSpec + #'label:' 'owner' + #'width:' 50 + #'model:' #owner + #'canSelect:' false + ) + #(#DataSetColumnSpec + #'label:' 'group' + #'width:' 50 + #'model:' #group + #'canSelect:' false + ) + ) + ) + #(#ComboBoxSpec + #'name:' 'formatComboBox' + #'layout:' #(#LayoutFrame 0 0.0 2 0 0 1.0 24 0) + #'model:' #selectionOfFileFilter + #'immediateAccept:' false + #'acceptOnTab:' false + #'comboList:' #listOfFileFilters + ) + #(#InputFieldSpec + #'name:' 'EditField' + #'layout:' #(#LayoutFrame 0 0.0 -22 1 0 1.0 0 1) + #'model:' #valueOfFileName + #'acceptOnReturn:' false + #'acceptOnTab:' false + ) + ) + ) + #'level:' -1 + ) + ) + ) + #'handles:' #(#Any 0.5 1.0) + ) + ) + ) + ) + #(#HorizontalPanelViewSpec + #'name:' 'horizontalPanelView' + #'layout:' #(#LayoutFrame 0 0.0 -40 1 0 1.0 0 1.0) + #'component:' + #(#SpecCollection + #'collection:' + #( + #(#ActionButtonSpec + #'name:' 'cancelButton' + #'label:' 'cancel' + #'model:' #cancel + #'extent:' #(#Point 100 22) + ) + #(#ActionButtonSpec + #'name:' 'okButton' + #'label:' 'ok' + #'model:' #accept + #'extent:' #(#Point 100 22) + ) + ) + ) + #'level:' 1 + #'horizontalLayout:' #center + #'verticalLayout:' #center + #'horizontalSpace:' 3 + #'verticalSpace:' 3 + ) + ) + ) + ) +! ! + +!FileSelectionBrowser methodsFor:'accessing'! + +fileName + + (fileName notNil and: [(fileName name ~= self valueOfFileName value and: [self valueOfFileName value notNil])]) + ifTrue: [^(LastFileSelectionDirectory, Filename separator, self valueOfFileName value) asFilename]. + ^fileName +! + +fileName: aFileName + + fileName := aFileName +! + +title: aString + + title := aString +! ! + +!FileSelectionBrowser methodsFor:'actions'! + +closeCancel + + readTask notNil ifTrue: [readTask terminate]. + fileName := nil. + super closeCancel +! + +closeRequest + + readTask notNil ifTrue: [readTask terminate]. + super closeRequest +! + +closeWindow + + readTask notNil ifTrue: [readTask terminate]. + super closeWindow +! + +fileDoubleClicked + + self valueOfFileName value: self selectionOfFile value baseName. + fileName := self selectionOfFile value fileName. + accept value: true. + self close +! + +fileSelected + + self valueOfFileName value: self selectionOfFile value baseName. + fileName := self selectionOfFile value fileName. +! + +readDirectory + + | file list dir lst| + self selectionOfDirectory value isNil ifTrue: [^nil]. + readTask notNil ifTrue: [readTask terminate]. + readTask := [ + + file := (builder componentAt: #directoryTreeView) selectedPathname asFilename. + builder window label: 'Reading: ''', file name, ''''. + self class lastSelection: file name. + (file isReadable and:[file isExecutable]) ifTrue:[ + list := self listOfFiles. + list removeAll. + lst := OrderedCollection new. + self listOfFileFilters value + do: [:filter| + (file filesMatchingWithoutDotDirs: filter) do: + [:aFileName| + lst add: (Row new fileName: (file name, Filename separator, aFileName) asFilename) + ]. + ]. + lst := lst asSortedCollection: [:r1 :r2| r1 baseName < r2 baseName]. + list addAll:lst beforeIndex:1]. + self selectionOfFile value: (self listOfFiles detect: [:r| r fileName = fileName] ifNone: [nil]). + self setLabel. + ] forkAt: 4 +! ! + +!FileSelectionBrowser methodsFor:'aspects'! + +listOfFileFilters + |holder| + + (holder := builder bindingAt:#listOfFileFilters) isNil ifTrue:[ + builder aspectAt:#listOfFileFilters put:(holder := List with: '*.*'). + ]. + ^ holder +! + +listOfFileFilters: aCollection + self listOfFileFilters contents: aCollection. +! + +listOfFiles + + |holder| + (holder := builder bindingAt:#listOfFiles) isNil ifTrue:[ + builder aspectAt:#listOfFiles put:(holder := List new). + ]. + ^ holder + +! + +rootOfDirectory + + |holder| + + (holder := builder bindingAt:#rootOfDirectory) isNil ifTrue:[ + builder aspectAt:#rootOfDirectory put: (holder := ValueHolder with: Filename rootDirectory name). + ]. + ^ holder + +! + +selectionOfDirectory + + |holder| + (holder := builder bindingAt:#selectionOfDirectory) isNil ifTrue:[ + builder aspectAt:#selectionOfDirectory put: (holder := ValueHolder new) + ]. + ^ holder + +! + +selectionOfFile + + |holder| + (holder := builder bindingAt:#selectionOfFile) isNil ifTrue:[ + builder aspectAt:#selectionOfFile put:(holder := ValueHolder new). + ]. + ^ holder + +! + +selectionOfFileFilter + |holder| + + (holder := builder bindingAt:#selectionOfFileFilter) isNil ifTrue:[ + builder aspectAt:#selectionOfFileFilter put: + (holder := AspectAdaptor new subject:self; forAspect:#selectedFileFilter). + selectedFileFilter := '*.*'. + ]. + ^ holder +! + +valueOfFileName + + |holder| + (holder := builder bindingAt:#valueOfFileName) isNil ifTrue:[ + builder aspectAt:#valueOfFileName put:(holder := ValueHolder new). + ]. + ^ holder +! ! + +!FileSelectionBrowser methodsFor:'initialization'! + +open + + super open. + accept value + ifTrue: + [ + ^(self selectionOfDirectory value ? '') , Filename separator, (self valueOfFileName value ? '') + ]. + ^nil + + + +! + +postBuildWith:aBuilder + + (fileName notNil and: [fileName asFilename exists]) + ifTrue: + [ + self class lastSelection: fileName asFilename directoryName. + self valueOfFileName value: fileName asFilename baseName + ]. + (builder componentAt: #directoryTreeView) selectPathname: self class lastSelection. + self selectionOfFileFilter value: (self listOfFileFilters at: 1 ifAbsent: [nil]). + self readDirectory. + (builder componentAt: #directoryTreeView) monitoring: true. + ^super postBuildWith:aBuilder +! ! + +!FileSelectionBrowser methodsFor:'selection'! + +selectedFileFilter + + ^selectedFileFilter +! + +selectedFileFilter: aString + + selectedFileFilter := aString. + + self readDirectory +! ! + +!FileSelectionBrowser::Row methodsFor:'accessing'! + +baseName + baseName isNil ifTrue: [baseName := fileName baseName]. + ^ baseName + + + + + +! + +fileName + ^ fileName + +! + +fileName: aFileName + fileName := aFileName + +! + +group + group isNil ifTrue:[ + self validateAttributes + ]. + ^ group +! + +iconOn:aGC + |icon| + + iconKey isNil ifTrue:[ + self validateAttributes. + ]. + (iconKey == #image) | (iconKey == #imageFile) + ifTrue: + [ + Object errorSignal handle: [:ex|] + do: + [ + ((size < 5000) and: [(icon := Image fromFile: fileName name) notNil]) + ifTrue: [aGC registerImage: icon key:(iconKey :=fileName name asSymbol).] + ]. + ]. + (icon := aGC registeredImageAt:iconKey) isNil ifTrue:[ + self registerIconsOn:aGC. + icon := aGC registeredImageAt:iconKey. + ]. + ^ icon + + + +! + +owner + owner isNil ifTrue:[ + self validateAttributes + ]. + ^ owner + + +! + +permissions + permissions isNil ifTrue:[ + self validateAttributes + ]. + ^ permissions + + +! + +size + size isNil ifTrue:[ + self validateAttributes + ]. + ^ size + +! ! + +!FileSelectionBrowser::Row methodsFor:'private'! + +registerIconsOn:aGC + "register all file icons on the gc + " + |directory| + + directory := 'xpmBitmaps/document_images/'. + + #( + (#file 'tiny_file_plain.xpm' ) + (#fileLink 'tiny_file_link.xpm' ) + (#fileLocked 'tiny_file_lock.xpm' ) + (#imageFile 'tiny_file_pix.xpm' ) + + ) do:[:el| + aGC registerImage:(Image fromFile:(directory, el last)) key:(el first) + ]. + + + + + +! + +validateAttributes + |info mode| + + permissions := String new:9 withAll:$-. + + (info := fileName info) isNil ifTrue:[ + iconKey := #fileLocked. + size := owner := group := '?'. + ^ self + ]. + size := info size. + owner := OperatingSystem getUserNameFromID:(info uid). + group := OperatingSystem getGroupNameFromID:(info gid). + mode := info mode. + + 1 to:9 by:3 do:[:i| + (mode bitAt:i ) == 1 ifTrue:[permissions at:10 - i put:$x]. + (mode bitAt:i + 1) == 1 ifTrue:[permissions at:9 - i put:$w]. + (mode bitAt:i + 2) == 1 ifTrue:[permissions at:8 - i put:$r]. + ]. + + fileName isReadable ifTrue:[ + info type == #symbolicLink ifTrue:[ + iconKey == #fileLink + ] ifFalse:[ + (Image isImageFileSuffix:(fileName suffix)) ifTrue:[ + iconKey := #imageFile + ] ifFalse:[ + iconKey := #file + ] + ] + ] ifFalse:[ + iconKey := #fileLocked + ]. + +! ! + +!FileSelectionBrowser class methodsFor:'documentation'! + +version + ^ '$Header$' +! !