home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 December
/
PCWorld_2000-12_cd.bin
/
Komunikace
/
Comanche
/
extra
/
tkgetdir.tcl
< prev
Wrap
Text File
|
2000-11-02
|
12KB
|
397 lines
#########################################################
# Directory Selector TCL version 1.3
#
# Daniel Roche, <daniel.roche@bigfoot.com>
#
# thanks to :
# Cyrille Artho <cartho@netlink.ch> for the 'saving pwd fix'
# Terry Griffin <terryg@axian.com> for <Return> key bindings on buttons.
# Kenneth Kehl <Kenneth.Kehl@marconiastronics.com> for blocking at end of dir tree
#
#########################################################
#########################################################
#
# tk_getDirectory [option value ...]
#
# options are :
# [-initialdir dir] display in dir
# [-title string] make string title of dialog window
# [-ok string] make string the label of OK button
# [-open string] make string the label of OPEN button
# [-cancel string] make string the label of CANCEL button
# [-msg1 string] make string the label of the first directory message
# [-msg2 string] make string the label of the second directory message
#
#########################################################
namespace eval tkgetdir {
variable drives
variable fini
namespace export tk_getDirectory
}
proc tkgetdir::tk_getDirectory {args} {
global tcl_platform
#
# arguments
#
set _titre "Directory Selector"
set _ldir Directory:
set _ldnam "Directory Name:"
set _open Ok
set _expand Open
set _cancel Cancel
set ind 0
set max [llength $args]
set pwd [pwd]
while { $ind < $max } {
switch -exact -- [lindex $args $ind] {
"-initialdir" {
incr ind
cd [lindex $args $ind]
incr ind
}
"-title" {
incr ind
set _titre [lindex $args $ind]
incr ind
}
"-ok" {
incr ind
set _open [lindex $args $ind]
incr ind
}
"-open" {
incr ind
set _expand [lindex $args $ind]
incr ind
}
"-cancel" {
incr ind
set _cancel [lindex $args $ind]
incr ind
}
"-msg1" {
incr ind
set _ldir [lindex $args $ind]
incr ind
}
"-msg2" {
incr ind
set _ldnam [lindex $args $ind]
incr ind
}
default {
puts "unknown option [lindex $args $ind]"
return ""
}
}
}
#
# variables et data
#
set tkgetdir::fini 0
image create bitmap b_up -data "
#define up_width 31
#define up_height 23
static unsigned char up_bits[] = {
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x80, 0x00, 0x3f, 0x00, 0x80, 0x80, 0x40, 0x00, 0x80,
0x40, 0x80, 0x00, 0x80, 0xe0, 0xff, 0xff, 0x83, 0x20, 0x00, 0x00, 0x82,
0x20, 0x04, 0x00, 0x82, 0x20, 0x0e, 0x00, 0x82, 0x20, 0x1f, 0x00, 0x82,
0x20, 0x04, 0x00, 0x82, 0x20, 0x04, 0x00, 0x82, 0x20, 0x04, 0x00, 0x82,
0x20, 0xfc, 0x0f, 0x82, 0x20, 0x00, 0x00, 0x82, 0x20, 0x00, 0x00, 0x82,
0xe0, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80};"
image create bitmap b_dir -background #ffff80 -data "
#define dir_width 17
#define dir_height 16
static unsigned char dir_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x10, 0x02, 0x00,
0x08, 0x04, 0x00, 0xfc, 0x7f, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00,
0x04, 0x40, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00,
0x04, 0x40, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};" \
-maskdata "
#define dirm_width 17
#define dirm_height 16
static unsigned char dirm_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0xf0, 0x03, 0x00,
0xf8, 0x07, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00,
0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00,
0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
switch -exact $tcl_platform(platform) {
unix {
font create myfont -family lucida -size 14 -weight bold
}
windows {
font create myfont -family courier -size 12
}
}
#
# widgets
#
toplevel .dirsel
grab set .dirsel
wm geometry .dirsel 500x250
wm title .dirsel $_titre
event add <<RetEnt>> <Return> <KP_Enter>
frame .dirsel.f1 -relief flat -borderwidth 0
frame .dirsel.f2 -relief sunken -borderwidth 2
frame .dirsel.f3 -relief flat -borderwidth 0
frame .dirsel.f4 -relief flat -borderwidth 0
pack .dirsel.f1 -fill x
pack .dirsel.f2 -fill both -expand 1 -padx 6 -pady 6
pack .dirsel.f3 -fill x
pack .dirsel.f4 -fill x
label .dirsel.f1.lab -text $_ldir
menubutton .dirsel.f1.dir -relief raised -indicatoron 1 -anchor w \
-menu .dirsel.f1.dir.m
menu .dirsel.f1.dir.m -tearoff 0
button .dirsel.f1.up -image b_up -command tkgetdir::UpDir
bind .dirsel.f1.up <<RetEnt>> {.dirsel.f1.up invoke}
pack .dirsel.f1.up -side right -padx 4 -pady 4
pack .dirsel.f1.lab -side left -padx 4 -pady 4
pack .dirsel.f1.dir -side right -padx 4 -pady 4 -fill x -expand 1
canvas .dirsel.f2.cv -borderwidth 0 -yscrollcommand ".dirsel.f2.sb set"
if ![string compare $tcl_platform(platform) windows] {
.dirsel.f2.cv configure -background white
}
scrollbar .dirsel.f2.sb -command ".dirsel.f2.cv yview"
set scw 16
place .dirsel.f2.cv -x 0 -relwidth 1.0 -width [expr -$scw ] -y 0 \
-relheight 1.0
place .dirsel.f2.sb -relx 1.0 -x [expr -$scw ] -width $scw -y 0 \
-relheight 1.0
unset scw
.dirsel.f2.cv bind TXT <Any-Enter> tkgetdir::EnterItem
.dirsel.f2.cv bind TXT <Any-Leave> tkgetdir::LeaveItem
.dirsel.f2.cv bind TXT <Any-Button> tkgetdir::ClickItem
.dirsel.f2.cv bind TXT <Double-Button> tkgetdir::DoubleClickItem
.dirsel.f2.cv bind IMG <Any-Enter> tkgetdir::EnterItem
.dirsel.f2.cv bind IMG <Any-Leave> tkgetdir::LeaveItem
.dirsel.f2.cv bind IMG <Any-Button> tkgetdir::ClickItem
.dirsel.f2.cv bind IMG <Double-Button> tkgetdir::DoubleClickItem
label .dirsel.f3.lnam -text $_ldnam
entry .dirsel.f3.chosen -takefocus 0
pack .dirsel.f3.lnam -side left -padx 4 -pady 4
pack .dirsel.f3.chosen -side right -fill x -expand 1 -padx 4 -pady 4
button .dirsel.f4.open -text $_open -command {
set tmp [.dirsel.f3.chosen get]
if [ string length $tmp ] {
set tkgetdir::fini 1
}
}
bind .dirsel.f4.open <<RetEnt>> {.dirsel.f4.open invoke}
button .dirsel.f4.expand -text $_expand -command tkgetdir::DownDir
bind .dirsel.f4.expand <<RetEnt>> {.dirsel.f4.expand invoke}
button .dirsel.f4.cancel -text $_cancel -command {
set tkgetdir::fini -1
}
bind .dirsel.f4.cancel <<RetEnt>> {.dirsel.f4.cancel invoke}
pack .dirsel.f4.open .dirsel.f4.expand -side left -padx 10 -pady 4
pack .dirsel.f4.cancel -side right -padx 10 -pady 4
#
# realwork
#
tkgetdir::ShowDir [pwd]
#
# wait user
#
tkwait variable tkgetdir::fini
if { $tkgetdir::fini == 1 } {
set curdir [.dirsel.f1.dir cget -text]
set nnam [.dirsel.f3.chosen get]
set retval [ file join $curdir $nnam ]
} else {
set retval ""
}
font delete myfont
destroy .dirsel
event delete <<RetEnt>>
cd $pwd
return $retval
}
proc tkgetdir::ShowDir {curdir} {
global tcl_platform
variable drives
cd $curdir
.dirsel.f1.dir configure -text $curdir
set hi1 [font metrics myfont -linespace]
set hi2 [image height b_dir]
if { $hi1 > $hi2 } {
set hi $hi1
} else {
set hi $hi2
}
set wi1 [image width b_dir]
incr wi1 4
set wi2 [winfo width .dirsel.f2.cv]
set lidir [list]
foreach file [ glob -nocomplain * ] {
if [ file isdirectory [string trim $file "~"] ] {
lappend lidir $file
}
}
set sldir [lsort $lidir]
.dirsel.f2.cv delete all
set ind 0
foreach file $sldir {
if [ file isdirectory $file ] {
.dirsel.f2.cv create image 2 [expr $ind * $hi] \
-anchor nw -image b_dir -tags IMG
.dirsel.f2.cv create text $wi1 [expr $ind * $hi] \
-anchor nw -text $file -font myfont -tags TXT
set ind [ expr $ind + 1 ]
}
}
set ha [expr $ind * $hi]
.dirsel.f2.cv configure -scrollregion [list 0 0 $wi2 $ha]
set curlst [file split $curdir]
set nbr [llength $curlst]
.dirsel.f1.dir.m delete 0 last
incr nbr -2
for {set ind $nbr} {$ind >= 0} {incr ind -1} {
set tmplst [ lrange $curlst 0 $ind]
set tmpdir [ eval file join $tmplst]
.dirsel.f1.dir.m add command -label $tmpdir \
-command "tkgetdir::ShowDir {$tmpdir}"
}
if {[info exist drives] == 0} {
set drives [file volume]
}
if ![string compare $tcl_platform(platform) windows] {
foreach drive $drives {
.dirsel.f1.dir.m add command -label $drive \
-command "tkgetdir::ShowDir {$drive}"
}
}
}
proc tkgetdir::UpDir {} {
set curdir [.dirsel.f1.dir cget -text]
set curlst [file split $curdir]
set nbr [llength $curlst]
if { $nbr < 2 } {
return
}
set tmp [expr $nbr - 2]
set newlst [ lrange $curlst 0 $tmp ]
set newdir [ eval file join $newlst ]
.dirsel.f3.chosen delete 0 end
tkgetdir::ShowDir $newdir
}
proc tkgetdir::DownDir {} {
set curdir [.dirsel.f1.dir cget -text]
set nnam [.dirsel.f3.chosen get]
set newdir [ file join $curdir $nnam ]
# change 07/19/99
# If there are more dirs, permit display of one level down.
# Otherwise, block display and hilight selection in red.
set areDirs 0
foreach f [glob -nocomplain [file join $newdir *]] {
if {[file isdirectory $f]} {
set areDirs 1
break
}
}
if {$areDirs} {
.dirsel.f3.chosen delete 0 end
tkgetdir::ShowDir $newdir
} else {
set id [.dirsel.f2.cv find withtag HASBOX ]
.dirsel.f2.cv itemconfigure $id -fill #FF0000
}
}
proc tkgetdir::EnterItem {} {
global tcl_platform
set id [.dirsel.f2.cv find withtag current]
set wt [.dirsel.f2.cv itemcget $id -tags]
if {[lsearch -exact $wt IMG] >= 0} {
set id [.dirsel.f2.cv find above $id]
}
if [string compare $tcl_platform(platform) windows] {
set cocol #00FF00
} else {
set cocol #0000FF
}
.dirsel.f2.cv itemconfigure $id -fill $cocol
}
proc tkgetdir::LeaveItem {} {
set id [.dirsel.f2.cv find withtag current]
set wt [.dirsel.f2.cv itemcget $id -tags]
if {[lsearch -exact $wt IMG] >= 0} {
set id [.dirsel.f2.cv find above $id]
}
.dirsel.f2.cv itemconfigure $id -fill black
}
proc tkgetdir::ClickItem {} {
.dirsel.f2.cv delete BOX
.dirsel.f2.cv dtag HASBOX HASBOX
set id [.dirsel.f2.cv find withtag current]
set wt [.dirsel.f2.cv itemcget $id -tags]
if {[lsearch -exact $wt IMG] >= 0} {
set id [.dirsel.f2.cv find above $id]
}
set bxr [.dirsel.f2.cv bbox $id]
.dirsel.f2.cv addtag HASBOX withtag current
eval .dirsel.f2.cv create rectangle $bxr -fill #a2a2ff -outline #a2a2ff -tags BOX
.dirsel.f2.cv lower BOX
set nam [.dirsel.f2.cv itemcget $id -text]
.dirsel.f3.chosen delete 0 end
.dirsel.f3.chosen insert 0 $nam
}
proc tkgetdir::DoubleClickItem {} {
set id [.dirsel.f2.cv find withtag current]
tkgetdir::DownDir
}