#!/usr/local/bin/wish -f
#!/bin/sh
# exec wish -f "$0" "$@"
#
# This TCL-TK script generates a simple file selector box and
# returns the selected file as string
#
# Programmer: Rainer Kowallik
# Version:    2.0
#

# First we have to catch the tk 4.x Listbox and Entry bindings
#
if {$tk_version >= 4.0} {
bind Entry <ButtonRelease-2> {}
bind Entry <Left> {}
bind Entry <Right> {}

bind Listbox <1> {}
}
bind Entry <Control-k> {%W delete 0 end}
bind Entry <Left> {EntryCursor %W -1}
bind Entry <Right> {EntryCursor %W 1}
bind Entry <2> {%W insert insert "[GetXSelect]"}

frame .c1
pack .c1 -side top
label .labeldir -text "Directory:"
button .parent -text "Parent" -command { cdto ".." ; ChDir}
button .home -text "Home" -command { cdto "HOME" ; ChDir }
button .root -text "Root" -command { cdto "/" ; ChDir }
button .lastdir -text "Last" -command {GotoLast}
pack .labeldir .parent .home .root .lastdir\
         -side left -in .c1 -padx 2m -pady 2m

entry .dirname -width 40 -relief sunken -bd 2 -textvariable DirName
pack  .dirname -side top -after .c1 -fill x -padx 1m -pady 2m

frame .c2
pack .c2 -side bottom
label .labelfile -text "File:"
button .delete -text "Delete" -command Delete
button .rmdir -text "rmdir" -command RmDir
button .mkdir -text "mkdir" -command MakeDir
button .rename -text "Rename" -command Rename
button .view -text "View" -command ViewFile
pack .labelfile .view .delete .rmdir .mkdir .rename \
         -side left -in .c2 -padx 2m -pady 2m

entry .filename -width 40 -relief sunken -bd 2 \
                 -textvariable FileName 
pack  .filename -side bottom -before .c2 \
                 -fill x -padx 1m -pady 2m

frame .c3
pack .c3 -side bottom -before .filename
label .lpatt -text "show:"
entry .pattern -width 10  -relief sunken -bd 2 -textvariable Pattern
button .ok -text "OK" -command AcceptSelection
button .cancel -text "Cancel" -command exit
pack .lpatt .pattern .ok .cancel -side left -in .c3 -padx 3m -pady 2m

listbox .dirs -relief raised -borderwidth 2 \
		-yscrollcommand ".scrolldir set" \
                -setgrid 1
pack .dirs -side left -expand 1 -fill both
scrollbar .scrolldir -command ".dirs yview"
pack .scrolldir -side left -after .dirs -fill y

listbox .files -relief raised -borderwidth 2 \
		-yscrollcommand ".scrollfile set" \
                -setgrid 1
pack .files -side right -expand 1 -fill both
scrollbar .scrollfile -command ".files yview"
pack .scrollfile -side right -before .files -fill y

bind .filename <Return> AcceptSelection
bind .dirname <Return> ChDir

bind .files <1> {
  MarkSelect %W @%x,%y
}
bind .dirs <1> {
  MarkSelect %W @%x,%y
}
bind .files <Double-Button-1> {
    AcceptSelection
    }
bind .pattern <Return> ChDir
# bind .dirs <Double-Button-1> DirSelection

proc EntryCursor {w dir} {
   set x [$w index insert]
   set x [expr $x + $dir]
   $w icursor $x
}

proc GetXSelect { } {

   set s ""   
   catch {set s [selection get STRING]}
   return "$s"
}

proc ChDir { } {
        global DirName Pattern
        cd $DirName
        .dirs delete 0 end
        .files delete 0 end
        .dirs insert end ".."
        if {[catch {set allfiles [glob *]}]} {return}
        foreach i [lsort $allfiles] {
           if { [file isdirectory $i] } {
              .dirs insert end $i
           } else {
	      if {[string match $Pattern $i]} {.files insert end $i}
           }
        }
}

proc DoCmd command {
   global DirName FileName
   
   set s $DirName
   set l [string length $s]
   if {$l > 0} {set s ${s}/}
   regsub -all "%" $command "${s}${FileName}" cmd
   eval $cmd
   set f [open "~/.lastdir" w]
   puts $f $s
   close $f
}

