2 if {![info exists UseNativeDialogs
] ||
$UseNativeDialogs == ""} {
3 if {$tcl_platform(platform
) == "windows"} {
12 set fileselect
(toplevel) .fileselect
13 set fileselect
(button) ""
14 set fileselect
(filter
) *
15 set fileselect
(filename) ""
16 set fileselect
(xpos
) -1
17 set fileselect
(ypos
) -1
18 set fileselect
(down
) [image create
bitmap -data "
20 #define down_height 10
21 static unsigned char down_bits[] = {
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0xf0, 0x1f, 0x00,
23 0xe0, 0x0f, 0x00, 0xc0, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x01, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"]
26 proc fileselect
{title defname
{x
-1} {y
-1} {filter
*}} {
30 set top
$fileselect(toplevel)
34 wm transient
$top [winfo toplevel [winfo parent
$top]]
38 set w
[frame $top.
button -relief sunken
-bd 2]
39 pack $w -side bottom
-fill x
-padx 2 -pady 2 -anchor s
-expand 1
40 button $w.accept
-relief raised
-text Accept
\
41 -command "set fileselect(button) 1"
42 button $w.cancel
-relief raised
-text Cancel
\
43 -command "set fileselect(button) 0"
44 pack $w.accept
$w.cancel
-side left
-expand 1 -fill x
-padx 5 -pady 2
46 $fileselect(down
) configure
-foreground [$w.accept cget
-foreground]
50 set w
[frame $top.filter
]
51 pack $w -side top
-fill x
-padx 2 -pady 2 -anchor n
52 label $w.
label -text "Filter:"
53 pack $w.
label -side left
-anchor w
54 entry $w.
entry -relief sunken
55 pack $w.
entry -side left
-fill x
-expand 1
56 menubutton $w.menubut
-relief raised
-image $fileselect(down
) \
57 -menu $w.menubut.m
-direction left
58 menu $w.menubut.m
-tearoff 0
59 pack $w.menubut
-side right
-fill y
61 bind $w.
entry <Escape
> {filesel
:entry %W
[pwd]/$fileselect(filter
)}
62 bind $w.
entry <Return
> {
65 set fileselect
(filter
) "*"
66 set fileselect
(filename) ""
67 if {![file isdirectory
$dir]} {
68 set fileselect
(filter
) [file tail
$dir]
69 set dir
[file dirname
$dir]
74 bind $w.
entry <Control-u
> {%W delete
0 end
}
76 #--- file selection entry
78 set w
[frame $top.
filename]
79 pack $w -side bottom
-fill x
-padx 2 -pady 2 -anchor s
80 label $w.
label -text "Filename:"
81 pack $w.
label -side left
-anchor w
82 entry $w.
entry -relief sunken
83 pack $w.
entry -side left
-fill x
-expand 1
85 bind $w.
entry <Escape
> {filesel
:entry %W
[pwd]/$fileselect(filename)}
86 bind $w.
entry <Return
> {
88 if [file isdirectory
[%W get
]] {
89 set fileselect
(filename) ""
93 set fileselect
(button) 1
96 bind $w.
entry <Control-u
> {%W delete
0 end
}
100 set w
[frame $top.dirlist
]
101 pack $w -side left
-fill both
-padx 2 -expand 1
102 label $w.
label -text "Directories:"
103 pack $w.
label -side top
-anchor w
104 scrollbar $w.scroll
-relief sunken
-command "$w.list yview"
105 pack $w.scroll
-side right
-fill y
106 listbox $w.
list -relief sunken
-yscroll "$w.scroll set" \
108 pack $w.
list -side left
-fill both
-expand 1
110 bind $w.
list <Double-Button-1
> {filesel
:Directory
%W
}
111 bind $w.
list <Return
> {filesel
:Directory
%W
}
115 set w
[frame $top.filelist
]
116 pack $w -side left
-fill both
-padx 2 -expand 1
117 label $w.
label -text "Files:"
118 pack $w.
label -side top
-anchor w
119 scrollbar $w.scroll
-relief sunken
-command "$w.list yview"
120 pack $w.scroll
-side right
-fill y
121 listbox $w.
list -relief sunken
-yscroll "$w.scroll set" \
123 pack $w.
list -side left
-fill both
-expand 1
125 bind $w.
list <ButtonRelease-1
> {filesel
:Filename
%W
}
126 bind $w.
list <Return
> {filesel
:Filename
%W
}
127 bind $w.
list <Double-Button-1
> {
129 if [filesel
:Filename
%W
] {set fileselect
(button) 1}
134 set fileselect
(filter
) ""
135 foreach filt
$filter {
136 if {[llength $filt] == 2} {
138 foreach ext
[lindex $filt 1] {
139 if {[string index
$ext 0] != "*"} {
144 if {$extlist == ""} {
150 $top.filter.menubut.m add command
\
151 -label "[lindex $filt 0] \($extlist\)" \
152 -command "set fileselect(filter) $extlist; filesel:Select"
153 if {$fileselect(filter
) == ""} {
154 set fileselect
(filter
) $extlist
158 if {$fileselect(filter
) == ""} {
159 $top.filter.menubut configure
-state disabled
160 set fileselect
(filter
) $filter
162 set fileselect
(filename) ""
163 if {$defname != ""} {
164 if [file isdirectory
$defname] {
167 catch {cd [file dirname
$defname]}
168 if [string match
"*\[*?\]*" [file tail
$defname]] {
169 set fileselect
(filter
) [file tail
$defname]
171 set fileselect
(filename) [file tail
$defname]
177 #--- locate the window
179 if {$x != "" && [winfo exists
$x]} {
180 center_window
$top $x
184 set ww
[winfo reqwidth
$top]
185 set wh
[winfo reqheight
$top]
188 if {$fileselect(xpos
) < 0} {
189 if [winfo ismapped .
] {
190 set x
[expr [winfo rootx .
] + ([winfo width .
] - $ww) / 2]
192 set x
[expr ([winfo screenwidth
$top] - $ww) / 2]
195 set x
$fileselect(xpos
)
198 set x
[expr $x - $ww / 2]
202 } elseif
{[expr $x + $ww] > [winfo screenwidth
$top]} {
209 if {$fileselect(ypos
) < 0} {
210 if [winfo ismapped .
] {
211 set y
[expr [winfo rooty .
] + ([winfo height .
] - $wh) / 2]
213 set y
[expr ([winfo screenheight
$top] - $wh) / 2]
216 set y
$fileselect(ypos
)
219 set y
[expr $y - $wh / 2]
223 } elseif
{[expr $y + $wh] > [winfo screenheight
$top]} {
233 #--- wait for button click
236 set oldGrab
[grab current
$w]
237 if {$oldGrab != ""} {
238 set grabStatus
[grab status
$oldGrab]
241 $top.
filename.
entry selection range
0 end
242 focus $top.
filename.
entry
243 tkwait variable fileselect
(button)
244 if $fileselect(button) {
245 set filename [$top.
filename.
entry get
]
249 set fileselect
(xpos
) [winfo rootx
$top]
250 set fileselect
(ypos
) [winfo rooty
$top]
252 catch {focus $oldFocus}
253 if {$oldGrab != ""} {
254 if {$grabStatus == "global"} {
255 grab -global $oldGrab
264 proc filesel
:Directory
{w
} {
266 if {[$w curselection
] != ""} {
267 set dir
[$w get
[$w curselection
]]
268 if {$dir == ".. <up>"} {
272 if {$fileselect(filename) != "" &&
273 ![file isfile
$fileselect(filename)]} {
274 set fileselect
(filename) ""
280 proc filesel
:Filename
{w
} {
282 if {[$w curselection
] != ""} {
283 set fileselect
(filename) [$w get
[$w curselection
]]
284 filesel
:entry $fileselect(toplevel).
filename.
entry \
285 [pwd]/$fileselect(filename)
291 proc filesel
:Select
{{vis
1}} {
292 global fileselect tcl_platform
294 if {[info exists tcl_platform
(platform
)] &&
295 $tcl_platform(platform
) == "windows" &&
296 [string index
$curdir 1] == ":"} {
297 set curdir
[string range
$curdir 2 end
]
300 $fileselect(toplevel) configure
-cursor watch
304 #--- fill in directories
306 set w
$fileselect(toplevel).dirlist.
list
307 catch {set files
[lsort [glob -nocomplain *]]}
309 if {$curdir != "/"} {
310 $w insert
0 ".. <up>"
313 if [file isdirectory
"./$f"] {
320 set w
$fileselect(toplevel).filelist.
list
321 catch {set files
[lsort [eval glob -nocomplain \
322 [split $fileselect(filter
) ,]]]}
326 if [file isfile
"./$f"] {
328 if {$f == $fileselect(filename)} {
335 #--- update filter and filename entries
337 if {$curdir == "/"} {
338 filesel
:entry $fileselect(toplevel).filter.
entry \
339 [pwd]$fileselect(filter
)
340 filesel
:entry $fileselect(toplevel).
filename.
entry \
341 [pwd]$fileselect(filename)
343 filesel
:entry $fileselect(toplevel).filter.
entry \
344 [pwd]/$fileselect(filter
)
345 filesel
:entry $fileselect(toplevel).
filename.
entry \
346 [pwd]/$fileselect(filename)
349 $fileselect(toplevel) configure
-cursor {}
353 proc filesel
:entry {w s
} {
357 set c
[$w index insert
]
358 if {($c < [$w index
@0]) ||
($c > [$w index
@[winfo width
$w]])} {
364 #----- directory selection
366 proc dirselect
{title defname
{x
-1} {y
-1}} {
370 set top
$fileselect(toplevel)
374 wm transient
$top [winfo toplevel [winfo parent
$top]]
378 set w
[frame $top.filter
]
379 pack $w -side top
-fill x
-padx 2 -pady 2 -anchor n
380 label $w.
label -text "Filter:"
381 pack $w.
label -side left
-anchor w
382 entry $w.
entry -relief sunken
383 pack $w.
entry -side left
-fill x
-expand 1
385 bind $w.
entry <Escape
> {filesel
:entry %W
[pwd]/$fileselect(filter
)}
386 bind $w.
entry <Return
> {
389 set fileselect
(filter
) "*"
390 set fileselect
(filename) ""
391 if {![file isdirectory
$dir]} {
392 set fileselect
(filter
) [file tail
$dir]
393 set dir
[file dirname
$dir]
398 bind $w.
entry <Control-u
> {%W delete
0 end
}
402 set w
[frame $top.
button -relief sunken
-bd 2]
403 pack $w -side bottom
-fill x
-padx 2 -pady 2 -anchor s
-expand 1
404 button $w.accept
-relief raised
-text Accept
\
405 -command "set fileselect(button) 1"
406 button $w.cancel
-relief raised
-text Cancel
\
407 -command "set fileselect(button) 0"
408 pack $w.accept
$w.cancel
-side left
-expand 1 -fill x
-padx 5 -pady 2
410 #--- file selection entry
412 set w
[frame $top.
filename]
413 pack $w -side bottom
-fill x
-padx 2 -pady 2 -anchor s
414 label $w.
label -text "Directory:"
415 pack $w.
label -side left
-anchor w
416 entry $w.
entry -relief sunken
417 pack $w.
entry -side left
-fill x
-expand 1
419 bind $w.
entry <Escape
> {filesel
:entry %W
[pwd]/}
420 bind $w.
entry <Return
> {
422 if [file isdirectory
[%W get
]] {
423 set fileselect
(button) 1
426 bind $w.
entry <Control-u
> {%W delete
0 end
}
430 set w
[frame $top.dirlist
]
431 pack $w -side left
-fill both
-padx 2 -expand 1
432 label $w.
label -text "Directories:"
433 pack $w.
label -side top
-anchor w
434 scrollbar $w.scroll
-relief sunken
-command "$w.list yview"
435 pack $w.scroll
-side right
-fill y
436 listbox $w.
list -relief sunken
-yscroll "$w.scroll set" \
437 -selectmode browse
-exportselection 0
438 pack $w.
list -side left
-fill both
-expand 1
440 bind $w.
list <Double-Button-1
> {filesel
:Directory
%W
}
441 bind $w.
list <Return
> {filesel
:Directory
%W
}
445 set fg
[$top.
button.accept cget
-disabledforeground]
446 set bg
[$w.
list cget
-bg]
447 if {[winfo rgb
$w.
list $fg] == [winfo rgb
$w.
list $bg]} {
448 set fg
[$w.
list cget
-fg]
450 set w
[frame $top.filelist
]
451 pack $w -side left
-fill both
-padx 2 -expand 1
452 label $w.
label -text "Files:"
453 pack $w.
label -side top
-anchor w
454 scrollbar $w.scroll
-relief sunken
-command "$w.list yview"
455 pack $w.scroll
-side right
-fill y
456 listbox $w.
list -relief sunken
-yscroll "$w.scroll set" \
457 -fg $fg -bg $bg -selectforeground $fg -selectbackground $bg \
458 -selectborderwidth 0 -takefocus 0 -highlightthickness 0
459 pack $w.
list -side left
-fill both
-expand 1
461 bind $w.
list <Button-1
> {}
462 bind $w.
list <Double-Button-1
> {}
466 set fileselect
(filter
) "*"
467 set fileselect
(filename) ""
468 if {$defname != ""} {
469 if [file isdirectory
$defname] {
472 catch {cd [file dirname
$defname]}
473 if [string match
"*\[*?\]*" [file tail
$defname]] {
474 set fileselect
(filter
) [file tail
$defname]
480 #--- locate the window
482 if {$x != "" && [winfo exists
$x]} {
483 center_window
$top $x
487 set ww
[winfo reqwidth
$top]
488 set wh
[winfo reqheight
$top]
491 if {$fileselect(xpos
) < 0} {
492 if [winfo ismapped .
] {
493 set x
[expr [winfo rootx .
] + ([winfo width .
] - $ww) / 2]
495 set x
[expr ([winfo screenwidth
$top] - $ww) / 2]
498 set x
$fileselect(xpos
)
501 set x
[expr $x - $ww / 2]
505 } elseif
{[expr $x + $ww] > [winfo screenwidth
$top]} {
512 if {$fileselect(ypos
) < 0} {
513 if [winfo ismapped .
] {
514 set y
[expr [winfo rooty .
] + ([winfo height .
] - $wh) / 2]
516 set y
[expr ([winfo screenheight
$top] - $wh) / 2]
519 set y
$fileselect(ypos
)
522 set y
[expr $y - $wh / 2]
526 } elseif
{[expr $y + $wh] > [winfo screenheight
$top]} {
536 #--- wait for button click
539 set oldGrab
[grab current
$top]
540 if {$oldGrab != ""} {
541 set grabStatus
[grab status
$oldGrab]
544 $top.filter.
entry selection range
0 end
545 focus -force $top.filter.
entry
546 tkwait variable fileselect
(button)
547 if $fileselect(button) {
548 set dirname
[$top.
filename.
entry get
]
549 if ![catch {cd $dirname}] {
555 set fileselect
(xpos
) [winfo rootx
$top]
556 set fileselect
(ypos
) [winfo rooty
$top]
558 catch {focus $oldFocus}
559 if {$oldGrab != ""} {
560 if {$grabStatus == "global"} {
561 grab -global $oldGrab
570 proc FileOpen
{title defname
{wref .
} {types
""}} {
571 global UseNativeDialogs
572 if {$defname == ""} {
576 if [file isdirectory
$defname] {
580 set dir
[file dirname
$defname]
581 set file [file tail
$defname]
587 if $UseNativeDialogs {
588 set opts
"-title {$title} -initialdir {$dir}"
589 if {$defname != "" && [file exists
$defname]} {
590 append opts
" -initialfile {[file tail $defname]}"
593 append opts
" -initialfile {$file}"
595 if {$wref != "" && [winfo exists
$wref]} {
596 append opts
" -parent $wref"
599 append opts
" -filetypes {$types}"
601 return [eval tk_getOpenFile $opts]
607 set fname
[fileselect
$title $dir/$file $wref {} $types]
608 if {$fname == "" ||
[file exists
$fname]} {return $fname}
609 dialog .fileopen
$wref {} $title "$fname
610 Cannot find this file. Please verify the path and filename." info 0 Ok
614 proc FileSave
{title defname
{wref .
} {types
""} {defext
""}} {
615 global UseNativeDialogs
616 if {$defname == ""} {
620 if [file isdirectory
$defname] {
624 set dir
[file dirname
$defname]
625 set file [file tail
$defname]
631 if $UseNativeDialogs {
632 set opts
"-title {$title} -initialdir {$dir}"
634 append opts
" -initialfile {$file}"
636 if {$wref != "" && [winfo exists
$wref]} {
637 append opts
" -parent $wref"
640 append opts
" -filetypes {$types}"
643 append opts
" -defaultextension $defext"
645 return [eval tk_getSaveFile $opts]
651 set fname
[fileselect
$title $dir/$file $wref {} $types]
652 if {$fname == ""} {return ""}
653 if {$defext != "" && [file extension
$fname] == ""} {
654 append fname
".$defext"
656 if {![file exists
$fname]} {return $fname}
657 if ![dialog .filesave
$wref {} $title "$fname
658 This file already exists. Replace the existing file ?" info 0 Yes No
] {
664 proc GetDirectory
{title dir
{wref .
}} {
665 global UseNativeDialogs
666 if {$dir == "" ||
$dir == "." ||
![file isdirectory
$dir]} {
669 if {$UseNativeDialogs} {
670 set opts
"-title {$title} -initialdir {$dir}"
671 if {$wref != "" && [winfo exists
$wref]} {
672 append opts
" -parent $wref"
674 return [eval tk_getDirectory
$opts]
676 return [dirselect
$title $dir $wref]
679 proc TempName
{{prefix
""} {extlist
{}}} {
680 if {$prefix == ""} {set prefix temp
}
682 foreach ext
$extlist {
683 if {[file exists
$name.
$ext]} {
688 if {$name != ""} {return $name}
689 for {set n
0} {$n < 1000} {incr n
} {
690 set name
[format "$prefix%3.3d" $n]
691 if {[file exists
$name]} continue
692 foreach ext
$extlist {
693 if {[file exists
$name.
$ext]} {
698 if {$name != ""} {return $name}