DirBrwsr.st
author Claus Gittinger <cg@exept.de>
Fri, 17 Apr 1998 21:00:31 +0200
changeset 1555 756ab2711237
parent 1333 7e0b35b6a769
permissions -rw-r--r--
checkin from browser

"
 COPYRIGHT (c) 1991 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.
"

SimpleView subclass:#DirectoryBrowser
	instanceVariableNames:'levelViews labelViews codeView currentDirs queryBox'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Browsers'
!

!DirectoryBrowser class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1991 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.
"
!

documentation
"
    to browse Directories
    This browser will eventually vanish, and its directory-list functions
    be brought into the fileBrowser.
"
! !

!DirectoryBrowser class methodsFor:'startup'!

open
    |topView|

    topView := StandardSystemView
		    label:'Directory Browser'
		    icon:(Image fromFile:'bitmaps/DirBrowser.icon' resolution:100).

    self origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView.

    topView open.
    ^ topView

    "DirectoryBrowser open"
! !

!DirectoryBrowser methodsFor:'initialization'!

initialize
    |v l panel helpView fraction x proto upButton protoHeight
     fontToUse|

    super initialize.

    fontToUse := Font family:(resources at:'FONT_FAMILY' default:'helvetica')
			face:(resources at:'FONT_FACE' default:'medium')
		       style:(resources at:'FONT_STYLE' default:'roman')
			size:(resources at:'FONT_SIZE' default:10).

    levelViews := Array new:4.
    currentDirs := Array new:4.
    labelViews := Array new:4.

    proto := Label in:self.
    protoHeight := proto heightIncludingBorder.
    proto destroy.

    panel := VariableVerticalPanel
		   origin:(borderWidth negated @ (protoHeight + (ViewSpacing * 2)))
		   extent:[width @ (height - protoHeight 
					   - borderWidth
					   - (ViewSpacing * 2))]
		   in:self.

    helpView := View origin:(0.0 @ 0.0) corner:(1.0 @ 0.2) in:panel.

    fraction := 0.25.
    x := 0.0.
    1 to:4 do:[:lvl |
	v := ScrollableView for:SelectionInListView in:helpView.
	v origin:(x @ 0.0) corner:(x + fraction @ 1.0).
	l := v scrolledView.
	l font:fontToUse.
" "
	l action:[:lineNr | self selectionInLevel:lvl].
" "
	levelViews at:lvl put:l.
	l := Label origin:(x @ 0.0)
		   corner:(x + fraction @ protoHeight)
	      borderWidth:0
		       in:self.
	l adjust:#centerRight.
	l sizeFixed:true.
	labelViews at:lvl put:l.
	x := (x + fraction) asFloat
    ].
    upButton := ArrowButton leftIn:self.
    upButton origin:((ViewSpacing / 2) rounded @ (ViewSpacing / 2) rounded).
    upButton action:[self levelUp].

"
    (levelViews at:1) action:[:lineNr | self selectionInLevel:1].
    (levelViews at:2) action:[:lineNr | self selectionInLevel:2].
    (levelViews at:3) action:[:lineNr | self selectionInLevel:3].
    (levelViews at:4) action:[:lineNr | self selectionInLevel:4].
"

    codeView := HVScrollableView for:CodeView miniScrollerH:true miniScrollerV:false in:panel.
    codeView origin:(0.0 @ 0.2) corner:(1.0 @ 1.0).

    self setDirectory:'.' inLevel:1.
    self initializeMenus

!

initializeMenus
    (levelViews at:1)
	middleButtonMenu:(PopUpMenu
				labels:(resources array:#('up'
							  'goto directory'))
			     selectors:#(levelUp
					 gotoDirectory)
			      receiver:self
				   for:(levelViews at:1))
! !

!DirectoryBrowser methodsFor:'private'!

changedLevel:lvl
    self withCursor:(Cursor wait) do:[
	(lvl + 1) to:4 do:[:nextLevel |
	    (labelViews at:nextLevel) label:nil.
	    (levelViews at:nextLevel) contents:nil
	].
	codeView contents:nil
    ].
    self readLevel:lvl
!

readFile:fileName in:aDirectory
    "read in the file, answer its contents as Text"

    |stream text|

    stream := FileStream readonlyFileNamed:fileName in:aDirectory.
    stream isNil ifTrue:[^ nil].
    text := stream contents.
    stream close.
    ^ text
!

