# Path dialog module.
# Rick Smereka, Copyright (C) 2004-2005.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, get a copy via the Internet at
# http://gnu.org/copyleft/gpl.html or write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA

# You can contact the author via email at rsmereka@future-lab.com

# Initial tcl version. Feb/2004, Rick Smereka
global prevpath curpath

proc pathdlg {start_path} {
   # Get a directory path from the user
   # by presenting a dialog. Returns the
   # path upon success, an empty string
   # otherwise.
   global prevpath curpath ad_close
   set ret ""

   # check for already existing path dialog
   # window open
   if {[winfo exists .pathdialog]} {
      focus .pathdialog
      return $ret
   }

   if {$start_path == ""} {
      return ret
   }

   set ad_close -1

   # set starting point
   set curpath $start_path

   # save current path
   set prevpath [pwd]
   cd $start_path

   # create dialog window
   set dlg .pathdialog
   toplevel $dlg
   wm protocol $dlg WM_DELETE_WINDOW "set ad_close 0"
   wm title $dlg "Choose a directory"

   # current path display
   set fr $dlg.pdisp
   frame $fr -bd 1 -relief groove
   label $fr.curdir -text "Dir" -anchor w
   pack $fr.curdir -fill x
   pack $fr -fill x

   set fr $dlg.buttons
   frame $fr -bd 1 -relief raised
   button $fr.up -text "Up" -command go_up
   button $fr.ok -text "Ok" -command "set ad_close 1" \
      -default active
   bind all <Key-Return> "set ad_close 1"
   button $fr.cancel -text "Cancel" -command "set ad_close 0"
   pack $fr.up $fr.ok $fr.cancel -side left -fill x -expand true
   pack $fr -fill x

   set fr $dlg.flist
   frame $fr -bd 0
   listbox $fr.list -height 10 \
      -selectmode single \
      -yscrollcommand "$fr.scroll set"
   scrollbar $fr.scroll -command "$fr.list yview"
   pack $fr.scroll -side right -fill y
   pack $fr.list -side left -fill both -expand true
   pack $fr -side bottom -fill both -expand true

   bind $dlg.flist.list <Double-Button-1> {
      # change dir on double-click
      set diritem [.pathdialog.flist.list curselection]
      set dir [.pathdialog.flist.list get $diritem]

      # change directories
      cd $dir

      # fill lists
      read_dir .pathdialog.flist.list
   }

   # initial read
   read_dir $dlg.flist.list

   focus $dlg
   update

   # make this a model dialog
   tkwait variable ad_close

   # destory dialog
   destroy $dlg

   # restore original path
   cd $prevpath

   # return appropriate value
   if {$ad_close} {
      set ret $curpath
      return $ret
   }

   return $ret
}

proc read_dir {dirlist} {
   # Fill list with directory names. Returns nothing.
   global curpath

   # clear listbox
   $dirlist delete 0 end

   set unsorted [glob -nocomplain *]

   if {$unsorted != ""} {
      set files [lsort $unsorted]

      # separate out directories
      foreach filename $files {
         if {[file isdirectory $filename] != 0} {
            # is a directory
            $dirlist insert end "$filename"
         }
      }
   }

   # now store current directory in label
   # and in global
   .pathdialog.pdisp.curdir configure -text [pwd]
   set curpath [pwd]
}

proc go_up {} {
   # Go up one directory. Returns nothing.
   cd ..

   # read directory
   read_dir .pathdialog.flist.list
}
