Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / amd64 / lib / tk8.4 / xmfbox.tcl
CommitLineData
920dae64
AT
1# xmfbox.tcl --
2#
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.
6#
7# RCS: @(#) $Id: xmfbox.tcl,v 1.25.2.1 2004/10/27 16:37:59 dgp Exp $
8#
9# Copyright (c) 1996 Sun Microsystems, Inc.
10# Copyright (c) 1998-2000 Scriptics Corporation
11#
12# See the file "license.terms" for information on usage and redistribution
13# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14
15namespace eval ::tk::dialog {}
16namespace eval ::tk::dialog::file {}
17
18
19# ::tk::MotifFDialog --
20#
21# Implements a file dialog similar to the standard Motif file
22# selection box.
23#
24# Arguments:
25# type "open" or "save"
26# args Options parsed by the procedure.
27#
28# Results:
29# When -multiple is set to 0, this returns the absolute pathname
30# of the selected file. (NOTE: This is not the same as a single
31# element list.)
32#
33# When -multiple is set to > 0, this returns a Tcl list of absolute
34# pathnames. The argument for -multiple is ignored, but for consistency
35# with Windows it defines the maximum amount of memory to allocate for
36# the returned filenames.
37
38proc ::tk::MotifFDialog {type args} {
39 variable ::tk::Priv
40 set dataName __tk_filedialog
41 upvar ::tk::dialog::file::$dataName data
42
43 set w [MotifFDialog_Create $dataName $type $args]
44
45 # Set a grab and claim the focus too.
46
47 ::tk::SetFocusGrab $w $data(sEnt)
48 $data(sEnt) selection range 0 end
49
50 # Wait for the user to respond, then restore the focus and
51 # return the index of the selected button. Restore the focus
52 # before deleting the window, since otherwise the window manager
53 # may take the focus away so we can't redirect it. Finally,
54 # restore any grab that was in effect.
55
56 vwait ::tk::Priv(selectFilePath)
57 set result $Priv(selectFilePath)
58 ::tk::RestoreFocusGrab $w $data(sEnt) withdraw
59
60 return $result
61}
62
63# ::tk::MotifFDialog_Create --
64#
65# Creates the Motif file dialog (if it doesn't exist yet) and
66# initialize the internal data structure associated with the
67# dialog.
68#
69# This procedure is used by ::tk::MotifFDialog to create the
70# dialog. It's also used by the test suite to test the Motif
71# file dialog implementation. User code shouldn't call this
72# procedure directly.
73#
74# Arguments:
75# dataName Name of the global "data" array for the file dialog.
76# type "Save" or "Open"
77# argList Options parsed by the procedure.
78#
79# Results:
80# Pathname of the file dialog.
81
82proc ::tk::MotifFDialog_Create {dataName type argList} {
83 upvar ::tk::dialog::file::$dataName data
84
85 MotifFDialog_Config $dataName $type $argList
86
87 if {[string equal $data(-parent) .]} {
88 set w .$dataName
89 } else {
90 set w $data(-parent).$dataName
91 }
92
93 # (re)create the dialog box if necessary
94 #
95 if {![winfo exists $w]} {
96 MotifFDialog_BuildUI $w
97 } elseif {[string compare [winfo class $w] TkMotifFDialog]} {
98 destroy $w
99 MotifFDialog_BuildUI $w
100 } else {
101 set data(fEnt) $w.top.f1.ent
102 set data(dList) $w.top.f2.a.l
103 set data(fList) $w.top.f2.b.l
104 set data(sEnt) $w.top.f3.ent
105 set data(okBtn) $w.bot.ok
106 set data(filterBtn) $w.bot.filter
107 set data(cancelBtn) $w.bot.cancel
108 }
109 MotifFDialog_SetListMode $w
110
111 # Dialog boxes should be transient with respect to their parent,
112 # so that they will always stay on top of their parent window. However,
113 # some window managers will create the window as withdrawn if the parent
114 # window is withdrawn or iconified. Combined with the grab we put on the
115 # window, this can hang the entire application. Therefore we only make
116 # the dialog transient if the parent is viewable.
117
118 if {[winfo viewable [winfo toplevel $data(-parent)]] } {
119 wm transient $w $data(-parent)
120 }
121
122 MotifFDialog_FileTypes $w
123 MotifFDialog_Update $w
124
125 # Withdraw the window, then update all the geometry information
126 # so we know how big it wants to be, then center the window in the
127 # display (Motif style) and de-iconify it.
128
129 ::tk::PlaceWindow $w
130 wm title $w $data(-title)
131
132 return $w
133}
134
135# ::tk::MotifFDialog_FileTypes --
136#
137# Checks the -filetypes option. If present this adds a list of radio-
138# buttons to pick the file types from.
139#
140# Arguments:
141# w Pathname of the tk_get*File dialogue.
142#
143# Results:
144# none
145
146proc ::tk::MotifFDialog_FileTypes {w} {
147 upvar ::tk::dialog::file::[winfo name $w] data
148
149 set f $w.top.f3.types
150 catch {destroy $f}
151
152 # No file types: use "*" as the filter and display no radio-buttons
153 if {$data(-filetypes) == ""} {
154 set data(filter) *
155 return
156 }
157
158 # The filetypes radiobuttons
159 # set data(fileType) $data(-defaulttype)
160 set data(fileType) 0
161
162 MotifFDialog_SetFilter $w [lindex $data(-filetypes) $data(fileType)]
163
164 #don't produce radiobuttons for only one filetype
165 if {[llength $data(-filetypes)] == 1} {
166 return
167 }
168
169 frame $f
170 set cnt 0
171 if {$data(-filetypes) != {}} {
172 foreach type $data(-filetypes) {
173 set title [lindex [lindex $type 0] 0]
174 set filter [lindex $type 1]
175 radiobutton $f.b$cnt \
176 -text $title \
177 -variable ::tk::dialog::file::[winfo name $w](fileType) \
178 -value $cnt \
179 -command "[list tk::MotifFDialog_SetFilter $w $type]"
180 pack $f.b$cnt -side left
181 incr cnt
182 }
183 }
184 $f.b$data(fileType) invoke
185
186 pack $f -side bottom -fill both
187
188 return
189}
190
191# This proc gets called whenever data(filter) is set
192#
193proc ::tk::MotifFDialog_SetFilter {w type} {
194 upvar ::tk::dialog::file::[winfo name $w] data
195 variable ::tk::Priv
196
197 set data(filter) [lindex $type 1]
198 set Priv(selectFileType) [lindex [lindex $type 0] 0]
199
200 MotifFDialog_Update $w
201}
202
203# ::tk::MotifFDialog_Config --
204#
205# Iterates over the optional arguments to determine the option
206# values for the Motif file dialog; gives default values to
207# unspecified options.
208#
209# Arguments:
210# dataName The name of the global variable in which
211# data for the file dialog is stored.
212# type "Save" or "Open"
213# argList Options parsed by the procedure.
214
215proc ::tk::MotifFDialog_Config {dataName type argList} {
216 upvar ::tk::dialog::file::$dataName data
217
218 set data(type) $type
219
220 # 1: the configuration specs
221 #
222 set specs {
223 {-defaultextension "" "" ""}
224 {-filetypes "" "" ""}
225 {-initialdir "" "" ""}
226 {-initialfile "" "" ""}
227 {-parent "" "" "."}
228 {-title "" "" ""}
229 }
230 if { [string equal $type "open"] } {
231 lappend specs {-multiple "" "" "0"}
232 }
233
234 set data(-multiple) 0
235 # 2: default values depending on the type of the dialog
236 #
237 if {![info exists data(selectPath)]} {
238 # first time the dialog has been popped up
239 set data(selectPath) [pwd]
240 set data(selectFile) ""
241 }
242
243 # 3: parse the arguments
244 #
245 tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList
246
247 if {[string equal $data(-title) ""]} {
248 if {[string equal $type "open"]} {
249 if {$data(-multiple) != 0} {
250 set data(-title) "[mc {Open Multiple Files}]"
251 } else {
252 set data(-title) [mc "Open"]
253 }
254 } else {
255 set data(-title) [mc "Save As"]
256 }
257 }
258
259 # 4: set the default directory and selection according to the -initial
260 # settings
261 #
262 if {[string compare $data(-initialdir) ""]} {
263 if {[file isdirectory $data(-initialdir)]} {
264 set data(selectPath) [lindex [glob $data(-initialdir)] 0]
265 } else {
266 set data(selectPath) [pwd]
267 }
268
269 # Convert the initialdir to an absolute path name.
270
271 set old [pwd]
272 cd $data(selectPath)
273 set data(selectPath) [pwd]
274 cd $old
275 }
276 set data(selectFile) $data(-initialfile)
277
278 # 5. Parse the -filetypes option. It is not used by the motif
279 # file dialog, but we check for validity of the value to make sure
280 # the application code also runs fine with the TK file dialog.
281 #
282 set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)]
283
284 if {![info exists data(filter)]} {
285 set data(filter) *
286 }
287 if {![winfo exists $data(-parent)]} {
288 error "bad window path name \"$data(-parent)\""
289 }
290}
291
292# ::tk::MotifFDialog_BuildUI --
293#
294# Builds the UI components of the Motif file dialog.
295#
296# Arguments:
297# w Pathname of the dialog to build.
298#
299# Results:
300# None.
301
302proc ::tk::MotifFDialog_BuildUI {w} {
303 set dataName [lindex [split $w .] end]
304 upvar ::tk::dialog::file::$dataName data
305
306 # Create the dialog toplevel and internal frames.
307 #
308 toplevel $w -class TkMotifFDialog
309 set top [frame $w.top -relief raised -bd 1]
310 set bot [frame $w.bot -relief raised -bd 1]
311
312 pack $w.bot -side bottom -fill x
313 pack $w.top -side top -expand yes -fill both
314
315 set f1 [frame $top.f1]
316 set f2 [frame $top.f2]
317 set f3 [frame $top.f3]
318
319 pack $f1 -side top -fill x
320 pack $f3 -side bottom -fill x
321 pack $f2 -expand yes -fill both
322
323 set f2a [frame $f2.a]
324 set f2b [frame $f2.b]
325
326 grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
327 -sticky news
328 grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
329 -sticky news
330 grid rowconfig $f2 0 -minsize 0 -weight 1
331 grid columnconfig $f2 0 -minsize 0 -weight 1
332 grid columnconfig $f2 1 -minsize 150 -weight 2
333
334 # The Filter box
335 #
336 bind [::tk::AmpWidget label $f1.lab -text [mc "Fil&ter:"] -anchor w] \
337 <<AltUnderlined>> [list focus $f1.ent]
338 entry $f1.ent
339 pack $f1.lab -side top -fill x -padx 6 -pady 4
340 pack $f1.ent -side top -fill x -padx 4 -pady 0
341 set data(fEnt) $f1.ent
342
343 # The file and directory lists
344 #
345 set data(dList) [MotifFDialog_MakeSList $w $f2a \
346 [mc "&Directory:"] DList]
347 set data(fList) [MotifFDialog_MakeSList $w $f2b \
348 [mc "Fi&les:"] FList]
349
350 # The Selection box
351 #
352 bind [::tk::AmpWidget label $f3.lab -text [mc "&Selection:"] -anchor w] \
353 <<AltUnderlined>> [list focus $f3.ent]
354 entry $f3.ent
355 pack $f3.lab -side top -fill x -padx 6 -pady 0
356 pack $f3.ent -side top -fill x -padx 4 -pady 4
357 set data(sEnt) $f3.ent
358
359 # The buttons
360 #
361 set maxWidth [::tk::mcmaxamp &OK &Filter &Cancel]
362 set maxWidth [expr {$maxWidth<6?6:$maxWidth}]
363 set data(okBtn) [::tk::AmpWidget button $bot.ok -text [mc "&OK"] \
364 -width $maxWidth \
365 -command [list tk::MotifFDialog_OkCmd $w]]
366 set data(filterBtn) [::tk::AmpWidget button $bot.filter -text [mc "&Filter"] \
367 -width $maxWidth \
368 -command [list tk::MotifFDialog_FilterCmd $w]]
369 set data(cancelBtn) [::tk::AmpWidget button $bot.cancel -text [mc "&Cancel"] \
370 -width $maxWidth \
371 -command [list tk::MotifFDialog_CancelCmd $w]]
372
373 pack $bot.ok $bot.filter $bot.cancel -padx 10 -pady 10 -expand yes \
374 -side left
375
376 # Create the bindings:
377 #
378 bind $w <Alt-Key> [list ::tk::AltKeyInDialog $w %A]
379
380 bind $data(fEnt) <Return> [list tk::MotifFDialog_ActivateFEnt $w]
381 bind $data(sEnt) <Return> [list tk::MotifFDialog_ActivateSEnt $w]
382 bind $w <Escape> [list tk::MotifFDialog_CancelCmd $w]
383 bind $w.bot <Destroy> {set ::tk::Priv(selectFilePath) {}}
384
385 wm protocol $w WM_DELETE_WINDOW [list tk::MotifFDialog_CancelCmd $w]
386}
387
388proc ::tk::MotifFDialog_SetListMode {w} {
389 upvar ::tk::dialog::file::[winfo name $w] data
390
391 if {$data(-multiple) != 0} {
392 set selectmode extended
393 } else {
394 set selectmode browse
395 }
396 set f $w.top.f2.b
397 $f.l configure -selectmode $selectmode
398}
399
400# ::tk::MotifFDialog_MakeSList --
401#
402# Create a scrolled-listbox and set the keyboard accelerator
403# bindings so that the list selection follows what the user
404# types.
405#
406# Arguments:
407# w Pathname of the dialog box.
408# f Frame widget inside which to create the scrolled
409# listbox. This frame widget already exists.
410# label The string to display on top of the listbox.
411# under Sets the -under option of the label.
412# cmdPrefix Specifies procedures to call when the listbox is
413# browsed or activated.
414
415proc ::tk::MotifFDialog_MakeSList {w f label cmdPrefix} {
416 bind [::tk::AmpWidget label $f.lab -text $label -anchor w] \
417 <<AltUnderlined>> [list focus $f.l]
418 listbox $f.l -width 12 -height 5 -exportselection 0\
419 -xscrollcommand [list $f.h set] -yscrollcommand [list $f.v set]
420 scrollbar $f.v -orient vertical -takefocus 0 -command [list $f.l yview]
421 scrollbar $f.h -orient horizontal -takefocus 0 -command [list $f.l xview]
422 grid $f.lab -row 0 -column 0 -sticky news -rowspan 1 -columnspan 2 \
423 -padx 2 -pady 2
424 grid $f.l -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
425 grid $f.v -row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news
426 grid $f.h -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news
427
428 grid rowconfig $f 0 -weight 0 -minsize 0
429 grid rowconfig $f 1 -weight 1 -minsize 0
430 grid columnconfig $f 0 -weight 1 -minsize 0
431
432 # bindings for the listboxes
433 #
434 set list $f.l
435 bind $list <<ListboxSelect>> [list tk::MotifFDialog_Browse$cmdPrefix $w]
436 bind $list <Double-ButtonRelease-1> \
437 [list tk::MotifFDialog_Activate$cmdPrefix $w]
438 bind $list <Return> "tk::MotifFDialog_Browse$cmdPrefix [list $w]; \
439 tk::MotifFDialog_Activate$cmdPrefix [list $w]"
440
441 bindtags $list [list Listbox $list [winfo toplevel $list] all]
442 ListBoxKeyAccel_Set $list
443
444 return $f.l
445}
446
447# ::tk::MotifFDialog_InterpFilter --
448#
449# Interpret the string in the filter entry into two components:
450# the directory and the pattern. If the string is a relative
451# pathname, give a warning to the user and restore the pattern
452# to original.
453#
454# Arguments:
455# w pathname of the dialog box.
456#
457# Results:
458# A list of two elements. The first element is the directory
459# specified # by the filter. The second element is the filter
460# pattern itself.
461
462proc ::tk::MotifFDialog_InterpFilter {w} {
463 upvar ::tk::dialog::file::[winfo name $w] data
464
465 set text [string trim [$data(fEnt) get]]
466
467 # Perform tilde substitution
468 #
469 set badTilde 0
470 if {[string equal [string index $text 0] ~]} {
471 set list [file split $text]
472 set tilde [lindex $list 0]
473 if {[catch {set tilde [glob $tilde]}]} {
474 set badTilde 1
475 } else {
476 set text [eval file join [concat $tilde [lrange $list 1 end]]]
477 }
478 }
479
480 # If the string is a relative pathname, combine it
481 # with the current selectPath.
482
483 set relative 0
484 if {[string equal [file pathtype $text] "relative"]} {
485 set relative 1
486 } elseif {$badTilde} {
487 set relative 1
488 }
489
490 if {$relative} {
491 tk_messageBox -icon warning -type ok \
492 -message "\"$text\" must be an absolute pathname"
493
494 $data(fEnt) delete 0 end
495 $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
496 $data(filter)]
497
498 return [list $data(selectPath) $data(filter)]
499 }
500
501 set resolved [::tk::dialog::file::JoinFile [file dirname $text] [file tail $text]]
502
503 if {[file isdirectory $resolved]} {
504 set dir $resolved
505 set fil $data(filter)
506 } else {
507 set dir [file dirname $resolved]
508 set fil [file tail $resolved]
509 }
510
511 return [list $dir $fil]
512}
513
514# ::tk::MotifFDialog_Update
515#
516# Load the files and synchronize the "filter" and "selection" fields
517# boxes.
518#
519# Arguments:
520# w pathname of the dialog box.
521#
522# Results:
523# None.
524
525proc ::tk::MotifFDialog_Update {w} {
526 upvar ::tk::dialog::file::[winfo name $w] data
527
528 $data(fEnt) delete 0 end
529 $data(fEnt) insert 0 \
530 [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
531 $data(sEnt) delete 0 end
532 $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
533 $data(selectFile)]
534
535 MotifFDialog_LoadFiles $w
536}
537
538# ::tk::MotifFDialog_LoadFiles --
539#
540# Loads the files and directories into the two listboxes according
541# to the filter setting.
542#
543# Arguments:
544# w pathname of the dialog box.
545#
546# Results:
547# None.
548
549proc ::tk::MotifFDialog_LoadFiles {w} {
550 upvar ::tk::dialog::file::[winfo name $w] data
551
552 $data(dList) delete 0 end
553 $data(fList) delete 0 end
554
555 set appPWD [pwd]
556 if {[catch {cd $data(selectPath)}]} {
557 cd $appPWD
558
559 $data(dList) insert end ".."
560 return
561 }
562
563 # Make the dir and file lists
564 #
565 # For speed we only have one glob, which reduces the file system
566 # calls (good for slow NFS networks).
567 #
568 # We also do two smaller sorts (files + dirs) instead of one large sort,
569 # which gives a small speed increase.
570 #
571 set top 0
572 set dlist ""
573 set flist ""
574 foreach f [glob -nocomplain .* *] {
575 if {[file isdir ./$f]} {
576 lappend dlist $f
577 } else {
578 foreach pat $data(filter) {
579 if {[string match $pat $f]} {
580 if {[string match .* $f]} {
581 incr top
582 }
583 lappend flist $f
584 break
585 }
586 }
587 }
588 }
589 eval [list $data(dList) insert end] [lsort -dictionary $dlist]
590 eval [list $data(fList) insert end] [lsort -dictionary $flist]
591
592 # The user probably doesn't want to see the . files. We adjust the view
593 # so that the listbox displays all the non-dot files
594 $data(fList) yview $top
595
596 cd $appPWD
597}
598
599# ::tk::MotifFDialog_BrowseDList --
600#
601# This procedure is called when the directory list is browsed
602# (clicked-over) by the user.
603#
604# Arguments:
605# w The pathname of the dialog box.
606#
607# Results:
608# None.
609
610proc ::tk::MotifFDialog_BrowseDList {w} {
611 upvar ::tk::dialog::file::[winfo name $w] data
612
613 focus $data(dList)
614 if {[string equal [$data(dList) curselection] ""]} {
615 return
616 }
617 set subdir [$data(dList) get [$data(dList) curselection]]
618 if {[string equal $subdir ""]} {
619 return
620 }
621
622 $data(fList) selection clear 0 end
623
624 set list [MotifFDialog_InterpFilter $w]
625 set data(filter) [lindex $list 1]
626
627 switch -- $subdir {
628 . {
629 set newSpec [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
630 }
631 .. {
632 set newSpec [::tk::dialog::file::JoinFile [file dirname $data(selectPath)] \
633 $data(filter)]
634 }
635 default {
636 set newSpec [::tk::dialog::file::JoinFile [::tk::dialog::file::JoinFile \
637 $data(selectPath) $subdir] $data(filter)]
638 }
639 }
640
641 $data(fEnt) delete 0 end
642 $data(fEnt) insert 0 $newSpec
643}
644
645# ::tk::MotifFDialog_ActivateDList --
646#
647# This procedure is called when the directory list is activated
648# (double-clicked) by the user.
649#
650# Arguments:
651# w The pathname of the dialog box.
652#
653# Results:
654# None.
655
656proc ::tk::MotifFDialog_ActivateDList {w} {
657 upvar ::tk::dialog::file::[winfo name $w] data
658
659 if {[string equal [$data(dList) curselection] ""]} {
660 return
661 }
662 set subdir [$data(dList) get [$data(dList) curselection]]
663 if {[string equal $subdir ""]} {
664 return
665 }
666
667 $data(fList) selection clear 0 end
668
669 switch -- $subdir {
670 . {
671 set newDir $data(selectPath)
672 }
673 .. {
674 set newDir [file dirname $data(selectPath)]
675 }
676 default {
677 set newDir [::tk::dialog::file::JoinFile $data(selectPath) $subdir]
678 }
679 }
680
681 set data(selectPath) $newDir
682 MotifFDialog_Update $w
683
684 if {[string compare $subdir ..]} {
685 $data(dList) selection set 0
686 $data(dList) activate 0
687 } else {
688 $data(dList) selection set 1
689 $data(dList) activate 1
690 }
691}
692
693# ::tk::MotifFDialog_BrowseFList --
694#
695# This procedure is called when the file list is browsed
696# (clicked-over) by the user.
697#
698# Arguments:
699# w The pathname of the dialog box.
700#
701# Results:
702# None.
703
704proc ::tk::MotifFDialog_BrowseFList {w} {
705 upvar ::tk::dialog::file::[winfo name $w] data
706
707 focus $data(fList)
708 set data(selectFile) ""
709 foreach item [$data(fList) curselection] {
710 lappend data(selectFile) [$data(fList) get $item]
711 }
712 if {[llength $data(selectFile)] == 0} {
713 return
714 }
715
716 $data(dList) selection clear 0 end
717
718 $data(fEnt) delete 0 end
719 $data(fEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
720 $data(filter)]
721 $data(fEnt) xview end
722
723 # if it's a multiple selection box, just put in the filenames
724 # otherwise put in the full path as usual
725 $data(sEnt) delete 0 end
726 if {$data(-multiple) != 0} {
727 $data(sEnt) insert 0 $data(selectFile)
728 } else {
729 $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
730 [lindex $data(selectFile) 0]]
731 }
732 $data(sEnt) xview end
733}
734
735# ::tk::MotifFDialog_ActivateFList --
736#
737# This procedure is called when the file list is activated
738# (double-clicked) by the user.
739#
740# Arguments:
741# w The pathname of the dialog box.
742#
743# Results:
744# None.
745
746proc ::tk::MotifFDialog_ActivateFList {w} {
747 upvar ::tk::dialog::file::[winfo name $w] data
748
749 if {[string equal [$data(fList) curselection] ""]} {
750 return
751 }
752 set data(selectFile) [$data(fList) get [$data(fList) curselection]]
753 if {[string equal $data(selectFile) ""]} {
754 return
755 } else {
756 MotifFDialog_ActivateSEnt $w
757 }
758}
759
760# ::tk::MotifFDialog_ActivateFEnt --
761#
762# This procedure is called when the user presses Return inside
763# the "filter" entry. It updates the dialog according to the
764# text inside the filter entry.
765#
766# Arguments:
767# w The pathname of the dialog box.
768#
769# Results:
770# None.
771
772proc ::tk::MotifFDialog_ActivateFEnt {w} {
773 upvar ::tk::dialog::file::[winfo name $w] data
774
775 set list [MotifFDialog_InterpFilter $w]
776 set data(selectPath) [lindex $list 0]
777 set data(filter) [lindex $list 1]
778
779 MotifFDialog_Update $w
780}
781
782# ::tk::MotifFDialog_ActivateSEnt --
783#
784# This procedure is called when the user presses Return inside
785# the "selection" entry. It sets the ::tk::Priv(selectFilePath)
786# variable so that the vwait loop in tk::MotifFDialog will be
787# terminated.
788#
789# Arguments:
790# w The pathname of the dialog box.
791#
792# Results:
793# None.
794
795proc ::tk::MotifFDialog_ActivateSEnt {w} {
796 variable ::tk::Priv
797 upvar ::tk::dialog::file::[winfo name $w] data
798
799 set selectFilePath [string trim [$data(sEnt) get]]
800
801 if {[string equal $selectFilePath ""]} {
802 MotifFDialog_FilterCmd $w
803 return
804 }
805
806 if {$data(-multiple) == 0} {
807 set selectFilePath [list $selectFilePath]
808 }
809
810 if {[file isdirectory [lindex $selectFilePath 0]]} {
811 set data(selectPath) [lindex [glob $selectFilePath] 0]
812 set data(selectFile) ""
813 MotifFDialog_Update $w
814 return
815 }
816
817 set newFileList ""
818 foreach item $selectFilePath {
819 if {[string compare [file pathtype $item] "absolute"]} {
820 set item [file join $data(selectPath) $item]
821 } elseif {![file exists [file dirname $item]]} {
822 tk_messageBox -icon warning -type ok \
823 -message [mc {Directory "%1$s" does not exist.} \
824 [file dirname $item]]
825 return
826 }
827
828 if {![file exists $item]} {
829 if {[string equal $data(type) open]} {
830 tk_messageBox -icon warning -type ok \
831 -message [mc {File "%1$s" does not exist.} $item]
832 return
833 }
834 } else {
835 if {[string equal $data(type) save]} {
836 set message [format %s%s \
837 [mc "File \"%1\$s\" already exists.\n\n" \
838 $selectFilePath] \
839 [mc {Replace existing file?}]]
840 set answer [tk_messageBox -icon warning -type yesno \
841 -message $message]
842 if {[string equal $answer "no"]} {
843 return
844 }
845 }
846 }
847
848 lappend newFileList $item
849 }
850
851 if {$data(-multiple) != 0} {
852 set Priv(selectFilePath) $newFileList
853 } else {
854 set Priv(selectFilePath) [lindex $newFileList 0]
855 }
856
857 # Set selectFile and selectPath to first item in list
858 set Priv(selectFile) [file tail [lindex $newFileList 0]]
859 set Priv(selectPath) [file dirname [lindex $newFileList 0]]
860}
861
862
863proc ::tk::MotifFDialog_OkCmd {w} {
864 upvar ::tk::dialog::file::[winfo name $w] data
865
866 MotifFDialog_ActivateSEnt $w
867}
868
869proc ::tk::MotifFDialog_FilterCmd {w} {
870 upvar ::tk::dialog::file::[winfo name $w] data
871
872 MotifFDialog_ActivateFEnt $w
873}
874
875proc ::tk::MotifFDialog_CancelCmd {w} {
876 variable ::tk::Priv
877
878 set Priv(selectFilePath) ""
879 set Priv(selectFile) ""
880 set Priv(selectPath) ""
881}
882
883proc ::tk::ListBoxKeyAccel_Set {w} {
884 bind Listbox <Any-KeyPress> ""
885 bind $w <Destroy> [list tk::ListBoxKeyAccel_Unset $w]
886 bind $w <Any-KeyPress> [list tk::ListBoxKeyAccel_Key $w %A]
887}
888
889proc ::tk::ListBoxKeyAccel_Unset {w} {
890 variable ::tk::Priv
891
892 catch {after cancel $Priv(lbAccel,$w,afterId)}
893 catch {unset Priv(lbAccel,$w)}
894 catch {unset Priv(lbAccel,$w,afterId)}
895}
896
897# ::tk::ListBoxKeyAccel_Key--
898#
899# This procedure maintains a list of recently entered keystrokes
900# over a listbox widget. It arranges an idle event to move the
901# selection of the listbox to the entry that begins with the
902# keystrokes.
903#
904# Arguments:
905# w The pathname of the listbox.
906# key The key which the user just pressed.
907#
908# Results:
909# None.
910
911proc ::tk::ListBoxKeyAccel_Key {w key} {
912 variable ::tk::Priv
913
914 if { $key == "" } {
915 return
916 }
917 append Priv(lbAccel,$w) $key
918 ListBoxKeyAccel_Goto $w $Priv(lbAccel,$w)
919 catch {
920 after cancel $Priv(lbAccel,$w,afterId)
921 }
922 set Priv(lbAccel,$w,afterId) [after 500 \
923 [list tk::ListBoxKeyAccel_Reset $w]]
924}
925
926proc ::tk::ListBoxKeyAccel_Goto {w string} {
927 variable ::tk::Priv
928
929 set string [string tolower $string]
930 set end [$w index end]
931 set theIndex -1
932
933 for {set i 0} {$i < $end} {incr i} {
934 set item [string tolower [$w get $i]]
935 if {[string compare $string $item] >= 0} {
936 set theIndex $i
937 }
938 if {[string compare $string $item] <= 0} {
939 set theIndex $i
940 break
941 }
942 }
943
944 if {$theIndex >= 0} {
945 $w selection clear 0 end
946 $w selection set $theIndex $theIndex
947 $w activate $theIndex
948 $w see $theIndex
949 event generate $w <<ListboxSelect>>
950 }
951}
952
953proc ::tk::ListBoxKeyAccel_Reset {w} {
954 variable ::tk::Priv
955
956 catch {unset Priv(lbAccel,$w)}
957}
958
959proc ::tk_getFileType {} {
960 variable ::tk::Priv
961
962 return $Priv(selectFileType)
963}
964