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"
<resource: #canvas>
^
#(#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$'
! !