#
# Tcl Library for TkCVS
#

#
# $Id: dialog.tcl,v 1.14 2002/01/23 06:55:26 dorothyr Exp $
#
# Smallish dialogs - add, tag
#

proc add_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }

  set binflag ""
  toplevel .add

  set filelist [join $args]
  if {$filelist == ""} {
    set mess "This will add all new files"
  } else {
    set mess "This will add these files:\n\n"
    foreach file $filelist {
      append mess "   $file\n"
    }
  }

  message .add.top -justify left -aspect 300 -relief groove \
    -text "Add a file or files to the module.  The repository\
           will not be changed until you do a commit."
  pack .add.top -side top -fill x

  message .add.middle -text $mess -aspect 200
  pack .add.middle -side top -fill x

  checkbutton .add.binary -text "-kb (binary)" \
     -variable binflag -onvalue "-kb" -offvalue ""
  pack .add.binary -side top

  frame .add.down
  button .add.down.add -text "Add" \
    -command {
      cvs_add $binflag [workdir_list_files]
      destroy .add
    }
  button .add.down.cancel -text "Cancel" -command { destroy .add }
  pack .add.down -side bottom -fill x -expand 1
  pack .add.down.add .add.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .add "Add Files"
  wm minsize .add 1 1

  gen_log:log T "LEAVE"
}

proc file_tag_dialog {} {
  global incvs
  global cvscfg

  gen_log:log T "ENTER"

  if {! $incvs} {
    cvs_notincvs
    return 1
  }

  toplevel .tag

  message .tag.msg -justify left -aspect 300 -relief groove \
    -text "Apply a new tag or branch tag\
           to the marked files, recursively.\
           Will apply tag to repository and,\
           if a branch, also update local directory.\
           With the -F option, will move the tag\
           if it already exists."

  pack .tag.msg -side top -fill x -pady 1

  checkbutton .tag.force -text "-F (force)" \
     -variable forceflag -onvalue "-F" -offvalue ""
  pack .tag.force -side top -fill x -expand 1

  frame .tag.middle
  pack .tag.middle -side top -fill x

  label .tag.middle.lbl -text "Tag Name" -anchor w
  entry .tag.middle.entry -relief sunken -textvariable usertagname
  pack .tag.middle.lbl -side left -fill x -pady 3
  pack .tag.middle.entry -side right -fill x -expand 1 -pady 3 -padx 3

  frame .tag.down
  pack .tag.down -side bottom -fill x -expand 1
  button .tag.tag -text "Tag" \
    -command {
      cvs_tag $usertagname $forceflag no [workdir_list_files]
      destroy .tag
    }
  button .tag.branchtag -text "Branch Tag (-b)" \
    -command {
      cvs_tag $usertagname $forceflag yes [workdir_list_files]
      destroy .tag
    }
  button .tag.cancel -text "Cancel" -command { destroy .tag }

  pack .tag.tag .tag.branchtag .tag.cancel -in .tag.down -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .tag "tag"
  wm minsize .tag 1 1
  gen_log:log T "LEAVE"
}