proc AcceptSelection { } {
        global DirName FileName command1
        
        if {$command1 != ""} {DoCmd $command1 ; return}
        set s $DirName
        set l [string length $s]
        if {$l > 0} {set s ${s}/}
        puts ${s}${FileName}
        set f [open "~/.lastdir" w]
        puts $f $s
        close $f
        exit
}

proc MarkSelect {win pos} {
   global DirName FileName tk_version
   if {$tk_version >= 4.0} {
      $win selection clear active
      $win selection set [$win index $pos]
   } else {
      set y [lindex [split $pos ","] 1]
      $win select from [$win nearest $y]
   }
   switch $win {
      ".dirs" {DirSelection}
      ".files" {FileSelection}
   }
}

proc FileSelection { } {
        global DirName FileName
        set f [.files curselection]
        set FileName [.files get $f]
}

proc DirSelection { } {
        global DirName FileName
        set f [.dirs curselection]
        set d [.dirs get $f]
        cd $d
        set DirName [pwd]
        ChDir
}

proc GotoLast { } {

   if {![catch {set f [open "~/.lastdir" r]}]} {
      gets $f dir
      cdto "$dir" ; ChDir
   }
}

proc cdto dir { 
        global DirName FileName
        if { $dir == "HOME" } { cd } else { cd $dir }
        set DirName [pwd]
        ChDir
}

proc RmDir { } {
   global DirName FileName
   
   set s "exec rmdir $DirName"
   cdto ".."
   eval $s
   ChDir
}

proc Delete { } {
   global DirName FileName
   
   set s "exec rm $FileName"
   set FileName ""
   eval $s
   ChDir
}

proc Rename { } {
   global DirName FileName OldName
   
   set OldName $FileName
   set FileName ""
   focus .filename
   bind .filename <Return> DoRename
}

proc DoRename { } {
   global DirName FileName OldName
   
   set s "exec mv $OldName $FileName"
   set FileName ""
   eval $s
   bind .filename <Return> AcceptSelection
   ChDir
}

proc MakeDir { } {
   global DirName FileName
   
   set FileName ""
   focus .filename
   bind .filename <Return> DoMakeDir
}

proc DoMakeDir { } {
   global DirName FileName
   
   set s "exec mkdir $FileName"
   set FileName ""
   eval $s
   bind .filename <Return> AcceptSelection
   ChDir
}

proc ViewFile { } {
   global DirName FileName
   
   OpenTextWin
   set fp [open $FileName]
   while {![eof $fp]} {
      .help.win insert end [read $fp 8192]
   }
   close $fp
}

proc OpenTextWin { } {
   global env 

   catch {destroy .help}
   toplevel .help -class Dialog
   frame .help.top -relief raised -bd 1
   pack .help.top -side top -expand 1 -fill both
   frame .help.bot -relief raised -bd 1
   pack .help.bot -side bottom -fill x
   text .help.win -width 80 -height 24 \
         -setgrid 1 -bg white -fg black \
         -yscrollcommand ".help.scroll set"
   pack .help.win -in .help.top -side left -expand 1 -fill both
   scrollbar .help.scroll -command ".help.win yview" 
   pack .help.scroll -in .help.top -side left -fill y
   button .help.quit -text "Dismiss" -width 10  -command {destroy .help}
   button .help.edit -text "Select" -width 15 \
    -command {destroy .help ; AcceptSelection}
   pack .help.quit .help.edit -in .help.bot -side left -expand 1 -fill x
   wm maxsize .help 200 100
   wm minsize .help 10 2
}

set i [lsearch $argv "-patt"]
if {$i >= 0} {
   incr i
   set Pattern [lindex $argv $i]
} else {
   set Pattern "*"  
}

set i [lsearch $argv "-dir"]
if {$i >= 0} {
   incr i
   cdto [lindex $argv $i]
} else {
   set DirName [pwd]
   ChDir
}

set command1 ""
set i [lsearch $argv "-cmd1"]
if {$i >= 0} {
   incr i
   set text1 [lindex $argv $i]
   incr i
   set command1 [lindex $argv $i]
   button .cmd1 -text  $text1 -command {DoCmd $command1}
   pack .cmd1 -side left -in .c3
   pack forget .ok
}
set i [lsearch $argv "-cmd2"]
if {$i >= 0} {
   incr i
   set text2 [lindex $argv $i]
   incr i
   set command2 [lindex $argv $i]
   button .cmd2 -text  $text2 -command {DoCmd $command2}
   pack .cmd2 -side left -in .c3
}

focus .filename

set DoExecute ""

