#!/usr/local/bin/wish4.0
# jbrowser - Tk/Tcl-based directory browser
#
######################################################################
# Copyright 1992-1995 by Jay Sekora.  This file may be freely        #
# distributed, modified or unmodified, for any purpose, provided     #
# that this copyright notice is retained verbatim in all copies and  #
# no attempt is made to obscure the authorship of this file.  If you #
# distribute any modified versions, I ask, but do not require, that  #
# you clearly mark any changes you make as such and that you provide #
# your users with instructions for getting the original sources.     #
######################################################################
## begin boiler_header

if {[info exists env(JSTOOLS_LIB)]} {
  set jstools_library $env(JSTOOLS_LIB)
} else {
  set jstools_library /usr/local/lib/jstools
}

# add the jstools library to the library search path:

set auto_path [concat [list $jstools_library] $auto_path]

# check for ~/.tk and prepend it to the auto_path if it exists.
# that way the user can override and customise the jstools libraries.

if {[file isdirectory ~/.tk]} then {
  set auto_path [concat [list [glob ~/.tk]] $auto_path]
}

## end boiler_header

# URGENT:
#   rewrite to use plain paths
#   divide into libraries (gui, commands, etc.)
#   exportselection false

# TO DO:
#
# implement paul's idea of a `storage area' for files
#
# `fast' pref to skip directory check (/)
# use the right mouse button in the browser for something.
# make the information display more informative and prettier.
# jbr:configure_browser

######################################################################
# jbr:mkcolumn w - make a directory-column frame named $w
#    TO DO: args for label and initial contents
######################################################################

proc jbr:mkcolumn {w} {
  global env HOME USER
  global J_PREFS
  if {[lsearch [array names J_PREFS] {scrollbarside}] == -1} {
    set J_PREFS(scrollbarside) right ;# make sure it's defined
  }
  
  frame $w
  set label $w.l
  set lb $w.lb
  set sb $w.sb
  
  # actually, the exact value of -width doesn't matter, as long as it doesn't
  # make the label bigger than the listbox+scrollbar, because the label will
  # expand to the size of the parent window.  but specifying -width prevents
  # the label from expanding larger than the parent window and making the
  # whole top level window resize itself.
  
  label $label \
    -anchor center \
    -width 10 \
    -relief flat
  scrollbar $sb \
    -relief flat \
    -command "$lb yview"
  listbox $lb \
    -borderwidth 0 \
    -exportselection 0 \
    -yscroll "$sb set"
  j:tk3 {
    $lb configure -geometry 20x20
  }
  j:tk4 {
    $lb configure -width 20 -height 20
    $lb configure -selectmode extended
  }
  
  pack $label [j:rule $w] -in $w -side top -fill x
  pack $sb [j:rule $w] -in $w -side $J_PREFS(scrollbarside) -fill y
  pack $lb -in $w -side $J_PREFS(scrollbarside) -fill both -expand yes
  
  return $w
}

######################################################################
# jbr:emptycolumn w - clear column w
######################################################################

proc jbr:emptycolumn {w} {
  set label $w.l
  set lb $w.lb
  
  $label configure -text " "
  $lb delete 0 end
}

######################################################################
# jbr:fill_column w dir - fill column w with contents of dir
######################################################################