proc rtag_dialog {mcode branch} {
  global mod_tagA
  global mod_tagB
  global cvscfg
  global usertagname
  global forceflag

  gen_log:log T "ENTER ($mcode $branch)"
  gen_log:log T "$mod_tagA $mod_tagB"

  toplevel .modtag

  set rtag_opts ""
  set mess1 ""
  if {$branch == "yes"} {
    set rtag_opts "-b"
    append mess1 "Branch "
  }
  append mess1 "module \"$mcode\""

  if {$mod_tagB == ""} {
    set mess "The head revision of all files will be labeled"
    append mess " with the new tag.  To tag a different revision, enter"
    append mess " the existing tag in \"Tag B\"."

  } else {
    set mess "The revisions tagged with \"$mod_tagB\" will be labeled"
    append mess " with the new tag."
    append rtag_opts " -r$mod_tagB"
  }

  label .modtag.lbl -text "Tag module \"$mcode\""
  frame .modtag.top -relief groove -bd 2
  message .modtag.top.msg -justify left -width 300 -text $mess
  frame .modtag.frm
  label .modtag.frm.lbl -text "Tag Name"
  entry .modtag.frm.entry -relief sunken -textvariable mod_tagA
  bind .modtag.frm.entry <Return> \
    "rtag_run $mcode \"$rtag_opts\"; destroy .modtag"

  pack .modtag.lbl -side top -fill both -expand 1
  pack .modtag.top -side top -fill both -expand 1
  pack .modtag.top.msg -side top -fill x
  pack .modtag.frm -side top -fill x
  pack .modtag.frm.lbl -side left -fill x -pady 3 -padx 2
  pack .modtag.frm.entry -side right -fill x -expand 1 -pady 3 -padx 2


  frame .modtag.down
  checkbutton .modtag.down.force -text "-F (force)" \
     -variable forceflag -onvalue "-F" -offvalue ""
  pack .modtag.down.force -side top -fill x -expand 1
  pack .modtag.down -side bottom -fill x -expand 1
  button .modtag.tag -text "Tag" \
    -command "rtag_run $mcode \"$rtag_opts\"; destroy .modtag"

  button .modtag.cancel -text "Cancel" -command { destroy .modtag }

  pack .modtag.tag .modtag.cancel -in .modtag.down -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .modtag "rtag"
  wm minsize .modtag 1 1
  gen_log:log T "LEAVE"
}

proc subtract_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }
  toplevel .subtract

  set filelist [join $args]
  if {$filelist == ""} {
    cvsfail "Please select some files to delete first!"
    return
  }

  set mess "This will remove these files:\n\n"
  foreach file $filelist {
    append mess "   $file\n"
  }

  message .subtract.top -justify left -aspect 300 -relief groove \
    -text "Remove a file or files from the module.  The repository\
           will not be changed until you do a commit."
  pack .subtract.top -side top -fill x

  message .subtract.middle -text $mess -aspect 200
  pack .subtract.middle -side top -fill x
  frame .subtract.down
  button .subtract.down.remove -text "Remove" \
    -command {
      cvs_remove [workdir_list_files]
      destroy .subtract
    }
  button .subtract.down.cancel -text "Cancel" -command { destroy .subtract }
  pack .subtract.down -side bottom -fill x -expand 1
  pack .subtract.down.remove .subtract.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .subtract "Remove Files"
  wm minsize .subtract 1 1

  gen_log:log T "LEAVE"
}

proc edit_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }

  if {$args == "."} {
    cvsfail "Please select some files to edit first!"
    return
  }
  toplevel .editflag

  set filelist [join $args]
  set mess "This will set the edit flag on these files:\n\n"
  foreach file $filelist {
    append mess "   $file\n"
  }

  message .editflag.top -justify left -aspect 300 -relief groove \
    -text "Set the edit flag on a file or files from the module"
  pack .editflag.top -side top -fill x

  message .editflag.middle -text $mess -aspect 200
  pack .editflag.middle -side top -fill x

  frame .editflag.down
  button .editflag.down.remove -text "Edit" \
    -command {
      cvs_edit [workdir_list_files]
      destroy .editflag
    }
  button .editflag.down.cancel -text "Cancel" -command { destroy .editflag }
  pack .editflag.down -side bottom -fill x -expand 1
  pack .editflag.down.remove .editflag.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .editflag "Edit Files"
  wm minsize .editflag 1 1

  gen_log:log T "LEAVE"
}

proc unedit_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }

  if {$args == "."} {
    cvsfail "Please select some files to unedit first!"
    return
  }
  toplevel .uneditflag

  set filelist [join $args]
  set mess "This will reset the edit flag on these files:\n\n"
  foreach file $filelist {
    append mess "   $file\n"
  }

  message .uneditflag.top -justify left -aspect 300 -relief groove \
    -text "Reset the edit flag on a file or files from the module."
  pack .uneditflag.top -side top -fill x

  message .uneditflag.middle -text $mess -aspect 200
  pack .uneditflag.middle -side top -fill x

  frame .uneditflag.down
  button .uneditflag.down.remove -text "Unedit" \
    -command {
      cvs_unedit [workdir_list_files]
      destroy .uneditflag
    }
  button .uneditflag.down.cancel -text "Cancel" -command { destroy .uneditflag }
  pack .uneditflag.down -side bottom -fill x -expand 1
  pack .uneditflag.down.remove .uneditflag.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .uneditflag "Unedit Files"
  wm minsize .uneditflag 1 1

  gen_log:log T "LEAVE"
}

