intitial checkin
authortz
Wed, 03 Dec 1997 22:12:21 +0100
changeset 384 395b851346df
parent 383 c643ead8ede7
child 385 059ced1c8344
intitial checkin
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"
+
+    <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$'
+! !