3 # Implements the "Motif" style file selection dialog for the
4 # Unix platform. This implementation is used only if the
5 # "::tk_strictMotif" flag is set.
7 # Copyright (c) 1996 Sun Microsystems, Inc.
8 # Copyright (c) 1998-2000 Scriptics Corporation
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 namespace eval ::tk::dialog {}
14 namespace eval ::tk::dialog::file {}
17 # ::tk::MotifFDialog --
19 # Implements a file dialog similar to the standard Motif file
23 # type "open" or "save"
24 # args Options parsed by the procedure.
27 # When -multiple is set to 0, this returns the absolute pathname
28 # of the selected file. (NOTE: This is not the same as a single
31 # When -multiple is set to > 0, this returns a Tcl list of absolute
32 # pathnames. The argument for -multiple is ignored, but for consistency
33 # with Windows it defines the maximum amount of memory to allocate for
34 # the returned filenames.
36 proc ::tk::MotifFDialog {type args
} {
38 set dataName __tk_filedialog
39 upvar ::tk::dialog::file::$dataName data
41 set w
[MotifFDialog_Create
$dataName $type $args]
43 # Set a grab and claim the focus too.
45 ::tk::SetFocusGrab $w $data(sEnt
)
46 $data(sEnt
) selection range
0 end
48 # Wait for the user to respond, then restore the focus and
49 # return the index of the selected button. Restore the focus
50 # before deleting the window, since otherwise the window manager
51 # may take the focus away so we can't redirect it. Finally,
52 # restore any grab that was in effect.
54 vwait ::tk::Priv(selectFilePath
)
55 set result
$Priv(selectFilePath
)
56 ::tk::RestoreFocusGrab $w $data(sEnt
) withdraw
61 # ::tk::MotifFDialog_Create --
63 # Creates the Motif file dialog (if it doesn't exist yet) and
64 # initialize the internal data structure associated with the
67 # This procedure is used by ::tk::MotifFDialog to create the
68 # dialog. It's also used by the test suite to test the Motif
69 # file dialog implementation. User code shouldn't call this
73 # dataName Name of the global "data" array for the file dialog.
74 # type "Save" or "Open"
75 # argList Options parsed by the procedure.
78 # Pathname of the file dialog.
80 proc ::tk::MotifFDialog_Create {dataName type argList
} {
81 upvar ::tk::dialog::file::$dataName data
83 MotifFDialog_Config
$dataName $type $argList
85 if {$data(-parent) eq
"."} {
88 set w
$data(-parent).
$dataName
91 # (re)create the dialog box if necessary
93 if {![winfo exists
$w]} {
94 MotifFDialog_BuildUI
$w
95 } elseif
{[winfo class
$w] ne
"TkMotifFDialog"} {
97 MotifFDialog_BuildUI
$w
99 set data
(fEnt
) $w.top.f1.ent
100 set data
(dList
) $w.top.f2.a.l
101 set data
(fList
) $w.top.f2.b.l
102 set data
(sEnt
) $w.top.f3.ent
103 set data
(okBtn
) $w.bot.ok
104 set data
(filterBtn
) $w.bot.filter
105 set data
(cancelBtn
) $w.bot.cancel
107 MotifFDialog_SetListMode
$w
109 # Dialog boxes should be transient with respect to their parent,
110 # so that they will always stay on top of their parent window. However,
111 # some window managers will create the window as withdrawn if the parent
112 # window is withdrawn or iconified. Combined with the grab we put on the
113 # window, this can hang the entire application. Therefore we only make
114 # the dialog transient if the parent is viewable.
116 if {[winfo viewable
[winfo toplevel $data(-parent)]] } {
117 wm transient
$w $data(-parent)
120 MotifFDialog_FileTypes
$w
121 MotifFDialog_Update
$w
123 # Withdraw the window, then update all the geometry information
124 # so we know how big it wants to be, then center the window in the
125 # display (Motif style) and de-iconify it.
128 wm title
$w $data(-title)
133 # ::tk::MotifFDialog_FileTypes --
135 # Checks the -filetypes option. If present this adds a list of radio-
136 # buttons to pick the file types from.
139 # w Pathname of the tk_get*File dialogue.
144 proc ::tk::MotifFDialog_FileTypes {w
} {
145 upvar ::tk::dialog::file::[winfo name
$w] data
147 set f
$w.top.f3.types
150 # No file types: use "*" as the filter and display no radio-buttons
151 if {$data(-filetypes) eq
""} {
156 # The filetypes radiobuttons
157 # set data(fileType) $data(-defaulttype)
158 # Default type to first entry
159 set initialTypeName
[lindex $data(-filetypes) 0 0]
160 if {$data(-typevariable) ne
""} {
161 upvar #0 $data(-typevariable) typeVariable
162 if {[info exist typeVariable
]} {
163 set initialTypeName
$typeVariable
168 foreach fltr
$data(-filetypes) {
169 set fname
[lindex $fltr 0]
170 if {[string first
$initialTypeName $fname] == 0} {
171 set data
(fileType
) $ix
177 MotifFDialog_SetFilter
$w [lindex $data(-filetypes) $data(fileType
)]
179 #don't produce radiobuttons for only one filetype
180 if {[llength $data(-filetypes)] == 1} {
186 if {$data(-filetypes) ne
{}} {
187 foreach type
$data(-filetypes) {
188 set title
[lindex [lindex $type 0] 0]
189 set filter
[lindex $type 1]
190 radiobutton $f.b
$cnt \
192 -variable ::tk::dialog::file::[winfo name
$w](fileType
) \
194 -command [list tk::MotifFDialog_SetFilter $w $type]
195 pack $f.b
$cnt -side left
199 $f.b
$data(fileType
) invoke
201 pack $f -side bottom
-fill both
206 # This proc gets called whenever data(filter) is set
208 proc ::tk::MotifFDialog_SetFilter {w type
} {
209 upvar ::tk::dialog::file::[winfo name
$w] data
212 set data
(filter
) [lindex $type 1]
213 set Priv
(selectFileType
) [lindex [lindex $type 0] 0]
215 MotifFDialog_Update
$w
218 # ::tk::MotifFDialog_Config --
220 # Iterates over the optional arguments to determine the option
221 # values for the Motif file dialog; gives default values to
222 # unspecified options.
225 # dataName The name of the global variable in which
226 # data for the file dialog is stored.
227 # type "Save" or "Open"
228 # argList Options parsed by the procedure.
230 proc ::tk::MotifFDialog_Config {dataName type argList
} {
231 upvar ::tk::dialog::file::$dataName data
235 # 1: the configuration specs
238 {-defaultextension "" "" ""}
239 {-filetypes "" "" ""}
240 {-initialdir "" "" ""}
241 {-initialfile "" "" ""}
244 {-typevariable "" "" ""}
246 if {$type eq
"open"} {
247 lappend specs
{-multiple "" "" "0"}
249 if {$type eq
"save"} {
250 lappend specs
{-confirmoverwrite "" "" "1"}
253 set data
(-multiple) 0
254 set data
(-confirmoverwrite) 1
255 # 2: default values depending on the type of the dialog
257 if {![info exists data
(selectPath
)]} {
258 # first time the dialog has been popped up
259 set data
(selectPath
) [pwd]
260 set data
(selectFile
) ""
263 # 3: parse the arguments
265 tclParseConfigSpec
::tk::dialog::file::$dataName $specs "" $argList
267 if {$data(-title) eq
""} {
268 if {$type eq
"open"} {
269 if {$data(-multiple) != 0} {
270 set data
(-title) "[mc {Open Multiple Files}]"
272 set data
(-title) [mc
"Open"]
275 set data
(-title) [mc
"Save As"]
279 # 4: set the default directory and selection according to the -initial
282 if {$data(-initialdir) ne
""} {
283 if {[file isdirectory
$data(-initialdir)]} {
284 set data
(selectPath
) [lindex [glob $data(-initialdir)] 0]
286 set data
(selectPath
) [pwd]
289 # Convert the initialdir to an absolute path name.
293 set data
(selectPath
) [pwd]
296 set data
(selectFile
) $data(-initialfile)
298 # 5. Parse the -filetypes option. It is not used by the motif
299 # file dialog, but we check for validity of the value to make sure
300 # the application code also runs fine with the TK file dialog.
302 set data
(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]
304 if {![info exists data
(filter
)]} {
307 if {![winfo exists
$data(-parent)]} {
308 error "bad window path name \"$data(-parent)\""
312 # ::tk::MotifFDialog_BuildUI --
314 # Builds the UI components of the Motif file dialog.
317 # w Pathname of the dialog to build.
322 proc ::tk::MotifFDialog_BuildUI {w
} {
323 set dataName
[lindex [split $w .
] end
]
324 upvar ::tk::dialog::file::$dataName data
326 # Create the dialog toplevel and internal frames.
328 toplevel $w -class TkMotifFDialog
329 set top
[frame $w.top
-relief raised
-bd 1]
330 set bot
[frame $w.bot
-relief raised
-bd 1]
332 pack $w.bot
-side bottom
-fill x
333 pack $w.top
-side top
-expand yes
-fill both
335 set f1
[frame $top.f1
]
336 set f2
[frame $top.f2
]
337 set f3
[frame $top.f3
]
339 pack $f1 -side top
-fill x
340 pack $f3 -side bottom
-fill x
341 pack $f2 -expand yes
-fill both
343 set f2a
[frame $f2.a
]
344 set f2b
[frame $f2.b
]
346 grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
348 grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
350 grid rowconfigure
$f2 0 -minsize 0 -weight 1
351 grid columnconfigure
$f2 0 -minsize 0 -weight 1
352 grid columnconfigure
$f2 1 -minsize 150 -weight 2
356 bind [::tk::AmpWidget label $f1.lab
-text [mc
"Fil&ter:"] -anchor w
] \
357 <<AltUnderlined
>> [list focus $f1.ent
]
359 pack $f1.lab
-side top
-fill x
-padx 6 -pady 4
360 pack $f1.ent
-side top
-fill x
-padx 4 -pady 0
361 set data
(fEnt
) $f1.ent
363 # The file and directory lists
365 set data
(dList
) [MotifFDialog_MakeSList
$w $f2a \
366 [mc
"&Directory:"] DList
]
367 set data
(fList
) [MotifFDialog_MakeSList
$w $f2b \
368 [mc
"Fi&les:"] FList
]
372 bind [::tk::AmpWidget label $f3.lab
-text [mc
"&Selection:"] -anchor w
] \
373 <<AltUnderlined
>> [list focus $f3.ent
]
375 pack $f3.lab
-side top
-fill x
-padx 6 -pady 0
376 pack $f3.ent
-side top
-fill x
-padx 4 -pady 4
377 set data
(sEnt
) $f3.ent
381 set maxWidth
[::tk::mcmaxamp &OK
&Filter
&Cancel
]
382 set maxWidth
[expr {$maxWidth<6?
6:$maxWidth}]
383 set data
(okBtn
) [::tk::AmpWidget button $bot.ok
-text [mc
"&OK"] \
385 -command [list tk::MotifFDialog_OkCmd $w]]
386 set data
(filterBtn
) [::tk::AmpWidget button $bot.filter
-text [mc
"&Filter"] \
388 -command [list tk::MotifFDialog_FilterCmd $w]]
389 set data
(cancelBtn
) [::tk::AmpWidget button $bot.cancel
-text [mc
"&Cancel"] \
391 -command [list tk::MotifFDialog_CancelCmd $w]]
393 pack $bot.ok
$bot.filter
$bot.cancel
-padx 10 -pady 10 -expand yes
\
396 # Create the bindings:
398 bind $w <Alt-Key
> [list ::tk::AltKeyInDialog $w %A
]
400 bind $data(fEnt
) <Return
> [list tk::MotifFDialog_ActivateFEnt $w]
401 bind $data(sEnt
) <Return
> [list tk::MotifFDialog_ActivateSEnt $w]
402 bind $w <Escape
> [list tk::MotifFDialog_CancelCmd $w]
403 bind $w.bot
<Destroy
> {set ::tk::Priv(selectFilePath
) {}}
405 wm protocol
$w WM_DELETE_WINDOW
[list tk::MotifFDialog_CancelCmd $w]
408 proc ::tk::MotifFDialog_SetListMode {w
} {
409 upvar ::tk::dialog::file::[winfo name
$w] data
411 if {$data(-multiple) != 0} {
412 set selectmode extended
414 set selectmode browse
417 $f.l configure
-selectmode $selectmode
420 # ::tk::MotifFDialog_MakeSList --
422 # Create a scrolled-listbox and set the keyboard accelerator
423 # bindings so that the list selection follows what the user
427 # w Pathname of the dialog box.
428 # f Frame widget inside which to create the scrolled
429 # listbox. This frame widget already exists.
430 # label The string to display on top of the listbox.
431 # under Sets the -under option of the label.
432 # cmdPrefix Specifies procedures to call when the listbox is
433 # browsed or activated.
435 proc ::tk::MotifFDialog_MakeSList {w f
label cmdPrefix
} {
436 bind [::tk::AmpWidget label $f.lab
-text $label -anchor w
] \
437 <<AltUnderlined
>> [list focus $f.l
]
438 listbox $f.l
-width 12 -height 5 -exportselection 0\
439 -xscrollcommand [list $f.h
set] -yscrollcommand [list $f.v
set]
440 scrollbar $f.v
-orient vertical
-takefocus 0 -command [list $f.l yview
]
441 scrollbar $f.h
-orient horizontal
-takefocus 0 -command [list $f.l xview
]
442 grid $f.lab
-row 0 -column 0 -sticky news
-rowspan 1 -columnspan 2 \
444 grid $f.l
-row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
445 grid $f.v
-row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news
446 grid $f.h
-row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news
448 grid rowconfigure
$f 0 -weight 0 -minsize 0
449 grid rowconfigure
$f 1 -weight 1 -minsize 0
450 grid columnconfigure
$f 0 -weight 1 -minsize 0
452 # bindings for the listboxes
455 bind $list <<ListboxSelect
>> [list tk::MotifFDialog_Browse$cmdPrefix $w]
456 bind $list <Double-ButtonRelease-1
> \
457 [list tk::MotifFDialog_Activate$cmdPrefix $w]
458 bind $list <Return
> "tk::MotifFDialog_Browse$cmdPrefix [list $w]; \
459 tk::MotifFDialog_Activate$cmdPrefix [list $w]"
461 bindtags $list [list Listbox
$list [winfo toplevel $list] all
]
462 ListBoxKeyAccel_Set
$list
467 # ::tk::MotifFDialog_InterpFilter --
469 # Interpret the string in the filter entry into two components:
470 # the directory and the pattern. If the string is a relative
471 # pathname, give a warning to the user and restore the pattern
475 # w pathname of the dialog box.
478 # A list of two elements. The first element is the directory
479 # specified # by the filter. The second element is the filter
482 proc ::tk::MotifFDialog_InterpFilter {w
} {
483 upvar ::tk::dialog::file::[winfo name
$w] data
485 set text [string trim
[$data(fEnt
) get
]]
487 # Perform tilde substitution
490 if {[string index
$text 0] eq
"~"} {
491 set list [file split $text]
492 set tilde
[lindex $list 0]
493 if {[catch {set tilde
[glob $tilde]}]} {
496 set text [eval file join [concat $tilde [lrange $list 1 end
]]]
500 # If the string is a relative pathname, combine it
501 # with the current selectPath.
504 if {[file pathtype
$text] eq
"relative"} {
506 } elseif
{$badTilde} {
511 tk_messageBox -icon warning
-type ok
\
512 -message "\"$text\" must be an absolute pathname"
514 $data(fEnt
) delete
0 end
515 $data(fEnt
) insert
0 [::tk::dialog::file::JoinFile $data(selectPath
) \
518 return [list $data(selectPath
) $data(filter
)]
521 set resolved
[::tk::dialog::file::JoinFile [file dirname
$text] [file tail
$text]]
523 if {[file isdirectory
$resolved]} {
525 set fil
$data(filter
)
527 set dir
[file dirname
$resolved]
528 set fil
[file tail
$resolved]
531 return [list $dir $fil]
534 # ::tk::MotifFDialog_Update
536 # Load the files and synchronize the "filter" and "selection" fields
540 # w pathname of the dialog box.
545 proc ::tk::MotifFDialog_Update {w
} {
546 upvar ::tk::dialog::file::[winfo name
$w] data
548 $data(fEnt
) delete
0 end
549 $data(fEnt
) insert
0 \
550 [::tk::dialog::file::JoinFile $data(selectPath
) $data(filter
)]
551 $data(sEnt
) delete
0 end
552 $data(sEnt
) insert
0 [::tk::dialog::file::JoinFile $data(selectPath
) \
555 MotifFDialog_LoadFiles
$w
558 # ::tk::MotifFDialog_LoadFiles --
560 # Loads the files and directories into the two listboxes according
561 # to the filter setting.
564 # w pathname of the dialog box.
569 proc ::tk::MotifFDialog_LoadFiles {w
} {
570 upvar ::tk::dialog::file::[winfo name
$w] data
572 $data(dList
) delete
0 end
573 $data(fList
) delete
0 end
576 if {[catch {cd $data(selectPath
)}]} {
579 $data(dList
) insert end
".."
583 # Make the dir and file lists
585 # For speed we only have one glob, which reduces the file system
586 # calls (good for slow NFS networks).
588 # We also do two smaller sorts (files + dirs) instead of one large sort,
589 # which gives a small speed increase.
594 foreach f
[glob -nocomplain .
* *] {
595 if {[file isdir .
/$f]} {
598 foreach pat
$data(filter
) {
599 if {[string match
$pat $f]} {
600 if {[string match .
* $f]} {
609 eval [list $data(dList
) insert end
] [lsort -dictionary $dlist]
610 eval [list $data(fList
) insert end
] [lsort -dictionary $flist]
612 # The user probably doesn't want to see the . files. We adjust the view
613 # so that the listbox displays all the non-dot files
614 $data(fList
) yview
$top
619 # ::tk::MotifFDialog_BrowseDList --
621 # This procedure is called when the directory list is browsed
622 # (clicked-over) by the user.
625 # w The pathname of the dialog box.
630 proc ::tk::MotifFDialog_BrowseDList {w
} {
631 upvar ::tk::dialog::file::[winfo name
$w] data
634 if {[$data(dList
) curselection
] eq
""} {
637 set subdir
[$data(dList
) get
[$data(dList
) curselection
]]
642 $data(fList
) selection clear
0 end
644 set list [MotifFDialog_InterpFilter
$w]
645 set data
(filter
) [lindex $list 1]
649 set newSpec
[::tk::dialog::file::JoinFile $data(selectPath
) $data(filter
)]
652 set newSpec
[::tk::dialog::file::JoinFile [file dirname
$data(selectPath
)] \
656 set newSpec
[::tk::dialog::file::JoinFile [::tk::dialog::file::JoinFile \
657 $data(selectPath
) $subdir] $data(filter
)]
661 $data(fEnt
) delete
0 end
662 $data(fEnt
) insert
0 $newSpec
665 # ::tk::MotifFDialog_ActivateDList --
667 # This procedure is called when the directory list is activated
668 # (double-clicked) by the user.
671 # w The pathname of the dialog box.
676 proc ::tk::MotifFDialog_ActivateDList {w
} {
677 upvar ::tk::dialog::file::[winfo name
$w] data
679 if {[$data(dList
) curselection
] eq
""} {
682 set subdir
[$data(dList
) get
[$data(dList
) curselection
]]
687 $data(fList
) selection clear
0 end
691 set newDir
$data(selectPath
)
694 set newDir
[file dirname
$data(selectPath
)]
697 set newDir
[::tk::dialog::file::JoinFile $data(selectPath
) $subdir]
701 set data
(selectPath
) $newDir
702 MotifFDialog_Update
$w
704 if {$subdir ne
".."} {
705 $data(dList
) selection set 0
706 $data(dList
) activate
0
708 $data(dList
) selection set 1
709 $data(dList
) activate
1
713 # ::tk::MotifFDialog_BrowseFList --
715 # This procedure is called when the file list is browsed
716 # (clicked-over) by the user.
719 # w The pathname of the dialog box.
724 proc ::tk::MotifFDialog_BrowseFList {w
} {
725 upvar ::tk::dialog::file::[winfo name
$w] data
728 set data
(selectFile
) ""
729 foreach item
[$data(fList
) curselection
] {
730 lappend data
(selectFile
) [$data(fList
) get
$item]
732 if {[llength $data(selectFile
)] == 0} {
736 $data(dList
) selection clear
0 end
738 $data(fEnt
) delete
0 end
739 $data(fEnt
) insert
0 [::tk::dialog::file::JoinFile $data(selectPath
) \
741 $data(fEnt
) xview end
743 # if it's a multiple selection box, just put in the filenames
744 # otherwise put in the full path as usual
745 $data(sEnt
) delete
0 end
746 if {$data(-multiple) != 0} {
747 $data(sEnt
) insert
0 $data(selectFile
)
749 $data(sEnt
) insert
0 [::tk::dialog::file::JoinFile $data(selectPath
) \
750 [lindex $data(selectFile
) 0]]
752 $data(sEnt
) xview end
755 # ::tk::MotifFDialog_ActivateFList --
757 # This procedure is called when the file list is activated
758 # (double-clicked) by the user.
761 # w The pathname of the dialog box.
766 proc ::tk::MotifFDialog_ActivateFList {w
} {
767 upvar ::tk::dialog::file::[winfo name
$w] data
769 if {[$data(fList
) curselection
] eq
""} {
772 set data
(selectFile
) [$data(fList
) get
[$data(fList
) curselection
]]
773 if {$data(selectFile
) eq
""} {
776 MotifFDialog_ActivateSEnt
$w
780 # ::tk::MotifFDialog_ActivateFEnt --
782 # This procedure is called when the user presses Return inside
783 # the "filter" entry. It updates the dialog according to the
784 # text inside the filter entry.
787 # w The pathname of the dialog box.
792 proc ::tk::MotifFDialog_ActivateFEnt {w
} {
793 upvar ::tk::dialog::file::[winfo name
$w] data
795 set list [MotifFDialog_InterpFilter
$w]
796 set data
(selectPath
) [lindex $list 0]
797 set data
(filter
) [lindex $list 1]
799 MotifFDialog_Update
$w
802 # ::tk::MotifFDialog_ActivateSEnt --
804 # This procedure is called when the user presses Return inside
805 # the "selection" entry. It sets the ::tk::Priv(selectFilePath)
806 # variable so that the vwait loop in tk::MotifFDialog will be
810 # w The pathname of the dialog box.
815 proc ::tk::MotifFDialog_ActivateSEnt {w
} {
817 upvar ::tk::dialog::file::[winfo name
$w] data
819 set selectFilePath
[string trim
[$data(sEnt
) get
]]
821 if {$selectFilePath eq
""} {
822 MotifFDialog_FilterCmd
$w
826 if {$data(-multiple) == 0} {
827 set selectFilePath
[list $selectFilePath]
830 if {[file isdirectory
[lindex $selectFilePath 0]]} {
831 set data
(selectPath
) [lindex [glob $selectFilePath] 0]
832 set data
(selectFile
) ""
833 MotifFDialog_Update
$w
838 foreach item
$selectFilePath {
839 if {[file pathtype
$item] ne
"absolute"} {
840 set item
[file join $data(selectPath
) $item]
841 } elseif
{![file exists
[file dirname
$item]]} {
842 tk_messageBox -icon warning
-type ok
\
843 -message [mc
{Directory
"%1$s" does not exist.
} \
844 [file dirname
$item]]
848 if {![file exists
$item]} {
849 if {$data(type
) eq
"open"} {
850 tk_messageBox -icon warning
-type ok
\
851 -message [mc
{File
"%1$s" does not exist.
} $item]
854 } elseif
{$data(type
) eq
"save" && $data(-confirmoverwrite)} {
855 set message [format %s
%s
\
856 [mc
"File \"%1\$s\" already exists.\n\n" $selectFilePath] \
857 [mc
{Replace existing
file?
}]]
858 set answer
[tk_messageBox -icon warning
-type yesno
\
860 if {$answer eq
"no"} {
865 lappend newFileList
$item
868 # Return selected filter
869 if {[info exists data
(-typevariable)] && $data(-typevariable) ne
""
870 && [info exists data
(-filetypes)] && $data(-filetypes) ne
""} {
871 upvar #0 $data(-typevariable) typeVariable
872 set typeVariable
[lindex $data(-filetypes) $data(fileType
) 0]
875 if {$data(-multiple) != 0} {
876 set Priv
(selectFilePath
) $newFileList
878 set Priv
(selectFilePath
) [lindex $newFileList 0]
881 # Set selectFile and selectPath to first item in list
882 set Priv
(selectFile
) [file tail
[lindex $newFileList 0]]
883 set Priv
(selectPath
) [file dirname
[lindex $newFileList 0]]
887 proc ::tk::MotifFDialog_OkCmd {w
} {
888 upvar ::tk::dialog::file::[winfo name
$w] data
890 MotifFDialog_ActivateSEnt
$w
893 proc ::tk::MotifFDialog_FilterCmd {w
} {
894 upvar ::tk::dialog::file::[winfo name
$w] data
896 MotifFDialog_ActivateFEnt
$w
899 proc ::tk::MotifFDialog_CancelCmd {w
} {
902 set Priv
(selectFilePath
) ""
903 set Priv
(selectFile
) ""
904 set Priv
(selectPath
) ""
907 proc ::tk::ListBoxKeyAccel_Set {w
} {
908 bind Listbox
<Any-KeyPress
> ""
909 bind $w <Destroy
> [list tk::ListBoxKeyAccel_Unset $w]
910 bind $w <Any-KeyPress
> [list tk::ListBoxKeyAccel_Key $w %A
]
913 proc ::tk::ListBoxKeyAccel_Unset {w
} {
916 catch {after cancel
$Priv(lbAccel
,$w,afterId
)}
917 unset -nocomplain Priv
(lbAccel
,$w) Priv
(lbAccel
,$w,afterId
)
920 # ::tk::ListBoxKeyAccel_Key--
922 # This procedure maintains a list of recently entered keystrokes
923 # over a listbox widget. It arranges an idle event to move the
924 # selection of the listbox to the entry that begins with the
928 # w The pathname of the listbox.
929 # key The key which the user just pressed.
934 proc ::tk::ListBoxKeyAccel_Key {w key
} {
940 append Priv
(lbAccel
,$w) $key
941 ListBoxKeyAccel_Goto
$w $Priv(lbAccel
,$w)
943 after cancel
$Priv(lbAccel
,$w,afterId
)
945 set Priv
(lbAccel
,$w,afterId
) [after 500 \
946 [list tk::ListBoxKeyAccel_Reset $w]]
949 proc ::tk::ListBoxKeyAccel_Goto {w
string} {
952 set string [string tolower
$string]
953 set end
[$w index end
]
956 for {set i
0} {$i < $end} {incr i
} {
957 set item
[string tolower
[$w get
$i]]
958 if {[string compare
$string $item] >= 0} {
961 if {[string compare
$string $item] <= 0} {
967 if {$theIndex >= 0} {
968 $w selection clear
0 end
969 $w selection set $theIndex $theIndex
970 $w activate
$theIndex
972 event generate
$w <<ListboxSelect
>>
976 proc ::tk::ListBoxKeyAccel_Reset {w
} {
979 unset -nocomplain Priv
(lbAccel
,$w)
982 proc ::tk_getFileType {} {
985 return $Priv(selectFileType
)