#
# Set up a small(?) update dialog.
#
proc update_setup {} {
  global cvscfg
  global cvsglb

  gen_log:log T "ENTER"

  # Set defaults if not already set
  if {! [info exists cvsglb(tagmode_selection)]} {
    update_set_defaults
  }

  toplevel .update
  frame .update.explaintop
  frame .update.options
  frame .update.down

  frame .update.options.keep -relief groove -border 2
  frame .update.options.trunk -relief groove -border 2
  frame .update.options.getrev -relief groove -border 2
  frame .update.options.newdir -relief groove -border 2
  frame .update.options.normbin -relief groove -border 2
  frame .update.getrevleft
  frame .update.getrevright
  frame .update.getreventry

  frame .update.getdirsleft
  frame .update.getdirsright
  frame .update.getdirsentry

  pack .update.down -side bottom -fill x
  pack .update.explaintop -side top -fill x -pady 1
  pack .update.options -side top -fill x -pady 1


  # Provide an explanation of this dialog box
  label .update.explain1 -relief raised -bd 1 \
    -text "Update files in local directory"

 message .update.explain2 -font $cvscfg(listboxfont) \
     -justify left -width 400 \
     -text "Always recursive.
Empty directories always pruned (-P).
'Reset defaults' button will show defaults."

  pack .update.explain1 .update.explain2 \
    -in .update.explaintop -side top -fill x

  pack .update.options.keep -in .update.options -side top -fill x
  pack .update.options.trunk -in .update.options -side top -fill x
  pack .update.options.getrev -in .update.options -side top -fill x
  pack .update.options.newdir -in .update.options -side top -fill x
  pack .update.options.normbin -in .update.options -side top -fill x



  # If the user wants to simply do a normal update
  radiobutton .update.options.keep.select -text "Keep same branch or trunk." \
    -variable cvsglb(tagmode_selection) -value "Keep" -anchor w

  message .update.options.keep.explain1 -font $cvscfg(listboxfont) \
    -justify left -width 400 \
    -text "If local directory is on main trunk, get latest on main trunk.
If local directory is on a branch, get latest on that branch.
If local directory/file has \"sticky\" non-branch tag, no update."

  pack .update.options.keep.select -in .update.options.keep \
    -side top -fill x
  pack .update.options.keep.explain1 \
    -in .update.options.keep -side top -fill x -pady 1 -ipady 0

  # If the user wants to update to the head revision
  radiobutton .update.options.trunk.select \
    -text "Update local files to be on main trunk (-A)" \
    -variable cvsglb(tagmode_selection) -value "Trunk" -anchor w

  message .update.options.trunk.explain1 -font $cvscfg(listboxfont) \
    -justify left -width 400 \
    -text "Advice:  If your local directories are currently on a branch, \
you may want to commit any local changes to that branch first."

  pack .update.options.trunk.select \
    -in .update.options.trunk -side top -fill x
  pack .update.options.trunk.explain1 \
    -in .update.options.trunk -side top -fill x -pady 1 -ipady 0

  # If the user wants to update local files to a branch/tag

  # Where user enters a tag name (optional)
  radiobutton .update.options.getrev.select \
    -text "Update (-r) local files to be on tag/branch:" \
    -variable cvsglb(tagmode_selection) -value "Getrev" -anchor w

  message .update.options.getrev.explain -font $cvscfg(listboxfont) \
    -justify left -width 400 \
    -text "Advice:  Update local files to main trunk (head) first.
Note:  The tag will be 'sticky' for the directory and for each file."

  label .update.lname -text "Tag Name" -anchor w

  entry .update.tname -relief sunken -textvariable cvsglb(updatename)

  # bind_motifentry .update.tname

  pack .update.lname -in .update.getrevleft \
    -side top -fill x -pady 4

  pack .update.tname -in .update.getrevright \
    -side top -fill x -padx 2 -pady 4

  # Where user chooses the action to take if tag is not on a file
  label .update.lnotfound -text "If tag not found for file," \
    -anchor w

  radiobutton .update.notfoundremove -text "Remove file from local directory" \
    -variable cvsglb(action_notag) -value "Remove"

  radiobutton .update.notfoundhead -text "Get head revision (-f)" \
    -variable cvsglb(action_notag) -value "Get_head"

  pack .update.options.getrev.select -in .update.options.getrev \
    -side top -fill x
  pack .update.options.getrev.explain -in .update.options.getrev \
    -side top -fill x
  pack .update.getreventry -in .update.options.getrev \
    -side top -fill x
  pack .update.lnotfound -in .update.options.getrev \
    -side top -fill x
  pack .update.notfoundhead .update.notfoundremove \
    -in .update.options.getrev -side bottom -anchor w \
    -ipadx 8 -padx 4

  pack .update.getrevleft -in .update.getreventry \
     -side left -fill y
  pack .update.getrevright -in .update.getreventry \
     -side left -fill both -expand 1


  # Where user chooses whether to pick up directories not currently in local
  label .update.lalldirs \
    -text "If directory is in repository but not in local:" -anchor w

  radiobutton .update.noalldirs -text "Ignore it" \
    -variable cvsglb(get_all_dirs) -value "No" -anchor w
  radiobutton .update.getalldirs -text "Get it (-d)" \
    -variable cvsglb(get_all_dirs) -value "Yes" -anchor w

  label .update.lgetdirname -text "Specific directory (optional)" -anchor w
  entry .update.tgetdirname -relief sunken -textvariable cvsglb(getdirname)

  pack .update.lgetdirname -in .update.getdirsleft \
    -side top -fill x
  pack .update.tgetdirname -in .update.getdirsright \
    -side top -fill x -padx 2 -pady 1

  pack .update.getdirsleft -in .update.getdirsentry \
    -side left -fill y
  pack .update.getdirsright -in .update.getdirsentry \
    -side left -fill both -expand 1

  pack .update.lalldirs -in .update.options.newdir \
    -side top -fill x
  pack .update.getdirsentry -in .update.options.newdir \
    -side bottom -fill x
  pack .update.noalldirs .update.getalldirs -in .update.options.newdir \
    -side left -fill both -ipadx 2 -ipady 2 -padx 4 -expand 1

  # Where user chooses whether file is normal or binary
  label .update.lnormalbinary -text "Treat each file as:" -anchor w

  radiobutton .update.normalfile -text "Normal File" \
    -variable cvsglb(norm_bin) -value "Normal" -anchor w
  radiobutton .update.binaryfile -text "Binary File (-kb)" \
    -variable cvsglb(norm_bin) -value "Binary" -anchor w

  pack .update.lnormalbinary -in .update.options.normbin -side top -fill both
  pack .update.normalfile .update.binaryfile -in .update.options.normbin \
    -side left -fill both -ipadx 2 -ipady 2 -padx 4 -expand 1

  # The OK/Cancel buttons
  button .update.ok -text "OK" \
    -command { update_with_options; wm withdraw .update }

  button .update.apply -text "Apply" \
    -command update_with_options

  button .update.reset -text "Reset defaults" \
    -command update_set_defaults

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

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

  # Window Manager stuff
  wm withdraw .update
  wm title .update "Update a Module"
  wm minsize .update 1 1
  gen_log:log T "LEAVE"
}