readLevel:lvl
    |dir files|

    dir := currentDirs at:lvl.
    dir notNil ifTrue:[
        files := dir asOrderedCollection.
        (files size ~~ 0) ifTrue:[
            files sort.
            ((files at:1) = '.') ifTrue:[
                files removeFirst
            ].
            ((files at:1) = '..') ifTrue:[
                files removeFirst
            ].
            files := files collect:[:aName |
                        ((dir typeOf:aName) == #directory) ifTrue:[
                            aName , ' ...'

                        ] ifFalse:[
                            aName
                        ]
                     ].
        ]
    ].
    (levelViews at:lvl) list:files

    "Modified: 24.9.1997 / 16:41:04 / stefan"
!

setDirectory:aString inLevel:lvl
    |dir|

    aString isNil ifFalse:[
	(lvl == 1) ifTrue:[
	    dir := FileDirectory directoryNamed:aString
	] ifFalse:[
	    dir := FileDirectory directoryNamed:aString 
					     in:(currentDirs at:(lvl - 1))
	].
	(lvl == 1) ifFalse:[
	    (levelViews at:(lvl - 1)) selectElement:aString
	]
    ].
    dir notNil ifTrue:[
	(labelViews at:lvl) label:(dir baseName)
    ].
    currentDirs at:lvl put:dir.
    self changedLevel:lvl
!

showFile:fileName in:aDirectory
    "show contents of fileName in codeView"

    |contents|

    ((aDirectory typeOf:fileName) == #regular) ifFalse:[
	"clicked on something else - ignore it ..."
	contents := fileName , ' is not a regular file'.
	codeView acceptAction:nil
    ] ifTrue:[
	contents := self readFile:fileName in:aDirectory.
	codeView acceptAction:[:theCode |
	    self writeFile:fileName in:aDirectory text:theCode
	]
    ].
    codeView contents:contents
!

writeFile:fileName in:aDirectory text:someText 
    |stream|

    self withCursor:Cursor write do:[
	stream := FileStream fileNamed:fileName in:aDirectory.
	stream isNil ifTrue:[
	    self warn:'cannot write'
	] ifFalse:[
	    someText isString ifTrue:[
		stream nextPutAll:someText.
	    ] ifFalse:[
		someText do:[:line |
		    line notNil ifTrue:[
			stream nextPutAll:line.
		    ].
		    stream cr.
		]
	    ].
	    stream close
	]
    ].
! !

!DirectoryBrowser methodsFor:'user interaction'!

gotoDirectory
    queryBox isNil ifTrue:[
	queryBox := EnterBox
			title:'directory:'
			okText:'goto'
			abortText:'abort'
			action:[:path | self setDirectory:path inLevel:1]
    ].
    queryBox showAtPointer
!

levelDown
    "move down one level"

    |nextLevel|

    1 to:3 do:[:lvl |
	nextLevel := lvl + 1.
	(labelViews at:lvl) label:(labelViews at:nextLevel) label.
	(levelViews at:lvl) setList:(levelViews at:nextLevel) list.
	(levelViews at:lvl) selectElement:(levelViews at:nextLevel)
							selectionValue.
	currentDirs at:lvl put:(currentDirs at:nextLevel)
    ].
    (levelViews at:4) list:nil
!

levelUp
    "move up one level"

    |prevLevel dir|

    ((currentDirs at:1) baseName = '/') ifTrue:[^ self].

    4 to:2 by:-1 do:[:lvl |
	prevLevel := lvl - 1.
	(labelViews at:lvl) label:(labelViews at:prevLevel) label.
	(levelViews at:lvl) setList:(levelViews at:prevLevel) list.
	(levelViews at:lvl) selectElement:(levelViews at:prevLevel) selectionValue.
	currentDirs at:lvl put:(currentDirs at:prevLevel)
    ].
    dir := FileDirectory directoryNamed:'..' in:(currentDirs at:1).
    currentDirs at:1 put:dir.
    (labelViews at:1) label:(dir baseName).
    self readLevel:1.
    (levelViews at:1) selectElement:(labelViews at:2) label , ' ...'
!

selectionInLevel:lvl
    |dir fileName|

    self withCursor:(Cursor wait) do:[
	dir := currentDirs at:lvl.
	fileName := (levelViews at:lvl) selectionValue.
	(fileName endsWith:' ...') ifTrue:[
	    fileName := fileName copyTo:(fileName size - 4).
	].
	((dir typeOf:fileName) == #directory) ifTrue:[
	    (lvl < 4) ifTrue:[
		self setDirectory:fileName inLevel:(lvl + 1)
	    ] ifFalse:[
		self levelDown.
		self setDirectory:fileName inLevel:4
	    ]
	] ifFalse:[
	    (lvl < 4) ifTrue:[
		self setDirectory:nil inLevel:(lvl + 1)
	    ].
	    self showFile:fileName in:dir
	]
    ]
! !

!DirectoryBrowser class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/Attic/DirBrwsr.st,v 1.16 1997-09-24 15:38:51 stefan Exp $'
! !