home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / extra / chooseDir.tcl < prev    next >
Text File  |  2000-11-02  |  5KB  |  197 lines

  1. # A platform-independent, pure Tcl version of tk_chooseDirectory
  2. # for use on non-Win32 platforms.
  3.  
  4. package require opt
  5.  
  6. namespace eval ::tkChooseDirectory {
  7.     variable value
  8. }
  9.  
  10. ::tcl::OptProc ::tkChooseDirectory::tk_chooseDirectory {
  11.     {-initialdir -string ""  
  12.             "Initial directory for browser"}
  13.     {-mustexist              
  14.             "If specified, user can't type in a new directory"}
  15.     {-parent     -string "."
  16.             "Parent window for browser"}
  17.     {-title      -string "Choose Directory"
  18.             "Title for browser window"}
  19. } {
  20.     # Handle default directory
  21.     if {[string length $initialdir] == 0} {
  22.     set initialdir [pwd]
  23.     }
  24.  
  25.     # Handle default parent window
  26.     if {[string compare $parent "."] == 0} {
  27.     set parent ""
  28.     }
  29.  
  30.     set w [toplevel $parent.choosedirectory]
  31.     wm title $w $title
  32.  
  33.     label $w.label -text "Directory:"
  34.     grid $w.label -sticky w 
  35.  
  36.     # Some frames for grouping
  37.  
  38.     frame $w.list
  39.     grid $w.list -sticky news -pady 1m -padx 1m
  40.  
  41.     if {[llength [file volumes]]} {
  42.     # On Macs it would be nice to add a volume combobox here.
  43.     }
  44.  
  45.     frame $w.entry
  46.     grid $w.entry -sticky news -pady 1m -padx 1m
  47.  
  48.     frame $w.buttons
  49.     grid $w.buttons -sticky news -pady 1m -padx 1m
  50.  
  51.     # Only directory list expands height
  52.     grid rowconfigure $w 1 -weight 1
  53.     # All resize width
  54.     grid columnconfigure $w 0 -weight 1
  55.  
  56.     #----------------------------------------
  57.     # Fill the top frame (user entry)
  58.     label $w.entry.l -text "Selection:"
  59.     pack $w.entry.l -side left
  60.     entry $w.entry.e -width 30
  61.     pack $w.entry.e -side left -expand 1 -fill x
  62.     
  63.     $w.entry.e insert end $initialdir
  64.  
  65.     #----------------------------------------
  66.     # Fill the middle frame (directory content list)
  67.     listbox $w.list.lb -height 8 \
  68.         -yscrollcommand [list $w.list.sb set] \
  69.         -selectmode browse \
  70.         -setgrid true \
  71.         -exportselection 0 \
  72.         -takefocus 1
  73.     scrollbar $w.list.sb -orient vertical \
  74.         -command [list $w.list.lb yview]
  75.  
  76.     grid $w.list.lb $w.list.sb -sticky news
  77.     grid configure $w.list.lb -ipadx 2m
  78.     grid rowconfigure $w.list 0 -weight 1
  79.     grid columnconfigure $w.list 0 -weight 1
  80.  
  81.     #----------------------------------------
  82.     # Commands for various bindings (which follow)
  83.     set okCommand  [namespace code \
  84.         [list Done $w ok ::tkChooseDirectory::value($w)]]
  85.  
  86.     set cancelCommand  [namespace code \
  87.         [list Done $w cancel ::tkChooseDirectory::value($w)]]
  88.  
  89.     #----------------------------------------
  90.     # Fill the bottom frame (buttons)
  91.     button $w.buttons.ok     -width 8 -text OK \
  92.         -command $okCommand
  93.     button $w.buttons.cancel -width 8 -text Cancel \
  94.         -command $cancelCommand
  95.     pack $w.buttons.ok $w.buttons.cancel -side left -expand 1
  96.  
  97.     #-----------------------------------------
  98.     # Other bindings
  99.     # <Return> is the same as OK
  100.     bind $w <Return> $okCommand
  101.  
  102.     # <Escape> is the same as cancel
  103.     bind $w <Escape> $cancelCommand
  104.  
  105.     # Closing the window is the same as cancel
  106.     wm protocol $w WM_DELETE_WINDOW $cancelCommand
  107.     
  108.     #----------------------------------------
  109.     # Fill listbox and bind for browsing
  110.     Refresh $w.list.lb $initialdir
  111.     
  112.     bind $w.list.lb <Double-Button-1> [namespace code \
  113.         [list Update $w.entry.e $w.list.lb]]
  114.  
  115.     # WUZ - need to center $w over parent
  116.  
  117.     # Set the min size when the size is known
  118. #    tkwait visibility $w
  119. #    tkChooseDirectory::MinSize $w
  120.  
  121.     focus $w.entry.e
  122.     $w.entry.e selection range 0 end
  123.     grab set $w
  124.  
  125.     # Wait for OK, Cancel or close
  126.     tkwait window $w
  127.  
  128.     grab release $w
  129.     
  130.     set dir $::tkChooseDirectory::value($w)
  131.     unset ::tkChooseDirectory::value($w)
  132.     return $dir
  133. }
  134. # tkChooseDirectory::tk_chooseDirectory
  135.  
  136. proc ::tkChooseDirectory::MinSize { w } {
  137.     set geometry [wm geometry $w]
  138.  
  139.     regexp {([0-9]*)x([0-9]*)\+} geometry whole width height
  140.  
  141.     wm minsize $w $width $height
  142. }
  143.  
  144. proc ::tkChooseDirectory::Done { w why varName } {
  145.     variable value
  146.  
  147.     switch -- $why {
  148.     ok {
  149.         # If mustexist, validate with [cd]
  150.         set value($w) [$w.entry.e get]
  151.     }
  152.     cancel {
  153.         set value($w) ""
  154.     }
  155.     }
  156.  
  157.     destroy $w
  158. }
  159.  
  160. proc ::tkChooseDirectory::Refresh { listbox dir } {
  161.     $listbox delete 0 end
  162.  
  163.     $listbox insert end ".."
  164.     foreach f [lsort [glob -nocomplain $dir/*]] {
  165.     if {[file isdirectory $f]} {
  166.         $listbox insert end "[file tail $f]/"
  167.     }
  168.     }
  169. }
  170.  
  171. proc ::tkChooseDirectory::Update { entry listbox } {
  172.     set subdir [$listbox get [$listbox curselection]]
  173.     if {[string compare $subdir ".."] == 0} {
  174.     set fullpath [file dirname [$entry get]]
  175.     } else {
  176.     set fullpath [file join [$entry get] $subdir]
  177.     }
  178.     $entry delete 0 end
  179.     $entry insert end $fullpath
  180.     Refresh $listbox $fullpath
  181. }
  182.  
  183. # Some test code
  184. if {[string compare [info script] $argv0] == 0} {
  185.     catch {rename ::tk_chooseDirectory tk_chooseDir}
  186.     
  187.     proc tk_chooseDirectory { args } {
  188.     uplevel ::tkChooseDirectory::tk_chooseDirectory $args
  189.     }
  190.  
  191.     wm withdraw .
  192.     set dir [tk_chooseDirectory -initialdir [pwd] \
  193.         -title "Choose a directory"]
  194.     tk_messageBox -message "dir:<<$dir>>"
  195.     exit
  196. }
  197.