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 " 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 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