# Set defaults for "Update with Options" dialog
proc update_set_defaults {} {
  global cvsglb

  set cvsglb(tagmode_selection) "Keep"
  set cvsglb(updatename) ""
  set cvsglb(action_notag) "Remove"
  set cvsglb(get_all_dirs) "No"
  set cvsglb(getdirname) ""
  set cvsglb(norm_bin) "Normal"
}

# Do what was setup in the "Update with Options" dialog
proc update_with_options {} {
  global cvsglb

  gen_log:log T "ENTER"

  if { $cvsglb(updatename) == "" } {
    set tagname "BASE"
  } else {
    set tagname $cvsglb(updatename)
  }
  if { $cvsglb(get_all_dirs) == "No" } { set cvsglb(getdirname) "" }
  if { $cvsglb(getdirname) == "" } {
    set dirname " "
  } else {
    set dirname $cvsglb(getdirname)
  }
  #puts "from update_setup, tagname $tagname.  norm_bin $cvsglb(norm_bin)"
  if { $cvsglb(tagmode_selection) == "Keep" } {
    eval "cvs_update {BASE} \
       {$cvsglb(norm_bin)} {$cvsglb(action_notag)} {$cvsglb(get_all_dirs)} \
       {$dirname} [workdir_list_files]"
  } elseif { $cvsglb(tagmode_selection) == "Trunk" } {
    eval "cvs_update {HEAD} \
       {$cvsglb(norm_bin)} {$cvsglb(action_notag)} {$cvsglb(get_all_dirs)} \
       {$dirname} [workdir_list_files]"
  } elseif { $cvsglb(tagmode_selection) == "Getrev" } {
    eval "cvs_update {$tagname} \
       {$cvsglb(norm_bin)} {$cvsglb(action_notag)} {$cvsglb(get_all_dirs)} \
       {$dirname} [workdir_list_files]"
  } else {
    cvsfail "Internal TkCVS error.\ntagmode_selection $cvsglb(tagmode_selection)."
  }
  gen_log:log T "LEAVE"
}