proc jbr:fill_column {w dir} {
  set label $w.l
  set lb $w.lb
  set sb $w.sb
  
  set COLDIR($w) $dir
  
  $lb delete 0 end
  $lb insert end ..
  
  set files [lsort [glob -nocomplain $dir/*]]
  if {1} {					;# pref. to show hidden
    eval lappend files [lsort [glob -nocomplain $dir/.*]]
  }
  
  set dirtail [file tail $dir]
  if {[string length $dirtail] == 0} {
    set dirtail "/"
  }
  $label configure -text $dirtail
  
  foreach path $files {
    set file [file tail $path]
    if {"x$file" != "x." && "x$file" != "x.."} {
      $lb insert end $file
    }
  }
}

######################################################################
# jbr:fill_window w dir - fill window $w with contents of dir
######################################################################

proc jbr:fill_window {w dir} {
  global WINDIR
  set WINDIR($w) dir
  
  set done 0
  for {set level 0} {[winfo exists $w.col$level]} {incr level} {
    set thisdir [j:path:ancestor $level $dir]
    if {$done} {
      jbr:emptycolumn $w.col$level
    } else {
      jbr:fill_column $w.col$level [j:path:ancestor $level $dir]
    }
    if {$thisdir == "/"} {
      set done 1
    }
  }
}

######################################################################
# jbr:mkwindow w dir ?columns? -
#   create a browser window at $dir with $columns columns shown
######################################################################

proc jbr:mkwindow {w dir {columns DEFAULT}} {
  global env HOME USER argv0
  global BROWSERPREFS
  global WINDIR
  set script [file tail $argv0]
  ####
  set BROWSERPREFS(0) 0
  ####
  j:default BROWSERPREFS(columns) 3
  
  if {"x$columns" == "xDEFAULT"} {
    set columns $BROWSERPREFS(columns)
  }
  
  set WINDIR($w) $dir
  
  toplevel $w
  wm title $w "$script"
  
  if {$w == ".jbrowser0"} {
    wm protocol $w WM_DELETE_WINDOW {if [j:confirm -text quitting] {exit 0}}
  }
  
  jbr:mkmenu $w.menu $w
  
  for {set level 0} {$level < $columns} {incr level} {
    jbr:mkcolumn $w.col$level
    if {$level != 0} {
      pack [j:rule $w] -in $w -side right -fill y
      bind $w.col$level.lb <Any-Button-1> [format {
        jbr:cd [winfo toplevel %%W] \
          [j:path:ancestor %s [jbr:pwd [winfo toplevel %%W]]] \
      } $level]
      j:tk4 {bind $w.col$level.lb <Any-Button-1> "+\nbreak"}
      bind $w.col$level.lb <ButtonRelease-1> {#nothing; catch {break}}
    } else {
      bind $w.col$level.lb <Double-1> {jbr:browse [winfo toplevel %W]}
    }
    pack $w.col$level -in $w -side right -fill y
  }
  
  jbr:mkbindings $w
  focus $w
  
  jbr:fill_window $w $dir
  
  return $w
}

######################################################################
# jbr:mkmenu mb w - create the menu frame mb for window $w
######################################################################

proc jbr:mkmenu { mb w } {
  global env HOME USER argv0
  global BROWSERPREFS
  
  jbr:register_commands
  
  frame $mb -borderwidth 2 -relief raised
  jbr:mkmenu:browser $mb.browser $w
  jbr:mkmenu:file $mb.file $w

  pack $mb.browser $mb.file -side left
  pack $mb -side top -fill x
  
  tk_menuBar $mb $mb.browser $mb.file
}
  
######################################################################
# jbr:mkmenu:browser m w - create browser menu w for window $w
######################################################################

proc jbr:mkmenu:browser { m w } {
  global env HOME USER
  
  j:menu:menubutton $m $m.m JBmenu:browser
  j:menu:commands $m.m $w {
    jbr:cmd:about
    j:cmd:global_pref_panel
    jbr:cmd:browser_prefs
    -
    jbr:cmd:up
    jbr:cmd:home
    jbr:cmd:root
    jbr:cmd:cd
    -
    j:cmd:prompt_tcl
    j:cmd:prompt_unix
    -
    jbr:cmd:refresh
    jbr:cmd:quit
  }
}
  
######################################################################
# jbr:mkmenu:file m w - create file menu $m for window $w
######################################################################

proc jbr:mkmenu:file { m w } {
  global env HOME USER
  
  menubutton $m -text {File} -menu $m.m
  menu $m.m
  $m.m add command -label {View} -accelerator {CR} \
    -command "jbr:cmd:view $w"
  $m.m add command -label {Edit} -accelerator {[e]} \
    -command "jbr:cmd:edit $w"
  $m.m add command -label {Process} -accelerator {[u]} \
    -command "jbr:cmd:process $w"
  $m.m add command -label {Print} -accelerator {[p]} \
    -command "jbr:cmd:print $w"
  $m.m add separator
  $m.m add command -label {Create Directory . . .} -accelerator {[n]} \
    -command "jbr:cmd:newdir $w"
  $m.m add command -label {Move . . .} -accelerator {[m]} \
    -command "jbr:cmd:move $w"
  $m.m add command -label {Rename . . .} -accelerator {[M]} \
    -command "jbr:cmd:rename $w"
  $m.m add command -label {Duplicate} -accelerator {[d]} \
    -command "jbr:cmd:duplicate $w"
  $m.m add command -label {Destroy} -accelerator {[r]} \
    -command "jbr:cmd:destroy $w"
  $m.m add command -label {Get Info} -accelerator {[i]} \
    -command "jbr:cmd:info $w"
  $m.m add cascade -label {Misc.} -accelerator {  >} \
    -menu $m.m.misc
  
  #####
  # $m.m add command -label {Execute} -command "jbr:cmd:execute
  # $m.m add command -label {Execute in xterm} \
  #   -command "jbr:cmd:xterm_execute
  #####
  
  menu $m.m.misc
  $m.m.misc add command -label {TeX File} -accelerator {[t]} \
    -command "jbr:cmd:tex $w"
  $m.m.misc add command -label {LaTeX File} -accelerator {[l]} \
    -command "jbr:cmd:latex $w"
  $m.m.misc add command -label {Compress File} \
    -command "jbr:cmd:compress $w"
  $m.m.misc add command -label {Tar Directory} \
    -command "jbr:cmd:maketar $w"
  $m.m.misc add command -label {Run `make' in This Directory} \
    -command "jbr:cmd:make $w"
  $m.m.misc add command -label {Edit with `jedit'} \
    -command "jbr:cmd:jedit $w"
  $m.m.misc add command -label {Edit with `xedit'} \
    -command "jbr:cmd:xedit $w"
  $m.m.misc add command -label {Print with `lpr'} \
    -command "jbr:cmd:lpr $w"

}


######################################################################
# jbr:mkbindings count w - make keyboard equivalents for commands
######################################################################

proc jbr:mkbindings { w } {
  global env HOME USER
  ############################
  ##### NOTHING HERE
  ############################
}

######################################################################

jbr:init

wm withdraw .

jbr:mkwindow [jbr:new_window_name] [pwd] 3










