#
# $Header: /home/rockware/cvs-main/operator/tcl/opDirView.tcl,v 1.39 1995/03/16 12:43:21 erez Exp $
# Written by: Erez Strauss (C) All Rights Reserved 1994, 1995.
#
#  2. DirView - Directory views support - text display of the directories.
#

itcl_class OpDirView {
    inherit OpDirDisplay

    constructor {directory config} {

        set tmp_menus "$tl_menus $dird_menus $dv_menus"

        OpDirDisplay::constructor $directory \
            -menus $tmp_menus \
            -menu_bar $dv_menubar \
            -pipe_cmd {ls -a .} \
            -iconbitmap treasure \
            -balloon_help "Directory View of $dir"

        set ws $work_space.i
        set dlist $ws.d.l
        set flist $ws.f.l
        frame $ws
        ::pack $ws -expand on -fill both

        frame $ws.d -bd 1 -relief raised
        scrollbar $ws.d.s -relief sunken -command "$dlist yview"
        ::pack $ws.d.s -side right -fill y
        listbox $ws.d.l -yscroll "$ws.d.s set" -setgrid yes
        ::pack $ws.d.l -side left -expand on -fill both
        bind $ws.d.l <Double-1> "$this select_entry"

        frame $ws.f -bd 1 -relief raised
        scrollbar $ws.f.s -relief sunken -command "$ws.f.l yview"
        ::pack $ws.f.s -side right -fill y
        listbox $ws.f.l -yscroll "$ws.f.s set" -setgrid yes
        ::pack $ws.f.l -side left -expand on -fill both
        bind $ws.f.l <Double-1> {opFileActivate [opSelectionGet]}

        global OPDirView
        set OPDirView($this,files) $urq_files
        set OPDirView($this,dirs)  $urq_dirs
        set OPDirView($this,orient)  $orient

        blt_drag&drop source $ws.d.l config \
            -button 3 \
            -packagecmd "$this dd_pkg d" \
            -send all \
            -sitecmd "$this dd_valid" \
            -tokenanchor nw \
            -selftarget true

        blt_drag&drop source $ws.d.l handler \
            file_name "$this dd_send_file"

        blt_drag&drop source $ws.f.l config \
            -button 3 \
            -packagecmd "$this dd_pkg f" \
            -send all \
            -sitecmd "$this dd_valid" \
            -tokenanchor nw \
            -selftarget true

        blt_drag&drop source $ws.f.l handler \
            file_name "$this dd_send_file"

        update
    }
    destructor {
        OpDirDisplay::destructor
    }
    method disp_start {} {
        # puts "display starts for $this"
        $dlist delete 0 end
        $flist delete 0 end
        set f_count 0
        set d_count 0
    }
    method disp_entry entry {
        set f [lindex $entry [expr [llength $entry] - 1]]
        if [file isdirectory $dir/$f] {
            $dlist insert end $entry
            incr d_count
        } {
            $flist insert end $entry
            incr f_count
        }
    }
    method disp_end {} {
        # puts "display ends for $this"
        if $d_count==0 {set d_show 0} {set d_show 1}
        if $f_count==0 {set f_show 0} {set f_show 1}
        if $d_count>0 "set d_gmy $d_count" "set d_gmy 1"
        if $f_count>0 "set f_gmy $f_count" "set f_gmy 1"
        if $d_count>12 "set d_gmy 12"
        if $f_count>12 "set f_gmy 12"
        $dlist configure -geometry 24x$d_gmy
        $flist configure -geometry 24x$f_gmy
        view_pack
        if {$d_count == 0 && $f_count == 0} {.fileEmptyDisplay on}
    }
    method view_pack config {
        if {$d_show && $urq_dirs} {
            if {$orient == "horizontal"} {
                ::pack $this.info.i.d -side left -expand on -fill both
            } {
                ::pack $this.info.i.d -side top -expand on -fill both
            }
        } {
            ::pack forget $this.info.i.d
        }
        if {$f_show && $urq_files} {
            if {$orient == "horizontal"} {
                ::pack $this.info.i.f -side right -expand on -fill both
            } {
                ::pack $this.info.i.f -side bottom -expand on -fill both
            }
        } {
            ::pack forget $this.info.i.f
        }
    }
    method select_entry {} {
        set f [opSelectionGet]
        if {$f == {}} return
        if $open_new_win {
            opFileActivate $f
        } {
            if [file isdirectory $f] {
                $this move_to_dir $f
            } {
                opFileActivate $f
            }
        }
    }

    # Drag and Drop handling methods.
    method dd_pkg {df token} {
        if {[winfo children $token] == {}} {
            label $token.value
            ::pack $token.value
        }
        if {$df == "f"} {
            set type file
            set li $flist
        } {
            set type directory
            set li $dlist
        }
        set xy [blt_drag&drop location]
        set y  [expr [lindex $xy 1] - [winfo rooty $li]]
        set str [$li get [$li nearest $y]]

        # should be bitmap with file or directory.
        $token.value config -text "$this - $type - $str"
        # puts "Source $type from '$this', [what_dir]/$str."
        return [what_dir]/$str
    }

    # End of Drag and Drop support functions.
    method what_label {} {return DirView}
    # The open proc search whether we already have a instance for the wanted
    # directory.
    proc open d {
        set swd [pwd]
        if ![file isdirectory $d] {set d [file dirname $d]}
        cd $d
        set d [pwd]
        cd $swd
        # puts "OpDirView::open '$d'"
        if [::info exists dir2obj(OpDirView,$d)] {
            puts "OpDirView::open '$d' - '$dir2obj(OpDirView,$d)'"
            $dir2obj(OpDirView,$d) raise
        } {
            incr serial_number
            OpDirView .dir_view$serial_number $d
        }
    }
    # files, directoris, count, show flag.
    public urq_files 1 {if $after_constructor {if {!$urq_files && !$urq_dirs} {set urq_dirs 1} ; global OPDirView ; set OPDirView($this,files) $urq_files ; set OPDirView($this,dirs) $urq_dirs ; view_pack}}
    public urq_dirs  1 {if $after_constructor {if {!$urq_files && !$urq_dirs} {set urq_dirs 1} ; global OPDirView ; set OPDirView($this,files) $urq_files ; set OPDirView($this,dirs) $urq_dirs ; view_pack}}
    public orient horizontal {if $after_constructor view_pack}
    protected f_count 0
    protected f_show  1
    protected d_count 0
    protected d_show  1
    protected flist {}
    protected dlist {}
    common serial_number 0
    common dv_menus {
        {dv_view {
            {checkbutton -label {Show Filter} -onvalue 1 -offvalue 0 -variable OPDirDisplay(THIS,filter) -command {global OPDirDisplay ; THIS config -disp_filter_flag $OPDirDisplay(THIS,filter)}}
            {checkbutton -label {Dir Entry} -onvalue 1 -offvalue 0 -variable OPDirDisplay(THIS,dir_disp) -command {global OPDirDisplay ; THIS config -disp_dir_flag $OPDirDisplay(THIS,dir_disp)}}
            {checkbutton -label {Vertical} -onvalue vertical -offvalue horizontal -variable OPDirView(THIS,orient) -command {global OPDirView ; THIS config -orient $OPDirView(THIS,orient)}}
            {checkbutton -label {Files} -onvalue 1 -offvalue 0 -variable OPDirView(THIS,files) -command {global OPDirView ; THIS config -urq_files $OPDirView(THIS,files)}}
            {checkbutton -label {Directories} -onvalue 1 -offvalue 0 -variable OPDirView(THIS,dirs) -command {global OPDirView ; THIS config -urq_dirs $OPDirView(THIS,dirs)}}
            {checkbutton -label {New Win} -onvalue 1 -offvalue 0 -variable OPDirDisplay(new_win) -command {global OPDirDisplay ; [THIS info class] :: set_new_win $OPDirDisplay(new_win)}}
            {command -label {Go Home} -under 0 -command {THIS move_to_dir [glob ~]}}
            {command -label {Move up} -under 0 -command {THIS move_to_dir [THIS what_dir]/..}}}
        }
    }
    common dv_menubar {{File 0 dird_file} {Edit 0 dird_edit} {View 0 dv_view} {Windows 0 tl_wins} {Help 0 tl_help right}}
}

# to open a dir view write 'OpDirView :: open dir'

# The Order of things in itcl_classes that I use in the Operator packages is:
# (as written in the itcl manual)
#  inherit
#  constructor
#  destructor
#  config method
#  methods
#  procs
#  public
#  protected
#  common
#
# End of opDirView.tcl file.
