FileSelectionBox.st
author claus
Wed, 13 Oct 1993 03:49:56 +0100
changeset 5 7b4fb1b170e5
parent 3 9d7eefb5e69f
child 7 15a9291b9bd0
permissions -rw-r--r--
(none)

"
 COPYRIGHT (c) 1990 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

ListSelectionBox subclass:#FileSelectionBox
       instanceVariableNames:'patternField directory timeStamp directoryId
                              directoryContents directoryFileTypes'
       classVariableNames:''
       poolDictionaries:''
       category:'Views-Interactors'
!

FileSelectionBox comment:'

COPYRIGHT (c) 1990 by Claus Gittinger
              All Rights Reserved

this class implements file selection boxes. They show a list of
files, and perform an action block with the selected pathname as
argument when ok is clicked.

$Header: /cvs/stx/stx/libwidg/FileSelectionBox.st,v 1.3 1993-10-13 02:47:44 claus Exp $
written Jan 90 by claus
'!

!FileSelectionBox methodsFor:'initialization'!

initialize
    directory := FileDirectory currentDirectory.
    super initialize.

    labelField extent:(0.7 @ labelField height).
    labelField label:(resources string:'select a file:').
    labelField adjust:#left.

    patternField := EditField
                        origin:(0.7 @ labelField origin y)
                        corner:(1.0 @ labelField corner y)
                            in:self.
    patternField initialText:'*'.
    patternField leaveAction:[:p | self updateList].
    patternField hidden:true.

    "selections in list get forwarded to enterfield if not a directory;
     otherwise directory is changed"

    selectionList action:[:lineNr |
        |entry|

        entry := selectionList selectionValue.
        (entry endsWith:' ...') ifTrue:[
            entry := entry copyTo:(entry size - 4).
        ].
        ((directory typeOf:entry) == #directory) ifTrue:[
            self directory:(directory pathName , '/' , entry)
        ] ifFalse:[
            enterField contents:entry
        ]
    ]

    "FileSelectionBox new show"
!

reinitialize
    directory := FileDirectory currentDirectory.
    super reinitialize
! !

!FileSelectionBox methodsFor:'accessing'!

directory:nameOrDirectory
    "set the lists contents to the filenames in the directory name"

    |oldPath name|

    (nameOrDirectory isKindOf:String) ifTrue:[
        name := nameOrDirectory
    ] ifFalse:[
        name := nameOrDirectory pathName
    ].
    oldPath := directory pathName.
    directory pathName:name.
    (directory pathName = oldPath) ifFalse:[
        self updateList
    ]
!

pattern:aPattern
    patternField initialText:aPattern.
    patternField hidden:false.
    realized ifTrue:[
        patternField realize.
        self updateList
    ].
! !

!FileSelectionBox methodsFor:'private'!

updateList
    "set the lists contents to the filenames in the directory"

    |oldCursor oldListCursor files pattern newList index|

    oldCursor := cursor.
    oldListCursor := selectionList cursor.
    self cursor:(Cursor read).
    selectionList cursor:(Cursor read).
    directoryId == directory id ifFalse:[
        timeStamp := directory timeOfLastChange.
        directoryId := directory id.
        directoryContents := directory asText sort.
        ((directoryContents at:1) = '.') ifTrue:[
            directoryContents removeIndex:1
        ].
        directoryFileTypes := OrderedCollection new.
        directoryContents do:[:name | directoryFileTypes add:(directory typeOf:name)].
    ].
    files := directoryContents.
    pattern := patternField contents.
    newList := OrderedCollection new.
    index := 1.
    files do:[:name |
        (directoryFileTypes at:index) == #directory ifTrue:[
            name = '..' ifTrue:[
                newList add:name
            ] ifFalse:[
                newList add:(name , ' ...')
            ]
        ] ifFalse:[
            (pattern isEmpty or:[pattern match:name]) ifTrue:[
                newList add:name
            ]
        ].
        index := index + 1
    ].
    self list:newList.
    self cursor:oldCursor.
    selectionList cursor:oldListCursor
! !

!FileSelectionBox methodsFor:'events'!

show
    "make the box visible; redefined to check if directory is still 
     valid (using timestamp and inode numbers) - reread if not"

    (timeStamp isNil 
     or:[(directory timeOfLastChange > timeStamp) 
     or:[(directoryId isNil)
     or:[directoryId ~~ directory id]]]) ifTrue:[
        directoryId := nil.
        self updateList
    ].
    super show
! !

!FileSelectionBox methodsFor:'user interaction'!

okPressed
    "redefined, since action will be evaluated with full path as argument
     (instead of enterfields contents only as inherited by EnterBox"

    self hideAndEvaluate:[:string |
        okAction notNil ifTrue:[
            okAction value:(directory pathName , '/' , string)
        ]
    ]
! !