📄 tkfbox.tcl
字号:
upvar #0 $dataName data global tk_library tkPriv catch {unset data(updateId)} if {![info exists tkPriv(folderImage)]} { set tkPriv(folderImage) [image create photo -data {R0lGODlhEAAMAKEAAAD//wAAAPD/gAAAACH5BAEAAAAALAAAAAAQAAwAAAIghINhyycvVFsBQtmS3rjaH1Hg141WaT5ouprt2HHcUgAAOw==}] set tkPriv(fileImage) [image create photo -data {R0lGODlhDAAMAKEAALLA3AAAAP//8wAAACH5BAEAAAAALAAAAAAMAAwAAAIgRI4Ha+IfWHsOrSASvJTGhnhcV3EJlo3kh53ltF5nAhQAOw==}] } set folder $tkPriv(folderImage) set file $tkPriv(fileImage) set appPWD [pwd] if {[catch { cd $data(selectPath) }]} { # We cannot change directory to $data(selectPath). $data(selectPath) # should have been checked before tkFDialog_Update is called, so # we normally won't come to here. Anyways, give an error and abort # action. tk_messageBox -type ok -parent $data(-parent) -message \ "Cannot change to the directory \"$data(selectPath)\".\nPermission denied."\ -icon warning cd $appPWD return } # Turn on the busy cursor. BUG?? We haven't disabled X events, though, # so the user may still click and cause havoc ... # set entCursor [$data(ent) cget -cursor] set dlgCursor [$w cget -cursor] $data(ent) config -cursor watch $w config -cursor watch update idletasks tkIconList_DeleteAll $data(icons) # Make the dir list # foreach f [lsort -dictionary [glob -nocomplain .* *]] { if {![string compare $f .]} { continue } if {![string compare $f ..]} { continue } if {[file isdir ./$f]} { if {![info exists hasDoneDir($f)]} { tkIconList_Add $data(icons) $folder $f set hasDoneDir($f) 1 } } } # Make the file list # if {![string compare $data(filter) *]} { set files [lsort -dictionary \ [glob -nocomplain .* *]] } else { set files [lsort -dictionary \ [eval glob -nocomplain $data(filter)]] } set top 0 foreach f $files { if {![file isdir ./$f]} { if {![info exists hasDoneFile($f)]} { tkIconList_Add $data(icons) $file $f set hasDoneFile($f) 1 } } } tkIconList_Arrange $data(icons) # Update the Directory: option menu # set list "" set dir "" foreach subdir [file split $data(selectPath)] { set dir [file join $dir $subdir] lappend list $dir } $data(dirMenu) delete 0 end set var [format %s(selectPath) $dataName] foreach path $list { $data(dirMenu) add command -label $path -command [list set $var $path] } # Restore the PWD to the application's PWD # cd $appPWD # turn off the busy cursor. # $data(ent) config -cursor $entCursor $w config -cursor $dlgCursor}# tkFDialog_SetPathSilently --## Sets data(selectPath) without invoking the trace procedure#proc tkFDialog_SetPathSilently {w path} { upvar #0 [winfo name $w] data trace vdelete data(selectPath) w "tkFDialog_SetPath $w" set data(selectPath) $path trace variable data(selectPath) w "tkFDialog_SetPath $w"}# This proc gets called whenever data(selectPath) is set#proc tkFDialog_SetPath {w name1 name2 op} { if {[winfo exists $w]} { upvar #0 [winfo name $w] data tkFDialog_UpdateWhenIdle $w }}# This proc gets called whenever data(filter) is set#proc tkFDialog_SetFilter {w type} { upvar #0 [winfo name $w] data upvar \#0 $data(icons) icons set data(filter) [lindex $type 1] $data(typeMenuBtn) config -text [lindex $type 0] -indicatoron 1 $icons(sbar) set 0.0 0.0 tkFDialog_UpdateWhenIdle $w}# tkFDialogResolveFile --## Interpret the user's text input in a file selection dialog.# Performs:## (1) ~ substitution# (2) resolve all instances of . and ..# (3) check for non-existent files/directories# (4) check for chdir permissions## Arguments:# context: the current directory you are in# text: the text entered by the user# defaultext: the default extension to add to files with no extension## Return vaue:# [list $flag $directory $file]## flag = OK : valid input# = PATTERN : valid directory/pattern# = PATH : the directory does not exist# = FILE : the directory exists by the file doesn't# exist# = CHDIR : Cannot change to the directory# = ERROR : Invalid entry## directory : valid only if flag = OK or PATTERN or FILE# file : valid only if flag = OK or PATTERN## directory may not be the same as context, because text may contain# a subdirectory name#proc tkFDialogResolveFile {context text defaultext} { set appPWD [pwd] set path [tkFDialog_JoinFile $context $text] if {[file ext $path] == ""} { set path "$path$defaultext" } if {[catch {file exists $path}]} { # This "if" block can be safely removed if the following code # stop generating errors. # # file exists ~nonsuchuser # return [list ERROR $path ""] } if {[file exists $path]} { if {[file isdirectory $path]} { if {[catch { cd $path }]} { return [list CHDIR $path ""] } set directory [pwd] set file "" set flag OK cd $appPWD } else { if {[catch { cd [file dirname $path] }]} { return [list CHDIR [file dirname $path] ""] } set directory [pwd] set file [file tail $path] set flag OK cd $appPWD } } else { set dirname [file dirname $path] if {[file exists $dirname]} { if {[catch { cd $dirname }]} { return [list CHDIR $dirname ""] } set directory [pwd] set file [file tail $path] if {[regexp {[*]|[?]} $file]} { set flag PATTERN } else { set flag FILE } cd $appPWD } else { set directory $dirname set file [file tail $path] set flag PATH } } return [list $flag $directory $file]}# Gets called when the entry box gets keyboard focus. We clear the selection# from the icon list . This way the user can be certain that the input in the # entry box is the selection.#proc tkFDialog_EntFocusIn {w} { upvar #0 [winfo name $w] data if {[string compare [$data(ent) get] ""]} { $data(ent) selection from 0 $data(ent) selection to end $data(ent) icursor end } else { $data(ent) selection clear } tkIconList_Unselect $data(icons) if {![string compare $data(type) open]} { $data(okBtn) config -text "Open" } else { $data(okBtn) config -text "Save" }}proc tkFDialog_EntFocusOut {w} { upvar #0 [winfo name $w] data $data(ent) selection clear}# Gets called when user presses Return in the "File name" entry.#proc tkFDialog_ActivateEnt {w} { upvar #0 [winfo name $w] data set text [string trim [$data(ent) get]] set list [tkFDialogResolveFile $data(selectPath) $text \ $data(-defaultextension)] set flag [lindex $list 0] set path [lindex $list 1] set file [lindex $list 2] switch -- $flag { OK { if {![string compare $file ""]} { # user has entered an existing (sub)directory set data(selectPath) $path $data(ent) delete 0 end } else { tkFDialog_SetPathSilently $w $path set data(selectFile) $file tkFDialog_Done $w } } PATTERN { set data(selectPath) $path set data(filter) $file } FILE { if {![string compare $data(type) open]} { tk_messageBox -icon warning -type ok -parent $data(-parent) \ -message "File \"[file join $path $file]\" does not exist." $data(ent) select from 0 $data(ent) select to end $data(ent) icursor end } else { tkFDialog_SetPathSilently $w $path set data(selectFile) $file tkFDialog_Done $w } } PATH { tk_messageBox -icon warning -type ok -parent $data(-parent) \ -message "Directory \"$path\" does not exist." $data(ent) select from 0 $data(ent) select to end $data(ent) icursor end } CHDIR { tk_messageBox -type ok -parent $data(-parent) -message \ "Cannot change to the directory \"$path\".\nPermission denied."\ -icon warning $data(ent) select from 0 $data(ent) select to end $data(ent) icursor end } ERROR { tk_messageBox -type ok -parent $data(-parent) -message \ "Invalid file name \"$path\"."\ -icon warning $data(ent) select from 0 $data(ent) select to end $data(ent) icursor end } }}# Gets called when user presses the Alt-s or Alt-o keys.#proc tkFDialog_InvokeBtn {w key} { upvar #0 [winfo name $w] data if {![string compare [$data(okBtn) cget -text] $key]} { tkButtonInvoke $data(okBtn) }}# Gets called when user presses the "parent directory" button#proc tkFDialog_UpDirCmd {w} { upvar #0 [winfo name $w] data if {[string compare $data(selectPath) "/"]} { set data(selectPath) [file dirname $data(selectPath)] }}# Join a file name to a path name. The "file join" command will break# if the filename begins with ~#proc tkFDialog_JoinFile {path file} { if {[string match {~*} $file] && [file exists $path/$file]} { return [file join $path ./$file] } else { return [file join $path $file] }}# Gets called when user presses the "OK" button#proc tkFDialog_OkCmd {w} { upvar #0 [winfo name $w] data set text [tkIconList_Get $data(icons)] if {[string compare $text ""]} { set file [tkFDialog_JoinFile $data(selectPath) $text] if {[file isdirectory $file]} { tkFDialog_ListInvoke $w $text return } } tkFDialog_ActivateEnt $w}# Gets called when user presses the "Cancel" button#proc tkFDialog_CancelCmd {w} { upvar #0 [winfo name $w] data global tkPriv set tkPriv(selectFilePath) ""}# Gets called when user browses the IconList widget (dragging mouse, arrow# keys, etc)#proc tkFDialog_ListBrowse {w text} { upvar #0 [winfo name $w] data if {$text == ""} { return } set file [tkFDialog_JoinFile $data(selectPath) $text] if {![file isdirectory $file]} { $data(ent) delete 0 end $data(ent) insert 0 $text if {![string compare $data(type) open]} { $data(okBtn) config -text "Open" } else { $data(okBtn) config -text "Save" } } else { $data(okBtn) config -text "Open" }}# Gets called when user invokes the IconList widget (double-click, # Return key, etc)#proc tkFDialog_ListInvoke {w text} { upvar #0 [winfo name $w] data if {$text == ""} { return } set file [tkFDialog_JoinFile $data(selectPath) $text] if {[file isdirectory $file]} { set appPWD [pwd] if {[catch {cd $file}]} { tk_messageBox -type ok -parent $data(-parent) -message \ "Cannot change to the directory \"$file\".\nPermission denied."\ -icon warning } else { cd $appPWD set data(selectPath) $file } } else { set data(selectFile) $file tkFDialog_Done $w }}# tkFDialog_Done --## Gets called when user has input a valid filename. Pops up a# dialog box to confirm selection when necessary. Sets the# tkPriv(selectFilePath) variable, which will break the "tkwait"# loop in tkFDialog and return the selected filename to the# script that calls tk_getOpenFile or tk_getSaveFile#proc tkFDialog_Done {w {selectFilePath ""}} { upvar #0 [winfo name $w] data global tkPriv if {![string compare $selectFilePath ""]} { set selectFilePath [tkFDialog_JoinFile $data(selectPath) \ $data(selectFile)] set tkPriv(selectFile) $data(selectFile) set tkPriv(selectPath) $data(selectPath) if {[file exists $selectFilePath] && ![string compare $data(type) save]} { set reply [tk_messageBox -icon warning -type yesno\ -parent $data(-parent) -message "File\ \"$selectFilePath\" already exists.\nDo\ you want to overwrite it?"] if {![string compare $reply "no"]} { return } } } set tkPriv(selectFilePath) $selectFilePath}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -