1#! /bin/sh
2# The next line restarts using wish \
3exec uuwish "$0" ${1+"$@"}
4
5#
6# Init Options
7#
8
9proc ifndef { var val } {
10    global $var
11    if { [ catch { set $var } ] } {
12	set $var $val
13    }
14}
15
16#
17# read in rc file
18#
19
20if { ! [ catch { set env(HOME) } ] } {
21    catch { source $env(HOME)/.xdeviewrc }
22}
23
24#
25# overridable options for decoding
26#
27
28ifndef OptionFast 0
29ifndef OptionBracket 0
30ifndef OptionOverwrite 0
31ifndef OptionDesperate 0
32ifndef OptionVerbose 0
33ifndef OptionDumbness 0
34ifndef OptionUsetext 0
35ifndef SaveFilePath [ pwd ]
36ifndef OptionDebug 0
37ifndef OptionAutoInfo 0
38ifndef OptionRemove 0
39ifndef OptionMoreMime 0
40
41#
42# overridable encoding options
43#
44
45ifndef EncodeMaxLines	0
46ifndef EncodeEncoding	0
47ifndef EncodeSubject	""
48ifndef EncodeFrom       ""
49ifndef EncodeReplyTo    ""
50ifndef EncodeFileYes	1
51ifndef EncodeFilePath	$SaveFilePath
52ifndef EncodeMailYes	0
53ifndef EncodeMailAddr	""
54ifndef EncodeNewsYes	0
55ifndef EncodeNewsGroup	""
56ifndef NNTPServer	""
57
58#
59# MIME configuration
60#
61
62ifndef MIMEGlobalTypes	""
63ifndef MIMEGlobalCap	""
64if { ! [ catch { set env(HOME) } ] } {
65    ifndef MIMELocalTypes	$env(HOME)/.mime.types
66    ifndef MIMELocalCap		$env(HOME)/.mailcap
67} else {
68    ifndef MIMELocalTypes	""
69    ifndef MIMELocalCap		""
70}
71
72#
73# check whether we are started from within uudeview and have tk support
74#
75
76if { [ catch { uu_Info have_tk } have_tk ] } {
77    puts "Xdeview error: this file must be loaded from within uudeview"
78    exit 1
79}
80if { ! [ lindex [ lindex $have_tk 0 ] 1 ] } {
81    puts "Xdeview error: tk support not compiled"
82    exit 1
83}
84
85##############################################################################
86# General Helper functions
87##############################################################################
88
89#
90# Get a file type from .mime.types
91#
92
93proc GetTypeByExtension { ext } {
94    global MIMELocalTypes MIMEGlobalTypes
95
96    foreach fname "$MIMELocalTypes $MIMEGlobalTypes" {
97	if { [ catch { open $fname r } fileID ] } {
98	    return
99	}
100	while { ! [ eof $fileID ] } {
101	    if { [ gets $fileID TheLine ] < 0 } {
102		break
103	    }
104	    if { [ string index $TheLine 0 ] == "#" } {
105		continue
106	    } elseif { [ llength $TheLine ] < 2 } {
107		continue
108	    }
109	    for { set index 1 } { $index < [ llength $TheLine ] } { incr index } {
110		if { [ string tolower [ lindex $TheLine $index ] ] == \
111			[ string tolower $ext ] } {
112		    close $fileID
113		    return [ lindex $TheLine 0 ]
114		}
115	    }
116	}
117	close $fileID
118    }
119    return
120}
121
122#
123# see what to do with this type by reading .mailcap
124#
125
126proc GetTypeAction { type } {
127    global MIMELocalCap MIMEGlobalCap
128    foreach fname "$MIMELocalCap $MIMEGlobalCap" {
129	if { [ catch { open $fname r } fileID ] } {
130	    continue
131	}
132	while { ! [ eof $fileID ] } {
133	    if { [ gets $fileID TheLine ] < 0 } {
134		break
135	    }
136	    if { [ string index $TheLine 0 ] == "#" } {
137		continue
138	    }
139
140	    if { [ set ThisType [ lindex [ split $TheLine ";" ] 0 ] ] == "" } {
141		continue
142	    }
143
144	    if { [ string match \
145		    [ string tolower $ThisType ] [ string tolower $type ] ] } {
146		close $fileID
147		return [ lindex [ split $TheLine ";" ] 1 ]
148	    }
149	}
150	close $fileID
151    }
152    return
153}
154
155##############################################################################
156# Specific helper functions
157##############################################################################
158
159#
160# Retrieve the current global FileList and display it. Store in $FileList
161#
162
163proc ShowFileList {} {
164    global FileList
165
166    proc GetStatus { Code } {
167	if { [ expr $Code & 0x08 ] } {
168	    return "No Data"
169	} elseif { [ expr $Code & 0x20 ] } {
170	    return "Error"
171	} elseif { [ expr $Code & 0x10 ] } {
172	    return "OK"
173	} elseif { [ expr $Code & 0x01 ] } {
174	    return "Incomplete"
175	} elseif { [ expr $Code & 0x02 ] } {
176	    return "No Begin"
177	} elseif { [ expr $Code & 0x04 ] } {
178	    return "No End"
179	} elseif { $Code == 0 } {
180	    return "Oops"
181	}
182	return "Error"
183    }
184
185    ._MainFrame._FileList._Status delete 0 end
186    ._MainFrame._FileList._Liste delete 0 end
187
188    set FileList [uu_GetListOfFiles]
189
190    foreach item $FileList {
191	._MainFrame._FileList._Status insert end [GetStatus [lindex $item 1]]
192	._MainFrame._FileList._Liste insert end [ lindex $item 2 ]
193    }
194}
195
196#
197# Check the Path
198#
199
200proc CheckWritable { Path } {
201    if { ! [ expr [ file isdirectory $Path ] && [ file writable $Path ] ] } {
202	tk_dialog ._Dialog { Illegal Save Path } "You do not have the\
203		proper permissions to write to the selected Save Path.\
204		Please use a different Directory" \
205		warning 0 OK
206	return 0
207    }
208    return 1
209}
210
211#
212# Callback function for warnings and errors
213#
214
215proc OpenMessageWindow { } {
216    if { [ catch { .messages configure } ] } {
217	toplevel .messages
218	frame .messages.top
219	frame .messages.bot
220	text .messages.top.text -relief raised -bd 2 -wrap none \
221		-xscrollcommand ".messages.top.sbx set" \
222		-yscrollcommand ".messages.top.sby set"
223	scrollbar .messages.top.sbx -command ".messages.top.text xview" \
224		-orient horizontal
225	scrollbar .messages.top.sby -command ".messages.top.text yview"
226
227	pack .messages.top.sbx -side bottom -fill x
228	pack .messages.top.sby -side right -fill y
229	pack .messages.top.text -fill both -expand 1
230
231	button .messages.bot.done -text "Done" -command "destroy .messages"
232	pack .messages.bot.done -side right -padx 4 -pady 4
233
234	pack .messages.top -side top -fill both -expand 1
235	pack .messages.bot -side bottom
236
237	wm title .messages "Runtime Messages"
238    }
239}
240
241#
242# Display a message in our Runtime Messages window, if verbose
243#
244
245proc DisplayMessage { level string } {
246    global OptionVerbose
247
248    if { $OptionVerbose } {
249	OpenMessageWindow
250	.messages.top.text insert end $string
251	.messages.top.text insert end "\n"
252	.messages.top.text yview end
253	update
254    }
255    if { $level == 2 } {
256	tk_dialog ._Dialog "Warning" $string warning 0 OK
257    } elseif { $level > 2 } {
258	tk_dialog ._Dialog "Error" $string error 0 OK
259    }
260}
261
262#
263# Dump the current File List in the Runtime Messages window
264#
265
266proc DumpFileList { } {
267    global FileList
268
269    OpenMessageWindow
270
271    if { [ llength $FileList ] == 0 } {
272	return
273    }
274
275    .messages.top.text insert end "\n"
276
277    foreach file $FileList {
278	if { [ expr [ lindex $file 1 ] & 0x08 ] } {
279	    continue
280	}
281	.messages.top.text insert end \
282		"Found '[lindex $file 2]'\
283		State [lindex $file 1] [lindex $file 4]\
284		Parts [lindex $file 5]\n"
285    }
286    .messages.top.text insert end "\n"
287    .messages.top.text yview end
288}
289
290#
291# Handle Busy Callback
292#
293
294proc WeAreBusy {} {
295    set BusyInfo [uu_GetProgressInfo]
296
297    if { [ lindex $BusyInfo 0 ] == 1 } {
298	._Status._Text config -text \
299		"Loading [ file tail [ lindex $BusyInfo 1 ] ] --\
300		[ lindex $BusyInfo 4 ]% done"
301    } elseif { [ lindex $BusyInfo 0 ] == 2 } {
302	set percent [expr 100*[lindex $BusyInfo 2]+[lindex $BusyInfo 4]-100]
303	set percent [expr $percent / [lindex $BusyInfo 3]]
304
305	._Status._Text configure -text \
306		"Decoding [file tail [lindex $BusyInfo 1 ] ] --\
307		$percent% done"
308    } elseif { [ lindex $BusyInfo 0 ] == 3 } {
309	._Status._Text config -text \
310		"Copying [ file tail [ lindex $BusyInfo 1 ] ] --\
311		[ lindex $BusyInfo 4 ]% done"
312    } elseif { [ lindex $BusyInfo 0 ] == 4 } {
313	set percent [expr 100*[lindex $BusyInfo 2]+[lindex $BusyInfo 4]-100]
314	set percent [expr $percent / [lindex $BusyInfo 3]]
315
316	._Status._Text configure -text \
317		"Encoding [file tail [lindex $BusyInfo 1 ] ] --\
318		$percent% done"
319    }
320    update
321}
322
323#
324# Helper function to load a bunch of files
325#
326
327proc LoadFiles { LoadFileList } {
328    set oldCursor [ lindex [ . config -cursor ] 4 ]
329    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
330
331    . config -cursor watch
332
333    foreach file $LoadFileList {
334	#
335	# recurse into subdirectories
336	#
337	if { [ file isdirectory $file ] && [ file readable $file ] } {
338	    LoadFiles [ glob -nocomplain [ file join $file * ] ]
339	    continue
340	} elseif { ! [ file readable $file ] || [ file isdirectory $file ] } {
341	    tk_dialog ._Dialog "File Unreadable" "File $file is read\
342		    protected or is a directory" warning 0 OK
343	    continue
344	}
345	._Status._Text config -text "Loading [ file tail $file ] ..."
346	update
347	uu_LoadFile $file
348    }
349
350    ._Status._Text config -text $oldText
351    . config -cursor $oldCursor
352}
353
354##############################################################################
355# Button bindings && Menu functions
356##############################################################################
357
358#
359# Menu Command File->Quit
360#
361
362proc Quit {} {
363    uu_CleanUp
364    destroy .
365    exit 0
366}
367
368#
369# Menu Command File->Load
370#
371
372proc Load {} {
373    global OptionVerbose
374
375    set oldText [ lindex [ ._Status._Text config -text ] 4 ]
376    ._Status._Text config -text "Waiting for you to Select Files"
377    set LoadFileList [ tk_SelectFiles "Select Files for Decoding" 1 1 ]
378    ._Status._Text config -text $oldText
379
380    if { $LoadFileList != {} } {
381	LoadFiles $LoadFileList
382	ShowFileList
383	if { $OptionVerbose } {
384	    DumpFileList
385	}
386    }
387}
388
389#
390# Menu Command File->Helper Setup
391#
392
393proc MimeSetup {} {
394    global MIMEGlobalTypes MIMELocalCap MIMEGlobalCap MIMELocalTypes
395    global tempGlobalTypes tempLocalCap tempGlobalCap tempLocalTypes
396    global MSFinish
397
398    set tempGlobalTypes $MIMEGlobalTypes
399    set tempLocalCap    $MIMELocalCap
400    set tempGlobalCap   $MIMEGlobalCap
401    set tempLocalTypes  $MIMELocalTypes
402
403    set oldCursor [ lindex [ . config -cursor ] 4 ]
404    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
405    set oldFocus  [ focus ]
406
407    toplevel .mime
408    wm title .mime "Helper Setup"
409
410    frame .mime.top -relief groove -bd 1
411    frame .mime.top.gt
412    frame .mime.top.lt
413    frame .mime.top.gc
414    frame .mime.top.lc
415
416    label .mime.top.gt.lab -text "Global Types File" -width 16 \
417	    -justify left -anchor w
418    entry .mime.top.gt.ent -relief sunken -width 30 \
419	    -textvariable MIMEGlobalTypes
420    button .mime.top.gt.but -text "Browse" -width 8 -command {
421	set OldDir [ file dirname $MIMEGlobalTypes ]
422	set NewFile [ tk_SelectFiles "Global Types File" 0 0 $OldDir ]
423	if { $NewFile != "" } { set MIMEGlobalTypes $NewFile }
424    }
425    label .mime.top.lt.lab -text "Local Types File" -width 16 \
426	    -justify left -anchor w
427    entry .mime.top.lt.ent -relief sunken -width 30 \
428	    -textvariable MIMELocalTypes
429    button .mime.top.lt.but -text "Browse" -width 8 -command {
430	set OldDir [ file dirname $MIMELocalTypes ]
431	set NewFile [ tk_SelectFiles "Local Types File" 0 0 $OldDir ]
432	if { $NewFile != "" } { set MIMELocalTypes $NewFile }
433    }
434    label .mime.top.gc.lab -text "Global Mailcap File" -width 16 \
435	    -justify left -anchor w
436    entry .mime.top.gc.ent -relief sunken -width 30 \
437	    -textvariable MIMEGlobalCap
438    button .mime.top.gc.but -text "Browse" -width 8 -command {
439	set OldDir [ file dirname $MIMEGlobalCap ]
440	set NewFile [ tk_SelectFiles "Global Mailcap File" 0 0 $OldDir ]
441	if { $NewFile != "" } { set MIMEGlobalCap $NewFile }
442    }
443    label .mime.top.lc.lab -text "Local Mailcap File" -width 16 \
444	    -justify left -anchor w
445    entry .mime.top.lc.ent -relief sunken -width 30 \
446	    -textvariable MIMELocalCap
447    button .mime.top.lc.but -text "Browse" -width 8 -command {
448	set OldDir [ file dirname $MIMELocalCap ]
449	set NewFile [ tk_SelectFiles "Local Mailcap File" 0 0 $OldDir ]
450	if { $NewFile != "" } { set MIMELocalCap $NewFile }
451    }
452
453    pack .mime.top.gt.lab -side left -padx 4 -pady 4
454    pack .mime.top.gt.but -side right -padx 4
455    pack .mime.top.gt.ent -side right -padx 4 -pady 4 -expand true -fill x
456
457    pack .mime.top.lt.lab -side left -padx 4 -pady 4
458    pack .mime.top.lt.but -side right -padx 4
459    pack .mime.top.lt.ent -side right -padx 4 -pady 4 -expand true -fill x
460
461    pack .mime.top.gc.lab -side left -padx 4 -pady 4
462    pack .mime.top.gc.but -side right -padx 4
463    pack .mime.top.gc.ent -side right -padx 4 -pady 4 -expand true -fill x
464
465    pack .mime.top.lc.lab -side left -padx 4 -pady 4
466    pack .mime.top.lc.but -side right -padx 4
467    pack .mime.top.lc.ent -side right -padx 4 -pady 4 -expand true -fill x
468
469    pack .mime.top.gt .mime.top.lt .mime.top.gc .mime.top.lc \
470	    -side top -expand true -fill both
471
472    frame .mime.but -relief raised -bd 2
473    frame .mime.but.b
474
475    button .mime.but.b.ok -text "Ok" -width 8 -command {
476	if { $MIMEGlobalTypes != "" && \
477		! [ file readable $MIMEGlobalTypes ] } {
478	    tk_dialog ._Dialog "File Does not Exist" "Global Types File\
479		    $MIMEGlobalTypes does not exist or is not readable." \
480		    error 0 OK
481	} elseif { $MIMELocalTypes != "" && \
482		! [ file readable $MIMELocalTypes ] } {
483	    tk_dialog ._Dialog "File Does not Exist" "Local Types File\
484		    $MIMELocalTypes does not exist or is not readable." \
485		    error 0 OK
486	} elseif { $MIMEGlobalCap != "" && \
487		! [ file readable $MIMEGlobalCap ] } {
488	    tk_dialog ._Dialog "File Does not Exist" "Global Mailcap File\
489		    $MIMEGlobalCap does not exist or is not readable." \
490		    error 0 OK
491	} elseif { $MIMELocalCap != "" && \
492		! [ file readable $MIMELocalCap ] } {
493	    tk_dialog ._Dialog "File Does not Exist" "Local Mailcap File\
494		    $MIMELocalCap does not exist or is not readable." \
495		    error 0 OK
496	} else {
497	    set MSFinish ok
498	}
499    }
500    button .mime.but.b.cancel -text "Cancel" -width 8 \
501	    -command { set MSFinish cancel }
502
503    pack .mime.but.b.ok .mime.but.b.cancel -side left -ipadx 4 -ipady 4 \
504	    -padx 4 -pady 4 -expand true
505    pack .mime.but.b -fill both -expand true -fill both
506
507    pack .mime.top -side top -fill x
508    pack .mime.but -side bottom -fill both -expand true
509
510    bind .mime.top.gt.ent <Return> {
511	if { $MIMEGlobalTypes != "" } {
512	    if { ! [ file readable $MIMEGlobalTypes ] } {
513		tk_dialog ._Dialog "File Does not Exist" "Global Types File\
514			$MIMEGlobalTypes does not exist or is not readable." \
515			error 0 OK
516	    }
517	}
518    }
519    bind .mime.top.lt.ent <Return> {
520	if { $MIMELocalTypes != "" } {
521	    if { ! [ file readable $MIMELocalTypes ] } {
522		tk_dialog ._Dialog "File Does not Exist" "Local Types File\
523			$MIMELocalTypes does not exist or is not readable." \
524			error 0 OK
525	    }
526	}
527    }
528    bind .mime.top.gc.ent <Return> {
529	if { $MIMEGlobalCap != "" } {
530	    if { ! [ file readable $MIMEGlobalCap ] } {
531		tk_dialog ._Dialog "File Does not Exist" "Global Mailcap File\
532			$MIMEGlobalCap does not exist or is not readable." \
533			error 0 OK
534	    }
535	}
536    }
537    bind .mime.top.lc.ent <Return> {
538	if { $MIMELocalCap != "" } {
539	    if { ! [ file readable $MIMELocalCap ] } {
540		tk_dialog ._Dialog "File Does not Exist" "Local Mailcap File\
541			$MIMELocalCap does not exist or is not readable." \
542			error 0 OK
543	    }
544	}
545    }
546
547    . config -cursor watch
548    tkwait visibility .mime
549    ._Status._Text config -text "Waiting for Configuration"
550    grab set .mime
551    focus .mime
552    set MSFinish {}
553
554    tkwait variable MSFinish
555
556    if { $MSFinish != "ok" } {
557	set MIMEGlobalTypes $tempGlobalTypes
558	set MIMELocalCap    $tempLocalCap
559	set MIMEGlobalCap   $tempGlobalCap
560	set MIMELocalTypes  $tempLocalTypes
561    }
562    . config -cursor $oldCursor
563    ._Status._Text config -text $oldText
564    focus $oldFocus
565    destroy .mime
566}
567
568#
569# Menu Command File->Save Setup
570#
571
572proc SaveSetup {} {
573    global OptionFast OptionBracket OptionOverwrite
574    global OptionDesperate OptionVerbose OptionAutoInfo
575    global SaveFilePath EncodeMaxLines EncodeEncoding
576    global EncodeFilePath NNTPServer MIMELocalTypes
577    global MIMEGlobalTypes MIMELocalCap MIMEGlobalCap
578    global OptionDumbness OptionUsetext OptionRemove
579    global OptionMoreMime EncodeFrom EncodeReplyTo
580    global env
581
582    set oldCursor [ lindex [ . config -cursor ] 4 ]
583    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
584
585    . config -cursor watch
586    ._Status._Text config -text "Saving Setup"
587
588    if { [ catch { set env(HOME) } ] || $env(HOME) == "" } {
589	tk_dialog ._Dialog "OOps" "Could not find your home directory." \
590		error 0 OK
591	. config -cursor $oldCursor
592	._Status._Text config -text $oldText
593	return
594    }
595
596    #
597    # need temp file
598    #
599    if { ! [ catch { set $env(TEMP) } ] } {
600	set tempname "$env(TEMP)/xdeview[pid]"
601    } else {
602	set tempname "/tmp/xdeview.[pid]"
603    }
604
605    if { [ file exists $tempname ] } {
606	foreach ext { 001 002 003 004 005 006 007 008 009 010 042 } {
607	    if { ! [ catch { set $env(TEMP) } ] } {
608		set tempname "$env(TEMP)/xdeview.$ext"
609	    } else {
610		set tempname "/tmp/xdeview.$ext"
611	    }
612	    if { [ file exists $tempname ] } {
613		break
614	    }
615	}
616	if { [ file exits $tempname] } {
617	    tk_dialog ._Dialog "OOps" "Could not save your setup. Couldn't\
618		    find suitable temporary file" error 0 OK
619	    . config -cursor $oldCursor
620	    ._Status._Text config -text $oldText
621	    return
622	}
623    }
624    if { [ catch { open $tempname w } writeID ] } {
625	tk_dialog ._Dialog "OOps" "Cannot write to temp file $tempname.\
626		Setup not saved." error 0 OK
627	. config -cursor $oldCursor
628	._Status._Text config -text $oldText
629	return
630    }
631
632    set rcfile $env(HOME)/.xdeviewrc
633
634    if { ! [ catch { open $rcfile r } readID ] } {
635	#
636	# copy existing resouce file
637	#
638	while { ! [ eof $readID ] } {
639	    if { [ gets $readID TheLine ] < 0 } {
640		break
641	    }
642	    puts $writeID $TheLine
643
644	    if { [ string first "--xdeview--" $TheLine ] != -1 } {
645		break
646	    }
647	}
648	if { [ eof $readID ] } {
649	    puts $writeID "#"
650	    puts $writeID "# --xdeview-- auto-generated do not add code below"
651	}
652	close $readID
653    } else {
654	puts $writeID "#"
655	puts $writeID "# --xdeview-- auto-generated do not add code below"
656    }
657    #
658    # save configuration information
659    #
660    puts $writeID "#"
661    puts $writeID "# options for decoding"
662    puts $writeID "#"
663    puts $writeID "ifndef OptionFast       $OptionFast"
664    puts $writeID "ifndef OptionBracket    $OptionBracket"
665    puts $writeID "ifndef OptionOverwrite  $OptionOverwrite"
666    puts $writeID "ifndef OptionDesperate  $OptionDesperate"
667    puts $writeID "ifndef OptionVerbose    $OptionVerbose"
668    puts $writeID "ifndef OptionDumbness   $OptionDumbness"
669    puts $writeID "ifndef OptionAutoInfo   $OptionAutoInfo"
670    puts $writeID "ifndef OptionUsetext    $OptionUsetext"
671    puts $writeID "ifndef SaveFilePath     \"$SaveFilePath\""
672    puts $writeID "ifndef OptionRemove     $OptionRemove"
673    puts $writeID "ifndef OptionMoreMime   $OptionMoreMime"
674    puts $writeID "#"
675    puts $writeID "# encoding options"
676    puts $writeID "#"
677    puts $writeID "ifndef EncodeMaxLines   $EncodeMaxLines"
678    puts $writeID "ifndef EncodeEncoding   $EncodeEncoding"
679    puts $writeID "ifndef EncodeFilePath   \"$EncodeFilePath\""
680    puts $writeID "ifndef EncodeFrom       \"$EncodeFrom\""
681    puts $writeID "ifndef EncodeReplyTo    \"$EncodeReplyTo\""
682    puts $writeID "ifndef NNTPServer       \"$NNTPServer\""
683    puts $writeID "#"
684    puts $writeID "# MIME capabilities"
685    puts $writeID "#"
686    puts $writeID "ifndef MIMELocalTypes   \"$MIMELocalTypes\""
687    puts $writeID "ifndef MIMEGlobalTypes  \"$MIMEGlobalTypes\""
688    puts $writeID "ifndef MIMELocalCap     \"$MIMELocalCap\""
689    puts $writeID "ifndef MIMEGlobalCap    \"$MIMEGlobalCap\""
690    puts $writeID "#"
691    puts $writeID ""
692
693    close $writeID
694
695    #
696    # copy temp file back to real ./xdeviewrc
697    #
698
699    if { [ catch { open $tempname r } readID ] } {
700	tk_dialog ._Dialog "This is weird" "Could not re-open the temp\
701		file $tempname. Setup not saved." error 0 OK
702	. config -cursor $oldCursor
703	._Status._Text config -text $oldText
704	exec -- rm -f $tempname
705	return
706    }
707    if { [ catch { open $rcfile w } writeID ] } {
708	tk_dialog ._Dialog "OOps" "Cannot write to setup file $rcfile.\
709		Setup not saved." error 0 OK
710	. config -cursor $oldCursor
711	._Status._Text config -text $oldText
712	close $readID
713	exec -- rm -f $tempname
714	return
715    }
716    while { ! [ eof $readID ] } {
717	if { [ gets $readID TheLine ] < 0 } {
718	    break
719	}
720	puts $writeID $TheLine
721    }
722    close $writeID
723    close $readID
724
725    exec -- rm -f $tempname
726
727    . config -cursor $oldCursor
728    ._Status._Text config -text $oldText
729
730    tk_dialog ._Dialog "OK" "Setup successfully saved to $rcfile." \
731	    "" 0 OK
732}
733
734#
735# Menu Command File->Encode
736#
737
738proc Encode {} {
739    global EncodeFileName
740    global EncodeMaxLines
741    global EncodeEncoding
742    global EncodeSubject
743    global EncodeFrom
744    global EncodeReplyTo
745
746    global EncodeFileYes
747    global EncodeFilePath
748    global EncodeMailYes
749    global EncodeMailAddr
750    global EncodeNewsYes
751    global EncodeNewsGroup
752    global SaveFilePath
753    global EncodeButton
754    global HaveNNTPServer
755    global NNTPServer
756    global env
757
758    ifndef EncodeMaxLines	0
759    ifndef EncodeEncoding	0
760    ifndef EncodeSubject	""
761    ifndef EncodeFrom           ""
762    ifndef EncodeReplyTo        ""
763    ifndef EncodeFileYes	1
764    ifndef EncodeFilePath	$SaveFilePath
765    ifndef EncodeMailYes	0
766    ifndef EncodeMailAddr	""
767    ifndef EncodeNewsYes	0
768    ifndef EncodeNewsGroup	""
769    ifndef NNTPServer		""
770
771    set oldCursor [ lindex [ . config -cursor ] 4 ]
772    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
773    set oldFocus  [ focus ]
774
775    set have_mail [ lindex [ lindex [ uu_Info have_mail ] 0 ] 1 ]
776    set have_news [ lindex [ lindex [ uu_Info have_news ] 0 ] 1 ]
777    set need_nntp [ lindex [ lindex [ uu_Info need_nntpserver ] 0 ] 1 ]
778
779    if { $have_news && $need_nntp && $NNTPServer == "" } {
780	if { [ catch { set NNTPServer $env(NNTPSERVER) } ] } {
781	    set NNTPServer ""
782	}
783    }
784
785    ._Status._Text config -text "Waiting for you to Select Files for Encoding"
786    set EncodeFileList [ tk_SelectFiles "Select Files for Encoding" 1 0 ]
787
788    if { $EncodeFileList == {} } {
789	._Status._Text config -text $oldText
790	return
791    }
792
793    set EncodeFileCount [ llength $EncodeFileList ]
794
795    #
796    # what to do with these files?
797    #
798
799    toplevel ._Encode
800    wm title ._Encode "Encode Files"
801
802    #
803    # first section: How many files left?
804    #
805
806    frame ._Encode._Toplab -relief raised -bd 2
807    label ._Encode._Toplab.lab -text "0 Files left to Encode"
808    pack ._Encode._Toplab.lab -padx 2 -pady 2 -anchor w
809
810    #
811    # second section: file names of source and sent file
812    #
813
814    frame ._Encode._Names -relief raised -bd 2
815    frame ._Encode._Names.top
816    frame ._Encode._Names.bot
817
818    label ._Encode._Names.top.lab -text "Filename:" -width 12 \
819	    -justify left -anchor w
820    entry ._Encode._Names.top.nam -relief sunken -width 30
821    label ._Encode._Names.bot.lab -text "Send as:" -width 12 \
822	    -justify left -anchor w
823    entry ._Encode._Names.bot.nam -relief sunken -width 30 \
824	    -textvariable EncodeFileName
825
826    pack ._Encode._Names.top.lab -side left -padx 2 -pady 2
827    pack ._Encode._Names.top.nam -side right -padx 2 -pady 2 \
828	    -fill x -expand true
829    pack ._Encode._Names.bot.lab -side left -padx 2 -pady 2
830    pack ._Encode._Names.bot.nam -side right -padx 2 -pady 2 \
831	    -fill x -expand true
832
833    pack ._Encode._Names.top ._Encode._Names.bot \
834	    -padx 4 -pady 4 -side top -fill x -expand true
835
836    frame ._Encode._Header -relief raised -bd 2
837    frame ._Encode._Header.from
838    frame ._Encode._Header.replyto
839    frame ._Encode._Header.subject
840
841    label ._Encode._Header.from.msg -text "From:" -width 12 \
842	    -justify left -anchor w
843    entry ._Encode._Header.from.ent -relief sunken -width 30 \
844	    -textvariable EncodeFrom
845
846    label ._Encode._Header.replyto.msg -text "Reply To:" -width 12 \
847	    -justify left -anchor w
848    entry ._Encode._Header.replyto.ent -relief sunken -width 30 \
849	    -textvariable EncodeReplyTo
850
851    label ._Encode._Header.subject.msg -text "Subject:" -width 12 \
852	    -justify left -anchor w
853    entry ._Encode._Header.subject.ent -relief sunken -width 30 \
854	    -textvariable EncodeSubject
855
856    pack ._Encode._Header.from.msg -side left -padx 2 -pady 2
857    pack ._Encode._Header.from.ent -side right -padx 2 -pady 2 \
858	    -expand true -fill x
859
860    pack ._Encode._Header.replyto.msg -side left -padx 2 -pady 2
861    pack ._Encode._Header.replyto.ent -side right -padx 2 -pady 2 \
862	    -expand true -fill x
863
864    pack ._Encode._Header.subject.msg -side left -padx 2 -pady 2
865    pack ._Encode._Header.subject.ent -side right -padx 2 -pady 2 \
866	    -expand true -fill x
867
868
869    pack ._Encode._Header.from ._Encode._Header.replyto \
870	    ._Encode._Header.subject \
871	    -padx 4 -pady 4 -side top -fill x -expand true
872
873    #
874    # third section: encoding options
875    #
876
877    frame ._Encode._Options -relief raised -bd 2
878    frame ._Encode._Options.left
879    frame ._Encode._Options.right
880    frame ._Encode._Options.righter
881    frame ._Encode._Options.left.top
882    frame ._Encode._Options.left.empty
883    frame ._Encode._Options.left.bot
884
885    label ._Encode._Options.left.top.msg -text "Encoding Options:"
886
887    entry ._Encode._Options.left.bot.lines -relief sunken -width 5 \
888	    -textvariable EncodeMaxLines
889    label ._Encode._Options.left.bot.msg -text "Lines per File" \
890	    -justify left
891
892    radiobutton ._Encode._Options.right.uue -text "UU Encoding" \
893	    -variable EncodeEncoding -value 0 -relief flat -anchor w \
894	    -selectcolor black
895    radiobutton ._Encode._Options.right.xxe -text "XX Encoding" \
896	    -variable EncodeEncoding -value 1 -relief flat -anchor w \
897	    -selectcolor black
898    radiobutton ._Encode._Options.right.b64 -text "Base64 Encoding" \
899	    -variable EncodeEncoding -value 2 -relief flat -anchor w \
900	    -selectcolor black
901    radiobutton ._Encode._Options.righter.pt -text "Plain Text" \
902	    -variable EncodeEncoding -value 3 -relief flat -anchor w \
903	    -selectcolor black
904    radiobutton ._Encode._Options.righter.qp -text "Quoted Printable" \
905	    -variable EncodeEncoding -value 4 -relief flat -anchor w \
906	    -selectcolor black
907    radiobutton ._Encode._Options.righter.ye -text "yEnc Encoding" \
908	    -variable EncodeEncoding -value 5 -relief flat -anchor w \
909	    -selectcolor black
910
911    pack ._Encode._Options.left.bot.lines ._Encode._Options.left.bot.msg \
912	    -padx 4 -pady 4 -side left
913    pack ._Encode._Options.left.top.msg -padx 2 -pady 2 -anchor nw
914    pack ._Encode._Options.left.top -fill x -side top
915    pack ._Encode._Options.left.bot -anchor sw -side bottom -padx 4 -pady 4
916    pack ._Encode._Options.left.empty -fill both -expand true
917
918    pack ._Encode._Options.right.uue ._Encode._Options.right.xxe \
919	    ._Encode._Options.right.b64 \
920	    -padx 4 -pady 2 -fill x
921
922    pack ._Encode._Options.righter.pt ._Encode._Options.righter.qp \
923	    -padx 4 -pady 2 -fill x
924
925    pack ._Encode._Options.righter.ye \
926	    -padx 4 -pady 2 -fill x
927
928    pack ._Encode._Options.left ._Encode._Options.right \
929	    ._Encode._Options.righter \
930	    -side left -fill both -expand true
931
932    #
933    # fourth section: what to do with encoded data
934    #
935
936    frame ._Encode._Actions -relief raised -bd 2
937    frame ._Encode._Actions.title
938    frame ._Encode._Actions.file
939    frame ._Encode._Actions.mail
940    frame ._Encode._Actions.news
941
942    label ._Encode._Actions.title.lab -text "Encoding Actions:"
943    pack ._Encode._Actions.title.lab -padx 2 -pady 2 -anchor w
944
945    checkbutton ._Encode._Actions.file.but -variable EncodeFileYes \
946	    -text "File In (Path):" -width 12 -justify left -anchor w \
947	    -selectcolor black
948    entry ._Encode._Actions.file.ent -relief sunken -width 30 \
949	    -textvariable EncodeFilePath
950    button ._Encode._Actions.file.bb -text "Browse" -command {
951	set NewPath [ tk_SelectFiles "Encoding Path" 0 2 ]
952	if { $NewPath != "" } {
953	    if { [ CheckWritable $NewPath ] } {
954		set EncodeFilePath [ CompressSlashes $NewPath ]
955	    }
956	}
957    }
958
959    checkbutton ._Encode._Actions.mail.but -variable EncodeMailYes \
960	    -text "Email To ..." -width 12 -justify left -anchor w \
961	    -selectcolor black
962    entry ._Encode._Actions.mail.ent -relief sunken -width 30 \
963	    -textvariable EncodeMailAddr
964
965    checkbutton ._Encode._Actions.news.but -variable EncodeNewsYes \
966	    -text "Post To ..." -width 12 -justify left -anchor w \
967	    -selectcolor black
968    entry ._Encode._Actions.news.ent -relief sunken -width 30 \
969	    -textvariable EncodeNewsGroup
970
971    #
972    # if we need an NNTP server, add a button
973    #
974
975    if { $have_news && $need_nntp } {
976	frame ._Encode._Actions.nntp
977	checkbutton ._Encode._Actions.nntp.but -variable HaveNNTPServer \
978		-text "NNTP Server" -width 12 -justify left -anchor w \
979		-selectcolor black
980	entry ._Encode._Actions.nntp.ent -relief sunken -width 30 \
981		-textvariable NNTPServer
982	._Encode._Actions.nntp.but select
983    }
984
985    pack ._Encode._Actions.file.but -side left -padx 4 -pady 4
986    pack ._Encode._Actions.file.bb  -side right -padx 4
987    pack ._Encode._Actions.file.ent -side right -padx 4 -pady 4 \
988	    -expand true -fill x
989
990    pack ._Encode._Actions.mail.but -side left -padx 4 -pady 4
991    pack ._Encode._Actions.mail.ent -side right -padx 4 -pady 4 \
992	    -expand true -fill x
993
994    pack ._Encode._Actions.news.but -side left -padx 4 -pady 4
995    pack ._Encode._Actions.news.ent -side right -padx 4 -pady 4 \
996	    -expand true -fill x
997
998    pack ._Encode._Actions.title -side top -fill x -expand true
999    pack ._Encode._Actions.file  -side top -fill x -expand true
1000    pack ._Encode._Actions.mail  -side top -fill x -expand true
1001    pack ._Encode._Actions.news  -side top -fill x -expand true
1002
1003    if { $have_news && $need_nntp } {
1004	pack ._Encode._Actions.nntp.but -side left -padx 4 -pady 4
1005	pack ._Encode._Actions.nntp.ent -side right -padx 4 -pady 4 \
1006		-expand true -fill x
1007	pack ._Encode._Actions.nntp -side top -fill x -expand true
1008    }
1009
1010    #
1011    # fifth section: the buttons
1012    #
1013
1014    frame ._Encode._Buttons -relief raised -bd 2
1015    frame ._Encode._Buttons.b
1016
1017    button ._Encode._Buttons.b._Ok -text "Ok" -width 8 \
1018	    -command { set EncodeButton ok }
1019    button ._Encode._Buttons.b._OkAll -text "Ok to All" -width 8 \
1020	    -command { set EncodeButton okall }
1021    button ._Encode._Buttons.b._Next -text "Next" -width 8 \
1022	    -command { set EncodeButton next }
1023    button ._Encode._Buttons.b._Cancel -text "Cancel" -width 8 \
1024	    -command { set EncodeButton cancel }
1025
1026    pack ._Encode._Buttons.b._Ok ._Encode._Buttons.b._OkAll \
1027	    ._Encode._Buttons.b._Next ._Encode._Buttons.b._Cancel \
1028	    -side left -ipadx 4 -ipady 4 -padx 4 -pady 4 -expand true
1029    pack ._Encode._Buttons.b -fill both -expand true
1030
1031
1032    pack ._Encode._Toplab ._Encode._Names ._Encode._Header \
1033	    ._Encode._Options ._Encode._Actions \
1034	    -fill x -side top
1035    pack ._Encode._Buttons -fill both -side bottom -expand true
1036
1037    #
1038    # wow, dialog box is finally drawn. now make it do something
1039    #
1040
1041    if { $have_mail == 0 } {
1042	._Encode._Actions.mail.but deselect
1043	._Encode._Actions.mail.ent delete 0 end
1044	._Encode._Actions.mail.ent insert 0 "(Email not Available)"
1045	._Encode._Actions.mail.but configure -state disabled
1046	._Encode._Actions.mail.ent configure -state disabled
1047    }
1048    if { $have_news == 0 } {
1049	._Encode._Actions.news.but deselect
1050	._Encode._Actions.news.ent delete 0 end
1051	._Encode._Actions.news.ent insert 0 "(Posting not Available)"
1052	._Encode._Actions.news.but configure -state disabled
1053	._Encode._Actions.news.ent configure -state disabled
1054    }
1055
1056    bind ._Encode._Actions.file.ent <Return> {
1057	if { $EncodeFilePath == {} } {
1058	    set EncodeFilePath [ pwd ]
1059	}
1060	set EncodeFilePath [ CompressSlashes $EncodeFilePath ]
1061	CheckWritable $EncodeFilePath
1062    }
1063    bind ._Encode._Options.left.bot.lines <Return> {
1064	if { $EncodeMaxLines < 200 && $EncodeMaxLines != 0 } {
1065	    tk_dialog ._Dialog { Illegal Number of Lines } "You have\
1066		    entered an invalid value for the number of lines\
1067		    per encoded file. It must either be 0 (no limit)\
1068		    or greater than 200." error 0 OK
1069	    set EncodeMaxLines 0
1070	}
1071    }
1072
1073    #
1074    # iterate through files
1075    #
1076
1077    . config -cursor watch
1078    tkwait visibility ._Encode
1079    grab set ._Encode
1080    focus ._Encode
1081
1082    set index 0
1083    set EncodeButton {}
1084
1085    while { $index < $EncodeFileCount } {
1086	set EFPath [ lindex $EncodeFileList $index ]
1087	set EFName [ file tail $EFPath ]
1088
1089	._Encode config -cursor {}
1090
1091	if { ! [ file readable $EFPath ] || [ file isdirectory $EFPath ] } {
1092	    tk_dialog ._Dialog { Cannot read File } "Cannot read $EFPath" \
1093		    error 0 OK
1094	    incr index
1095	    continue
1096	}
1097
1098	._Encode._Names.top.nam configure -state normal
1099	._Encode._Names.top.nam delete 0 end
1100	._Encode._Names.top.nam insert 0 $EFPath
1101	._Encode._Names.top.nam configure -state disabled
1102
1103	._Encode._Names.bot.nam delete 0 end
1104	._Encode._Names.bot.nam insert 0 $EFName
1105
1106	._Encode._Toplab.lab config -text \
1107		"[ expr $EncodeFileCount - $index ] Files left to Encode"
1108
1109	._Status._Text config -text "Waiting for action on $EFName"
1110
1111	if { $EncodeButton != "okall" } {
1112	    while { 42 } {
1113		set EncodeButton {}
1114		tkwait variable EncodeButton
1115		if { $EncodeButton == "cancel" } {
1116		    break
1117		}
1118		#
1119		# check parameter
1120		#
1121		if { $EncodeFilePath == {} } {
1122		    set EncodeFilePath [ pwd ]
1123		}
1124		set EncodeFilePath [ CompressSlashes $EncodeFilePath ]
1125		if { $EncodeFileYes && ! [ CheckWritable $EncodeFilePath ] } {
1126		    continue
1127		}
1128		if { $EncodeMaxLines < 200 && $EncodeMaxLines != 0 } {
1129		    tk_dialog ._Dialog { Illegal Number of Lines } "You have\
1130			    entered an invalid value for the number of lines\
1131			    per encoded file. It must either be 0 (no limit)\
1132			    or greater than 200." error 0 OK
1133		    set EncodeMaxLines 0
1134		    continue
1135		}
1136		if { $have_news && $need_nntp && $EncodeNewsYes } {
1137		    if { $HaveNNTPServer == 0 || $NNTPServer == {} } {
1138			tk_dialog ._Dialog { No NNTP Server } "You must\
1139				provide the address of an NNTP server in\
1140				order to post a file. You can also set\
1141				your environment variable\
1142				\$NNTPSERVER or define the address at\
1143				compile time." error 0 OK
1144			continue
1145		    }
1146		}
1147		break
1148	    }
1149	}
1150	#
1151	# check which button was pressed
1152	#
1153	if { $EncodeButton == "cancel" } {
1154	    break
1155	} elseif { $EncodeButton == "next" } {
1156	    incr index
1157	    continue
1158	}
1159	#
1160	# at this point, we want to process the file (either ok or okall)
1161	#
1162
1163	if { $have_news && $need_nntp && $EncodeNewsYes } {
1164	    set env(NNTPSERVER) $NNTPServer
1165	}
1166
1167	._Encode config -cursor watch
1168
1169	if { $EncodeFileYes } {
1170	    ._Status._Text config -text "Encoding $EFName to File ..."
1171	    update
1172	    if { [ catch { uu_EncodeToFile $EFPath \
1173		    [ file join $EncodeFilePath $EncodeFileName] \
1174		    $EncodeFileName $EncodeSubject "" $EncodeMaxLines \
1175		    $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } {
1176		tk_dialog ._Dialog { Error while Encoding } "The following\
1177			error occured while encoding into a file: $message" \
1178			error 0 OK
1179	    }
1180	}
1181	if { $EncodeMailYes } {
1182	    ._Status._Text config -text "Encoding and Emailing $EFName ..."
1183	    update
1184	    if { [ catch { uu_EncodeToMail $EFPath $EncodeMailAddr \
1185		    $EncodeFileName $EncodeSubject "" $EncodeMaxLines \
1186		    $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } {
1187		tk_dialog ._Dialog { Error while Encoding } "The following\
1188			error occured while sending the file via mail:\
1189			$message" \
1190			error 0 OK
1191	    }
1192	}
1193	if { $EncodeNewsYes } {
1194	    ._Status._Text config -text "Encoding and Emailing $EFName ..."
1195	    update
1196	    if { [ catch { uu_EncodeToNews $EFPath $EncodeNewsGroup \
1197		    $EncodeFileName $EncodeSubject "" $EncodeMaxLines \
1198		    $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } {
1199		tk_dialog ._Dialog { Error while Encoding } "The following\
1200			error occured while sending the file via news:\
1201			$message" \
1202			error 0 OK
1203	    }
1204	}
1205	#
1206	# end of processing
1207	#
1208	incr index
1209    }
1210    . config -cursor $oldCursor
1211    ._Status._Text config -text $oldText
1212    focus $oldFocus
1213    destroy ._Encode
1214}
1215
1216#
1217# Helper function to decode a bunch of files
1218#
1219
1220proc DecodeProc { DecodeList } {
1221    global OptionOverwrite
1222    global OptionDesperate
1223    global SaveFilePath
1224    global FileList
1225
1226    set count      [ llength $DecodeList ]
1227    set oldCursor  [ lindex [ . config -cursor ] 4 ]
1228    set oldText    [ lindex [ ._Status._Text config -text ] 4 ]
1229
1230    if { $DecodeList == {} } {
1231	return;
1232    }
1233
1234    if { ! [ CheckWritable $SaveFilePath ] } {
1235	return;
1236    }
1237
1238    . config -cursor watch
1239
1240    for { set index 0 } { $index < $count } { incr index } {
1241	set ItemNo     [ lindex $DecodeList $index ]
1242	set FileName   [ lindex [ lindex $FileList $ItemNo ] 2 ]
1243	set FileNumber [ lindex [ lindex $FileList $ItemNo ] 0 ]
1244	set FilePath   [ file join $SaveFilePath $FileName ]
1245
1246	._Status._Text configure -text "Decoding $FileName ..."
1247
1248	if { [ file exists $FilePath ] && ! [ file writable $FilePath ] } {
1249	    tk_dialog ._Dialog { File Error } "The File $FilePath exists\
1250		    and can not be written" error 0 OK
1251	    continue
1252	} elseif { [ file exists $FilePath ] && ! $OptionOverwrite } {
1253	    set answer [ tk_dialog ._Dialog "File Exists" "$FileName\
1254		    already exists in $SaveFilePath." question 0 \
1255		    "Overwrite" "Next File" "Cancel" ]
1256	    if { $answer == "1" } {
1257		continue
1258	    } elseif { $answer == "2" } {
1259		break
1260	    }
1261	}
1262	#
1263	# At this point, the target file either does not exist or
1264	# we want to overwrite it
1265	#
1266
1267	update
1268
1269	set result [ catch { uu_DecodeFile $FileNumber $FilePath } errorMsg ]
1270
1271	if { $result } {
1272	    tk_dialog ._Dialog "Error while Decoding" "The following\
1273		    problem occured while decoding: $errorMsg" \
1274		    error 0 OK
1275	    continue
1276	}
1277    }
1278
1279    ._Status._Text config -text $oldText
1280    . config -cursor $oldCursor
1281}
1282
1283#
1284# Button 'Decode'
1285#
1286
1287proc Decode {} {
1288    DecodeProc [ ._MainFrame._FileList._Liste curselection ]
1289}
1290
1291#
1292# Button 'Decode All'
1293#
1294
1295proc DecodeAll {} {
1296    set count [ ._MainFrame._FileList._Liste size ]
1297
1298    set DecodeList {}
1299
1300    for { set index 0 } { $index < $count } { incr index } {
1301	lappend DecodeList $index
1302    }
1303
1304    DecodeProc $DecodeList
1305}
1306
1307#
1308# Action 'Info'
1309#
1310# Info about a file. This displays either the zeroeth part of a file or
1311# the first part up to the first encoded line
1312#
1313
1314proc Info {} {
1315    set TheInfoFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ]
1316
1317    if { $TheInfoFile == {} } {
1318	return
1319    }
1320    InfoFile $TheInfoFile
1321}
1322
1323proc InfoFile { TheInfoFile } {
1324    global FileList
1325
1326    set oldCursor  [ lindex [ . config -cursor ] 4 ]
1327    set oldText    [ lindex [ ._Status._Text config -text ] 4 ]
1328    set FileName   [ lindex [ lindex $FileList $TheInfoFile ] 2 ]
1329    set FileNumber [ lindex [ lindex $FileList $TheInfoFile ] 0 ]
1330
1331    if { $FileName == "" } {
1332	return
1333    }
1334
1335    . config -cursor watch
1336    ._Status._Text config -text "Getting File Info for $FileName"
1337
1338    if { [ catch { .info configure } ] } {
1339	toplevel .info
1340	frame .info.top
1341	frame .info.bot
1342	text .info.top.text -relief raised -bd 2 -wrap none \
1343		-xscrollcommand ".info.top.sbx set" \
1344		-yscrollcommand ".info.top.sby set"
1345	scrollbar .info.top.sbx -command ".info.top.text xview" \
1346		-orient horizontal
1347	scrollbar .info.top.sby -command ".info.top.text yview"
1348
1349	pack .info.top.sbx -side bottom -fill x
1350	pack .info.top.sby -side right -fill y
1351	pack .info.top.text -fill both -expand 1
1352
1353	button .info.bot.done -text "Done" -command "destroy .info"
1354	pack .info.bot.done -side right -padx 4 -pady 4
1355
1356	pack .info.top -side top -fill both -expand 1
1357	pack .info.bot -side bottom
1358    }
1359
1360    wm title .info "Info about [ file tail $FileName ]"
1361
1362    .info.top.text configure -state normal
1363
1364    if { [ catch { uu_InfoFile $FileNumber .info.top.text } errorMsg ] } {
1365	tk_dialog ._Dialog "No Info" "The following problem occured\
1366		while trying to get Info: $errorMsg" error 0 OK
1367    }
1368
1369    .info.top.text configure -state disabled
1370
1371    ._Status._Text config -text $oldText
1372    . config -cursor $oldCursor
1373}
1374
1375#
1376# Action 'List'
1377#
1378
1379proc List {} {
1380    global FileList
1381
1382    set ListFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ]
1383
1384    if { $ListFile == {} } {
1385	return;
1386    }
1387
1388    set oldCursor [ lindex [ . config -cursor ] 4 ]
1389    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
1390    set FileName  [ lindex [ lindex $FileList $ListFile ] 2 ]
1391
1392    . config -cursor watch
1393    ._Status._Text config -text "Listing $FileName"
1394
1395    if { [ catch { .list configure } ] } {
1396	toplevel .list
1397	frame .list.top
1398	frame .list.bot
1399	text .list.top.text -relief raised -bd 2 -wrap none \
1400		-xscrollcommand ".list.top.sbx set" \
1401		-yscrollcommand ".list.top.sby set"
1402	scrollbar .list.top.sbx -command ".list.top.text xview" \
1403		-orient horizontal
1404	scrollbar .list.top.sby -command ".list.top.text yview"
1405
1406	pack .list.top.sbx -side bottom -fill x
1407	pack .list.top.sby -side right -fill y
1408	pack .list.top.text -fill both -expand 1
1409
1410	button .list.bot.done -text "Done" -command "destroy .list"
1411	pack .list.bot.done -side right -padx 4 -pady 4
1412
1413	pack .list.top -side top -fill both -expand 1
1414	pack .list.bot -side bottom
1415    }
1416
1417    wm title .list "Listing of [ file tail $FileName ]"
1418
1419    .list.top.text configure -state normal
1420
1421    if { [ catch { uu_ListFile $ListFile .list.top.text } errorMsg ] } {
1422	tk_dialog ._Dialog "Oops" "The following problem occured\
1423		while trying to list the file: $errorMsg" error 0 OK
1424    }
1425
1426    .list.top.text configure -state disabled
1427
1428    ._Status._Text config -text $oldText
1429    . config -cursor $oldCursor
1430}
1431
1432#
1433# Action 'Rename'
1434#
1435
1436proc Rename {} {
1437    global FileList
1438    global NewName
1439    global OldName
1440    global RenBut
1441
1442    set RenameList [ ._MainFrame._FileList._Liste curselection ]
1443    set count      [ llength $RenameList ]
1444    set oldCursor  [ lindex [ . config -cursor ] 4 ]
1445    set oldText    [ lindex [ ._Status._Text config -text ] 4 ]
1446    set oldFocus   [ focus ]
1447
1448    if { $RenameList == {} } {
1449	return;
1450    }
1451
1452    toplevel .rename
1453    frame .rename.cur -relief raised -bd 1
1454    frame .rename.new -relief raised -bd 1
1455    frame .rename.but -relief raised -bd 2
1456    frame .rename.but.but
1457
1458    label .rename.cur.lab -text "Old Name: "
1459    entry .rename.cur.nam -width 40 -relief sunken -bd 2 \
1460	    -textvariable OldName
1461    label .rename.new.lab -text "New Name: "
1462    entry .rename.new.nam -width 40 -relief sunken -bd 2 \
1463	    -textvariable NewName
1464
1465    pack .rename.cur.nam -side right -padx 8 -pady 8
1466    pack .rename.new.nam -side right -padx 8 -pady 8
1467    pack .rename.cur.lab -side left -padx 8 -pady 8 -fill x
1468    pack .rename.new.lab -side left -padx 8 -pady 8 -fill x
1469
1470    button .rename.but.but.ok  -text "Ok"     -command "set RenBut 1"
1471    button .rename.but.but.can -text "Cancel" -command "set RenBut 0"
1472
1473    pack .rename.but.but.ok  -side left -padx 4 -pady 4 -fill x
1474    pack .rename.but.but.can -side left -padx 4 -pady 4 -fill x
1475    pack .rename.but.but
1476
1477    pack .rename.cur -side top -fill x
1478    pack .rename.new -side top -fill x
1479    pack .rename.but -side bottom -fill x
1480
1481    bind .rename.new.nam <Return> "set RenBut 1"
1482
1483    wm title .rename "Rename"
1484    . config -cursor watch
1485    set oldFocus [ focus ]
1486    tkwait visibility .rename
1487    grab set .rename
1488    focus .rename
1489
1490    for { set index 0 } { $index < $count } { incr index } {
1491	set ItemNo     [ lindex $RenameList $index ]
1492	set FileName   [ lindex [ lindex $FileList $ItemNo ] 2 ]
1493	set FileNumber [ lindex [ lindex $FileList $ItemNo ] 0 ]
1494
1495	._Status._Text config -text "Renaming $FileName"
1496
1497	.rename.cur.nam configure -state normal
1498	set OldName $FileName
1499	set NewName $FileName
1500	.rename.cur.nam configure -state disabled
1501	set RenBut {}
1502	update
1503	tkwait variable RenBut
1504
1505	if { $RenBut == 0 } {
1506	    break
1507	} elseif { $RenBut == 1 && $NewName != {} } {
1508	    if { [ catch { uu_Rename $ItemNo [file tail $NewName] } eMsg ] } {
1509		tk_dialog ._Dialog "Oops" "Couldn't rename the file for\
1510			the following reason: $eMsg" error 0 OK
1511	    }
1512	}
1513    }
1514    ._Status._Text config -text $oldText
1515    . config -cursor $oldCursor
1516    destroy .rename
1517    focus $oldFocus
1518
1519    ShowFileList
1520}
1521
1522#
1523# Action 'Execute'
1524#
1525
1526proc Execute {} {
1527    global FileList
1528    global FileTypes
1529    global ExeCom
1530    global ExeBut
1531
1532    ifndef ExeCom {}
1533
1534    set ListFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ]
1535    set app {}
1536
1537    if { $ListFile == {} } {
1538	return;
1539    }
1540
1541    set oldCursor [ lindex [ . config -cursor ] 4 ]
1542    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
1543    set FileName  [ lindex [ lindex $FileList $ListFile ] 2 ]
1544    set FileNumb  [ lindex [ lindex $FileList $ListFile ] 0 ]
1545    set mimtype   [ lindex [ lindex $FileList $ListFile ] 3 ]
1546    set oldFocus  [ focus ]
1547
1548    . config -cursor watch
1549    ._Status._Text config -text "Decoding $FileName to temp file"
1550    update
1551
1552    if { [ catch { uu_GetTempFile $FileNumb } tempFile ] } {
1553	tk_dialog ._Dialog "Error while decoding" "The following problem\
1554		occured while decoding: $tempFile" \
1555		error 0 OK
1556    } else {
1557	#
1558	# Do we have a Content-Type:
1559	#
1560
1561	if { $mimtype != "" } {
1562	    set app [ GetTypeAction $mimtype ]
1563	}
1564
1565	#
1566	# try to determine app from file extension
1567	#
1568
1569	if { $app == "" } {
1570	    set lfn [ split [ string tolower $FileName ] . ]
1571	    set ext [ lindex $lfn [ expr [ llength $lfn ] - 1 ] ]
1572
1573	    if { [ set mimtype [ GetTypeByExtension $ext ] ] != "" } {
1574		set app [ GetTypeAction $mimtype ]
1575	    }
1576	}
1577
1578	#
1579	# if we have no app yet, ask the user
1580	#
1581
1582	if { $app == "" } {
1583	    toplevel .app
1584	    label .app.msg -wraplength 3i -relief raised -bd 1 -text "Enter \
1585		    a command line to execute. Use %s for the file name.\
1586		    Do not attempt to background the command."
1587
1588	    pack .app.msg -side top -ipadx 8 -ipady 8 -fill x
1589
1590	    frame .app.com
1591	    label .app.com.lab -text "Command: "
1592	    entry .app.com.ent -relief sunken -bd 2 \
1593		    -textvariable ExeCom
1594	    pack .app.com.lab -side left -padx 8 -pady 8
1595	    pack .app.com.ent -side right -padx 8 -pady 8 -fill x -expand 1
1596	    pack .app.com -side top -fill x
1597
1598	    frame .app.but -relief raised -bd 2
1599	    frame .app.but.but
1600	    button .app.but.but.ok -text "Execute" -command "set ExeBut 1"
1601	    button .app.but.but.can -text "Cancel" -command "set ExeBut 0"
1602	    pack .app.but.but.ok -side left -padx 4 -pady 4 -fill x
1603	    pack .app.but.but.can -side left -padx 4 -pady 4 -fill x
1604	    pack .app.but.but
1605	    pack .app.but -side bottom -fill x
1606
1607	    bind .app.com.ent <Return> "set ExeBut 1"
1608
1609	    wm title .app "Execute Command"
1610	    tkwait visibility .app
1611	    grab set .app
1612	    focus .app
1613
1614	    ._Status._Text config -text "Watiting for you to enter command"
1615	    set ExeBut {}
1616	    update
1617	    tkwait variable ExeBut
1618	    destroy .app
1619	    focus $oldFocus
1620
1621	    if { $ExeBut == 1 } {
1622		set app $ExeCom
1623	    }
1624	}
1625
1626	if { $app != "" } {
1627	    set RunString [ format $app $tempFile ]
1628
1629	    ._Status._Text config -text "Watiting for child to terminate"
1630
1631	    update
1632
1633	    if { [ catch { eval exec $RunString } errorMsg ] } {
1634		tk_dialog ._Dialog "Execution failed" "The following problem\
1635			occured while executing your command: $errorMsg" \
1636			error 0 OK
1637	    }
1638	}
1639    }
1640    ._Status._Text config -text $oldText
1641    . config -cursor $oldCursor
1642    focus $oldFocus
1643}
1644
1645#
1646# Menu Help->About
1647#
1648
1649proc About {} {
1650    global AboutFinish
1651    global FrankPic
1652
1653    set w ._About
1654    set AboutFinish {}
1655
1656    toplevel $w
1657    wm title $w "About UUDeview"
1658
1659    #
1660    # don't load the image if less than 256 colors or colormap full
1661    #
1662
1663    if { [ catch { winfo colormapfull $w } cmf ] } {
1664	set cmf 0
1665    }
1666
1667    if { [ winfo depth $w ] >= 8 && ! $cmf } {
1668	if { ! [ catch { image create photo Frank -data $FrankPic } ] } {
1669	    frame $w._Image -relief raised -bd 2
1670	    label $w._Image._Frank -image Frank
1671	    label $w._Image._Name -text "This Is Me"
1672	    pack $w._Image._Frank $w._Image._Name -side top
1673	    pack $w._Image -side left -padx 3 -pady 3
1674	}
1675    }
1676    frame $w._Right
1677    label $w._Right._Text1 -text "UUDeview Version\
1678	[ lindex [ lindex [ uu_Info version ] 0 ] 1 ]" \
1679	    -font -Adobe-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*
1680    label $w._Right._Text2 -text "Written by Frank Pilhofer"
1681    label $w._Right._Text3 -text "fp@fpx.de\
1682	    \nhttp://www.fpx.de/"
1683    label $w._Right._Text4 -text "This software is Freeware and may be\
1684	    distributed freely. But if you happen to like it, why not\
1685	    surprise the Author with a postcard, sent to" \
1686	    -font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-* \
1687	    -wraplength 3i
1688    label $w._Right._Addr -text "Frank Pilhofer\nIn Der Wink 3\
1689	    \n60437 Frankfurt\nGermany" -justify left
1690    button $w._Right._Button -text "Ok" -command { set AboutFinish ok }
1691
1692    pack $w._Right._Button -fill both -padx 10 -pady 3 -side bottom
1693    pack $w._Right._Text1 $w._Right._Text2 $w._Right._Text3 \
1694	    $w._Right._Text4 $w._Right._Addr \
1695	    -fill both -padx 10 -pady 5 -side top
1696    pack $w._Right -fill both
1697
1698    set oldFocus [ focus ]
1699    tkwait visibility $w
1700    grab set $w
1701    focus $w
1702    tkwait variable AboutFinish
1703    destroy $w
1704    focus $oldFocus
1705}
1706
1707#
1708# Menu Help->License
1709#
1710
1711proc License {} {
1712    global COPYING
1713
1714    set oldCursor [ lindex [ . config -cursor ] 4 ]
1715    set oldText   [ lindex [ ._Status._Text config -text ] 4 ]
1716
1717    . config -cursor watch
1718    ._Status._Text config -text "Loading and Displaying License"
1719
1720    if { [ catch { set COPYING } ] } {
1721	tk_dialog ._Dialog "Not Available" "I could not load the License\
1722		file. You received a copy of the GPL (GNU General Public\
1723		License) in the file COPYING along with the UUDeview\
1724		distribution. Please refer to this file instead." \
1725		error 0 OK
1726    } elseif { [ catch { .license configure } ] } {
1727	toplevel .license
1728	frame .license.top
1729	frame .license.bot
1730	text .license.top.text -relief raised -bd 2 -wrap none \
1731		-xscrollcommand ".license.top.sbx set" \
1732		-yscrollcommand ".license.top.sby set" \
1733		-font -*-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*
1734	scrollbar .license.top.sbx -command ".license.top.text xview" \
1735		-orient horizontal
1736	scrollbar .license.top.sby -command ".license.top.text yview"
1737
1738	pack .license.top.sbx -side bottom -fill x
1739	pack .license.top.sby -side right -fill y
1740	pack .license.top.text -fill both -expand 1
1741
1742	button .license.bot.done -text "Done" -command "destroy .license"
1743	pack .license.bot.done -side right -padx 4 -pady 4
1744
1745	pack .license.top -side top -fill both -expand 1
1746	pack .license.bot -side bottom
1747
1748	wm title .license "GPL - Gnu General Public License"
1749
1750	regsub -all "#" $COPYING "" TempText
1751
1752	.license.top.text insert 1.0 $TempText
1753	.license.top.text configure -state disabled
1754    }
1755
1756    ._Status._Text config -text $oldText
1757    . config -cursor $oldCursor
1758}
1759
1760##############################################################################
1761## Display helper functions
1762##############################################################################
1763
1764#
1765# these two procedures are needed to keep 2 listboxes in sync
1766#
1767
1768proc ScrollCommand { args } {
1769    eval ._MainFrame._FileList._Status yview $args
1770    eval ._MainFrame._FileList._Liste  yview $args
1771}
1772
1773proc UpdateListScroll { idlb1 idlb2 idsb first last } {
1774    set InMotion 1
1775    if { [ $idlb1 size ] } {
1776	set lbnf [ expr $first + 0.5 / [ $idlb1 size ] ]
1777    } else {
1778	set lbnf $first
1779    }
1780    $idsb set $first $last
1781
1782    $idlb1 yview moveto $lbnf
1783    $idlb2 yview moveto $lbnf
1784}
1785
1786proc UpdateSBScroll { idlb1 idlb2 idsb command number { units "" } } {
1787    set InMotion 1
1788    if { [ $idlb1 size ] } {
1789	set lbnf [ expr $number + 0.5 / [ $idlb1 size ] ]
1790    } else {
1791	set lbnf $number
1792    }
1793    if { $command == "scroll" } {
1794	$idlb1 yview $command $number $units
1795	$idlb2 yview $command $number $units
1796	update
1797    } elseif { $command == "moveto" } {
1798	$idlb1 yview $command $lbnf
1799	$idlb2 yview $command $lbnf
1800	update
1801    } else {
1802	puts "Unknown Scrolling Command: $view $command $number $units"
1803    }
1804}
1805
1806##############################################################################
1807## Build our Main Frame
1808##############################################################################
1809
1810#
1811# Menu Bar
1812#
1813
1814frame ._MainMenu -relief raised -bd 2
1815
1816menubutton ._MainMenu._File    -text File    -underline 0 \
1817	-menu ._MainMenu._File._Menu
1818menubutton ._MainMenu._Options -text Options -underline 0 \
1819	-menu ._MainMenu._Options._Menu
1820menubutton ._MainMenu._Actions -text Actions -underline 0 \
1821	-menu ._MainMenu._Actions._Menu
1822menubutton ._MainMenu._Help    -text Help    -underline 0 \
1823	-menu ._MainMenu._Help._Menu
1824
1825menu ._MainMenu._File._Menu
1826menu ._MainMenu._Options._Menu
1827menu ._MainMenu._Actions._Menu
1828menu ._MainMenu._Help._Menu
1829
1830._MainMenu._File._Menu add command -label "Load ..." -underline 0 \
1831	-command "Load"
1832._MainMenu._File._Menu add command -label "Encode ..." -underline 0 \
1833	-command "Encode"
1834._MainMenu._File._Menu add separator
1835._MainMenu._File._Menu add command -label "Helpers" -underline 0 \
1836	-command "MimeSetup"
1837._MainMenu._File._Menu add command -label "Save Setup" -underline 0 \
1838	-command "SaveSetup"
1839._MainMenu._File._Menu add separator
1840._MainMenu._File._Menu add command -label "Quit" -underline 0 \
1841	-command "Quit"
1842
1843._MainMenu._Options._Menu add checkbutton -label "Fast Scanning" \
1844	-underline 0 -selectcolor black -variable OptionFast
1845._MainMenu._Options._Menu add checkbutton -label "Automatic Overwrite" \
1846	-underline 10 -selectcolor black -variable OptionOverwrite
1847._MainMenu._Options._Menu add checkbutton -label "Desperate Mode" \
1848	-underline 10 -selectcolor black -variable OptionDesperate
1849._MainMenu._Options._Menu add checkbutton -label "Verbose Mode" \
1850	-underline 0 -selectcolor black -variable OptionVerbose
1851._MainMenu._Options._Menu add checkbutton -label "Alternate Bracket Policy" \
1852	-underline 0 -selectcolor black -variable OptionBracket
1853._MainMenu._Options._Menu add checkbutton -label "Dumb Mode" \
1854	-underline 0 -selectcolor black -variable OptionDumbness
1855._MainMenu._Options._Menu add checkbutton -label "Handle Text Files" \
1856	-underline 0 -selectcolor black -variable OptionUsetext
1857._MainMenu._Options._Menu add checkbutton -label "Auto Info" \
1858	-underline 5 -selectcolor black -variable OptionAutoInfo
1859._MainMenu._Options._Menu add checkbutton -label "Remove Input Files" \
1860	-underline 0 -selectcolor black -variable OptionRemove
1861._MainMenu._Options._Menu add checkbutton -label "MIME Compliance" \
1862	-underline 0 -selectcolor black -variable OptionMoreMime
1863
1864._MainMenu._Actions._Menu add command -label "Decode" -underline 0 \
1865	-command "Decode"
1866._MainMenu._Actions._Menu add command -label "Rename" -underline 0 \
1867	-command "Rename"
1868._MainMenu._Actions._Menu add command -label "Decode All" -underline 7 \
1869	-command "DecodeAll"
1870._MainMenu._Actions._Menu add command -label "Info" -underline 0 \
1871	-command "Info"
1872._MainMenu._Actions._Menu add command -label "Execute" -underline 0 \
1873	-command "Execute"
1874._MainMenu._Actions._Menu add command -label "List Text File" -underline 0 \
1875	-command "List"
1876
1877._MainMenu._Help._Menu add command -label "About ..."   -underline 0 \
1878	-command "About"
1879._MainMenu._Help._Menu add command -label "License ..." -underline 0 \
1880	-command "License"
1881#._MainMenu._Help._Menu add command -label "Index ..."   -underline 0 \
1882#	-command "Index"
1883
1884pack ._MainMenu._File ._MainMenu._Options ._MainMenu._Actions \
1885	._MainMenu._Help -side left
1886pack ._MainMenu._Help -side right
1887
1888tk_menuBar ._MainMenu ._MainMenu._File ._MainMenu._Options \
1889	._MainMenu._Actions ._MainMenu._Help
1890
1891#
1892# middle part, on the left the file listboxes, on the right some buttons
1893#
1894
1895frame ._MainFrame -relief raised -bd 2
1896
1897#
1898# Left: file listboxes and scrollbar
1899#
1900
1901frame ._MainFrame._FileList
1902#
1903# definition of the second listbox which I couldn't get to work properly
1904#
1905# Design 1
1906#
1907#listbox ._MainFrame._FileList._Status -relief sunken -width 4 \
1908#	-yscrollcommand "\
1909#	UpdateListScroll ._MainFrame._FileList._Status \
1910#	                 ._MainFrame._FileList._Liste \
1911#                         ._MainFrame._FileList._Scrollbar "
1912#listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \
1913#	-yscrollcommand "\
1914#	UpdateListScroll ._MainFrame._FileList._Status \
1915#	                 ._MainFrame._FileList._Liste \
1916#                         ._MainFrame._FileList._Scrollbar "
1917#scrollbar ._MainFrame._FileList._Scrollbar -command " \
1918#	UpdateSBScroll ._MainFrame._FileList._Status \
1919#	                 ._MainFrame._FileList._Liste \
1920#			 ._MainFrame._FileList._Scrollbar "
1921#pack ._MainFrame._FileList._Status -side left -padx 8 -pady 8 -fill y
1922#
1923# Design 2
1924#
1925#listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \
1926#	-yscrollcommand "._MainFrame._FileList._Scrollbar set"
1927#scrollbar ._MainFrame._FileList._Scrollbar \
1928#	-command "._MainFrame._FileList._Liste yview"
1929#pack ._MainFrame._FileList._Liste -side left -padx 8 -pady 8 \
1930#	-expand true -fill both
1931#
1932# Design 3
1933#
1934listbox ._MainFrame._FileList._Status -relief sunken -width 8 \
1935	-yscrollcommand { ._MainFrame._FileList._Scrollbar set } \
1936	-exportselection false
1937listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \
1938	-yscrollcommand { ._MainFrame._FileList._Scrollbar set } \
1939	-exportselection false
1940scrollbar ._MainFrame._FileList._Scrollbar \
1941	-command ScrollCommand
1942pack ._MainFrame._FileList._Status -side left -padx 8 -pady 8 -fill y
1943pack ._MainFrame._FileList._Liste -side left -padx 8 -pady 8 \
1944	-expand true -fill both
1945pack ._MainFrame._FileList._Scrollbar -pady 8 -side right -fill y
1946
1947if { [ lindex [ ._MainFrame._FileList._Liste configure -width ] 4 ] < 20 } {
1948    ._MainFrame._FileList._Liste configure -width 20
1949}
1950
1951#
1952# Right: some buttons
1953#
1954
1955frame ._MainFrame._Buttons
1956button ._MainFrame._Buttons._Load    -text "Load"    -command "Load"
1957button ._MainFrame._Buttons._Decode  -text "Decode"  -command "Decode"
1958button ._MainFrame._Buttons._Execute -text "Execute" -command "Execute"
1959button ._MainFrame._Buttons._Info    -text "Info"    -command "Info"
1960button ._MainFrame._Buttons._Quit    -text "Quit"    -command "Quit"
1961
1962pack ._MainFrame._Buttons._Load \
1963	._MainFrame._Buttons._Decode ._MainFrame._Buttons._Execute \
1964	._MainFrame._Buttons._Info   ._MainFrame._Buttons._Quit \
1965	-ipadx 4 -ipady 4 -fill x -padx 2 -pady 2
1966
1967#
1968# packe MainFrame
1969#
1970
1971pack ._MainFrame._FileList -side left -expand true -fill both
1972pack ._MainFrame._Buttons  -side right -padx 8 -pady 8 -anchor center
1973
1974#
1975# Down: Save Path
1976#
1977
1978frame  ._SPEntry -relief raised -bd 2
1979button ._SPEntry._Label -text "Save Path:" -bd 1 -command {
1980    set NewPath [ tk_SelectFiles "Savefile Path" 0 2 $SaveFilePath ]
1981    if { $NewPath != "" } {
1982	if { [ CheckWritable $NewPath ] } {
1983	    set SaveFilePath [ CompressSlashes $NewPath ]
1984	}
1985    }
1986}
1987entry  ._SPEntry._Path -relief sunken -textvariable SaveFilePath
1988pack   ._SPEntry._Label -side left -padx 4 -pady 4
1989pack   ._SPEntry._Path -side right -padx 4 -pady 4 -fill x -expand true
1990
1991#
1992# noch weiter unten: Statuszeile
1993#
1994
1995frame ._Status -relief sunken -bd 1
1996label ._Status._Desc -text "Status: " \
1997	-font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-*
1998label ._Status._Text -text "OK" -justify left -anchor w \
1999	-font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-*
2000pack ._Status._Desc -side left -padx 2 -pady 2
2001pack ._Status._Text -side left -pady 2 -fill x
2002
2003#
2004# Packe alles zusammen
2005#
2006
2007pack ._MainMenu -side top -fill x
2008pack ._Status -side bottom -fill x
2009pack ._SPEntry -side bottom -fill x
2010pack ._MainFrame -expand true -fill both
2011
2012#
2013# Bindings
2014#
2015
2016bind ._SPEntry._Path <Return> {
2017    if { $SaveFilePath == {} } {
2018	set SaveFilePath [ pwd ]
2019    }
2020    set SaveFilePath [ CompressSlashes $SaveFilePath ]
2021    CheckWritable $SaveFilePath
2022}
2023
2024#
2025# AutoInfo pops up Info about a file whenever the user clicks on it
2026#
2027
2028bind ._MainFrame._FileList._Liste <Button-1> {
2029    if { $OptionAutoInfo } {
2030	set TheInfoFile [ ._MainFrame._FileList._Liste index @%x,%y ]
2031
2032	if { $TheInfoFile != "" } {
2033	    InfoFile $TheInfoFile
2034	}
2035    }
2036}
2037
2038#
2039# ----------------------------------------------------------------------
2040#
2041
2042#
2043# A File Selector Box for multiple files in Tk
2044#
2045# Frank Pilhofer Feb/Mar 1996
2046#
2047
2048#
2049# Default Path and Pattern
2050#
2051
2052set MFSLoadFilterPath [pwd]
2053set MFSLoadFilterPattern "*"
2054
2055#
2056# directory separator
2057#
2058
2059if { $tcl_platform(platform) == "windows" } {
2060    set ds "\\"
2061    set parent ".."
2062} elseif { $tcl_platform(platform) == "macintosh" } {
2063    set ds ":"
2064    set parent ":"
2065} else {
2066    set ds "/"
2067    set parent ".."
2068}
2069
2070##############################################################################
2071## General helper functions
2072##############################################################################
2073
2074#
2075# Canonicalize a path: compress multiple slashes, remove slash at end,
2076#                      expand double-dots and perform tilde expansion
2077#
2078
2079proc CompressSlashes { Path } {
2080    global ds parent
2081
2082    set thepath [ file split $Path ]
2083    set lastel  [ expr [ llength $thepath ] - 1 ]
2084    set newpat  {}
2085    set ignore  0
2086
2087    set element "."
2088    for { set index $lastel } { $index >= 0 } { incr index -1 } {
2089	set element [ lindex $thepath $index ]
2090
2091	if { $element == {} } {
2092	} elseif { $element == "." } {
2093	} elseif { $element == $parent } {
2094	    incr ignore
2095	} elseif { $index == 0 && [ string range $element 0 0 ] == "~" } {
2096	    set hopath [ file split [ glob -nocomplain $element ] ]
2097
2098	    if { $hopath == {} } {
2099		tk_dialog ._Dialog { User does not exist } "This user does\
2100			not exist." {} 0 OK
2101	    } elseif { $ignore } {
2102		if { $ignore > [ llength $hopath ] } {
2103		    set newpat [ linsert $newpat 0 {} ]
2104		} else {
2105		    set holen [ llength $hopath ]
2106		    set newpat [ concat [ lrange $hopath 0 \
2107			    [ expr $holen - $ignore - 1 ] ] \
2108			    $newpat ]
2109		}
2110	    } else {
2111		set newpat [ concat $hopath $newpat ]
2112	    }
2113	} elseif { $ignore } {
2114	    incr ignore -1
2115	} else {
2116	    set newpat [ linsert $newpat 0 $element ]
2117	}
2118    }
2119    if { $element == {} } {
2120	set newpat [ linsert $newpat 0 {} ]
2121    } elseif { $element == $ds } {
2122    } elseif { $element == "." || $element == $parent } {
2123	if { $ignore } {
2124	    set curdir [ file split [ pwd ] ]
2125	    if { $ignore > [ llength $curdir ] } {
2126		set newpat [ linsert $newpat 0 {} ]
2127	    } else {
2128		set cdlen [ llength $curdir ]
2129		set newpat [ concat [ lrange $curdir 0 \
2130			[ expr $cdlen - $ignore - 1 ] ] \
2131			$newpat ]
2132	    }
2133	} else {
2134	    set newpat [ linsert $newpat 0 "." ]
2135	}
2136    } else {
2137	set newpat [ linsert $newpat 0 "." ]
2138    }
2139    set ThePath [ eval file join $newpat ]
2140
2141#    if { $ThePath == {} } {
2142#	set ThePath [ file join "" ]
2143#    }
2144
2145    return $ThePath
2146}
2147
2148#
2149# Canonize our search pattern
2150#
2151
2152proc CanonPattern { Pattern } {
2153    global MFSLoadFilterPath
2154    global MFSLoadFilterPattern
2155    global ds parent
2156
2157    set ThePath [ CompressSlashes $Pattern ]
2158    set TheDir  [ file dirname $ThePath ]
2159    set TheFile [ file tail $ThePath ]
2160
2161    # split up by directory and pattern
2162
2163    if { $TheDir == {} } {
2164	set MFSLoadFilterPath "."
2165	set MFSLoadFilterPattern "*"
2166    } elseif { [ file exists $ThePath ] && [ file isdirectory $ThePath ] } {
2167	set MFSLoadFilterPath $ThePath
2168	if { $MFSLoadFilterPattern == {} } {
2169	    set MFSLoadFilterPattern "*"
2170	}
2171    } else {
2172	set MFSLoadFilterPath $TheDir
2173	set MFSLoadFilterPattern $TheFile
2174    }
2175    set MFSCurPattern [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ]
2176
2177    return $MFSCurPattern
2178}
2179
2180#
2181# Add new value to a listbox if it's not already there
2182#
2183
2184proc AddToLb { lb value } {
2185    set count [ $lb size ]
2186    for { set index 0 ; set found 0 } { $index < $count } { incr index } {
2187	if { [ $lb get $index ] == $value } {
2188	    set found 1
2189	    break
2190	}
2191    }
2192    if { $found == 0 } {
2193	$lb insert end $value
2194    }
2195}
2196
2197#
2198# Update elements in Listboxes after directory or filter change
2199#
2200
2201proc MFSSelectShow { havefiles } {
2202    global MFSLoadFilterPath
2203    global MFSLoadFilterPattern
2204    global ds parent
2205
2206    if { $havefiles } {
2207	global MFSlbf
2208    }
2209    global MFSlbd
2210
2211    if { $havefiles } {
2212	$MFSlbf delete 0 end
2213    }
2214    $MFSlbd delete 0 end
2215
2216    if { ! [ file readable $MFSLoadFilterPath ] } {
2217	tk_dialog ._Dialog { File Error } "You do not have the proper\
2218		permissions to browse this Directory: $MFSLoadFilterPath" \
2219		{} 0 OK
2220	if { [ file pathtype $MFSLoadFilterPath ] == "absolute" } {
2221	    if { [ llength [ file split $MFSLoadFilterPath ] ] > 1 } {
2222		$MFSlbd insert 0 $parent$ds
2223	    }
2224	}
2225	return
2226    }
2227    #
2228    # insert files into file list
2229    #
2230    if { $havefiles } {
2231	set pat [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ]
2232	foreach file [ lsort [ glob -nocomplain -- $pat ] ] {
2233	    set basename [ file tail $file ]
2234
2235	    if { ! [ file isdirectory $file ] } {
2236		$MFSlbf insert end $basename
2237	    }
2238	}
2239    }
2240    #
2241    # insert directories into directory list
2242    #
2243    set pat [ file join $MFSLoadFilterPath * ]
2244    foreach file [ lsort [ glob -nocomplain -- $pat ] ] {
2245	set basename [ file tail $file ]
2246
2247	if { [ file isdirectory $file ] } {
2248	    append basename /
2249	    $MFSlbd insert end $basename
2250	}
2251    }
2252    if { [ file pathtype $MFSLoadFilterPath ] == "absolute" } {
2253	if { [ llength [ file split $MFSLoadFilterPath ] ] > 1 } {
2254	    $MFSlbd insert 0 $parent$ds
2255	}
2256    }
2257    $MFSlbd insert 0 "./"
2258}
2259
2260proc SelectAddFromList { lb } {
2261    global MFSLoadFilterPath
2262    global MFSLoadFilterPattern
2263    global ds parent
2264    global MFSlbi
2265
2266    set Selection [ $lb curselection ]
2267    set SelItems  [ llength $Selection ]
2268
2269    for { set index 0 } { $index < $SelItems } { incr index } {
2270	set SelFile [ $lb get [ lindex $Selection $index ] ]
2271	set TheFile [ file join $MFSLoadFilterPath $SelFile ]
2272
2273	if { ! [ file readable $TheFile ] } {
2274	    tk_dialog ._Dialog { File Error } "You do not have the proper\
2275		    permissions to read this file or directory: $TheFile" \
2276		    {} 0 OK
2277	} else {
2278	    set TheFile [ CompressSlashes $TheFile ]
2279	    if { [ file isdirectory $TheFile ] && $TheFile != $ds } {
2280		append TheFile $ds
2281	    }
2282	    AddToLb $MFSlbi $TheFile
2283	}
2284    }
2285    return 0
2286}
2287
2288##############################################################################
2289# Main function
2290##############################################################################
2291#
2292# title:      Title of this dialog box. Printed in the title bar
2293# multifile:  whether we allow to select multiple files
2294# allowdir:   Whether we allow directories to be selected:
2295#             0: no directories may be added to the selection
2296#             1: directories may be selected
2297#             2: only directories may be selected
2298# startpath:  the path where we want the selection to start
2299#
2300
2301proc tk_SelectFiles { title multifile allowdir { startpath "" } } {
2302    global MFSLoadFilterPath
2303    global MFSLoadFilterPattern
2304    global MFSSelectFinish
2305    global MFSCurPattern
2306    global MFSCurSelection
2307    global MFSlbf
2308    global MFSlbd
2309    global MFSlbi
2310    global ds parent
2311
2312    set MFSLoadFilterPath [ CompressSlashes $MFSLoadFilterPath ]
2313    set OldFilterPath $MFSLoadFilterPath
2314    set OldFilterPattern $MFSLoadFilterPattern
2315    if { $startpath != "" } {
2316	set MFSLoadFilterPath [ CompressSlashes $startpath ]
2317    }
2318    set MFSCurPattern [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ]
2319    set MFSSelectFinish {}
2320    set MFSCurSelection ""
2321
2322    set MFSlbf ._Selector._Top._FileList.sub.box
2323    set MFSlbd ._Selector._Top._DirList.sub.box
2324    set MFSlbi ._Selector._SelList._FileList._List
2325
2326    toplevel ._Selector
2327    wm title ._Selector $title
2328    wm minsize ._Selector 300 200
2329
2330    frame ._Selector._Filter -relief raised -bd 1
2331    label ._Selector._Filter._Label -text "Filter:"
2332    entry ._Selector._Filter._Filter -relief sunken -textvariable MFSCurPattern
2333    pack ._Selector._Filter._Label -side left -padx 4 -pady 4
2334    pack ._Selector._Filter._Filter -side right -padx 8 -pady 4 \
2335	    -fill x -expand true
2336    pack ._Selector._Filter -side top -fill x
2337
2338    frame ._Selector._Top -relief groove -bd 1
2339    frame ._Selector._Top._DirList
2340    frame ._Selector._Top._DirList.sub
2341
2342    label ._Selector._Top._DirList.label -text "Directories"
2343    listbox ._Selector._Top._DirList.sub.box -relief sunken \
2344	    -xscrollcommand "._Selector._Top._DirList.sub.xsb set" \
2345	    -yscrollcommand "._Selector._Top._DirList.sub.ysb set" \
2346	    -selectmode normal -height 8
2347    scrollbar ._Selector._Top._DirList.sub.xsb -orient horizontal \
2348	    -command "._Selector._Top._DirList.sub.box xview"
2349    scrollbar ._Selector._Top._DirList.sub.ysb \
2350	    -command "._Selector._Top._DirList.sub.box yview"
2351
2352    pack ._Selector._Top._DirList.sub.xsb -side bottom -fill x
2353    pack ._Selector._Top._DirList.sub.ysb -side right  -fill y
2354    pack ._Selector._Top._DirList.sub.box -side left -expand true -fill both
2355
2356    pack ._Selector._Top._DirList.label -side top -anchor w -padx 4
2357    pack ._Selector._Top._DirList.sub -side bottom -expand true -fill both
2358
2359
2360    if { $allowdir != 2 } {
2361	frame ._Selector._Top._FileList
2362	frame ._Selector._Top._FileList.sub
2363
2364	label ._Selector._Top._FileList.label -text "Files"
2365
2366	if { $multifile } {
2367	    listbox ._Selector._Top._FileList.sub.box -relief sunken \
2368		    -xscrollcommand "._Selector._Top._FileList.sub.xsb set" \
2369		    -yscrollcommand "._Selector._Top._FileList.sub.ysb set" \
2370		    -selectmode extended -height 8
2371	} else {
2372	    listbox ._Selector._Top._FileList.sub.box -relief sunken \
2373		    -xscrollcommand "._Selector._Top._FileList.sub.xsb set" \
2374		    -yscrollcommand "._Selector._Top._FileList.sub.ysb set" \
2375		    -selectmode normal -height 8
2376	}
2377	scrollbar ._Selector._Top._FileList.sub.xsb -orient horizontal \
2378		-command "._Selector._Top._FileList.sub.box xview"
2379	scrollbar ._Selector._Top._FileList.sub.ysb \
2380		-command "._Selector._Top._FileList.sub.box yview"
2381
2382	pack ._Selector._Top._FileList.sub.xsb -side bottom -fill x
2383	pack ._Selector._Top._FileList.sub.ysb -side right  -fill y
2384	pack ._Selector._Top._FileList.sub.box -side left \
2385		-expand true -fill both
2386
2387	pack ._Selector._Top._FileList.label -side top -anchor w -padx 4
2388	pack ._Selector._Top._FileList.sub -side bottom \
2389		-expand true -fill both
2390    }
2391
2392    if { $multifile } {
2393	frame ._Selector._Top._Buttons
2394	frame ._Selector._Top._Buttons.b
2395
2396	if { $allowdir == 2 } {
2397	    button ._Selector._Top._Buttons.b._Add -text "Add" -width 8 \
2398		    -command { SelectAddFromList $MFSlbd }
2399	} else {
2400	    button ._Selector._Top._Buttons.b._Add -text "Add" -width 8 \
2401		    -command { SelectAddFromList $MFSlbf }
2402
2403	    if { $allowdir == 1 } {
2404		button ._Selector._Top._Buttons.b._AddPath -text "Add Path" \
2405			-width 8 -command { SelectAddFromList $MFSlbd }
2406	    }
2407	}
2408	if { $allowdir != 2 } {
2409	    button ._Selector._Top._Buttons.b._AddAll -text "Add All" \
2410		    -width 8 -command {
2411		set ThePath $MFSLoadFilterPath
2412		set count [ $MFSlbf size ]
2413		if { $ThePath != $ds } { append ThePath $ds }
2414		for { set index 0 } { $index < $count} { incr index } {
2415		    set TheFile $ThePath
2416		    append TheFile [ $MFSlbf get $index ]
2417		    AddToLb $MFSlbi $TheFile
2418		}
2419	    }
2420	}
2421
2422	if { $allowdir == 1 } {
2423	    pack ._Selector._Top._Buttons.b._Add \
2424		    ._Selector._Top._Buttons.b._AddPath \
2425		    ._Selector._Top._Buttons.b._AddAll \
2426		    -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2
2427	} elseif { $allowdir == 2 } {
2428	    pack ._Selector._Top._Buttons.b._Add \
2429		    -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2
2430	} else {
2431	    pack ._Selector._Top._Buttons.b._Add \
2432		    ._Selector._Top._Buttons.b._AddAll \
2433		    -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2
2434	}
2435
2436	pack ._Selector._Top._Buttons.b
2437    }
2438
2439    if { $multifile } {
2440	pack ._Selector._Top._Buttons -side bottom -fill x -padx 4 -pady 4
2441    }
2442
2443    pack ._Selector._Top._DirList -side left -expand true -fill both -padx 4
2444
2445    if { $allowdir != 2 } {
2446	pack ._Selector._Top._FileList -side right -expand true \
2447		-fill both -padx 4
2448    }
2449
2450    if { $multifile } {
2451	frame ._Selector._SelList -relief groove -bd 1
2452	frame ._Selector._SelList._FileList
2453	frame ._Selector._SelList._Buttons -bd 4
2454
2455	label ._Selector._SelList._Label -text "Selected Files" -relief groove
2456
2457	listbox ._Selector._SelList._FileList._List -relief sunken \
2458		-xscrollcommand "._Selector._SelList._FileList._XScrollbar set" \
2459		-yscrollcommand "._Selector._SelList._FileList._YScrollbar set" \
2460		-selectmode extended -height 4
2461	scrollbar ._Selector._SelList._FileList._XScrollbar -orient horizontal \
2462		-command "._Selector._SelList._FileList._List xview"
2463	scrollbar ._Selector._SelList._FileList._YScrollbar \
2464		-command "._Selector._SelList._FileList._List yview"
2465
2466	pack ._Selector._SelList._FileList._XScrollbar -side bottom -fill x
2467	pack ._Selector._SelList._FileList._YScrollbar -side right  -fill y
2468	pack ._Selector._SelList._FileList._List -side left -expand true \
2469		-fill both
2470
2471	button ._Selector._SelList._Buttons._Remove -text "Remove" -width 8 \
2472		-command {
2473	    set Selection [ $MFSlbi curselection ]
2474	    set count 0
2475	    foreach index $Selection {
2476		$MFSlbi delete [ expr $index - $count ]
2477		incr count
2478	    }
2479	}
2480
2481	pack ._Selector._SelList._Buttons._Remove -ipadx 4 -ipady 4 -fill x \
2482		-padx 2 -pady 2 -anchor center
2483
2484	pack ._Selector._SelList._Label -side top -fill x -padx 4 -pady 4
2485	pack ._Selector._SelList._FileList -side left -expand true -fill both \
2486		-padx 4 -pady 4
2487	pack ._Selector._SelList._Buttons -side right -padx 4 -pady 4
2488    } else {
2489	frame ._Selector._Selection -relief groove -bd 1
2490	label ._Selector._Selection.lab -text "Selection"
2491	entry ._Selector._Selection.ent -relief sunken \
2492		-textvariable MFSCurSelection
2493	pack ._Selector._Selection.ent -side bottom -padx 4 -fill x
2494	pack ._Selector._Selection.lab -side bottom -anchor w -padx 4
2495    }
2496
2497    frame ._Selector._Buttons -relief raised -bd 1
2498    frame ._Selector._Buttons.b
2499
2500    if { $multifile } {
2501	button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command {
2502	    set MFSSelectFinish ok
2503	}
2504    } else {
2505	if { $allowdir == 0 } {
2506	    button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command {
2507		if { ! [ file exists $MFSCurSelection ] || \
2508			! [ file readable $MFSCurSelection ] || \
2509			[ file isdirectory $MFSCurSelection ] } {
2510		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2511			    does not exist, is not readable or is a\
2512			    directory" {} 0 OK
2513		} else {
2514		    set MFSSelectFinish ok
2515		}
2516	    }
2517	} elseif { $allowdir == 2 } {
2518	    button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command {
2519		if { ! [ file exists $MFSCurSelection ] || \
2520			! [ file readable $MFSCurSelection ] || \
2521			! [ file isdirectory $MFSCurSelection ] } {
2522		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2523			    does not exist, is not readable or is not a\
2524			    directory" {} 0 OK
2525		} else {
2526		    set MFSSelectFinish ok
2527		}
2528	    }
2529	} else {
2530	    button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command {
2531		if { ! [ file exists $MFSCurSelection ] || \
2532			! [ file readable $MFSCurSelection ] } {
2533		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2534			    does not exist or is not readable" {} 0 OK
2535		} else {
2536		    set MFSSelectFinish ok
2537		}
2538	    }
2539	}
2540    }
2541    if { $allowdir != 2 } {
2542	button ._Selector._Buttons.b._Filter -text "Filter" -width 8 -command {
2543	    set MFSCurPattern [ CanonPattern $MFSCurPattern ]
2544	    MFSSelectShow 1
2545	}
2546    } else {
2547	button ._Selector._Buttons.b._Filter -text "Filter" -width 8 -command {
2548	    set MFSCurPattern [ CanonPattern $MFSCurPattern ]
2549	    MFSSelectShow 0
2550	}
2551    }
2552    button ._Selector._Buttons.b._Cancel -text "Cancel" -width 8 \
2553	    -command { set MFSSelectFinish cancel }
2554
2555    pack ._Selector._Buttons.b._Ok \
2556	    ._Selector._Buttons.b._Filter \
2557	    ._Selector._Buttons.b._Cancel \
2558	    -side left -ipadx 4 -ipady 4 -padx 4 -pady 4
2559    pack ._Selector._Buttons.b
2560
2561    pack ._Selector._Top -side top -expand true -fill both -ipadx 8 -ipady 8
2562
2563    if { $multifile } {
2564	pack ._Selector._SelList -side top -expand true -fill both \
2565		-ipadx 8 -ipady 8
2566    } else {
2567	pack ._Selector._Selection -side top -fill both -ipadx 8 -ipady 4
2568    }
2569    pack ._Selector._Buttons -side bottom -fill x
2570
2571    #
2572    # the items are up on screen. define bindings
2573    #
2574
2575    if { $allowdir != 2 } {
2576	bind ._Selector._Filter._Filter <Return> {
2577	    set MFSCurPattern [ CanonPattern $MFSCurPattern ]
2578	    MFSSelectShow 1
2579	}
2580    } else {
2581	bind ._Selector._Filter._Filter <Return> {
2582	    set MFSCurPattern [ CanonPattern $MFSCurPattern ]
2583	    MFSSelectShow 0
2584	}
2585    }
2586    if { $multifile } {
2587	if { $allowdir != 2 } {
2588	    bind $MFSlbd <Double-Button-1> {
2589		set Selection [ lindex [ $MFSlbd curselection ] 0 ]
2590
2591		if { $Selection != "" } {
2592		    set TheFile [ $MFSlbd get $Selection ]
2593		    set MFSLoadFilterPath [ CompressSlashes \
2594			    [ file join $MFSLoadFilterPath $TheFile ] ]
2595		    set MFSCurPattern [ \
2596			    file join $MFSLoadFilterPath $MFSLoadFilterPattern]
2597		    MFSSelectShow 1
2598		}
2599	    }
2600	} else {
2601	    bind $MFSlbd <Double-Button-1> {
2602		set Selection [ lindex [ $MFSlbd curselection ] 0 ]
2603
2604		if { $Selection != "" } {
2605		    set TheFile [ $MFSlbd get $Selection ]
2606		    set MFSLoadFilterPath [ CompressSlashes \
2607			    [ file join $MFSLoadFilterPath $TheFile ] ]
2608		    set MFSCurPattern [ \
2609			    file join $MFSLoadFilterPath $MFSLoadFilterPattern]
2610		    MFSSelectShow 0
2611		}
2612	    }
2613	}
2614	if { $allowdir != 2 } {
2615	    bind $MFSlbf <Double-Button-1> {
2616		SelectAddFromList $MFSlbf
2617	    }
2618	}
2619    } else {
2620	if { $allowdir != 2 } {
2621	    bind $MFSlbd <Double-Button-1> {
2622		set Selection [ lindex [ $MFSlbd curselection ] 0 ]
2623
2624		if { $Selection != "" } {
2625		    set TheFile [ $MFSlbd get $Selection ]
2626		    set MFSLoadFilterPath [ CompressSlashes \
2627			    [ file join $MFSLoadFilterPath $TheFile ] ]
2628		    set MFSCurPattern [ \
2629			    file join $MFSLoadFilterPath $MFSLoadFilterPattern]
2630		    MFSSelectShow 1
2631		}
2632	    }
2633	} else {
2634	    bind $MFSlbd <Double-Button-1> {
2635		set Selection [ lindex [ $MFSlbd curselection ] 0 ]
2636
2637		if { $Selection != "" } {
2638		    set TheFile [ $MFSlbd get $Selection ]
2639		    set MFSLoadFilterPath [ CompressSlashes \
2640			    [ file join $MFSLoadFilterPath $TheFile ] ]
2641		    set MFSCurPattern [ \
2642			    file join $MFSLoadFilterPath $MFSLoadFilterPattern]
2643		    MFSSelectShow 0
2644		}
2645	    }
2646	}
2647    }
2648    if { ! $multifile } {
2649	if { $allowdir } {
2650	    bind $MFSlbd <Button-1> {
2651		set Selection [ $MFSlbd index  @%x,%y ]
2652		set TheFile   [ $MFSlbd get $Selection ]
2653
2654		if { $TheFile != "" } {
2655		    set MFSCurSelection [ \
2656			    file join $MFSLoadFilterPath $TheFile ]$ds
2657		}
2658	    }
2659	}
2660	if { $allowdir != 2 } {
2661	    bind $MFSlbf <Button-1> {
2662		set Selection [ $MFSlbf index  @%x,%y ]
2663		set TheFile   [ $MFSlbf get $Selection ]
2664
2665		if { $TheFile != "" } {
2666		    set MFSCurSelection [ \
2667			    file join $MFSLoadFilterPath $TheFile ]
2668		}
2669	    }
2670	    bind $MFSlbf <Double-Button-1> {
2671		set Selection [ lindex [ $MFSlbf curselection ] 0 ]
2672
2673		if { $Selection != "" } {
2674		    set TheFile [ $MFSlbf get $Selection ]
2675
2676		    set MFSCurSelection [ \
2677			    file join $MFSLoadFilterPath $TheFile ]
2678		    set MFSSelectFinish ok
2679		}
2680	    }
2681	}
2682	if { $allowdir == 0 } {
2683	    bind ._Selector._Selection.ent <Return> {
2684		set MFSCurSelection [ CompressSlashes $MFSCurSelection ]
2685		if { ! [ file exists $MFSCurSelection ] || \
2686			! [ file readable $MFSCurSelection ] || \
2687			[ file isdirectory $MFSCurSelection ] } {
2688		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2689			    does not exist, is not readable or is a\
2690			    directory" {} 0 OK
2691		} else {
2692		    set MFSSelectFinish ok
2693		}
2694	    }
2695	} elseif { $allowdir == 2 } {
2696	    bind ._Selector._Selection.ent <Return> {
2697		set MFSCurSelection [ CompressSlashes $MFSCurSelection ]
2698		if { ! [ file exists $MFSCurSelection ] || \
2699			! [ file readable $MFSCurSelection ] || \
2700			! [ file isdirectory $MFSCurSelection ] } {
2701		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2702			    does not exist, is not readable or is not a\
2703			    directory" {} 0 OK
2704		} else {
2705		    set MFSSelectFinish ok
2706		}
2707	    }
2708	} else {
2709	    bind ._Selector._Selection.ent <Return> {
2710		set MFSCurSelection [ CompressSlashes $MFSCurSelection ]
2711		if { ! [ file exists $MFSCurSelection ] || \
2712			! [ file readable $MFSCurSelection ] } {
2713		    tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\
2714			    does not exist or is not readable" {} 0 OK
2715		} else {
2716		    set MFSSelectFinish ok
2717		}
2718	    }
2719	}
2720    }
2721
2722    if { $allowdir != 2 } {
2723	MFSSelectShow 1
2724    } else {
2725	MFSSelectShow 0
2726    }
2727
2728    set oldFocus [ focus ]
2729    tkwait visibility ._Selector
2730    grab set ._Selector
2731    focus ._Selector
2732    tkwait variable MFSSelectFinish
2733
2734    set FileList {}
2735
2736    if { $MFSSelectFinish == "cancel" } {
2737	set MFSLoadFilterPath $OldFilterPath
2738	set MFSLoadFilterPattern $OldFilterPattern
2739    } else {
2740	if { $multifile } {
2741	    set count [ ._Selector._SelList._FileList._List size ]
2742
2743	    for { set index 0 } { $index < $count } { incr index } {
2744		lappend FileList \
2745			[ ._Selector._SelList._FileList._List get $index ]
2746	    }
2747	} else {
2748	    set FileList $MFSCurSelection
2749	}
2750    }
2751
2752    destroy ._Selector
2753    focus $oldFocus
2754    return $FileList
2755}
2756
2757#
2758# ----------------------------------------------------------------------
2759#
2760
2761set FrankPic "
2762R0lGODdhcgCWAPUAADA0MDg4ODg8OEBAQEBEQEhISEhMSFBQUFBUUFhYWFhcWGBgYGBkYGhoaGhs
2763aHBwcHB0cHh4eHh8eICAgICEgIiIiIiMiJCQkJCUkJiYmJicmKCgoKCkoKioqKisqLCwsLC0sLi4
2764uLi8uMDAwMDEwMjIyMjMyNDQ0NDU0NjY2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2765AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAcgCWAAAG/kCDsEAsGA5I4fBQ
2766IBwPBkQCYtFkOBcOBGNZPCAQg7PgUFAqIg3Xs6VgKpoNVvJIIBSbTcPysHQ8ICIcHyMkIyAgGBEK
2767CY0JCgoLkQwMDZYODw8OlZSSCggIUEqjT6NNBEYGjQwWXREZHxsZERcHDhIOYowFCg4ZWRASGhwW
2768HBMVGRISFxkLDRMUbhcUGg/LE7AdsCGFIB4aEJCNUowKlJaXmJadkuNKSKJC8UNNjw6vGxAMHcMW
2769DmUMHmhocMACBAEGAm7AEA5CBwt5KAhMhkGDggoQOVTE0GELBgwZOnDIAKLDBg8kRHjA4ECKI0jm
2770KjX49w9dg06f7MgLNc9U/pEDD47F8WABmYUMDBQ0QMCggoIHGSxIaPDAFoUMZRwsrJBpCzMMDyoo
2771qoBMg4ZpGypQmCAhg5WUHwZ9SNYOVKNJ5y7JvMnAkx14CEr5bCIkwoMIECZw8FCBWQYKzhwcgNAg
2772AVcJGCZ8sQDWgoBbyh5QjfZ4wgQLFIpCuFAhArQLIA1G4GbCRIkQwy44aLCgEihGlIJfmrkOJiOe
2773POEpByXm2QQwYj1o1bgAVwTmEhSshjBX8QMDjBxAiBClAGXE1sxq6ICRAVMJEeAUkx7BA7cQ+L1V
2774A0VOyoL/eW3SV29+gYIEf8oxkQp4EVBwgAIQTfPFBhPwll0DAowHAWQh/nTwAQYUHNFAGM4Y8AAG
2775DEBxgQLYZOBBPlRgkAAzclDQAT9HeTBCCSPExQEWKbp0ByQAykQgJ4zYwZ8USx6oHCsLJOBGBhMw
2776MMFFFTCQgHsC0MKAPmp0gEguB/RlwAIIFFUVAAZMBQcG+UQQgQYW1CfSBmYRc9UGgYTwgQd/biBB
2777lHcw+QiRfUXSW6LiOOLSXwkeYU0BC7g2QWBeeKElAgIwsIEDaJ62gAaAIkCAewUshQBrByBQQAS2
27783LLaAhlgwEF0HGiDxQYdXLBeByIg8oE2IHTRVwKtPorofwC2Y8ddjSK43JcJEKfAAAUEEFgoChBA
2779QDgJ/OfBAg5UwFYC/gOI8Qh4lhAgXlJV3sKAbhHcytkFI5iEgQR5dPCAjt/IMtIGFhCUrF2HMjtg
2780JEkeatwjoRh4oBeMLBXFAAKgmQS2vxWQAQQIgNrIEQYMgCwqhEFgzQAPUsKia0VxpYCt34xKwQa0
2781xqJBY8xwhhUUByJczoDhNkzkfzCNg5w94TLgrRG6OSEEQkJ4K8GWCaDirQLZguLtACz3VYEkBBxQ
27827ZwVSODqAlZV4MEFC9UaNwcSUHABfBVw4KAoBz7rF7NJDjlJOY4i2+ojvZlKgAAFWDDBEEIgMAAB
2783ATQDXgECTI6KAIxjTADG4D2AAKzYInuRBAJI0NfiITtw1RUcqDGB/hp1SoVPBUkAbVeSkvSuJJEM
2784N9wIEnddzcTkBQywYQOnSF4yUAcQwCnGqQQQAMaZcw5e1gxgWzYkEGBCQRgJBEBAuH1cwAwyba1F
2785gQSmpcYQ0Ic7bFyj4TKLdMOh5B9BS8kzguSe4oAilAxzrSJZADiHrWwtkHOcKxsRSPY5J0DCdWAo
2786mfW+VzcI0M5FWGkK/Bo0gQgkIAp2IYdxPMG7//Blf0o60AMY0AQBlI1z4WJCAJJXQSGkC2MLnNwA
2787APBAzpmvANETQBK15rL/RGBxAgAA2LbnOoxsYC7XcYDt6hYBVdXPYQtj2JaCw452iKIXDRAD2Aag
2788uE+skXKLM0AT/pBoxOtRrogCCKL3sBVBzGFLFQVw2hAjCLqAOMA+ILiAJRIQFsOw5QGf4M8jmlYJ
2789FsJEf2FUEuK4tjjzScACA+AaxtYItuQhr45gsx4EIQi2VTLwaUTwlhqxZ0SwNQIbcGKke+Cnieew
27907WB3KFKzWIi0/ZVDCYzwVh5f1UVXMTB7qADb5xa4wGm68pmZA+IrP1dKbAmRgdQUAgPGNyIEQOAA
2791DZCAPlRGKIQljC/B8YTCkpI0JEZBDNwskwEs4MfsbTN71LRhHldJTVoONJukxB7LPofN690hIP8j
2792TgIMU4kHoAmFdmHWTeC5P2F6goIGsKH0AtMqz3DzmQy9ZuYC/gpBVbYUjwycHAMN8MABFBF5lYFA
2793lFzWAMPMREtH2B2i9sKbJB0NcFD4HA8l6IQESIAAAPCn5wZqU1ZWFY8ubakr9UhQPaYUeQlwQNaq
2794xZsRFSkVyUJcX9ZBCUdAS4xQEKK34siEBDwuiKsEojafydI6bvWvrMwjLVsZUyTyBgqPoARlkrIA
2795Oe7kLr0ZjnueZT9GMKGW2VwcUC6y1VSuVKug1SpWrRfQ0sIUnK00wFKY8FAGqEMKEwxawoiawkM1
2796QhJLxBwr2fSgRxC0kwcFrjazasSuqpK0xQUiHqvKuVSFomy3JRckT2jAoCJqoy2R5CZxa9PkFZFy
2797IS1ZSPN6/tBs/pW45c0jcpGbXpg+0FsRQ4XZFmVRKBTBCMSbrSWACa3/cGqHpazgDs1nUICSt6/q
2798BWwdj7ve9L5UsEiMMMeaRhUFyPG+j53ETSQpVEmElI3WG6VNRXza5Cq3vOgdLYNJW+LQlg0V+GzV
2799ASQBqgs/TR5mUxQllqRCmBxAczcVbXsDmkoWq3TBCzZyklWKxwmego0DrFYdkmBA4ukYTUt6iTi+
2800Rl7jFve4AFXyNY2c4ge3mJVO5mEBBtgX0YkCw1E41I55/JL/yNGgBc4qNd3L3jGz98/tdbBKsZUE
2801rUWPKRUmhWPjDIm+GEiSMEnK1JIr2iLueat9Vi+LLX3k/jF3Gpo21loBHjGTX86jb41OETCH1Jtr
2802Ye7SX8YrcR+4aeMq+biDJahfryniWGotc9JrRARUDY8noNoZPEbYfw4gUFgPVM9YTbKKxZy9Agv5
2803yL0+BUPBlgSLQop+ySLSamV8OEWVzKbOnvWsNd1gdju4goG9tkoXV0o5cll7yALVcRJktvzteDku
2804kYQpn23paa930wfPtDSL8Epa0prXQpzcEBj6Xig0IHDS6vei3KOc/nZLmQh2KcJHTnIihjibc4xl
2805c3noacLasJVrTupX10gZt0pMhZFNTrgZxuW+/pnkQCczShHrKlQAIK5QdKXmGHiKNX8ieimFpr7H
2806oSSh/kVGYmmd5BrB7O6gB724wJYjT8zEMgCcUKa6nmsfnRDMT4ghr+aLks0hrah/YF2o16L4ive8
2807aQCYfOQJfiV+mYTOyrBMAAoQRWeNsDgnQAFAN0FTE0hpvtvy763/2c1xtDvJkx404V6vtVTlqPHI
2808FlVqTw/p9YxYtuixbBW7OYwmdhEK3bKMcOGy7XUvHkOhZY2wtA494LVK6GAOxxKaSNH56iJijJkN
2809ChWbyRfkpKFgoOYBowTP/dQqHNc6y62TrKFphU9tYBshf9LPxBfEo3kCIK0R1JOjAB4Vvi8kpkHv
2810i4AFYJOBX3DzfLvTOwLoWmz1fcDzdrVGfgqHRA+F/gn/YH/2Fz43YQ5FJUqq0C1HAgYNIgFpQxYY
28110QpxIAf0ZjKXdFR9cQ4ywSjB40bS5nV/11d/ZAcZMCLrpzIqgxhg0BVT0RsHUgkGgAkaCD/ucwyt
2812gAHMMBQeMErncz8KE1lrVRP0pD9Rgm4KiHB5JUDhghhaeBiuEQHKUEJBqAmaEHsqM33KoAyt0Apw
2813ABsVcQUfAAIHsEDaV1kxYXpUQRMneIJoEkVVqGkHhTxmcxNfcBjBAD+GeIZe6IUlhINgEAxeyIHR
2814QBanQRbSUBFy8Ach8ADL9B/5syx6eBPo8UIoSFN853Ux9UbyhQDO4Fo6KCfUF4QqAx8j5BpnaBrQ
2815/mAutkgWaigWsJEnPxICnsE4KihP8FQJt5AJApIOGNKHr8RoRYIOD4iDrign8IEe01iN8AMNHGgu
2816ahENdYMRZ5CGbpEHw/IB2iNPHTVMN/EcYLAbl2BR7BZ6q/Q950ATmDCGmTCNj2iL6nSGyoAY71M3
28170LAWtqiN3RiJ6tMK4wgC2XImxGSClbQAi2gYmmCDDOCHL2WFhTVj6XeP6geEhjEe/niItqiPhyiL
2818BcmPrrEWZRgMbHE3ZVNMTKgoACKLOCiGM9RJpphX8hUZ6geBP6mBj0h9rhg/WpiIjkiNawEfGjge
2819XaQxKvQlF0AAkRB55SBGDCMJsliNIQkfcpRu/hr5SjMWENP3kfcojTa4CS5kCeRShqLxll0xHuwo
2820Gj4VGEbQdAiQThWgCuxQgu1wlaahDEKZiJTwateTPBkJU6VDFfh4k+04iLxRF6BwlzOWWJX0jofx
2821HJlwcT+mUItpDUdRJmRkSfijlWwRkIYYmIMiWG6XRNQGVjR4j434k6JhWfbGZW8kcRPUgPdAB7yH
2822mAVlQ0wBmh0QVk2YNNECCQLJFvrolJoIAKo4OYHhbjw5Yw4ohjn4Dxc1R8oUb/4EQajgHwGhMu5R
2823MoK1Q69mQ9VxAR1QjCqIey7xhRTgioLpig4wRHWQOegSlp4znP8QkuGjedtSP4FzBF8zSpm1/mar
28248AVJkTUhZlM/KAY7NAUWwAag0iziwD92QZBswZXTGAbfIjkPkmBBVkqqWJHIqA5/s3GJZ56odESx
2825dTiVAAZcc03kgixSMCIXAAKqQyAymTSOwo+GSI2JeDUGEAahpACYpXTpcqJAqDI1EZlHoxPAVVOC
2826RTVPsCX/CQFnp1cJ8SxUAD8a8AEXcA5SKEZVhwBs0aH0yZXhcKRE0BdWtUaZZTaGhIyaUByRZmHT
2827pEqaxQDnhjLW5QyWAqiAmEAI8AXIABu80gyjqT/isCQdGpi0iIhdFFauog8RNFeIOUUPco8PmKdW
2828OUl31jmmFACu9XvpkqVnc4sRoDEHYg7j/mE34+gBtppqZOQymxcKBYmNiDgeMwQyk9EA3YU8phSD
2829kbEbUWqV+4aYL1ZDvGCXTRA0iLYhHsg2gXEE4YIJHAgntiomSZGrwREtoRANlDqS1diIkCAazKY4
2830xwNL5uCANCFZnIijukN422I4gGEXIwINVQAZ49AqSjGrFZEr9iGuG1VUSnMAA6ma2eiPXigaI5IU
2831NlR5YiAGSLQlxGET6wA4vXNUckd14GZlX3IMvjILa1VREKCLIMEr9lEkKRhPC7uUJEmQD1tCl/AJ
2832/4cEjKetruWOykocZMQbA9IJkddOTWI2dzATDUIjYHEJj/iBVkCOIeCeCXsTMWQANluQ/hyaknl6
2833QrBkX471IMrojjNBExKLDnooT7j3F0yiFEGBEXByK4gBH2u6f4z6IyOgU0PLCfVqIB2ajfEDDWua
2834jYYBQAKkQskRE8tKgNeJp6KRF1e7MG5VlfdwGgXLBZKYGnZzhGYhJtkhrjjxbZO6lQVZpO/zBS2K
2835NSFjUXIXWbsRIPYoHm6JnThZhh1LTDORGI2RAXnwCxiBizzTsn8wNpgUmVHydEjQq194uoEJDeMh
2836GVFQGQeghfpAJGaLXR2Zg4TYkoP4k4kygIz5jZ+rEWnIGpzxEerxDeagMHxxHPqKmv8IsV/4hSGJ
2837KvzxPw64UQGyDqA6iE3piNmJp/CE/hfGaH2++7sXEDNFURHD8CMe0AFSGE8YBwqz2Kb0eZReaIN5
2838iiaZEBn8q4wJi7aY8IquyL0PqLbOAHm9mRpjqg1GqBZF0X9XYKuAkhedwChKMzrzW7e/6qGmEY0V
2839YjYSm6fZqxfbO5tgcIYcPIa5677i4YXI8AEfoAYL7IFwEoI2bBNHgqbjgJQmqcECGQ3/kwklxDZP
2840YUj/ILk/e4f/0Igt6aHoEaUDwsJUwbsV8SeUGA0K6RZxAAIb4MQ5/DDxOZFNSZSPGImOo37wgQnk
2841crZsxQlq+4Ch2pKFO5RjuBvFFCDWkBpX9CEbcot4238/8imNS0/3gyXM2cRBaBpq/iEWrQGB99gX
28422SscIByq4qF+cpmNa0F9kExM5PKA5DsI/iKfH/gRHJEBmayWdWxJewyGtKmIhJsai4wYUZp5HBsc
2843YzS7ESiSS6mIjSwgOIo4ziB9wdAY5EgBJVw3RWiJ+eCR7uijLNQK3qhOlGx/QpgaCywBP7iZEusM
2844omq2dvjGg6mIAekawCqgfGm0u7HEa2Erf7BOUowMIDESFPmWRvKxvYEavSwnyGjOxqwWD/A5XqAh
2845Rhy7fKG97wiSIrmP9Skacke260AcX2Aa8REd6lzCpqE+V8AQurwJBag/qEEW6WrEXyCfZ6DOnwOd
2846VHHRscsJUL2xQdmmzAkfyEgo/nYAwkNLu0FxDL9AGdbAzh/xECl6xJE5IM88m0E7fba4Fk5jRIGE
2847j2prtFf7v4P5j5jcoH9BgTjxjOPLgXQQxdEAG3rjlspKxxu3f+aiTtmprK1Yt91SS0qBgmzJCVF6
2848zx95yE4JBhWoNJEAdeQAWek0UURdwmvBDB2gzvVnzim8xnugFmyRnSv9pFq4AEtNOYuSvETFsWYb
2849lPegwTl4LETyF2qUOSgED5EQH0OYyDRSjWVNwpQspNYcpaLhkWWZPJ2ZrI0GT7ydDjipyyYN0+Xw
2850fq4icXwzX1aiyKwxqcjQASVEBzf4kT9pGPqIHk58ttYNBm0VGEox11drE4dN/rvcC6wf/ZfxJAnJ
2851EQokEy5UAYmU2KHy0wGymIP1973VV5Q4OK/pQJYATOHhQUZK0Rtm27iMqctAqXnmwNeMFTjUGi5y
2852mdRFgZrobKnB0BVx2aZc+ZMorQ67u8sgYVEkPLQz7bjpZ7spOoFrmYJ/WcED27ycW5BVoAEDiddw
2853XOVOSX02vpl7IYZtwQF54A/+KyAoKOSHTZtZ/kIbd7XGFAm/E8VeeAawPZC+IhWUGoHd/IpNLK/Z
2854O0NzEgI4I0VOcJkb654yEXuPW+TuuFZzLdCT0GqMQC7U2NbV+Boa4D7fbIPVd+VKfNJA/YAWIALt
2855iS1BlJcBQYGTK+QdCYR4/rrGMiGxlCCqRxJ5A5JO+EeQP1s3XGC3+afB0siFdGCWNTGvroUIkkM5
2856IxZWxFHOjxpPNhGUIky0d5jN8WSMZ2vj9cc2Z9JTbrCINjmUTJmDiKEZYji7HNsAF0ACGRBeA9UL
2857FWXqApLmhT6793y2sBvJzB55h92gLiSiTHEPqTGN1qAh1OihS8y9mVzut4ABJKABkoM9/V3OVWmV
2858PnqCN2GP6RC0toyOkJBAVfY7MtEIRbyy83nR1Se49Ssnsa3j5S59DqC5Sso5IQPtifVCWblxBFhR
28599qgJkpAo2epY1aVzLhEJBUCI/WgN5kLhmm7Q77OUiZHym7nyIyJ98HMt/trCCRoLCqtITEUb7xb/
2860vlGCgOa3IPxmb7bwj+5jfYwdl1cemDSrTjYt2yld6DOEJjQ5ao+O9e6BaMdCzu4ruckOIJCyVNtW
2861YFPkBY+0gRDelHjqzadJuP3IlKLKUekQJQhuDo+QVq2CW6rI85uEF/BuEy5zgsgSVBETDzn2JcHQ
28620GdAuMyJHk6JjRxaN/M7n1Aa1PHkupKZbIGRe6rALM/ChM3shBcqfby3E/OlUeog38odDWS8wU65
2863iE3PoUO5+rXPURrlupCgc1QmCjl0/BEjOI3uibndxq0GblIwmu7e9F+oFoh41JZiKb0a23UetMir
2864UfoDKaTAeKOG7ZuU/l8ziUlAwFAoFoxGgyFELA9NRCIxVESLjshkEpFQKhPJdwLRUrAVi6X7jayv
2865kvUDfkQuhtXGIppYIg4GQ78gcMBg6C9Kgc/gSYpxKoFhYeHIQe4ITw+K72BxiMHhAeLBiwINwo1N
2866YoJitaKCjOILQvZBbfbTwQGSToHhIXJqL7HAz6+AgEAxwaAgD/BAbwiKMTLJCClpN1p6T9oIbm31
2867IiI0NEu1lRQdS0LsU8wttIESOzLyISl6r4+YOLBgE8EwJnyGQTnEyKC1arqkGITihIonUBLMVNAS
28684YEVWudInakQ60EEXKC0ZIxDD9u9O3g09QFUbJi/PwQKPBGWzKEU/mpJ5tSjk0maQSKSGoSMQOGC
2869BFChlqbiwkWdUlAZxZiCg+sIPXuShjDxs28ZzGX+jP37A+ifNJ10ilzT9SuP0DpGcF0hdUHWLFls
2870VD115YVpxjdwTMrzxKutgnvAEPBzPJYsgQECBmkai3OKFK26sDVEQORaA1luJlS4UMEIBFwj36my
28718DTLuIwOZhHGSklSW0gOWG762qTJ40DFCFAeNrZ4skVRFiqs54gXJXmmvnxZhUGCu6mEW3ch48XN
28726lCfZleyZCQ7L2DA2T+GGejY5AH+jh07gKibEUjWfHZKctWUp9LBQAzZriJPjNKggsVA2ii5Sp5K
2873iugFBAvoWCKB/k3YC044mOobYACaPhzkGbUm5Ek/nlZzx5RzSruAgqrYIAyj6qzzYg1bVssowkly
2874WSACD0qg4IAFbGLPMg7DOo4+ySajbEQCPqOiiAkXmMeTI7jLawszzoitQIwCI60077LQ8bYHkJDD
2875CApCOOEDCDRBpCXg/uCHSciMcVK+EP0c4JkpqkwRtEmKms0dLNDA8ZQ38lojFSy8wFEWSlbESk01
2876HbBgBBNK4GACPb4KxiUl8XyvvmMEoAxEP2n6rA7z9CtqNTlo+8IVSFOpLsdQwOhiUtlUmwRCS+G4
2877YAQSSAjBAgmMbAwZgEptD61+mnRyVVYlEwCZQxYKTctPQrs1/otTUtGCUjjcUCPd8uShap6MMiBh
2878hHo1+EiIDAsAUVoN7zzrTibh2xPbVkE8Zhid9lvzDjl4tIKNBLXY4txec4yFHR6RMOlANTEQAYQQ
2879RgAhA3yfII4m4Ja4c0PH4IsvvmxbTXWTBOqBhJdZ5/DEilj2AkPS2CauRTXpkMBFtdoqEBkEEUbw
2880AMYJeHOiiT1VDg4sPMkiGFtWQ0TYjynr2IUOhTzRIKlxxolUlUm/M6eWSw8NTJRkPxBhWQ0wIAOC
2881BvSget/5NGnssawj29PggwcOu2abgLJ5WAww+KgpMrpcJejqACNsKgQFC6GED0JQVgQOYMToHkgS
2882qTrElmpi/tzlrVPFlqaw/mACScUm6IAD0ZHa4AOpHIjUqVYkTcUieHLs/CpQOiABBA5EMMGEEULY
2883II0Iesqwn8n+2TBrPa+NEplRM+HGATNK80AEEU5AIQUTNJhN1y0wRxeqYMPsezoIMCghBNKr3gic
2884JgIL4EhN+OCePyZDAA3ZSWvvGV99auIExz2BAWRQQAO4EAEN4A0FJ/AAVsL0hUVhYRWwSAM88mIo
2885N42AA6DrVAkAmIF0ZSUfaJHPWR7oniVNMGVPcAhzIDCBBSADD+m7AAc69QEAFQh5b+vLFiQFqXEY
2886iwOh64AJ7qasEmxAFW54GBIMogljrEpwvmkMh4ZxAIFF/iZVimiEYr4QOAMsoFm0mcC9aMMlSE1K
2887c+B5CtAkEKEKkOADQgoZCUpggg58ByRYMVIm/LWvAHBLje0RTky2JhOxFUEUEDCAZIzBAFkIQTQH
2888cscVJja0Aq2DkJCQwN0+GIIQUI+LB7ScbLByB0pa5kkBSOO/whK+frjsD2STRHYOcIxREm4/40kC
2889a0KiF2tSJ2J9Y4AGSuABEFjvBCagFwb6srwDWYIlrsuWAALQxqyZylpkMV9uiqK9BRjga02oj2Kw
2890wpNDmWRH/+SOGBUAARB8oAPtO8EJbPmBj/CqHTzKhiOgNQx2rioAUiImBL/yQ8csYYOUKGQSAAEo
2891BkBz/k2QONqDNMWaS9UKCUvrgMg8BTIQaABztdCUEX7BiJsUJ1vC9M1vwGIWTjrmPlEgT4zu0cxj
2892ZMIAs9qPJCx1qXP6yGgd2EAHRlYvp3nAFWTI0S2whDPPEASfFw2AMBUBPnie6nY2gwQENGABD0RA
2893D8YQhlR9gqJJWMMw1YiQAzagAa4SkF7Qy8CXztTLO7xFCl7hx5PYecnvtYSomjyOE9pCCzdwQE7L
2894WFkBejIUtuRsmtO5KjYY0IEM4C0E7WMfCNBxLkSJSwg9xcMziOGS4lwSAOw0C8B4CJCWHBcBV5IH
2895UiywAQc083YIuEM0xpZbf4pnPI8digdGV68QfHME/ntrBTsCUysjRDYYGaLJ934bVClRLbPGxR03
2896JBKBC0hOAwoQETIaQFFp+OREOyrPaRUAghKI4AMc4G4IOjBeWWABIzBdSDSa8Dd9RsuNAgDAWgFQ
2897mWnZ6Rn6gEhmPOHBIlbgHoHTQ3qrpDBrkKco0x3KgQ/aNBF0YHJtQ2AcbjuHrvBhIH0AW4YrS6IH
2898uoSHmMiQWnghDzcszEhFwtAinjOU1JJnHn0VgS2d9t0LXOA15C3Pith0iRU3hlQEi0ll1/o6Ue0D
2899xM+oGRTK1oAI5KYA+OFFiIWYGdPWQx63GRsd2uc0EBxUb+VSDcfIeg1qnA/IK/6b7DAaAABUsFQ8
2900/hwchkykJgMIgDd5zXMfbCJEJv8XRbmtgwK2fGgDf2ByyoPDsMiqpp4qoETnOzPhKLittWb0asEW
2901YjAW4YkCcMtZ+ronUeXSFVTf2s/tQ6wIwFyuGbljR+JCwhQCNcQyFnVPQc0ohpDEDYcA+QkNAJEC
2902KpCBvm1QLIrgA6TLeIie5gFvJjhBCTJAAUdpp2+YGjAk5JyZnIgYOduqtAPPEukK61rSCKCMsxTz
2903CAeIr42DM25O/AyFEiyU37DonIPk0RYfVYIBZwZIvS3sIcpW9ntHnvOK6QQFA1x6lIqoCQOQsafh
2904UIvYBzl3OAOYBe0QxlYa6yc2KMHtlQ8Rs/B5/rll4Rtdgzw9AcnxeR/0S8HhwJU9eaDoEkoAgg5c
2905oFxXueJExOQgbGybKPkqNSa6YidjgGidqxpue6Y8kAS005ltJMTX1itPfjwwCsPew8g4YBFhVfMi
2906a/ACxCqVC3T+yL+cwHVRY5b3771n2BpKrgNbtY/kcm1gZLEgpynpBBqKoK5fUkOkZGOgv+6HP0PJ
2907x8Ezffe8N1DenJxzifaFCHaG6B8LaFLqv756hJRaWSDwAAc2kIEMfLkLtVfTxvoZiVxMVVBVVksi
2908XL7OBgbCjSzT0IoFUNCsr2pbCThcWZr/9B/DN3TV10D1Cyu5ReUFaVIHH5KLLYqgIUzrAMmP/jjw
2909jjKgBP06ihj2gADWoJkaSDIYwI1Sr/CK64JwBzhMgGQm5y/CwQIwYLG4IAxoAxRyQcnoTAj8CwFt
2910ZvPwhE8koz4yEE/QbF8EAC0I5gFsZ2vm4zdYL0PAp8Fs7Sf+SzRM4zUgDA4i4SF+gyh+AjhAI7cs
2911A2Va5XAcqPmE6EnmQxBCJLRQBWEEzxAQwa0OwG9aj0M2YQGM4grCYDZIDA1BiqekwA86oR6QzEO8
2912jj4wTjQOQJhmxpkgQBn6sAw1jc/cSrI2q8IOoBdUEPIywkp+4VkeobTCxsrQkLj+sB/Kpx8OQAsc
2913AKMOJkQMAAKW7RPpL+M6sE4yED6KQTnWbKCqjGIOKAEC8KEa6GSDDEMB0I8IeOFvVudOggjOHrAA
2914TEkWCCC4hMlJULEBBK8sIGNUBsIDgaM+cu57dMee4g5ePqEacIEndAtLCIfKnkXjXqJm4CzwaAUC
2915BPGSvMYA5AHOMK4a0e0aDyAIAAA7
2916"
2917
2918#
2919# ----------------------------------------------------------------------
2920#
2921
2922catch { set COPYING "#		    GNU GENERAL PUBLIC LICENSE\n\
2923#		       Version 2, June 1991\n\
2924#\n\
2925# Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n\
2926#                          675 Mass Ave, Cambridge, MA 02139, USA\n\
2927# Everyone is permitted to copy and distribute verbatim copies\n\
2928# of this license document, but changing it is not allowed.\n\
2929#\n\
2930#			    Preamble\n\
2931#\n\
2932#  The licenses for most software are designed to take away your\n\
2933#freedom to share and change it.  By contrast, the GNU General Public\n\
2934#License is intended to guarantee your freedom to share and change free\n\
2935#software--to make sure the software is free for all its users.  This\n\
2936#General Public License applies to most of the Free Software\n\
2937#Foundation's software and to any other program whose authors commit to\n\
2938#using it.  (Some other Free Software Foundation software is covered by\n\
2939#the GNU Library General Public License instead.)  You can apply it to\n\
2940#your programs, too.\n\
2941#\n\
2942#  When we speak of free software, we are referring to freedom, not\n\
2943#price.  Our General Public Licenses are designed to make sure that you\n\
2944#have the freedom to distribute copies of free software (and charge for\n\
2945#this service if you wish), that you receive source code or can get it\n\
2946#if you want it, that you can change the software or use pieces of it\n\
2947#in new free programs; and that you know you can do these things.\n\
2948#\n\
2949#  To protect your rights, we need to make restrictions that forbid\n\
2950#anyone to deny you these rights or to ask you to surrender the rights.\n\
2951#These restrictions translate to certain responsibilities for you if you\n\
2952#distribute copies of the software, or if you modify it.\n\
2953#\n\
2954#  For example, if you distribute copies of such a program, whether\n\
2955#gratis or for a fee, you must give the recipients all the rights that\n\
2956#you have.  You must make sure that they, too, receive or can get the\n\
2957#source code.  And you must show them these terms so they know their\n\
2958#rights.\n\
2959#\n\
2960#  We protect your rights with two steps: (1) copyright the software, and\n\
2961#(2) offer you this license which gives you legal permission to copy,\n\
2962#distribute and/or modify the software.\n\
2963#\n\
2964#  Also, for each author's protection and ours, we want to make certain\n\
2965#that everyone understands that there is no warranty for this free\n\
2966#software.  If the software is modified by someone else and passed on, we\n\
2967#want its recipients to know that what they have is not the original, so\n\
2968#that any problems introduced by others will not reflect on the original\n\
2969#authors' reputations.\n\
2970#\n\
2971#  Finally, any free program is threatened constantly by software\n\
2972#patents.  We wish to avoid the danger that redistributors of a free\n\
2973#program will individually obtain patent licenses, in effect making the\n\
2974#program proprietary.  To prevent this, we have made it clear that any\n\
2975#patent must be licensed for everyone's free use or not licensed at all.\n\
2976#\n\
2977#  The precise terms and conditions for copying, distribution and\n\
2978#modification follow.\n\
2979#\n\
2980#		    GNU GENERAL PUBLIC LICENSE\n\
2981#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\
2982#\n\
2983#  0. This License applies to any program or other work which contains\n\
2984#a notice placed by the copyright holder saying it may be distributed\n\
2985#under the terms of this General Public License.  The \"Program\", below,\n\
2986#refers to any such program or work, and a \"work based on the Program\"\n\
2987#means either the Program or any derivative work under copyright law:\n\
2988#that is to say, a work containing the Program or a portion of it,\n\
2989#either verbatim or with modifications and/or translated into another\n\
2990#language.  (Hereinafter, translation is included without limitation in\n\
2991#the term \"modification\".)  Each licensee is addressed as \"you\".\n\
2992#\n\
2993#Activities other than copying, distribution and modification are not\n\
2994#covered by this License; they are outside its scope.  The act of\n\
2995#running the Program is not restricted, and the output from the Program\n\
2996#is covered only if its contents constitute a work based on the\n\
2997#Program (independent of having been made by running the Program).\n\
2998#Whether that is true depends on what the Program does.\n\
2999#\n\
3000#  1. You may copy and distribute verbatim copies of the Program's\n\
3001#source code as you receive it, in any medium, provided that you\n\
3002#conspicuously and appropriately publish on each copy an appropriate\n\
3003#copyright notice and disclaimer of warranty; keep intact all the\n\
3004#notices that refer to this License and to the absence of any warranty;\n\
3005#and give any other recipients of the Program a copy of this License\n\
3006#along with the Program.\n\
3007#\n\
3008#You may charge a fee for the physical act of transferring a copy, and\n\
3009#you may at your option offer warranty protection in exchange for a fee.\n\
3010#\n\
3011#  2. You may modify your copy or copies of the Program or any portion\n\
3012#of it, thus forming a work based on the Program, and copy and\n\
3013#distribute such modifications or work under the terms of Section 1\n\
3014#above, provided that you also meet all of these conditions:\n\
3015#\n\
3016#    a) You must cause the modified files to carry prominent notices\n\
3017#    stating that you changed the files and the date of any change.\n\
3018#\n\
3019#    b) You must cause any work that you distribute or publish, that in\n\
3020#    whole or in part contains or is derived from the Program or any\n\
3021#    part thereof, to be licensed as a whole at no charge to all third\n\
3022#    parties under the terms of this License.\n\
3023#\n\
3024#    c) If the modified program normally reads commands interactively\n\
3025#    when run, you must cause it, when started running for such\n\
3026#    interactive use in the most ordinary way, to print or display an\n\
3027#    announcement including an appropriate copyright notice and a\n\
3028#    notice that there is no warranty (or else, saying that you provide\n\
3029#    a warranty) and that users may redistribute the program under\n\
3030#    these conditions, and telling the user how to view a copy of this\n\
3031#    License.  (Exception: if the Program itself is interactive but\n\
3032#    does not normally print such an announcement, your work based on\n\
3033#    the Program is not required to print an announcement.)\n\
3034#\n\
3035#These requirements apply to the modified work as a whole.  If\n\
3036#identifiable sections of that work are not derived from the Program,\n\
3037#and can be reasonably considered independent and separate works in\n\
3038#themselves, then this License, and its terms, do not apply to those\n\
3039#sections when you distribute them as separate works.  But when you\n\
3040#distribute the same sections as part of a whole which is a work based\n\
3041#on the Program, the distribution of the whole must be on the terms of\n\
3042#this License, whose permissions for other licensees extend to the\n\
3043#entire whole, and thus to each and every part regardless of who wrote it.\n\
3044#\n\
3045#Thus, it is not the intent of this section to claim rights or contest\n\
3046#your rights to work written entirely by you; rather, the intent is to\n\
3047#exercise the right to control the distribution of derivative or\n\
3048#collective works based on the Program.\n\
3049#\n\
3050#In addition, mere aggregation of another work not based on the Program\n\
3051#with the Program (or with a work based on the Program) on a volume of\n\
3052#a storage or distribution medium does not bring the other work under\n\
3053#the scope of this License.\n\
3054#\n\
3055#  3. You may copy and distribute the Program (or a work based on it,\n\
3056#under Section 2) in object code or executable form under the terms of\n\
3057#Sections 1 and 2 above provided that you also do one of the following:\n\
3058#\n\
3059#    a) Accompany it with the complete corresponding machine-readable\n\
3060#    source code, which must be distributed under the terms of Sections\n\
3061#    1 and 2 above on a medium customarily used for software interchange; or,\n\
3062#\n\
3063#    b) Accompany it with a written offer, valid for at least three\n\
3064#    years, to give any third party, for a charge no more than your\n\
3065#    cost of physically performing source distribution, a complete\n\
3066#    machine-readable copy of the corresponding source code, to be\n\
3067#    distributed under the terms of Sections 1 and 2 above on a medium\n\
3068#    customarily used for software interchange; or,\n\
3069#\n\
3070#    c) Accompany it with the information you received as to the offer\n\
3071#    to distribute corresponding source code.  (This alternative is\n\
3072#    allowed only for noncommercial distribution and only if you\n\
3073#    received the program in object code or executable form with such\n\
3074#    an offer, in accord with Subsection b above.)\n\
3075#\n\
3076#The source code for a work means the preferred form of the work for\n\
3077#making modifications to it.  For an executable work, complete source\n\
3078#code means all the source code for all modules it contains, plus any\n\
3079#associated interface definition files, plus the scripts used to\n\
3080#control compilation and installation of the executable.  However, as a\n\
3081#special exception, the source code distributed need not include\n\
3082#anything that is normally distributed (in either source or binary\n\
3083#form) with the major components (compiler, kernel, and so on) of the\n\
3084#operating system on which the executable runs, unless that component\n\
3085#itself accompanies the executable.\n\
3086#\n\
3087#If distribution of executable or object code is made by offering\n\
3088#access to copy from a designated place, then offering equivalent\n\
3089#access to copy the source code from the same place counts as\n\
3090#distribution of the source code, even though third parties are not\n\
3091#compelled to copy the source along with the object code.\n\
3092#\n\
3093#  4. You may not copy, modify, sublicense, or distribute the Program\n\
3094#except as expressly provided under this License.  Any attempt\n\
3095#otherwise to copy, modify, sublicense or distribute the Program is\n\
3096#void, and will automatically terminate your rights under this License.\n\
3097#However, parties who have received copies, or rights, from you under\n\
3098#this License will not have their licenses terminated so long as such\n\
3099#parties remain in full compliance.\n\
3100#\n\
3101#  5. You are not required to accept this License, since you have not\n\
3102#signed it.  However, nothing else grants you permission to modify or\n\
3103#distribute the Program or its derivative works.  These actions are\n\
3104#prohibited by law if you do not accept this License.  Therefore, by\n\
3105#modifying or distributing the Program (or any work based on the\n\
3106#Program), you indicate your acceptance of this License to do so, and\n\
3107#all its terms and conditions for copying, distributing or modifying\n\
3108#the Program or works based on it.\n\
3109#\n\
3110#  6. Each time you redistribute the Program (or any work based on the\n\
3111#Program), the recipient automatically receives a license from the\n\
3112#original licensor to copy, distribute or modify the Program subject to\n\
3113#these terms and conditions.  You may not impose any further\n\
3114#restrictions on the recipients' exercise of the rights granted herein.\n\
3115#You are not responsible for enforcing compliance by third parties to\n\
3116#this License.\n\
3117#\n\
3118#  7. If, as a consequence of a court judgment or allegation of patent\n\
3119#infringement or for any other reason (not limited to patent issues),\n\
3120#conditions are imposed on you (whether by court order, agreement or\n\
3121#otherwise) that contradict the conditions of this License, they do not\n\
3122#excuse you from the conditions of this License.  If you cannot\n\
3123#distribute so as to satisfy simultaneously your obligations under this\n\
3124#License and any other pertinent obligations, then as a consequence you\n\
3125#may not distribute the Program at all.  For example, if a patent\n\
3126#license would not permit royalty-free redistribution of the Program by\n\
3127#all those who receive copies directly or indirectly through you, then\n\
3128#the only way you could satisfy both it and this License would be to\n\
3129#refrain entirely from distribution of the Program.\n\
3130#\n\
3131#If any portion of this section is held invalid or unenforceable under\n\
3132#any particular circumstance, the balance of the section is intended to\n\
3133#apply and the section as a whole is intended to apply in other\n\
3134#circumstances.\n\
3135#\n\
3136#It is not the purpose of this section to induce you to infringe any\n\
3137#patents or other property right claims or to contest validity of any\n\
3138#such claims; this section has the sole purpose of protecting the\n\
3139#integrity of the free software distribution system, which is\n\
3140#implemented by public license practices.  Many people have made\n\
3141#generous contributions to the wide range of software distributed\n\
3142#through that system in reliance on consistent application of that\n\
3143#system; it is up to the author/donor to decide if he or she is willing\n\
3144#to distribute software through any other system and a licensee cannot\n\
3145#impose that choice.\n\
3146#\n\
3147#This section is intended to make thoroughly clear what is believed to\n\
3148#be a consequence of the rest of this License.\n\
3149#\n\
3150#  8. If the distribution and/or use of the Program is restricted in\n\
3151#certain countries either by patents or by copyrighted interfaces, the\n\
3152#original copyright holder who places the Program under this License\n\
3153#may add an explicit geographical distribution limitation excluding\n\
3154#those countries, so that distribution is permitted only in or among\n\
3155#countries not thus excluded.  In such case, this License incorporates\n\
3156#the limitation as if written in the body of this License.\n\
3157#\n\
3158#  9. The Free Software Foundation may publish revised and/or new versions\n\
3159#of the General Public License from time to time.  Such new versions will\n\
3160#be similar in spirit to the present version, but may differ in detail to\n\
3161#address new problems or concerns.\n\
3162#\n\
3163#Each version is given a distinguishing version number.  If the Program\n\
3164#specifies a version number of this License which applies to it and \"any\n\
3165#later version\", you have the option of following the terms and conditions\n\
3166#either of that version or of any later version published by the Free\n\
3167#Software Foundation.  If the Program does not specify a version number of\n\
3168#this License, you may choose any version ever published by the Free Software\n\
3169#Foundation.\n\
3170#\n\
3171#  10. If you wish to incorporate parts of the Program into other free\n\
3172#programs whose distribution conditions are different, write to the author\n\
3173#to ask for permission.  For software which is copyrighted by the Free\n\
3174#Software Foundation, write to the Free Software Foundation; we sometimes\n\
3175#make exceptions for this.  Our decision will be guided by the two goals\n\
3176#of preserving the free status of all derivatives of our free software and\n\
3177#of promoting the sharing and reuse of software generally.\n\
3178#\n\
3179#			    NO WARRANTY\n\
3180#\n\
3181#  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n\
3182#FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n\
3183#OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n\
3184#PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n\
3185#OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n\
3186#MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n\
3187#TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n\
3188#PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n\
3189#REPAIR OR CORRECTION.\n\
3190#\n\
3191#  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n\
3192#WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n\
3193#REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n\
3194#INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n\
3195#OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n\
3196#TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n\
3197#YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n\
3198#PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n\
3199#POSSIBILITY OF SUCH DAMAGES.\n\
3200#\n\
3201#		     END OF TERMS AND CONDITIONS\n\
3202#\n\
3203#	Appendix: How to Apply These Terms to Your New Programs\n\
3204#\n\
3205#  If you develop a new program, and you want it to be of the greatest\n\
3206#possible use to the public, the best way to achieve this is to make it\n\
3207#free software which everyone can redistribute and change under these terms.\n\
3208#\n\
3209#  To do so, attach the following notices to the program.  It is safest\n\
3210#to attach them to the start of each source file to most effectively\n\
3211#convey the exclusion of warranty; and each file should have at least\n\
3212#the \"copyright\" line and a pointer to where the full notice is found.\n\
3213#\n\
3214#    <one line to give the program's name and a brief idea of what it does.>\n\
3215#    Copyright (C) 19yy  <name of author>\n\
3216#\n\
3217#    This program is free software; you can redistribute it and/or modify\n\
3218#    it under the terms of the GNU General Public License as published by\n\
3219#    the Free Software Foundation; either version 2 of the License, or\n\
3220#    (at your option) any later version.\n\
3221#\n\
3222#    This program is distributed in the hope that it will be useful,\n\
3223#    but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
3224#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
3225#    GNU General Public License for more details.\n\
3226#\n\
3227#    You should have received a copy of the GNU General Public License\n\
3228#    along with this program; if not, write to the Free Software\n\
3229#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
3230#\n\
3231#Also add information on how to contact you by electronic and paper mail.\n\
3232#\n\
3233#If the program is interactive, make it output a short notice like this\n\
3234#when it starts in an interactive mode:\n\
3235#\n\
3236#    Gnomovision version 69, Copyright (C) 19yy name of author\n\
3237#    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n\
3238#    This is free software, and you are welcome to redistribute it\n\
3239#    under certain conditions; type `show c' for details.\n\
3240#\n\
3241#The hypothetical commands `show w' and `show c' should show the appropriate\n\
3242#parts of the General Public License.  Of course, the commands you use may\n\
3243#be called something other than `show w' and `show c'; they could even be\n\
3244#mouse-clicks or menu items--whatever suits your program.\n\
3245#\n\
3246#You should also get your employer (if you work as a programmer) or your\n\
3247#school, if any, to sign a \"copyright disclaimer\" for the program, if\n\
3248#necessary.  Here is a sample; alter the names:\n\
3249#\n\
3250#  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n\
3251#  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\
3252#\n\
3253#  <signature of Ty Coon>, 1 April 1989\n\
3254#  Ty Coon, President of Vice\n\
3255#\n\
3256#This General Public License does not permit incorporating your program into\n\
3257#proprietary programs.  If your program is a subroutine library, you may\n\
3258#consider it more useful to permit linking proprietary applications with the\n\
3259#library.  If this is what you want to do, use the GNU Library General\n\
3260#Public License instead of this License.\n\
3261#\n\
3262#"
3263}
3264
3265
3266#
3267# ----------------------------------------------------------------------
3268#
3269
3270#
3271# set a trace on OptionDesperate, because the FileList might change
3272# with desperateness
3273#
3274
3275proc VarTrace { name element op } { ShowFileList }
3276trace variable OptionDesperate w VarTrace
3277
3278#
3279# Set Window title
3280#
3281
3282wm minsize . 300 250
3283wm title . "UUDeview for X"
3284
3285#
3286# Set Message Callback
3287#
3288
3289uu_SetMessageProc DisplayMessage
3290
3291#
3292# Set Busy Callback: update every 100 msecs
3293#
3294
3295uu_SetBusyProc WeAreBusy 100
3296
3297#
3298# Handle Command line arguments
3299#
3300
3301set FilesToLoad {}
3302set setpath 0
3303
3304foreach arg $argv {
3305    if { $setpath } {
3306	set setpath 0
3307	set SaveFilePath $arg
3308    }
3309    if { [ string index $arg 0 ] == "-" } {
3310	switch [ string index $arg 1 ] {
3311	    f { set OptionFast 1 }
3312	    b { set OptionBracket 1 }
3313	    o { set OptionOverwrite 1 }
3314	    d { set OptionDesperate 1 }
3315	    v { set OptionVerbose 0 }
3316	    p { set setpath 1 }
3317	    s { set OptionDumbness 1 }
3318	    t { set OptionUsetext 1 }
3319	    z { set OptionMoreMime 1 }
3320	    c { set OptionRemove 1 }
3321	    default {
3322		tk_dialog ._Dialog { Invalid Switch } "Invalid switch\
3323			found on command line: $arg" warning 0 OK
3324	    }
3325	}
3326    } else {
3327	lappend FilesToLoad $arg
3328    }
3329}
3330
3331if { $FilesToLoad != {} } {
3332    LoadFiles $FilesToLoad
3333    ShowFileList
3334    if { $OptionVerbose } {
3335	DumpFileList
3336    }
3337}
3338
3339#
3340# Initialize Listbox
3341#
3342
3343ShowFileList
3344
3345#
3346# go into event loop
3347#
3348
3349vwait forever
3350