123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- # -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
- #
- # $Id: DirTree.tcl,v 1.4 2004/03/28 02:44:57 hobbs Exp $
- #
- # DirTree.tcl --
- #
- # Implements directory tree for Unix file systems
- #
- # What the indicators mean:
- #
- # (+): There are some subdirectories in this directory which are not
- # currently visible.
- # (-): This directory has some subdirectories and they are all visible
- #
- # none: The dir has no subdirectori(es).
- #
- # Copyright (c) 1993-1999 Ioi Kim Lam.
- # Copyright (c) 2000-2001 Tix Project Group.
- # Copyright (c) 2004 ActiveState
- #
- # See the file "license.terms" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- ##
- ## The tixDirTree require special FS handling due to it's limited
- ## separator idea (instead of real tree).
- ##
- tixWidgetClass tixDirTree {
- -classname TixDirTree
- -superclass tixVTree
- -method {
- activate chdir refresh
- }
- -flag {
- -browsecmd -command -directory -disablecallback -showhidden -value
- }
- -configspec {
- {-browsecmd browseCmd BrowseCmd ""}
- {-command command Command ""}
- {-disablecallback disableCallback DisableCallback 0 tixVerifyBoolean}
- {-showhidden showHidden ShowHidden 0 tixVerifyBoolean}
- {-value value Value ""}
- }
- -alias {
- {-directory -value}
- }
- -default {
- {.scrollbar auto}
- {*Scrollbar.takeFocus 0}
- {*borderWidth 1}
- {*hlist.indicator 1}
- {*hlist.background #c3c3c3}
- {*hlist.drawBranch 1}
- {*hlist.height 10}
- {*hlist.highlightBackground #d9d9d9}
- {*hlist.indent 20}
- {*hlist.itemType imagetext}
- {*hlist.padX 3}
- {*hlist.padY 0}
- {*hlist.relief sunken}
- {*hlist.takeFocus 1}
- {*hlist.wideSelection 0}
- {*hlist.width 20}
- }
- }
- proc tixDirTree:InitWidgetRec {w} {
- upvar #0 $w data
- tixChainMethod $w InitWidgetRec
- if {$data(-value) == ""} {
- set data(-value) [pwd]
- }
- tixDirTree:SetDir $w [file normalize $data(-value)]
- }
- proc tixDirTree:ConstructWidget {w} {
- upvar #0 $w data
- tixChainMethod $w ConstructWidget
- tixDoWhenMapped $w [list tixDirTree:StartUp $w]
- $data(w:hlist) config -separator [tixFSSep] \
- -selectmode "single" -drawbranch 1
- # We must creat an extra copy of these images to avoid flashes on
- # the screen when user changes directory
- #
- set data(images) [image create compound -window $data(w:hlist)]
- $data(images) add image -image [tix getimage act_fold]
- $data(images) add image -image [tix getimage folder]
- $data(images) add image -image [tix getimage openfold]
- }
- proc tixDirTree:SetBindings {w} {
- upvar #0 $w data
- tixChainMethod $w SetBindings
- }
- # Add one dir into the node (parent directory), sorted alphabetically
- #
- proc tixDirTree:AddToList {w fsdir image} {
- upvar #0 $w data
- set dir [tixFSInternal $fsdir]
- if {[$data(w:hlist) info exists $dir]} { return }
- set parent [file dirname $fsdir]
- if {$fsdir eq $parent} {
- # root node
- set node ""
- } else {
- # regular node
- set node [tixFSInternal $parent]
- }
- set added 0
- set text [tixFSDisplayFileName $fsdir]
- foreach sib [$data(w:hlist) info children $node] {
- if {[string compare $dir $sib] < 0} {
- $data(w:hlist) add $dir -before $sib -text $text -image $image
- set added 1
- break
- }
- }
- if {!$added} {
- $data(w:hlist) add $dir -text $text -image $image
- }
- # Check to see if we have children (%% optimize!)
- if {[llength [tixFSListDir $fsdir 1 0 0 $data(-showhidden)]]} {
- tixVTree:SetMode $w $dir open
- }
- }
- proc tixDirTree:LoadDir {w fsdir {mode toggle}} {
- if {![winfo exists $w]} { return }
- upvar #0 $w data
- # Add the directory and set it to the active directory
- #
- set fsdir [tixFSNormalize $fsdir]
- set dir [tixFSInternal $fsdir]
- if {![$data(w:hlist) info exists $dir]} {
- # Add $dir and all ancestors of $dir into the HList widget
- set fspath ""
- set imgopenfold [tix getimage openfold]
- foreach part [tixFSAncestors $fsdir] {
- set fspath [file join $fspath $part]
- tixDirTree:AddToList $w $fspath $imgopenfold
- }
- }
- $data(w:hlist) entryconfig $dir -image [tix getimage act_fold]
- if {$mode eq "toggle"} {
- if {[llength [$data(w:hlist) info children $dir]]} {
- set mode flatten
- } else {
- set mode expand
- }
- }
- if {$mode eq "expand"} {
- # Add all the sub directories of fsdir into the HList widget
- tixBusy $w on $data(w:hlist)
- set imgfolder [tix getimage folder]
- foreach part [tixFSListDir $fsdir 1 0 0 $data(-showhidden)] {
- tixDirTree:AddToList $w [file join $fsdir $part] $imgfolder
- }
- tixWidgetDoWhenIdle tixBusy $w off $data(w:hlist)
- # correct indicator to represent children status (added above)
- if {[llength [$data(w:hlist) info children $dir]]} {
- tixVTree:SetMode $w $dir close
- } else {
- tixVTree:SetMode $w $dir none
- }
- } else {
- $data(w:hlist) delete offsprings $dir
- tixVTree:SetMode $w $dir open
- }
- }
- proc tixDirTree:ToggleDir {w value mode} {
- upvar #0 $w data
- tixDirTree:LoadDir $w $value $mode
- tixDirTree:CallCommand $w
- }
- proc tixDirTree:CallCommand {w} {
- upvar #0 $w data
- if {[llength $data(-command)] && !$data(-disablecallback)} {
- set bind(specs) {%V}
- set bind(%V) $data(-value)
- tixEvalCmdBinding $w $data(-command) bind $data(-value)
- }
- }
- proc tixDirTree:CallBrowseCmd {w ent} {
- upvar #0 $w data
- if {[llength $data(-browsecmd)] && !$data(-disablecallback)} {
- set bind(specs) {%V}
- set bind(%V) $data(-value)
- tixEvalCmdBinding $w $data(-browsecmd) bind [list $data(-value)]
- }
- }
- proc tixDirTree:StartUp {w} {
- if {![winfo exists $w]} { return }
- upvar #0 $w data
- # make sure that all the basic volumes are listed
- set imgopenfold [tix getimage openfold]
- foreach fspath [tixFSVolumes] {
- tixDirTree:AddToList $w $fspath $imgopenfold
- }
- tixDirTree:LoadDir $w [tixFSExternal $data(i-directory)]
- }
- proc tixDirTree:ChangeDir {w fsdir {forced 0}} {
- upvar #0 $w data
- set dir [tixFSInternal $fsdir]
- if {!$forced && $data(i-directory) eq $dir} {
- return
- }
- if {!$forced && [$data(w:hlist) info exists $dir]} {
- # Set the old directory to "non active"
- #
- if {[$data(w:hlist) info exists $data(i-directory)]} {
- $data(w:hlist) entryconfig $data(i-directory) \
- -image [tix getimage folder]
- }
- $data(w:hlist) entryconfig $dir -image [tix getimage act_fold]
- } else {
- if {$forced} {
- if {[llength [$data(w:hlist) info children $dir]]} {
- set mode expand
- } else {
- set mode flatten
- }
- } else {
- set mode toggle
- }
- tixDirTree:LoadDir $w $fsdir $mode
- tixDirTree:CallCommand $w
- }
- tixDirTree:SetDir $w $fsdir
- }
- proc tixDirTree:SetDir {w path} {
- upvar #0 $w data
- set data(i-directory) [tixFSInternal $path]
- set data(-value) [tixFSNativeNorm $path]
- }
- #----------------------------------------------------------------------
- #
- # Virtual Methods
- #
- #----------------------------------------------------------------------
- proc tixDirTree:OpenCmd {w ent} {
- set fsdir [tixFSExternal $ent]
- tixDirTree:ToggleDir $w $fsdir expand
- tixDirTree:ChangeDir $w $fsdir
- tixDirTree:CallBrowseCmd $w $fsdir
- }
- proc tixDirTree:CloseCmd {w ent} {
- set fsdir [tixFSExternal $ent]
- tixDirTree:ToggleDir $w $fsdir flatten
- tixDirTree:ChangeDir $w $fsdir
- tixDirTree:CallBrowseCmd $w $fsdir
- }
- proc tixDirTree:Command {w B} {
- upvar #0 $w data
- upvar $B bind
- set ent [tixEvent flag V]
- tixChainMethod $w Command $B
- if {[llength $data(-command)]} {
- set fsdir [tixFSExternal $ent]
- tixEvalCmdBinding $w $data(-command) bind $fsdir
- }
- }
- # This is a virtual method
- #
- proc tixDirTree:BrowseCmd {w B} {
- upvar #0 $w data
- upvar 1 $B bind
- set ent [tixEvent flag V]
- set fsdir [tixFSExternal $ent]
- # This is a hack because %V may have been modified by callbrowsecmd
- set fsdir [file normalize $fsdir]
- tixDirTree:ChangeDir $w $fsdir
- tixDirTree:CallBrowseCmd $w $fsdir
- }
- #----------------------------------------------------------------------
- #
- # Public Methods
- #
- #----------------------------------------------------------------------
- proc tixDirTree:chdir {w value} {
- tixDirTree:ChangeDir $w [file normalize $value]
- }
- proc tixDirTree:refresh {w {dir ""}} {
- upvar #0 $w data
- if {$dir eq ""} {
- set dir $data(-value)
- }
- set dir [file normalize $dir]
- tixDirTree:ChangeDir $w $dir 1
- # Delete any stale directories that no longer exist
- #
- foreach child [$data(w:hlist) info children [tixFSInternal $dir]] {
- if {![file exists [tixFSExternal $child]]} {
- $data(w:hlist) delete entry $child
- }
- }
- }
- proc tixDirTree:config-directory {w value} {
- tixDirTree:ChangeDir $w [file normalize $value]
- }
|