home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_tcl_tk8.3_choosedir.tcl < prev    next >
Encoding:
Text File  |  2001-07-26  |  8.1 KB  |  265 lines

  1. # choosedir.tcl --
  2. #
  3. #    Choose directory dialog implementation for Unix/Mac.
  4. #
  5. # Copyright (c) 1998-2000 by Scriptics Corporation.
  6. # All rights reserved.
  7. # RCS: @(#) $Id: choosedir.tcl,v 1.7 2000/04/19 23:12:56 hobbs Exp $
  8.  
  9. # Make sure the tk::dialog namespace, in which all dialogs should live, exists
  10. namespace eval ::tk::dialog {}
  11. namespace eval ::tk::dialog::file {}
  12.  
  13. # Make the chooseDir namespace inside the dialog namespace
  14. namespace eval ::tk::dialog::file::chooseDir {
  15. }
  16.  
  17. # ::tk::dialog::file::tkChooseDirectory --
  18. #
  19. #    Implements the TK directory selection dialog.
  20. #
  21. # Arguments:
  22. #    args        Options parsed by the procedure.
  23. #
  24. proc ::tk::dialog::file::chooseDir::tkChooseDirectory {args} {
  25.     global tkPriv
  26.     set dataName __tk_choosedir
  27.     upvar ::tk::dialog::file::$dataName data
  28.     ::tk::dialog::file::chooseDir::Config $dataName $args
  29.  
  30.     if {[string equal $data(-parent) .]} {
  31.         set w .$dataName
  32.     } else {
  33.         set w $data(-parent).$dataName
  34.     }
  35.  
  36.     # (re)create the dialog box if necessary
  37.     #
  38.     if {![winfo exists $w]} {
  39.     ::tk::dialog::file::Create $w TkChooseDir
  40.     } elseif {[string compare [winfo class $w] TkChooseDir]} {
  41.     destroy $w
  42.     ::tk::dialog::file::Create $w TkChooseDir
  43.     } else {
  44.     set data(dirMenuBtn) $w.f1.menu
  45.     set data(dirMenu) $w.f1.menu.menu
  46.     set data(upBtn) $w.f1.up
  47.     set data(icons) $w.icons
  48.     set data(ent) $w.f2.ent
  49.     set data(okBtn) $w.f2.ok
  50.     set data(cancelBtn) $w.f3.cancel
  51.     }
  52.     wm transient $w $data(-parent)
  53.  
  54.     trace variable data(selectPath) w [list ::tk::dialog::file::SetPath $w]
  55.     $data(dirMenuBtn) configure \
  56.         -textvariable ::tk::dialog::file::${dataName}(selectPath)
  57.  
  58.     set data(filter) "*"
  59.     set data(previousEntryText) ""
  60.     ::tk::dialog::file::UpdateWhenIdle $w
  61.  
  62.     # Withdraw the window, then update all the geometry information
  63.     # so we know how big it wants to be, then center the window in the
  64.     # display and de-iconify it.
  65.  
  66.     ::tk::PlaceWindow $w widget $data(-parent)
  67.     wm title $w $data(-title)
  68.  
  69.     # Set a grab and claim the focus too.
  70.  
  71.     ::tk::SetFocusGrab $w $data(ent)
  72.     $data(ent) delete 0 end
  73.     $data(ent) insert 0 $data(selectPath)
  74.     $data(ent) selection range 0 end
  75.     $data(ent) icursor end
  76.  
  77.     # Wait for the user to respond, then restore the focus and
  78.     # return the index of the selected button.  Restore the focus
  79.     # before deleting the window, since otherwise the window manager
  80.     # may take the focus away so we can't redirect it.  Finally,
  81.     # restore any grab that was in effect.
  82.  
  83.     tkwait variable tkPriv(selectFilePath)
  84.  
  85.     ::tk::RestoreFocusGrab $w $data(ent) withdraw
  86.  
  87.     # Cleanup traces on selectPath variable
  88.     #
  89.  
  90.     foreach trace [trace vinfo data(selectPath)] {
  91.     trace vdelete data(selectPath) [lindex $trace 0] [lindex $trace 1]
  92.     }
  93.     $data(dirMenuBtn) configure -textvariable {}
  94.  
  95.     # Return value to user
  96.     #
  97.     
  98.     return $tkPriv(selectFilePath)
  99. }
  100.  
  101. # ::tk::dialog::file::chooseDir::Config --
  102. #
  103. #    Configures the Tk choosedir dialog according to the argument list
  104. #
  105. proc ::tk::dialog::file::chooseDir::Config {dataName argList} {
  106.     upvar ::tk::dialog::file::$dataName data
  107.  
  108.     # 0: Delete all variable that were set on data(selectPath) the
  109.     # last time the file dialog is used. The traces may cause troubles
  110.     # if the dialog is now used with a different -parent option.
  111.     #
  112.     foreach trace [trace vinfo data(selectPath)] {
  113.     trace vdelete data(selectPath) [lindex $trace 0] [lindex $trace 1]
  114.     }
  115.  
  116.     # 1: the configuration specs
  117.     #
  118.     set specs {
  119.     {-mustexist "" "" 0}
  120.     {-initialdir "" "" ""}
  121.     {-parent "" "" "."}
  122.     {-title "" "" ""}
  123.     }
  124.  
  125.     # 2: default values depending on the type of the dialog
  126.     #
  127.     if {![info exists data(selectPath)]} {
  128.     # first time the dialog has been popped up
  129.     set data(selectPath) [pwd]
  130.     }
  131.  
  132.     # 3: parse the arguments
  133.     #
  134.     tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList
  135.  
  136.     if {$data(-title) == ""} {
  137.     set data(-title) "Choose Directory"
  138.     }
  139.  
  140.     # 4: set the default directory and selection according to the -initial
  141.     #    settings
  142.     #
  143.     if {$data(-initialdir) != ""} {
  144.     # Ensure that initialdir is an absolute path name.
  145.     if {[file isdirectory $data(-initialdir)]} {
  146.         set old [pwd]
  147.         cd $data(-initialdir)
  148.         set data(selectPath) [pwd]
  149.         cd $old
  150.     } else {
  151.         set data(selectPath) [pwd]
  152.     }
  153.     }
  154.  
  155.     if {![winfo exists $data(-parent)]} {
  156.     error "bad window path name \"$data(-parent)\""
  157.     }
  158. }
  159.  
  160. # Gets called when user presses Return in the "Selection" entry or presses OK.
  161. #
  162. proc ::tk::dialog::file::chooseDir::OkCmd {w} {
  163.     upvar ::tk::dialog::file::[winfo name $w] data
  164.  
  165.     # This is the brains behind selecting non-existant directories.  Here's
  166.     # the flowchart:
  167.     # 1.  If the icon list has a selection, join it with the current dir,
  168.     #     and return that value.
  169.     # 1a.  If the icon list does not have a selection ...
  170.     # 2.  If the entry is empty, do nothing.
  171.     # 3.  If the entry contains an invalid directory, then...
  172.     # 3a.   If the value is the same as last time through here, end dialog.
  173.     # 3b.   If the value is different than last time, save it and return.
  174.     # 4.  If entry contains a valid directory, then...
  175.     # 4a.   If the value is the same as the current directory, end dialog.
  176.     # 4b.   If the value is different from the current directory, change to
  177.     #       that directory.
  178.  
  179.     set iconText [tkIconList_Get $data(icons)]
  180.     if { ![string equal $iconText ""] } {
  181.     set iconText [file join $data(selectPath) $iconText]
  182.     ::tk::dialog::file::chooseDir::Done $w $iconText
  183.     } else {
  184.     set text [$data(ent) get]
  185.     if { [string equal $text ""] } {
  186.         return
  187.     }
  188.     set text [eval file join [file split [string trim $text]]]
  189.     if { ![file exists $text] || ![file isdirectory $text] } {
  190.         # Entry contains an invalid directory.  If it's the same as the
  191.         # last time they came through here, reset the saved value and end
  192.         # the dialog.  Otherwise, save the value (so we can do this test
  193.         # next time).
  194.         if { [string equal $text $data(previousEntryText)] } {
  195.         set data(previousEntryText) ""
  196.         ::tk::dialog::file::chooseDir::Done $w $text
  197.         } else {
  198.         set data(previousEntryText) $text
  199.         }
  200.     } else {
  201.         # Entry contains a valid directory.  If it is the same as the
  202.         # current directory, end the dialog.  Otherwise, change to that
  203.         # directory.
  204.         if { [string equal $text $data(selectPath)] } {
  205.         ::tk::dialog::file::chooseDir::Done $w $text
  206.         } else {
  207.         set data(selectPath) $text
  208.         }
  209.     }
  210.     }
  211.     return
  212. }
  213.  
  214. proc ::tk::dialog::file::chooseDir::DblClick {w} {
  215.     upvar ::tk::dialog::file::[winfo name $w] data
  216.     set text [tkIconList_Get $data(icons)]
  217.     if {[string compare $text ""]} {
  218.     set file $data(selectPath)
  219.     if {[file isdirectory $file]} {
  220.         ::tk::dialog::file::ListInvoke $w $text
  221.         return
  222.     }
  223.     }
  224. }    
  225.  
  226. # Gets called when user browses the IconList widget (dragging mouse, arrow
  227. # keys, etc)
  228. #
  229. proc ::tk::dialog::file::chooseDir::ListBrowse {w text} {
  230.     upvar ::tk::dialog::file::[winfo name $w] data
  231.  
  232.     if {[string equal $text ""]} {
  233.     return
  234.     }
  235.  
  236.     set file [::tk::dialog::file::JoinFile $data(selectPath) $text]
  237.     $data(ent) delete 0 end
  238.     $data(ent) insert 0 $file
  239. }
  240.  
  241. # ::tk::dialog::file::chooseDir::Done --
  242. #
  243. #    Gets called when user has input a valid filename.  Pops up a
  244. #    dialog box to confirm selection when necessary. Sets the
  245. #    tkPriv(selectFilePath) variable, which will break the "tkwait"
  246. #    loop in tk_chooseDirectory and return the selected filename to the
  247. #    script that calls tk_getOpenFile or tk_getSaveFile
  248. #
  249. proc ::tk::dialog::file::chooseDir::Done {w {selectFilePath ""}} {
  250.     upvar ::tk::dialog::file::[winfo name $w] data
  251.     global tkPriv
  252.  
  253.     if {[string equal $selectFilePath ""]} {
  254.     set selectFilePath $data(selectPath)
  255.     }
  256.     if { $data(-mustexist) } {
  257.     if { ![file exists $selectFilePath] || \
  258.         ![file isdir $selectFilePath] } {
  259.         return
  260.     }
  261.     }
  262.     set tkPriv(selectFilePath) $selectFilePath
  263. }
  264.