#
# $Id: venget.tcl,v 1.5 1995/11/08 04:12:24 davide Exp $
#
# Most of the code in this file was taken adapted from file checkout.tcl
# for use in selecting a module to be used as the vendor module when doing
# a Module Level Merge.
#   venselect_setup was adapted from checkout_setup
#   venselect_scroll was adapted from checkout_scroll
#   venselect_run was adapted from checkout_run
#   venselect_fill_listbox was adapted from checkout_fill_listbox
#   venselect_fill_dir was adapted from checkout_fill_dir
#   venselect_select_code was adapted from checkout_select_code
#   venselect_act_on_code was adapted from checkout_on_code
#
# By: Eugene Lee, Aerospace Corporation, 10/3/95  

proc venselect_setup {} {
  global venselect_mcode feedback
  global venselect_version

  # This variable is a list containing all of the directories and
  # subdirectories that are expanded on the listbox.

  global displayed_list

  toplevel .venselect
  frame .venselect.down -relief groove -border 2
  frame .venselect.up
  frame .venselect.up.left -relief raised
  frame .venselect.up.right -relief raised

  pack .venselect.up -side top -fill x
  set feedback(vget) [entry .venselect.feedback -relief sunken]
  pack .venselect.feedback -side bottom -fill x -expand yes
  pack .venselect.down -side bottom -fill x
  pack .venselect.up.left -side left -fill both
  pack .venselect.up.right -side left -fill both -expand 1

  label .venselect.lven -text "Vendor Module To Be Selected"
  entry .venselect.ven -relief sunken

  pack .venselect.lven -in .venselect.up.left \
    -side top -fill x -pady 3
  pack .venselect.ven -in .venselect.up.right \
    -side top -fill both -expand 1 -pady 3

  #
  # Create buttons
  #

  button .venselect.ok -text "OK" \
    -command {
      if {$venselect_mcode != ""} {
        feedback_vget \
          "Getting releasetags info for CVS module\
          $venselect_mcode, Please wait"
        put_rev_tags
        .merge.vendor.name.e config -state normal
        .merge.vendor.name.e delete 0 end
        .merge.vendor.name.e insert 0 $venselect_mcode
        .merge.vendor.name.e config -state disabled
        feedback_vget ""
      }
      wm withdraw .venselect
    }

  button .venselect.quit -text "Quit" \
    -command {wm withdraw .venselect}

  pack .venselect.ok  .venselect.quit \
    -in .venselect.down -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  # Create a scroll bar and three list boxes.
  scrollbar .venselect.scroll -relief sunken \
    -command {venselect_scroll}
  listbox .venselect.namelist \
    -yscroll {.venselect.scroll set} -relief sunken \
    -width 40 -height 20 -setgrid yes -selectmode single
  listbox .venselect.infolist \
    -yscroll {.venselect.scroll set} -relief sunken \
    -width 10 -height 20 -setgrid yes -selectmode single
  listbox .venselect.codelist \
    -yscroll {.venselect.scroll set} -relief sunken \
    -width 20 -height 20 -setgrid yes -selectmode single

  # Set up key bindings for the lists so that they all select as
  # if the code list was pointed to.
  bind .venselect.codelist <Double-Button-1> \
    {venselect_act_on_code %y}
  bind .venselect.namelist <Double-Button-1> \
    {venselect_act_on_code %y}
  bind .venselect.infolist <Double-Button-1> \
    {venselect_act_on_code %y}
  bind .venselect.codelist <1> {venselect_select_code %y}
  bind .venselect.codelist <Button-2> {nop}
  bind .venselect.codelist <Any-B2-Motion> {nop}
  bind .venselect.namelist <1> {venselect_select_code %y}
  bind .venselect.namelist <Button-2> {nop}
  bind .venselect.namelist <Any-B2-Motion> {nop}
  bind .venselect.infolist <1> {venselect_select_code %y}
  bind .venselect.infolist <Button-2> {nop}
  bind .venselect.infolist <Any-B2-Motion> {nop}

  # Pack the scroll bar and the 3 lists side by side.
  pack .venselect.scroll -side right -fill y -padx 2 -pady 2
  pack .venselect.namelist .venselect.infolist .venselect.codelist \
    -side left -fill both -expand 1

  # Disable "Vendor Module To Be Selected" entry so that user cannot
  # enter in data manually
  .venselect.ven configure -state disabled
  
  # Window manager stuff.
  wm withdraw .venselect
  wm title .venselect "Select A Module For Vendor Code"
  wm minsize .venselect 1 1

  set displayed_list {}
  venselect_fill_listbox
}

proc venselect_scroll args {

  # To support scrolling 3 listboxes simultaneously

  eval ".venselect.namelist yview $args"
  eval ".venselect.infolist yview $args"
  eval ".venselect.codelist yview $args"
}

proc venselect_run {} {
  wm deiconify .venselect
}

proc venselect_fill_listbox {} {
#
# Do this to update the display of the listbox.
#
  global displayed_list
  global dtitle

  .venselect.namelist delete 0 end
  .venselect.infolist delete 0 end
  .venselect.codelist delete 0 end

  if {! [info exists dtitle]} {
    return
  }

  foreach dname [array names dtitle] {
    if {[file dirname $dname] == "."} {
      .venselect.namelist insert end $dtitle($dname)
      .venselect.infolist insert end "Directory"
      .venselect.codelist insert end $dname
      if {[lsearch $displayed_list $dname] != -1} {
        venselect_fill_dir $dname
      }
    }
  }
}

proc venselect_fill_dir {dname} {
  global mtitle
  global dtitle
  global dcontents
  global dsubmenus
  global displayed_list

  # Display all of the modules in this subdir.
  if [info exists dcontents($dname)] {
    foreach mname $dcontents($dname) {
      .venselect.namelist insert end $mtitle($mname)
      .venselect.infolist insert end "Module"
      .venselect.codelist insert end $mname
    }
  }

  # Recurse through each subdir, only displaying sublevels of those
  # that are marked for display.

  if [info exists dsubmenus($dname)] {
    foreach subdir $dsubmenus($dname) {
      .venselect.namelist insert end $dtitle($subdir)
      .venselect.infolist insert end "Directory"
      .venselect.codelist insert end $subdir
      if {[lsearch $displayed_list $subdir] != -1} {
        venselect_fill_dir $subdir
      }
    }
  }
}

proc venselect_select_code {yposition} {
#
# Do this when a code is clicked on.
#
  global venselect_ypos
  global venselect_mcode

  set venselect_ypos $yposition

  # This does the actual selection
  .venselect.codelist select set \
    [.venselect.codelist nearest $yposition]
  set code [selection get]
  
  # This will update the "Module Name" entry box 
  set venselect_mcode [lindex $code 0]
  
  # Unlike checkout_select_code, only Modules will be displayed
  .venselect.ven config -state normal
  .venselect.ven delete 0 end
  .venselect.infolist select set \
    [.venselect.infolist nearest $yposition]
  set info [selection get]
  if {$info == "Module"} {
    .venselect.ven insert 0 $code
  }
  .venselect.ven config -state disabled
    
  
  return $code
}

proc venselect_act_on_code {yposition} {
#
# Do this when a code is double-clicked on.
#
  global venselect_mcode
  global displayed_list

  # Do the selection bit.
  set code [venselect_select_code $yposition]

  # If the module is displayed, remove it from the display.  If it is
  # not displayed, add it to the display.
  set pos [lsearch $displayed_list $venselect_mcode]
  if {$pos == -1} {
    lappend displayed_list $venselect_mcode
  } else {
    set displayed_list [lreplace $displayed_list $pos $pos]
  }

  # Redraw the listbox.
  venselect_fill_listbox

  # Do the selection bit again so that the item remains selected after the
  # redraw.
  set code [venselect_select_code $yposition]
}

proc feedback_vget { message } {
  #######################################################################    
  # This code is adapted from the text "Practical Programming in
  # Tcl and Tk", by Brent B. Welch (see page 209)
  # An entry widget is used because it won't change size
  # base on the message length, and it can be scrolled by
  # dragging with button 2.
  # Author: Eugene Lee, Aerospace Corporation, 9/23/95
  #######################################################################    
  global cvscfg feedback
  set e $feedback(vget)
  $e config -state normal
  $e delete 0 end
  $e insert 0 $message
  # Leave the entry is a read-only state
  $e config -state disabled
  # Force a disable update
  update idletasks
}