#
# Invoked by workdir Options->"Checkout with Options".
#
proc update_run {} {
  global incvs

  gen_log:log T "ENTER"

  if {! [winfo exists .update]} {
     update_setup
  }

  wm deiconify .update
  raise .update
  gen_log:log T "LEAVE"
}

proc rtag_run {mcode opts} {
  global mod_tagA

  gen_log:log T "ENTER ($mcode $opts)"
  cvs_rtag $mcode "$opts" $mod_tagA
  gen_log:log T "LEAVE"
}

proc addir_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }

  set binflag ""
  toplevel .add

  set filelist [join $args]
  if {$filelist == ""} {
    set mess "This will add all new directories"
  } else {
    set mess "This will add these directories:\n\n"
    foreach file $filelist {
      append mess "   $file\n"
    }
  }

  message .add.top -justify left -aspect 300 -relief groove \
    -text "Add (recursively) a directory to the module.\
           The repository will not be changed until you do a commit."
  pack .add.top -side top -fill x

  message .add.middle -text $mess -aspect 200
  pack .add.middle -side top -fill x

  checkbutton .add.binary -text "-kb (binary)" \
     -variable binflag -onvalue "-kb" -offvalue ""
  pack .add.binary -side top

  frame .add.down
  button .add.down.add -text "Add" \
    -command {
      cvs_add_dir $binflag [workdir_list_files]
      destroy .add
    }
  button .add.down.cancel -text "Cancel" -command { destroy .add }
  pack .add.down -side bottom -fill x -expand 1
  pack .add.down.add .add.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .add "Add Directories"
  wm minsize .add 1 1

  gen_log:log T "LEAVE"
}

proc subtractdir_dialog {args} {
  global cvs
  global incvs
  global cvscfg

  gen_log:log T "ENTER ($args)"
  if {! $incvs} {
    cvs_notincvs
    return 1
  }
  toplevel .subtract

  set filelist [join $args]
  if {$filelist == ""} {
    cvsfail "Please select some directoriess to delete first!"
    return
  }

  set mess "This will remove these directories:\n\n"
  foreach file $filelist {
    append mess "   $file\n"
  }

  message .subtract.top -justify left -aspect 300 -relief groove \
    -text "Remove (recursively) a directory from the module.  The repository\
           will not be changed until you do a commit."
  pack .subtract.top -side top -fill x

  message .subtract.middle -text $mess -aspect 200
  pack .subtract.middle -side top -fill x
  frame .subtract.down
  button .subtract.down.remove -text "Remove" \
    -command {
      cvs_remove_dir [workdir_list_files]
      destroy .subtract
    }
  button .subtract.down.cancel -text "Cancel" -command { destroy .subtract }
  pack .subtract.down -side bottom -fill x -expand 1
  pack .subtract.down.remove .subtract.down.cancel -side left \
    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1

  wm title .subtract "Remove Directories"
  wm minsize .subtract 1 1

  gen_log:log T "LEAVE"
}

