📄 xmfbox.tcl
字号:
# xmfbox.tcl --## Implements the "Motif" style file selection dialog for the# Unix platform. This implementation is used only if the# "tk_strictMotif" flag is set.## RCS: @(#) $Id: xmfbox.tcl,v 1.11.2.1 2001/10/16 23:39:16 hobbs Exp $## Copyright (c) 1996 Sun Microsystems, Inc.# Copyright (c) 1998-2000 Scriptics Corporation## See the file "license.terms" for information on usage and redistribution# of this file, and for a DISCLAIMER OF ALL WARRANTIES.namespace eval ::tk::dialog {}namespace eval ::tk::dialog::file {}# tkMotifFDialog --## Implements a file dialog similar to the standard Motif file# selection box.## Arguments:# type "open" or "save"# args Options parsed by the procedure.## Results:# A list of two members. The first member is the absolute# pathname of the selected file or "" if user hits cancel. The# second member is the name of the selected file type, or ""# which stands for "default file type"proc tkMotifFDialog {type args} { global tkPriv set dataName __tk_filedialog upvar ::tk::dialog::file::$dataName data set w [tkMotifFDialog_Create $dataName $type $args] # Set a grab and claim the focus too. ::tk::SetFocusGrab $w $data(sEnt) $data(sEnt) selection range 0 end # Wait for the user to respond, then restore the focus and # return the index of the selected button. Restore the focus # before deleting the window, since otherwise the window manager # may take the focus away so we can't redirect it. Finally, # restore any grab that was in effect. tkwait variable tkPriv(selectFilePath) ::tk::RestoreFocusGrab $w $data(sEnt) withdraw return $tkPriv(selectFilePath)}# tkMotifFDialog_Create --## Creates the Motif file dialog (if it doesn't exist yet) and# initialize the internal data structure associated with the# dialog.## This procedure is used by tkMotifFDialog to create the# dialog. It's also used by the test suite to test the Motif# file dialog implementation. User code shouldn't call this# procedure directly.## Arguments:# dataName Name of the global "data" array for the file dialog.# type "Save" or "Open"# argList Options parsed by the procedure.## Results:# Pathname of the file dialog.proc tkMotifFDialog_Create {dataName type argList} { global tkPriv upvar ::tk::dialog::file::$dataName data tkMotifFDialog_Config $dataName $type $argList if {[string equal $data(-parent) .]} { set w .$dataName } else { set w $data(-parent).$dataName } # (re)create the dialog box if necessary # if {![winfo exists $w]} { tkMotifFDialog_BuildUI $w } elseif {[string compare [winfo class $w] TkMotifFDialog]} { destroy $w tkMotifFDialog_BuildUI $w } else { set data(fEnt) $w.top.f1.ent set data(dList) $w.top.f2.a.l set data(fList) $w.top.f2.b.l set data(sEnt) $w.top.f3.ent set data(okBtn) $w.bot.ok set data(filterBtn) $w.bot.filter set data(cancelBtn) $w.bot.cancel } wm transient $w $data(-parent) tkMotifFDialog_Update $w # Withdraw the window, then update all the geometry information # so we know how big it wants to be, then center the window in the # display (Motif style) and de-iconify it. ::tk::PlaceWindow $w wm title $w $data(-title) return $w}# tkMotifFDialog_Config --## Iterates over the optional arguments to determine the option# values for the Motif file dialog; gives default values to# unspecified options.## Arguments:# dataName The name of the global variable in which# data for the file dialog is stored.# type "Save" or "Open"# argList Options parsed by the procedure.proc tkMotifFDialog_Config {dataName type argList} { upvar ::tk::dialog::file::$dataName data set data(type) $type # 1: the configuration specs # set specs { {-defaultextension "" "" ""} {-filetypes "" "" ""} {-initialdir "" "" ""} {-initialfile "" "" ""} {-parent "" "" "."} {-title "" "" ""} } # 2: default values depending on the type of the dialog # if {![info exists data(selectPath)]} { # first time the dialog has been popped up set data(selectPath) [pwd] set data(selectFile) "" } # 3: parse the arguments # tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList if {[string equal $data(-title) ""]} { if {[string equal $type "open"]} { set data(-title) "Open" } else { set data(-title) "Save As" } } # 4: set the default directory and selection according to the -initial # settings # if {[string compare $data(-initialdir) ""]} { if {[file isdirectory $data(-initialdir)]} { set data(selectPath) [glob $data(-initialdir)] } else { set data(selectPath) [pwd] } # Convert the initialdir to an absolute path name. set old [pwd] cd $data(selectPath) set data(selectPath) [pwd] cd $old } set data(selectFile) $data(-initialfile) # 5. Parse the -filetypes option. It is not used by the motif # file dialog, but we check for validity of the value to make sure # the application code also runs fine with the TK file dialog. # set data(-filetypes) [tkFDGetFileTypes $data(-filetypes)] if {![info exists data(filter)]} { set data(filter) * } if {![winfo exists $data(-parent)]} { error "bad window path name \"$data(-parent)\"" }}# tkMotifFDialog_BuildUI --## Builds the UI components of the Motif file dialog.## Arguments:# w Pathname of the dialog to build.## Results:# None.proc tkMotifFDialog_BuildUI {w} { set dataName [lindex [split $w .] end] upvar ::tk::dialog::file::$dataName data # Create the dialog toplevel and internal frames. # toplevel $w -class TkMotifFDialog set top [frame $w.top -relief raised -bd 1] set bot [frame $w.bot -relief raised -bd 1] pack $w.bot -side bottom -fill x pack $w.top -side top -expand yes -fill both set f1 [frame $top.f1] set f2 [frame $top.f2] set f3 [frame $top.f3] pack $f1 -side top -fill x pack $f3 -side bottom -fill x pack $f2 -expand yes -fill both set f2a [frame $f2.a] set f2b [frame $f2.b] grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \ -sticky news grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \ -sticky news grid rowconfig $f2 0 -minsize 0 -weight 1 grid columnconfig $f2 0 -minsize 0 -weight 1 grid columnconfig $f2 1 -minsize 150 -weight 2 # The Filter box # label $f1.lab -text "Filter:" -under 3 -anchor w entry $f1.ent pack $f1.lab -side top -fill x -padx 6 -pady 4 pack $f1.ent -side top -fill x -padx 4 -pady 0 set data(fEnt) $f1.ent # The file and directory lists # set data(dList) [tkMotifFDialog_MakeSList $w $f2a Directory: 0 DList] set data(fList) [tkMotifFDialog_MakeSList $w $f2b Files: 2 FList] # The Selection box # label $f3.lab -text "Selection:" -under 0 -anchor w entry $f3.ent pack $f3.lab -side top -fill x -padx 6 -pady 0 pack $f3.ent -side top -fill x -padx 4 -pady 4 set data(sEnt) $f3.ent # The buttons # set data(okBtn) [button $bot.ok -text OK -width 6 -under 0 \ -command [list tkMotifFDialog_OkCmd $w]] set data(filterBtn) [button $bot.filter -text Filter -width 6 -under 0 \ -command [list tkMotifFDialog_FilterCmd $w]] set data(cancelBtn) [button $bot.cancel -text Cancel -width 6 -under 0 \ -command [list tkMotifFDialog_CancelCmd $w]] pack $bot.ok $bot.filter $bot.cancel -padx 10 -pady 10 -expand yes \ -side left # Create the bindings: # bind $w <Alt-t> [list focus $data(fEnt)] bind $w <Alt-d> [list focus $data(dList)] bind $w <Alt-l> [list focus $data(fList)] bind $w <Alt-s> [list focus $data(sEnt)] bind $w <Alt-o> [list tkButtonInvoke $bot.ok] bind $w <Alt-f> [list tkButtonInvoke $bot.filter] bind $w <Alt-c> [list tkButtonInvoke $bot.cancel] bind $data(fEnt) <Return> [list tkMotifFDialog_ActivateFEnt $w] bind $data(sEnt) <Return> [list tkMotifFDialog_ActivateSEnt $w] wm protocol $w WM_DELETE_WINDOW [list tkMotifFDialog_CancelCmd $w]}# tkMotifFDialog_MakeSList --## Create a scrolled-listbox and set the keyboard accelerator# bindings so that the list selection follows what the user# types.## Arguments:# w Pathname of the dialog box.# f Frame widget inside which to create the scrolled# listbox. This frame widget already exists.# label The string to display on top of the listbox.# under Sets the -under option of the label.# cmdPrefix Specifies procedures to call when the listbox is# browsed or activated.proc tkMotifFDialog_MakeSList {w f label under cmdPrefix} { label $f.lab -text $label -under $under -anchor w listbox $f.l -width 12 -height 5 -selectmode browse -exportselection 0\ -xscrollcommand [list $f.h set] -yscrollcommand [list $f.v set] scrollbar $f.v -orient vertical -takefocus 0 -command [list $f.l yview] scrollbar $f.h -orient horizontal -takefocus 0 -command [list $f.l xview] grid $f.lab -row 0 -column 0 -sticky news -rowspan 1 -columnspan 2 \ -padx 2 -pady 2 grid $f.l -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news grid $f.v -row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news grid $f.h -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news grid rowconfig $f 0 -weight 0 -minsize 0 grid rowconfig $f 1 -weight 1 -minsize 0 grid columnconfig $f 0 -weight 1 -minsize 0 # bindings for the listboxes # set list $f.l bind $list <Up> [list tkMotifFDialog_Browse$cmdPrefix $w] bind $list <Down> [list tkMotifFDialog_Browse$cmdPrefix $w] bind $list <space> [list tkMotifFDialog_Browse$cmdPrefix $w] bind $list <1> [list tkMotifFDialog_Browse$cmdPrefix $w] bind $list <B1-Motion> [list tkMotifFDialog_Browse$cmdPrefix $w] bind $list <Double-ButtonRelease-1> \ [list tkMotifFDialog_Activate$cmdPrefix $w] bind $list <Return> "tkMotifFDialog_Browse$cmdPrefix [list $w]; \ tkMotifFDialog_Activate$cmdPrefix [list $w]" bindtags $list [list Listbox $list [winfo toplevel $list] all] tkListBoxKeyAccel_Set $list return $f.l}# tkMotifFDialog_InterpFilter --## Interpret the string in the filter entry into two components:# the directory and the pattern. If the string is a relative# pathname, give a warning to the user and restore the pattern# to original.## Arguments:# w pathname of the dialog box.## Results:# A list of two elements. The first element is the directory# specified # by the filter. The second element is the filter# pattern itself.proc tkMotifFDialog_InterpFilter {w} { upvar ::tk::dialog::file::[winfo name $w] data set text [string trim [$data(fEnt) get]] # Perform tilde substitution # set badTilde 0 if {[string equal [string index $text 0] ~]} { set list [file split $text] set tilde [lindex $list 0] if {[catch {set tilde [glob $tilde]}]} { set badTilde 1 } else { set text [eval file join [concat $tilde [lrange $list 1 end]]] } } # If the string is a relative pathname, combine it # with the current selectPath. set relative 0 if {[string equal [file pathtype $text] "relative"]} { set relative 1 } elseif {$badTilde} { set relative 1 } if {$relative} { tk_messageBox -icon warning -type ok \ -message "\"$text\" must be an absolute pathname" $data(fEnt) delete 0 end $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \ $data(filter)] return [list $data(selectPath) $data(filter)] } set resolved [::tk::dialog::file::JoinFile [file dirname $text] [file tail $text]] if {[file isdirectory $resolved]} { set dir $resolved set fil $data(filter) } else { set dir [file dirname $resolved] set fil [file tail $resolved] } return [list $dir $fil]}# tkMotifFDialog_Update## Load the files and synchronize the "filter" and "selection" fields# boxes.## Arguments:# w pathname of the dialog box.#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -