FileSelectionBrowser.st
author tz
Wed, 03 Dec 1997 22:12:21 +0100
changeset 384 395b851346df
child 388 45cf0af38948
permissions -rw-r--r--
intitial checkin

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$'
! !