1#
2# Tcl Library for TkCVS
3#
4
5#
6# Smallish dialogs - add, tag
7#
8
9if {[catch "image type arr_dn"]} {
10  workdir_images
11}
12
13# Creates the widgets for the dynamic form dialog
14proc dialog_FormCreate { title form_data } {
15  global cvscfg
16  global cvsglb
17  global dynamic_dialog
18  global dialog_action
19
20  set font_star $cvscfg(dialogfont)
21  set font_normal $cvscfg(listboxfont)
22  set font_bold $cvscfg(dialogfont)
23  set font_italic [font create -family Helvetica -size -12 -slant italic]
24
25  if {[winfo exists .dynamic_dialog]} {
26    destroy .dynamic_dialog
27  }
28  set w .dynamic_dialog
29  toplevel $w
30
31  frame $w.form
32  pack $w.form -side top -fill x
33
34  set row 0
35  foreach {field req type labeltext data} $form_data {
36    # If you wanted another default, set it in the calling function
37    if {! [info exists dynamic_dialog($field)]} {
38      set dynamic_dialog($field) {}
39    }
40    if {$type == {l}} {
41      # Section label
42      frame $w.form.rule$field -relief groove -borderwidth 2 -height 4
43      label $w.form.l$field -font $font_bold -text $labeltext
44      grid  $w.form.rule$field -column 0 -row [incr row] -columnspan 3 -sticky ew
45      grid  $w.form.l$field -column 0 -row [incr row] -sticky w
46    } else {
47      # It's something else.  It has a label and a req though.
48      label $w.form.l$field -anchor w -text "    $labeltext"
49      label $w.form.r$field -anchor e -foreground red \
50          -font $font_star -text [expr {$req ? "*" : " "}]
51        grid  $w.form.l$field -column 0 -row [incr row] -sticky w
52        grid  $w.form.r$field -column 1 -row $row -sticky w
53      if {$type == {t}} {
54        # It's an entry
55        entry $w.form.e$field -width 65 \
56           -textvariable dynamic_dialog($field)
57        grid  $w.form.e$field -column 2 -row $row -sticky w
58      } elseif {$type == {r}} {
59        # It's a radiobutton
60        frame $w.form.f$field
61        set k 1
62        foreach {text value} $data {
63          radiobutton $w.form.f$field$k -text $text -value $value \
64              -variable dynamic_dialog($field)
65          pack $w.form.f$field$k -in $w.form.f$field -side left
66          incr k
67        }
68        grid $w.form.f$field -column 2 -row $row -sticky ew
69      }
70    }
71  }
72
73  incr row
74  label $w.form.xstar -anchor e -foreground red \
75    -font $font_italic -text "* = required field"
76  grid $w.form.xstar -column 1 -columnspan 2 -row $row -sticky w
77
78  frame $w.buttons -relief groove -bd 2
79  pack $w.buttons -side top -fill x
80
81  button $w.ok -text "OK" \
82    -command "
83    if {\[dialog_FormComplete $w [list $form_data]\] } {
84      destroy $w
85      $dialog_action
86      exit_cleanup 0
87    }
88    "
89
90  button $w.apply -text "Apply" \
91    -command "
92    if {\[dialog_FormComplete $w [list $form_data]\] } {
93      $dialog_action
94    }
95    "
96
97  button $w.close -text "Cancel" \
98    -command "
99      destroy $w
100      exit_cleanup 0
101    "
102
103  pack $w.close $w.apply $w.ok -in $w.buttons -side right \
104    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
105
106  wm title $w $title
107  wm minsize $w 1 1
108
109  return
110}
111
112proc dialog_FormComplete { w form_data } {
113  global dynamic_dialog
114
115  gen_log:log T "ENTER ($w ...)"
116
117  foreach a [array names dynamic_dialog] {
118    gen_log:log D "$a $dynamic_dialog($a)"
119  }
120
121  set section {}
122  foreach {field req type labeltext data} $form_data {
123    if {$type == {l}} {
124      set section $dynamic_dialog($field)
125    } else {
126      if {$req && [set dynamic_dialog($field)] == {}} {
127        cvsok "$field may not be blank" $w.form
128        return 0
129      }
130    }
131  }
132  return 1
133}
134
135# Check out a CVS module from the Repository Browser
136proc dialog_cvs_checkout { cvsroot module {revtag {} } } {
137  global dynamic_dialog
138  global dialog_action
139
140  gen_log:log T "ENTER ($cvsroot $module $revtag)"
141
142  # Remember tags from last time
143  if {$revtag == {} && [info exists dynamic_dialog(revtag)]} {
144    set revtag $dynamic_dialog(revtag)
145  }
146  set dir [pwd]
147  set dynamic_dialog(cvsroot) $cvsroot
148  set dynamic_dialog(module) $module
149  set dynamic_dialog(revtag) $revtag
150  set dynamic_dialog(dir) $dir
151  set dynamic_dialog(prune) {-P}
152  set dynamic_dialog(kflag) {}
153
154  # field  req type labeltext          data
155  set dialog_form_checkout {
156    1       0   l  {CVS Repository}    1
157    cvsroot 1   t  {CVSROOT}           {}
158    2       0   l  {Module}            1
159    module  1   t  {Name/Path}         {}
160    revtag  0   t  {Revision/Tag}      {}
161    date    0   t  {Date}              {}
162    3       0   l  {Destination}       1
163    dir     1   t  {Current Directory} {}
164    target  0   t  {Working Directory} {}
165    4       0   l  {Merge }            0
166    mtag1   0   t  {Old tag}           {}
167    mtag2   0   t  {New tag}           {}
168    5       0   l  {Advanced}          0
169    prune   0   r  {Empty Directories} {{Create} {}
170                                        {Don't Create} {-P}}
171    kflag   0   r  {Keyword Expansion} {{Default} {}
172                                        {Keep as-is} {-ko}
173                                        {Treat files as binary} {-kb}
174                                        {Keywords only} {-kk}}
175  }
176  # Action function
177  set dialog_action {cvs_checkout $dynamic_dialog(dir) \
178     $dynamic_dialog(cvsroot) \
179     $dynamic_dialog(prune) $dynamic_dialog(kflag) \
180     $dynamic_dialog(revtag) $dynamic_dialog(date) $dynamic_dialog(target) \
181     $dynamic_dialog(mtag1) $dynamic_dialog(mtag2) $dynamic_dialog(module)
182  }
183
184  set form [dialog_FormCreate "Checkout Module" $dialog_form_checkout]
185  gen_log:log T "LEAVE"
186}
187
188# Export a CVS module from the Repository Browser
189proc dialog_cvs_export { cvsroot module {revtag {}} } {
190  global dynamic_dialog
191  global dialog_action
192
193  gen_log:log T "ENTER ($cvsroot $module $revtag)"
194
195  # Remember tags from last time
196  if {$revtag == {} && [info exists dynamic_dialog(revtag)]} {
197    set revtag $dynamic_dialog(revtag)
198  }
199  set dir [pwd]
200  set dynamic_dialog(cvsroot) $cvsroot
201  set dynamic_dialog(module) $module
202  set dynamic_dialog(revtag) $revtag
203  set dynamic_dialog(dir) $dir
204
205  # field  req type labeltext          data
206  set dialog_form_export {
207    1       0   l {CVS Repository}     1
208    cvsroot 1   t {CVSROOT}            {}
209    2       0   l {Module}             1
210    module  1   t {Name/Path}          {}
211    revtag  0   t {Revision/Tag}       {}
212    date    0   t {Date}               {}
213    3       0   l {Destination}        1
214    dir     1   t {Current Directory}  {}
215    target  0   t {Target Directory}   {}
216    4       0   l {Advanced}           0
217    kflag   0   r {Keyword Expansion}  {{Default} {}
218                                        {Keep as-is} {-ko}
219                                        {Treat files as binary} {-kb}
220                                        {Keywords only} {-kk}}
221  }
222  # Action function
223  set dialog_action {cvs_export  $dynamic_dialog(dir) \
224     $dynamic_dialog(cvsroot) $dynamic_dialog(kflag) \
225     $dynamic_dialog(revtag) $dynamic_dialog(date) \
226     $dynamic_dialog(target) $dynamic_dialog(module)
227  }
228
229  set form [dialog_FormCreate "Export Module" $dialog_form_export]
230  gen_log:log T "LEAVE"
231}
232
233# Checkout or Export a SVN module from the Repository Browser
234proc dialog_svn_checkout { svnroot path command } {
235  global dynamic_dialog
236  global dialog_action
237
238  if {[info exists dynamic_dialog(rev)]} {
239    set rev $dynamic_dialog(rev)
240  }
241  set dir [pwd]
242  set dynamic_dialog(path) $path
243  set dynamic_dialog(svnroot) $svnroot
244  set dynamic_dialog(command) $command
245  set dynamic_dialog(dir) $dir
246
247  # field  req type labeltext          data
248  set dialog_form_export {
249    1       0   l {SVN Repository}     1
250    svnroot 1   t {SVN URL}            {}
251    path    1   t {Path in Repository} {}
252    rev     0   t {Revision/Date}      {}
253    2       0   l {Destination}        1
254    dir     1   t {Current Directory}  {}
255    target  0   t {Target Directory}   {}
256    3       0   l {Working Copy or Unversioned Copy} {}
257    command 0   r {Versioning}         {{Versioned (Checkout)}  {checkout}
258                                        {Un-Versioned (Export)} {export}}
259  }
260  # Action function
261  set dialog_action {svn_checkout $dynamic_dialog(dir) \
262     $dynamic_dialog(svnroot) $dynamic_dialog(path) \
263     $dynamic_dialog(rev) $dynamic_dialog(target) \
264     $dynamic_dialog(command)
265  }
266
267  set form [dialog_FormCreate "Checkout or Export" $dialog_form_export]
268  gen_log:log T "LEAVE"
269}
270
271
272# Make a branch or tag (svn copy) from the Repository Browser
273proc dialog_svn_tag { svnroot path b_or_t } {
274  global dynamic_dialog
275  global dialog_action
276
277  set dynamic_dialog(path) $path
278  set dynamic_dialog(svnroot) $svnroot
279  set dynamic_dialog(b_or_t) $b_or_t
280  set dynamic_dialog(frompath) "$dynamic_dialog(svnroot)/$dynamic_dialog(path)"
281
282  # field     req type labeltext                     data
283  set dialog_form_tagcopy {
284    1           0   l  {Copy Path to Tag or Branch}  1
285    frompath    1   t  {Copy From}                   {}
286    b_or_t      0   r  {Tag or Branch}               {{Branch} {branches}
287                                                      {Tag} {tags}}
288    target      1   t  {New Branch/Tag}              {}
289  }
290  # Action function
291  set dialog_action {svn_rcopy $dynamic_dialog(svnroot)/$dynamic_dialog(path) \
292                               $dynamic_dialog(b_or_t) $dynamic_dialog(target)
293  }
294
295  set form [dialog_FormCreate "SVN Branch or Tag Copy" $dialog_form_tagcopy]
296  gen_log:log T "LEAVE"
297}
298
299
300# Compare two revisions of a module, from the module browser
301# Can make a patch file or send a summary to the screen
302proc dialog_cvs_patch { cvsroot module summary {revtagA {}} {revtagB {}} } {
303  global dynamic_dialog
304  global dialog_action
305
306  gen_log:log T "ENTER ( $cvsroot $module $summary $revtagA $revtagB )"
307
308  # Remember tags
309  if {$revtagA == {} && [info exists dynamic_dialog(revtagA)]} {
310    set revtagA $dynamic_dialog(revtagA)
311  }
312  if {$revtagB == {} && [info exists dynamic_dialog(revtagB)]} {
313    set revtagB $dynamic_dialog(revtagB)
314  }
315
316  set dynamic_dialog(cvsroot) $cvsroot
317  set dynamic_dialog(module) $module
318  set dynamic_dialog(revtagA) $revtagA
319  set dynamic_dialog(revtagB) $revtagB
320  set dynamic_dialog(outfile) "$module.patch"
321  if {$summary} {
322    set dynamic_dialog(outmode) 0
323    set dynamic_dialog(difffmt) {-s}
324  } else {
325    set dynamic_dialog(outmode) 1
326    set dynamic_dialog(difffmt) {}
327  }
328
329  # field  req type labeltext          data
330  set dialog_form_patch {
331  1         0     l {CVS Repository}   1
332  cvsroot   1     t {CVSROOT}          {}
333  2         0     l {Module}           1
334  module    1     t {Name/Path}        {}
335  3         0     l {Destination}      1
336  outmode   0     r {Output Mode}      {{To Screen} 0 {To File} 1}
337  outfile   0     t {Output File}      {outfile}
338  4         0     l {Old Revision}     1
339  revtagA   0     t {Revision/Tag}     {}
340  dateA     0     t {Date}             {}
341  5         0     l {New Revision}     1
342  revtagB   0     t {Revision/Tag}     {}
343  dateB     0     t {Date}             {}
344  6         0     l {Format}           1
345  difffmt   0     r {Diff Format}      {{Default}            {}
346                                        {Context diff}       {-c}
347                                        {Unidiff}            {-u}
348                                        {One liner}          {-s}}
349  }
350  # Action function
351  set dialog_action {cvs_patch $dynamic_dialog(cvsroot) \
352     $dynamic_dialog(module) $dynamic_dialog(difffmt) \
353     $dynamic_dialog(revtagA) $dynamic_dialog(dateA) \
354     $dynamic_dialog(revtagB) $dynamic_dialog(dateB) \
355     $dynamic_dialog(outmode) $dynamic_dialog(outfile)
356  }
357
358  set form [dialog_FormCreate "Diff/Patch Module" $dialog_form_patch]
359  gen_log:log T "LEAVE"
360}
361
362# Compare two revisions, from the module browser
363# Can make a patch file or send a summary to the screen
364proc dialog_svn_patch { cvsroot pathA pathB summary } {
365  global dynamic_dialog
366  global dialog_action
367
368  gen_log:log T "ENTER ( $cvsroot $pathA $pathB $summary )"
369
370  set dynamic_dialog(cvsroot) $cvsroot
371  set dynamic_dialog(pathA) $pathA
372  set dynamic_dialog(pathB) $pathB
373  if {$summary} {
374    set dynamic_dialog(outmode) 0
375  } else {
376    set dynamic_dialog(outmode) 1
377  }
378  set dynamic_dialog(outfile) "patchfile.patch"
379  set dynamic_dialog(fullA) "$cvsroot$pathA"
380  if {$pathB == ""} {
381    set dynamic_dialog(fullB) ""
382  } else {
383    set dynamic_dialog(fullB) "$cvsroot$pathB"
384  }
385
386  # field  req type labeltext          data
387  set dialog_form_patch {
388  1         0     l {Repository Paths} 1
389  pathA     1     t {Path A}           {}
390  pathB     0     t {Path B}           {}
391  3         0     l {Destination}      1
392  outmode   0     r {Output Mode}      {{To Screen} 0 {To File} 1}
393  outfile   0     t {Output File}      {outfile}
394  4         0     l {Old Revision}     1
395  revA      0     t {Revision}         {}
396  dateA     0     t {Date}             {}
397  5         0     l {New Revision}     1
398  revB      0     t {Revision}         {}
399  dateB     0     t {Date}             {}
400  }
401  # Action function
402  set dialog_action {
403    # Make new fullA and fullB from the pathA and pathB entries
404    set dynamic_dialog(fullA) "$dynamic_dialog(cvsroot)/$dynamic_dialog(pathA)"
405    if {$dynamic_dialog(pathB) == ""} {
406      set dynamic_dialog(fullB) ""
407    } else {
408      set dynamic_dialog(fullB) "$dynamic_dialog(cvsroot)/$dynamic_dialog(pathB)"
409    }
410    svn_patch $dynamic_dialog(fullA) \
411       $dynamic_dialog(fullB) \
412       $dynamic_dialog(revA) $dynamic_dialog(dateA) \
413       $dynamic_dialog(revB) $dynamic_dialog(dateB) \
414       $dynamic_dialog(outmode) $dynamic_dialog(outfile)
415  }
416
417  set form [dialog_FormCreate "SVN Diff/Patch" $dialog_form_patch]
418  gen_log:log T "LEAVE"
419}
420
421proc add_dialog {args} {
422  global cvs
423  global cvsglb
424  global incvs
425  global insvn
426
427  gen_log:log T "ENTER ($args)"
428
429  set binflag ""
430  toplevel .add
431  grab set .add
432
433  set filelist [join $args]
434  if {$filelist == ""} {
435    set mess "This will add all new files"
436  } else {
437    set mess "This will add these files:\n\n"
438    foreach file $filelist {
439      append mess "   $file\n"
440    }
441  }
442
443  message .add.top -justify left -aspect 300 -relief groove \
444    -text "Add a file or files to the module.  The repository\
445           will not be changed until you do a commit."
446  pack .add.top -side top -fill x
447
448  message .add.middle -text $mess -aspect 200
449  pack .add.middle -side top -fill x
450  frame .add.down
451  button .add.down.add -text "Add"
452  if {$incvs} {
453    .add.down.add configure -command {
454      grab release .add
455      destroy .add
456      cvs_add $binflag [workdir_list_files]
457    }
458    checkbutton .add.binary -text "-kb (binary)" \
459       -variable binflag -onvalue "-kb" -offvalue ""
460    pack .add.binary -side top
461  } elseif {$insvn} {
462    .add.down.add configure -command {
463      grab release .add
464      destroy .add
465      svn_add [workdir_list_files]
466    }
467  }
468
469  button .add.down.cancel -text "Cancel" \
470    -command { grab release .add; destroy .add }
471  pack .add.down -side bottom -fill x -expand 1
472  pack .add.down.add .add.down.cancel -side left \
473    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
474
475  wm title .add "Add Files"
476  wm minsize .add 1 1
477
478  gen_log:log T "LEAVE"
479}
480
481proc file_tag_dialog {branch} {
482  global incvs insvn inrcs
483  global cvscfg
484  global cvsglb
485  global branchflag
486
487  gen_log:log T "ENTER ($branch)"
488
489  # FIXME: This is too messy and should be split into two dialogs,
490  # one for cvs and one for svn
491  set branchflag $branch
492
493  toplevel .tag
494  #grab set .tag
495
496  frame .tag.top
497  pack .tag.top -side top -fill x
498
499  set msg ""
500  if {$incvs} {
501    set msg "Apply a new tag or branch tag \
502             to the marked files, recursively.\
503             Will change the repository.\
504             If a branch, it can also update local directory if desired."
505  } elseif {$insvn} {
506    set msg "Create a new branch or tag copy \
507             of the files in this directory"
508  }
509
510  message .tag.top.msg -justify left -aspect 300 -relief groove \
511    -text $msg
512  label .tag.top.lbl -text "Tag Name" -anchor w
513  entry .tag.top.entry -relief sunken -textvariable usertagname
514  checkbutton .tag.top.branch -text "Branch tag (-b)" \
515     -variable branchflag -onvalue "branch" -offvalue "tag" \
516     -command {
517        if {$branchflag == "tag"} {
518           .tag.mid.upd config -state disabled; set updflag "no"
519        } else {
520           .tag.mid.upd config -state normal
521        }
522      }
523  checkbutton .tag.top.force -text "Move existing (-F)" \
524     -variable forceflag -onvalue "yes" -offvalue "no"
525
526  frame .tag.mid -relief groove -bd 2
527  checkbutton .tag.mid.upd -text "Update current directory to be on the new tag" \
528      -variable updflag -onvalue "yes" -offvalue "no"
529
530  grid columnconf .tag.top 1 -weight 1
531  grid rowconf .tag.top 3 -weight 1
532  grid .tag.top.msg -column 0 -row 0 -columnspan 2 -pady 2 -sticky ew
533  grid .tag.top.lbl -column 0 -row 1 -sticky nw
534  grid .tag.top.entry -column 1 -row 1 -sticky ew
535  grid .tag.top.branch -column 1 -row 2 -sticky w
536  if {$incvs} {
537    grid .tag.top.force -column 1 -row 3 -sticky w
538  }
539
540  pack .tag.mid -side top
541  pack .tag.mid.upd
542
543  frame .tag.down -relief groove -bd 2
544  pack .tag.down -side bottom -fill x -expand 1
545  button .tag.down.tag -text "Tag"
546  if {$incvs} {
547    .tag.down.tag configure -command {
548      cvs_tag $usertagname $forceflag $branchflag $updflag \
549          [workdir_list_files]
550      grab release .tag
551      destroy .tag
552    }
553  } elseif {$insvn} {
554    if {$branchflag == "branch"} {set branchtag "branches"}
555    if {$branchflag == "tag"} {set branchtag "tags"}
556    .tag.down.tag configure -command {
557      svn_tag $usertagname $branchflag $updflag [workdir_list_files]
558      grab release .tag
559      destroy .tag
560    }
561  }
562  button .tag.down.cancel -text "Cancel" \
563    -command { grab release .tag; destroy .tag }
564
565  pack .tag.down.tag .tag.down.cancel -in .tag.down -side left \
566    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
567
568  if {$branchflag == "tag"} {
569     .tag.mid.upd config -state disabled
570     set updflag "no"
571  } else {
572     .tag.mid.upd config -state normal
573  }
574
575  wm title .tag "tag"
576  wm minsize .tag 1 1
577  gen_log:log T "LEAVE"
578}
579
580proc rtag_dialog { cvsroot module b_or_t } {
581  global cvscfg
582  global cvsglb
583
584  gen_log:log T "ENTER ($cvsroot $module $b_or_t)"
585
586  toplevel .modtag
587  grab set .modtag
588
589  frame .modtag.top
590  pack .modtag.top -side top -fill x
591
592  message .modtag.top.lbl -aspect 300 -relief groove \
593    -text "Tag the module \"$module\" with the new tag you specify.\
594           If you fill in \"Existing Tag\", the revisions having that tag will get\
595           the new tag.  Otherwise, the head revision will be tagged."
596  label .modtag.top.olbl -text "Existing Tag" -anchor w
597  entry .modtag.top.oentry -textvariable otag \
598    -relief sunken
599  label .modtag.top.nlbl -text "New Tag" -anchor w
600  entry .modtag.top.nentry -textvariable ntag \
601    -relief sunken
602  checkbutton .modtag.top.branch -text "Branch tag (-b)" \
603     -variable b_or_t -onvalue "branch" -offvalue "tag"
604  checkbutton .modtag.top.force -text "Move existing (-F)" \
605     -variable force -onvalue "yes" -offvalue "no"
606
607  grid columnconf .modtag.top 1 -weight 1
608  grid rowconf .modtag.top 4 -weight 1
609  grid .modtag.top.lbl -column 0 -row 0 -columnspan 2 -pady 2 -sticky ew
610  grid .modtag.top.olbl -column 0 -row 1 -sticky nw
611  grid .modtag.top.oentry -column 1 -row 1
612  grid .modtag.top.nlbl -column 0 -row 2 -sticky nw
613  grid .modtag.top.nentry -column 1 -row 2
614  grid .modtag.top.branch -column 1 -row 3 -sticky w
615  grid .modtag.top.force -column 1 -row 4 -sticky w
616
617  frame .modtag.down -relief groove -bd 2
618  pack .modtag.down -side top -fill x
619
620  button .modtag.down.tag -text "Tag" \
621    -command "
622               cvs_rtag $cvsroot $module $b_or_t \$force \$otag \$ntag; \
623               .modtag.down.cancel invoke
624             "
625
626  button .modtag.down.delete -text "Remove" \
627    -command "
628               cvs_rtag $cvsroot $module tag remove \$otag \$ntag; \
629               .modtag.down.cancel invoke
630             "
631
632  button .modtag.down.cancel -text "Cancel" \
633    -command {
634               grab release .modtag
635               destroy .modtag
636             }
637
638  pack .modtag.down.tag .modtag.down.delete .modtag.down.cancel -in .modtag.down -side left \
639    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
640
641  bind .modtag.top.nentry <Return> \
642    { .modtag.down.tag invoke }
643
644  wm title .modtag "Tag Module"
645  wm minsize .modtag 1 1
646  gen_log:log T "LEAVE"
647}
648
649proc subtract_dialog {args} {
650  global incvs
651  global insvn
652  global cvsglb
653
654  gen_log:log T "ENTER ($args)"
655
656  set filelist [join $args]
657  if {$filelist == ""} {
658    cvsfail "Please select some files to delete first!" .workdir
659    return
660  }
661
662  foreach f $filelist {
663    if {$incvs && [file isdirectory $f]} {
664      cvsfail "$f is a directory. Try \"Remove Recursively\" instead" .workdir
665      return
666    }
667  }
668
669  toplevel .subtract
670  grab set .subtract
671
672  set mess "This will remove these files:\n\n"
673  foreach file $filelist {
674    append mess "   $file\n"
675  }
676
677  message .subtract.top -justify left -aspect 300 -relief groove \
678    -text "Remove a file or files from the module.  The repository\
679           will not be changed until you do a commit."
680  pack .subtract.top -side top -fill x
681
682  message .subtract.middle -text $mess -aspect 200
683  pack .subtract.middle -side top -fill x
684  frame .subtract.down
685  button .subtract.down.remove -text "Remove"
686  if {$incvs} {
687    .subtract.down.remove configure -command {
688      grab release .subtract
689      destroy .subtract
690      cvs_remove [workdir_list_files]
691    }
692  } elseif {$insvn} {
693    .subtract.down.remove configure -command {
694      grab release .subtract
695      destroy .subtract
696      svn_remove [workdir_list_files]
697    }
698  }
699
700  button .subtract.down.cancel -text "Cancel" \
701    -command { grab release .subtract; destroy .subtract }
702  pack .subtract.down -side bottom -fill x -expand 1
703  pack .subtract.down.remove .subtract.down.cancel -side left \
704    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
705
706  wm title .subtract "Remove Files"
707  wm minsize .subtract 1 1
708
709  gen_log:log T "LEAVE"
710}
711
712proc edit_dialog {args} {
713  global incvs
714  global cvsglb
715
716  gen_log:log T "ENTER ($args)"
717  if {! $incvs} {
718    cvs_notincvs
719    return 1
720  }
721
722  if {$args == "."} {
723    cvsfail "Please select some files to edit first!" .workdir
724    return
725  }
726  toplevel .editflag
727  grab set .editflag
728
729  set filelist [join $args]
730  set mess "This will set the edit flag on these files:\n\n"
731  foreach file $filelist {
732    append mess "   $file\n"
733  }
734
735  message .editflag.top -justify left -aspect 300 -relief groove \
736    -text "Set the edit flag on a file or files from the module"
737  pack .editflag.top -side top -fill x
738
739  message .editflag.middle -text $mess -aspect 200
740  pack .editflag.middle -side top -fill x
741
742  frame .editflag.down
743  button .editflag.down.remove -text "Edit" \
744    -command {
745      grab release .editflag
746      destroy .editflag
747      cvs_edit [workdir_list_files]
748    }
749  button .editflag.down.cancel -text "Cancel" \
750    -command { grab release .editflag; destroy .editflag }
751  pack .editflag.down -side bottom -fill x -expand 1
752  pack .editflag.down.remove .editflag.down.cancel -side left \
753    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
754
755  wm title .editflag "Edit Files"
756  wm minsize .editflag 1 1
757
758  gen_log:log T "LEAVE"
759}
760
761proc unedit_dialog {args} {
762  global incvs
763  global cvsglb
764
765  gen_log:log T "ENTER ($args)"
766  if {! $incvs} {
767    cvs_notincvs
768    return 1
769  }
770
771  if {$args == "."} {
772    cvsfail "Please select some files to unedit first!" .workdir
773    return
774  }
775  toplevel .uneditflag
776  grab set .uneditflag
777
778  set filelist [join $args]
779  set mess "This will reset the edit flag on these files:\n\n"
780  foreach file $filelist {
781    append mess "   $file\n"
782  }
783
784  message .uneditflag.top -justify left -aspect 300 -relief groove \
785    -text "Reset the edit flag on a file or files from the module."
786  pack .uneditflag.top -side top -fill x
787
788  message .uneditflag.middle -text $mess -aspect 200
789  pack .uneditflag.middle -side top -fill x
790
791  frame .uneditflag.down
792  button .uneditflag.down.remove -text "Unedit" \
793    -command {
794      grab release .uneditflag
795      destroy .uneditflag
796      cvs_unedit [workdir_list_files]
797    }
798  button .uneditflag.down.cancel -text "Cancel" \
799    -command { grab release .uneditflag; destroy .uneditflag }
800  pack .uneditflag.down -side bottom -fill x -expand 1
801  pack .uneditflag.down.remove .uneditflag.down.cancel -side left \
802    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
803
804  wm title .uneditflag "Unedit Files"
805  wm minsize .uneditflag 1 1
806
807  gen_log:log T "LEAVE"
808}
809
810#
811# Set up a small(?) update dialog.
812#
813proc cvs_update_options {} {
814  global cvsglb
815  global cvscfg
816
817  gen_log:log T "ENTER"
818
819  if {[winfo exists .update]} {
820    wm deiconify .update
821    raise .update
822    grab set .update
823    gen_log:log T "LEAVE"
824    return
825  }
826
827  # Set defaults
828  if {! [info exists cvsglb(tagmode_selection)]} {
829    update_set_defaults
830  }
831
832  toplevel .update
833  grab set .update
834  frame .update.explaintop
835  # Provide an explanation of this dialog box
836  label .update.explaintop.explain -relief raised -bd 1 \
837    -text "Update files in local directory"
838
839  frame .update.options
840  frame .update.options.whichrev -relief groove -border 2
841  frame .update.options.diropts -relief groove -border 2
842  frame .update.options.normbin -relief groove -border 2
843
844  frame .update.down
845
846  # Always pack OK/Cancel first so they don't disappear
847  pack .update.down -side bottom -fill x
848  pack .update.explaintop -side top -fill x -pady 1
849  pack .update.explaintop.explain -side top -fill x -pady 1
850  pack .update.options -side top -fill x -pady 1
851
852  pack .update.options.whichrev -side top -fill x
853  pack .update.options.diropts -side top -fill x
854  pack .update.options.normbin -side top -fill x
855
856  # keep-same-tag update
857  radiobutton .update.options.whichrev.keep \
858    -text "Keep same branch or trunk" \
859    -variable cvsglb(tagmode_selection) -value "Keep" -anchor w \
860    -command {.update.options.whichrev.getrev.lblentry.tname configure -state disabled
861              .update.options.whichrev.getrev.lblentry.dirtag configure -state disabled}
862  # update to the head revision
863  radiobutton .update.options.whichrev.trunk \
864    -text "Update local files to be on main trunk (-A)" \
865    -variable cvsglb(tagmode_selection) -value "Trunk" -anchor w \
866    -command {.update.options.whichrev.getrev.lblentry.tname configure -state disabled
867              .update.options.whichrev.getrev.lblentry.dirtag configure -state disabled}
868  # update to different branch/tag or not
869  radiobutton .update.options.whichrev.tag \
870    -text "Update (-r) local files to be on tag/branch" \
871    -variable cvsglb(tagmode_selection) -value "Getrev" -anchor w \
872    -command {.update.options.whichrev.getrev.lblentry.tname configure -state normal
873              .update.options.whichrev.getrev.lblentry.dirtag configure -state normal}
874
875  message .update.options.whichrev.explainkeep -font $cvscfg(listboxfont) \
876    -justify left -width 400 \
877    -text "If local directory is on main trunk, get latest on main trunk.
878If local directory is on a branch, get latest on that branch.
879If local directory/file has \"sticky\" non-branch tag, no update."
880  message .update.options.whichrev.explaintrunk -font $cvscfg(listboxfont) \
881    -justify left -width 400 \
882    -text "Advice:  If your local directories are currently on a branch,
883you may want to commit any local changes to that branch first."
884
885  pack .update.options.whichrev.keep -side top -fill x
886  pack .update.options.whichrev.explainkeep \
887    -side top -fill x -pady 1 -ipady 0
888  pack .update.options.whichrev.trunk -side top -fill x
889  pack .update.options.whichrev.explaintrunk \
890    -side top -fill x -pady 1 -ipady 0
891  pack .update.options.whichrev.tag -side top -fill x
892
893  frame .update.options.whichrev.getrev
894  frame .update.options.whichrev.getrev.lblentry
895  label .update.options.whichrev.getrev.lblentry.tlbl -text "Tag Name" -anchor w
896  entry .update.options.whichrev.getrev.lblentry.tname -relief sunken \
897    -textvariable cvsglb(updatename)
898  button .update.options.whichrev.getrev.lblentry.dirtag -text "Dir Tag" \
899    -command {
900    set cvsglb(updatename) $current_tagname
901    }
902  message .update.options.whichrev.getrev.explaintag -font $cvscfg(listboxfont) \
903    -justify left -width 400 \
904    -text "Advice:  Update local files to main trunk (head) first.
905Note:  The tag will be 'sticky' for the directory and for each file."
906
907  pack .update.options.whichrev.getrev -side top -expand 1 -fill x
908  pack .update.options.whichrev.getrev.lblentry -side top -expand 1 -fill x
909  pack .update.options.whichrev.getrev.lblentry.tlbl -side left
910  pack .update.options.whichrev.getrev.lblentry.tname -side left -fill x -padx 2 -pady 4
911  pack .update.options.whichrev.getrev.lblentry.dirtag -side left -fill x -padx 2 -pady 4
912  pack .update.options.whichrev.getrev.explaintag \
913    -side top -fill x -pady 1 -ipady 0
914
915  # Where user chooses the action to take if tag is not on a file
916  label .update.options.whichrev.getrev.asknotfound \
917    -text "If file doesn't exist on this branch/tag:" -anchor w
918  frame .update.options.whichrev.getrev.notfound
919  radiobutton .update.options.whichrev.getrev.notfound.remove \
920    -text "Remove file from local directory" \
921    -variable cvsglb(action_notag) -value "Remove"
922  radiobutton .update.options.whichrev.getrev.notfound.gethead \
923    -text "Get head revision (-f)" \
924    -variable cvsglb(action_notag) -value "Get_head"
925
926  pack .update.options.whichrev.getrev.asknotfound -side top -fill x
927  pack .update.options.whichrev.getrev.notfound -side top -expand 1 -fill x
928  pack .update.options.whichrev.getrev.notfound.remove -side left
929  pack .update.options.whichrev.getrev.notfound.gethead -side left
930
931  # Recurse or not.
932  frame .update.options.diropts.radio1
933  radiobutton .update.options.diropts.radio1.recurse -text "Recurse the subdirectories" \
934     -variable cvsglb(update_recurse) -value "recurse" -anchor w \
935     -command {
936              .update.options.diropts.getdir configure -state normal
937              .update.options.diropts.prune configure -state normal
938              .update.options.diropts.lblentry.tdir configure -state normal
939              }
940  radiobutton .update.options.diropts.radio1.local -text "This directory only (-l)" \
941     -variable cvsglb(update_recurse) -value "local" -anchor w \
942     -command {
943              .update.options.diropts.getdir configure -state disabled
944              .update.options.diropts.prune configure -state disabled
945              .update.options.diropts.lblentry.tdir configure -state disabled
946              }
947
948  pack .update.options.diropts.radio1 -side top -expand 1 -fill x
949  pack .update.options.diropts.radio1.recurse -side left
950  pack .update.options.diropts.radio1.local -side left
951
952  label .update.options.diropts.prunelbl \
953    -text "\nIf directory is here but no longer in repository:" -anchor w
954  checkbutton .update.options.diropts.prune -text "Prune it (-P)" \
955     -variable cvsglb(update_prune) -onvalue "prune" -offvalue "no-prune" -anchor w
956  # Where user chooses whether to pick up directories not currently in local
957  label .update.options.diropts.getlbl \
958    -text "If directory is in repository but not in local:" -anchor w
959  checkbutton .update.options.diropts.getdir -text "Get it (-d)" \
960    -variable cvsglb(get_all_dirs) -onvalue "Yes" -offvalue "No" -anchor w \
961    -command {
962               if {$cvsglb(get_all_dirs) != "Yes"} {
963                 .update.options.diropts.lblentry.tdir configure -state disabled
964               } else {
965                 .update.options.diropts.lblentry.tdir configure -state normal
966               }
967             }
968  frame .update.options.diropts.lblentry
969  label .update.options.diropts.lblentry.tlbl -text "Specific directory (optional)" -anchor w
970  entry .update.options.diropts.lblentry.tdir -relief sunken -state disabled \
971    -textvariable cvsglb(getdirname)
972  # State of top radiobuttons (keep same, main, or tag)
973  if {$cvsglb(tagmode_selection) != "Getrev"} {
974    .update.options.whichrev.getrev.lblentry.tname configure -state disabled
975    .update.options.whichrev.getrev.lblentry.dirtag configure -state disabled
976  }
977  # state of -l radiobuttons
978  if {$cvsglb(update_recurse) != "recurse"} {
979    .update.options.diropts.getdir configure -state disabled
980    .update.options.diropts.prune configure -state disabled
981    .update.options.diropts.lblentry.tdir configure -state disabled
982  }
983  # State of -d checkbutton
984  if {$cvsglb(get_all_dirs) != "Yes"} {
985    .update.options.diropts.lblentry.tdir configure -state disabled
986  }
987
988  pack .update.options.diropts.prunelbl -side top -expand 1 -fill x
989  pack .update.options.diropts.prune -side top -expand 1 -fill x
990  pack .update.options.diropts.getlbl -side top -expand 1 -fill x
991  pack .update.options.diropts.getdir -side top -expand 1 -fill x
992  pack .update.options.diropts.lblentry -side top -expand 1 -fill x
993  pack .update.options.diropts.lblentry.tlbl -side left
994  pack .update.options.diropts.lblentry.tdir -side left -fill x -padx 2 -pady 4
995
996  # normal or binary?
997  label .update.options.normbin.lnormbin -text "Treat files as:" -anchor w
998  frame .update.options.normbin.radio
999  radiobutton .update.options.normbin.radio.normalfile -text "Normal file" \
1000    -variable cvsglb(norm_bin) -value "Normal" -anchor w
1001  radiobutton .update.options.normbin.radio.binaryfile -text "Binary file (-kb)" \
1002    -variable cvsglb(norm_bin) -value "Binary" -anchor w
1003
1004  pack .update.options.normbin.lnormbin -side top -fill both
1005  pack .update.options.normbin.radio -side top -expand 1 -fill x
1006  pack .update.options.normbin.radio.normalfile -side left
1007  pack .update.options.normbin.radio.binaryfile -side left
1008
1009  # The OK/Cancel buttons
1010  button .update.ok -text "OK" \
1011    -command { grab release .update; wm withdraw .update; update_with_options }
1012  button .update.apply -text "Apply" \
1013    -command update_with_options
1014  button .update.reset -text "Reset defaults" \
1015    -command update_set_defaults
1016  button .update.quit -text "Close" \
1017    -command { grab release .update; wm withdraw .update }
1018
1019  pack .update.ok .update.apply .update.reset .update.quit -in .update.down \
1020    -side left -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
1021
1022  # Window Manager stuff
1023  wm title .update "Update a Module"
1024  wm minsize .update 1 1
1025  gen_log:log T "LEAVE"
1026}
1027
1028# Set defaults for "Update with Options" dialog
1029proc update_set_defaults {} {
1030  global cvsglb
1031
1032  set cvsglb(tagmode_selection) "Keep"
1033  set cvsglb(updatename) ""
1034  set cvsglb(update_recurse) "recurse"
1035  set cvsglb(action_notag) "Remove"
1036  set cvsglb(update_prune) "prune"
1037  set cvsglb(get_all_dirs) "No"
1038  set cvsglb(getdirname) ""
1039  set cvsglb(norm_bin) "Normal"
1040}
1041
1042# Do what was setup in the "Update with Options" dialog
1043proc update_with_options {} {
1044  global cvsglb
1045
1046  gen_log:log T "ENTER"
1047
1048  if { $cvsglb(updatename) == "" } {
1049    set tagname "BASE"
1050  } else {
1051    set tagname $cvsglb(updatename)
1052  }
1053  if { $cvsglb(get_all_dirs) == "No" } { set cvsglb(getdirname) "" }
1054  if { $cvsglb(getdirname) == "" } {
1055    set dirname " "
1056  } else {
1057    set dirname $cvsglb(getdirname)
1058  }
1059  #puts "from update_setup, tagname $tagname.  norm_bin $cvsglb(norm_bin)"
1060  if { $cvsglb(tagmode_selection) == "Keep" } {
1061    set tagname "BASE"
1062  } elseif { $cvsglb(tagmode_selection) == "Trunk" } {
1063    set tagname "HEAD"
1064  }
1065
1066  eval "cvs_update {$tagname} {$cvsglb(norm_bin)} \
1067       {$cvsglb(action_notag)} \
1068       {$cvsglb(update_recurse)} {$cvsglb(update_prune)} \
1069       {$cvsglb(get_all_dirs)} {$dirname} \
1070       [workdir_list_files]"
1071
1072  gen_log:log T "LEAVE"
1073}
1074
1075proc addir_dialog {args} {
1076  global cvs
1077  global incvs
1078
1079  gen_log:log T "ENTER ($args)"
1080  if {! $incvs} {
1081    cvs_notincvs
1082    return 1
1083  }
1084
1085  set binflag ""
1086  toplevel .add
1087  grab set .add
1088
1089  set filelist [join $args]
1090  if {$filelist == ""} {
1091    set mess "This will add all new directories"
1092  } else {
1093    set mess "This will add these directories:\n\n"
1094    foreach file $filelist {
1095      append mess "   $file\n"
1096    }
1097  }
1098
1099  message .add.top -justify left -aspect 300 -relief groove \
1100    -text "Add (recursively) a directory to the module.\
1101           The repository will not be changed until you do a commit."
1102  pack .add.top -side top -fill x
1103
1104  message .add.middle -text $mess -aspect 200
1105  pack .add.middle -side top -fill x
1106
1107  checkbutton .add.binary -text "-kb (binary)" \
1108     -variable binflag -onvalue "-kb" -offvalue ""
1109  pack .add.binary -side top
1110
1111  frame .add.down
1112  button .add.down.add -text "Add" \
1113    -command {
1114      grab release .add
1115      destroy .add
1116      foreach dir [workdir_list_files] {
1117        cvs_add_dir $binflag $dir
1118      }
1119    }
1120  button .add.down.cancel -text "Cancel" \
1121    -command { grab release .add; destroy .add }
1122  pack .add.down -side bottom -fill x -expand 1
1123  pack .add.down.add .add.down.cancel -side left \
1124    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
1125
1126  wm title .add "Add Directories"
1127  wm minsize .add 1 1
1128
1129  gen_log:log T "LEAVE"
1130}
1131
1132proc subtractdir_dialog {args} {
1133  global cvs
1134  global incvs
1135
1136  gen_log:log T "ENTER ($args)"
1137  if {! $incvs} {
1138    cvs_notincvs
1139    return 1
1140  }
1141
1142  set filelist [join $args]
1143  if {$filelist == ""} {
1144    cvsfail "Please select some directories to remove first!" .workdir
1145    return
1146  }
1147
1148  toplevel .subtract
1149  grab set .subtract
1150
1151  set mess "This will remove these directories:\n\n"
1152  foreach file $filelist {
1153    append mess "   $file\n"
1154  }
1155
1156  message .subtract.top -justify left -aspect 300 -relief groove \
1157    -text "Remove (recursively) a directory from the module.  The repository\
1158           will not be changed until you do a commit."
1159  pack .subtract.top -side top -fill x
1160
1161  message .subtract.middle -text $mess -aspect 200
1162  pack .subtract.middle -side top -fill x
1163  frame .subtract.down
1164  button .subtract.down.remove -text "Remove" \
1165    -command {
1166      grab release .subtract
1167      destroy .subtract
1168      cvs_remove_dir [workdir_list_files]
1169    }
1170  button .subtract.down.cancel -text "Cancel" \
1171    -command { grab release .subtract; destroy .subtract }
1172  pack .subtract.down -side bottom -fill x -expand 1
1173  pack .subtract.down.remove .subtract.down.cancel -side left \
1174    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
1175
1176  wm title .subtract "Remove Directories"
1177  wm minsize .subtract 1 1
1178
1179  gen_log:log T "LEAVE"
1180}
1181
1182proc file_input_and_do {title command} {
1183  global filename
1184
1185  gen_log:log T "ENTER ($title $command)"
1186
1187  toplevel .file_input_and_do
1188  grab set .file_input_and_do
1189
1190  frame .file_input_and_do.top
1191  pack .file_input_and_do.top -side top -fill both -expand 1 -pady 4 -padx 4
1192
1193  label .file_input_and_do.top.lbl -text "File Name" -anchor w
1194  entry .file_input_and_do.top.entry -relief sunken -textvariable filename
1195  bind .file_input_and_do.top.entry <Return> \
1196    { .file_input_and_do.ok invoke }
1197  pack .file_input_and_do.top.lbl -side left
1198  pack .file_input_and_do.top.entry -side left -fill x -expand 1
1199
1200  frame .file_input_and_do.bottom
1201  pack .file_input_and_do.bottom -side bottom -fill x -pady 4 -padx 4
1202
1203  button .file_input_and_do.ok -text "Ok" \
1204    -command "
1205      .file_input_and_do.close invoke
1206      $command \$filename
1207    "
1208  button .file_input_and_do.close -text "Cancel" \
1209    -command {
1210      grab release .file_input_and_do
1211      destroy .file_input_and_do
1212    }
1213  pack .file_input_and_do.ok .file_input_and_do.close \
1214    -in .file_input_and_do.bottom \
1215    -side left -fill both -expand 1
1216
1217  wm title .file_input_and_do $title
1218  wm minsize .file_input_and_do 1 1
1219  focus .file_input_and_do.top.entry
1220
1221  gen_log:log T "LEAVE"
1222}
1223
1224proc release_dialog { args } {
1225
1226  gen_log:log T "ENTER ($args)"
1227
1228  set delflag ""
1229  toplevel .release
1230  grab set .release
1231
1232  set filelist [join $args]
1233  message .release.top -justify left -aspect 300 -relief groove \
1234    -text "Tell CVS that the directory is no longer being\
1235           worked on. CVS will stop tracking it in the\
1236           CVS history file.  Optionally, delete the directory."
1237  pack .release.top -side top -fill x
1238
1239  #set mess "This will release these directories:\n\n"
1240  #foreach file $filelist {
1241    #append mess "   $file\n"
1242  #}
1243  #message .release.middle -text $mess -aspect 200
1244  #pack .release.middle -side top -fill x
1245
1246  checkbutton .release.binary -text "delete (-d)" \
1247     -variable delflag -onvalue "-d" -offvalue ""
1248  pack .release.binary -side top
1249
1250  frame .release.down
1251  button .release.down.release -text "Release" \
1252    -command {
1253      grab release .release
1254      destroy .release
1255      cvs_release $delflag [workdir_list_files]
1256    }
1257  button .release.down.cancel -text "Cancel" \
1258    -command { grab release .release; destroy .release }
1259  pack .release.down -side bottom -fill x -expand 1
1260  pack .release.down.release .release.down.cancel -side left \
1261    -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
1262
1263  wm title .release "Release Directories"
1264  wm minsize .release 1 1
1265
1266  gen_log:log T "LEAVE"
1267}
1268
1269proc svn_update_options {} {
1270  global cvsglb
1271  global cvscfg
1272
1273  gen_log:log T "ENTER"
1274
1275  if {[winfo exists .svn_update]} {
1276    wm deiconify .svn_update
1277    raise .svn_update
1278    grab set .svn_update
1279    gen_log:log T "LEAVE"
1280    return
1281  }
1282
1283  if {! [info exists cvsglb(tagmode_selection)]} {
1284    set cvsglb(tagmode_selection) "Keep"
1285  }
1286
1287  toplevel .svn_update
1288  grab set .svn_update
1289  frame .svn_update.explaintop
1290  frame .svn_update.options
1291  frame .svn_update.down
1292
1293  frame .svn_update.options.keep -relief groove -border 2
1294  frame .svn_update.options.trunk -relief groove -border 2
1295  frame .svn_update.options.branch -relief groove -border 2
1296  frame .svn_update.options.revision -relief groove -border 2
1297
1298  pack .svn_update.down -side bottom -fill x
1299  pack .svn_update.explaintop -side top -fill x -pady 1
1300  pack .svn_update.options -side top -fill x -pady 1
1301
1302  # Provide an explanation of this dialog box
1303  label .svn_update.explain -relief raised -bd 1 \
1304    -text "Update files in local directory"
1305
1306  pack .svn_update.explain \
1307    -in .svn_update.explaintop -side top -fill x
1308
1309  pack .svn_update.options.keep -side top -fill x
1310  pack .svn_update.options.trunk -side top -fill x
1311  pack .svn_update.options.branch -side top -fill x
1312  pack .svn_update.options.revision -side top -fill x
1313
1314  # If the user wants to simply do a normal update
1315  radiobutton .svn_update.options.keep.select \
1316    -text "Update to most recent revision on same branch or trunk." \
1317    -variable cvsglb(tagmode_selection) -value "Keep" -anchor w
1318
1319  message .svn_update.options.keep.explain -font $cvscfg(listboxfont) \
1320    -justify left -width 400 \
1321    -text "If local directory is on main trunk, get latest on main trunk.
1322If local directory is on a branch, get latest on that branch."
1323
1324  pack .svn_update.options.keep.select -side top -fill x
1325  pack .svn_update.options.keep.explain -side top -fill x -pady 1 -ipady 0
1326
1327  # If the user wants to update to the head revision
1328  radiobutton .svn_update.options.trunk.select \
1329    -text "Switch local files to be on main trunk" \
1330    -variable cvsglb(tagmode_selection) -value "Trunk" -anchor w
1331
1332  message .svn_update.options.trunk.explain -font $cvscfg(listboxfont) \
1333    -justify left -width 400 \
1334    -text "Advice:  If your local directories are currently on a branch, \
1335you may want to commit any local changes to that branch first."
1336
1337  pack .svn_update.options.trunk.select -side top -fill x
1338  pack .svn_update.options.trunk.explain -side top -fill x -pady 1 -ipady 0
1339
1340  # If the user wants to update to a branch
1341  radiobutton .svn_update.options.branch.select \
1342    -text "Switch local files to be on a branch" \
1343    -variable cvsglb(tagmode_selection) -value "Branch" -anchor w
1344
1345  frame .svn_update.options.branch.lblentry
1346  label .svn_update.lbranch -text "Branch" -anchor w
1347  entry .svn_update.tbranch -relief sunken -textvariable cvsglb(branchname)
1348
1349  pack .svn_update.options.branch.select -side top -fill x
1350  pack .svn_update.options.branch.lblentry -side top -fill x \
1351    -expand y -pady 1 -ipady 0
1352  pack .svn_update.lbranch -in .svn_update.options.branch.lblentry \
1353    -side left -fill x -pady 4
1354  pack .svn_update.tbranch -in .svn_update.options.branch.lblentry \
1355    -side left -fill x -padx 2 -pady 4
1356
1357  # Where user enters a revision number
1358  radiobutton .svn_update.options.revision.select \
1359    -text "Update (-r) local files to be a specific revision:" \
1360    -variable cvsglb(tagmode_selection) -value "Revision" -anchor w
1361
1362  frame .svn_update.options.revision.lblentry
1363  label .svn_update.lrev -text "Revision" -anchor w
1364  entry .svn_update.trev -relief sunken -textvariable cvsglb(revnumber)
1365
1366  pack .svn_update.options.revision.select -side top -fill x
1367  pack .svn_update.options.revision.lblentry -side top -fill x \
1368    -expand y -pady 1 -ipady 0
1369  pack .svn_update.lrev -in .svn_update.options.revision.lblentry \
1370    -side left -fill x -pady 4
1371  pack .svn_update.trev -in .svn_update.options.revision.lblentry \
1372    -side left -fill x -padx 2 -pady 4
1373
1374  # The OK/Cancel buttons
1375  button .svn_update.ok -text "OK" \
1376    -command { grab release .svn_update
1377               wm withdraw .svn_update
1378               svn_opt_update }
1379
1380  button .svn_update.apply -text "Apply" \
1381    -command svn_opt_update
1382
1383  button .svn_update.quit -text "Close" \
1384    -command { grab release .svn_update
1385               wm withdraw .svn_update }
1386
1387  pack .svn_update.ok .svn_update.apply .svn_update.quit -in .svn_update.down \
1388    -side left -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
1389
1390  # Window Manager stuff
1391  wm title .svn_update "Update from Repository"
1392  wm minsize .svn_update 1 1
1393  gen_log:log T "LEAVE"
1394}
1395
1396proc assemble_mergetags {from} {
1397  global cvscfg
1398  global current_tagname
1399
1400  gen_log:log T "ENTER ($from)"
1401
1402  # Construct tag names
1403  set totagbegin [string first "_BRANCH_" $cvscfg(mergetoformat)]
1404  set totagend [expr {$totagbegin + 8}]
1405  set toprefix [string range $cvscfg(mergetoformat) 0 [expr {$totagbegin - 1}]]
1406  set fromtagbegin [string first "_BRANCH_" $cvscfg(mergefromformat)]
1407  set fromprefix [string range $cvscfg(mergefromformat) 0 [expr {$fromtagbegin - 1}]]
1408  set datef [string range $cvscfg(mergetoformat) $totagend end]
1409  set today [clock format [clock seconds] -format "$datef"]
1410
1411  if {[llength $current_tagname] == 1} {
1412    set curr_tag $current_tagname
1413  } else {
1414    set curr_tag "trunk"
1415  }
1416
1417  set curr $curr_tag
1418  gen_log:log D "curr_tag $curr"
1419  if {$curr == "trunk"} {set curr $cvscfg(mergetrunkname)}
1420  if {$from == "trunk"} {set from $cvscfg(mergetrunkname)}
1421  set totag "${toprefix}_${curr}_$today"
1422  set fromtag "${fromprefix}_${from}_$today"
1423  # I had symbolic tags in mind, but some people are using untagged versions.
1424  # Substitute the dots, which are illegal for tagnames.
1425  regsub -all {\.} $totag {-} totag
1426  regsub -all {\.} $fromtag {-} fromtag
1427
1428  gen_log:log T "LEAVE ($curr_tag $fromtag $totag)"
1429  return [list $curr_tag $fromtag $totag]
1430}
1431
1432proc dialog_merge_notice {sys from frombranch fromtag totag filelist} {
1433  global cvscfg
1434
1435  toplevel .reminder
1436  wm title .reminder "Tag and Commit"
1437  label .reminder.m1 -text \
1438    "Now, you must examine the merged files and resolve any conflicts.\
1439    \nLeave this dialog up, and when you are ready to commit,\
1440    press the Ready button"
1441  button .reminder.ready -text "I'm ready" \
1442    -command {
1443       foreach w {m2 totag fromtag bottom.ok} {
1444         .reminder.$w configure -state normal
1445       }
1446       foreach w {m1 ready} {
1447         .reminder.$w configure -state disabled
1448       }
1449    }
1450  label .reminder.m2 -text \
1451    "If you check the box, TkCVS will apply the \"to\" tag,\
1452    \ncommit your changes, and finally\napply the \"from\" tag.\
1453    \nIf you don't check the box, the changes will be committed\
1454    \nbut no tagging will be done"
1455  checkbutton .reminder.autotag -text "Apply these tags" \
1456    -variable cvscfg(auto_tag)
1457  entry .reminder.totag -width 32
1458  .reminder.totag insert end $totag
1459  entry .reminder.fromtag -width 32
1460  .reminder.fromtag insert end $fromtag
1461  frame .reminder.bottom -relief raised -bd 2
1462  button .reminder.bottom.cancel -text "Cancel" \
1463    -command {destroy .reminder}
1464  button .reminder.bottom.ok -text "OK" \
1465    -command "${sys}_merge_tag_seq $from $frombranch $totag $fromtag $filelist;\
1466              destroy .reminder"
1467  pack .reminder.bottom -side bottom -fill x
1468  pack .reminder.bottom.ok -side left -expand yes
1469  pack .reminder.bottom.cancel -side right -expand yes
1470  pack .reminder.m1 -side top
1471  pack .reminder.ready -side top
1472  pack .reminder.m2 -side top
1473  pack .reminder.autotag -side top
1474  pack .reminder.fromtag -side top -padx 2
1475  pack .reminder.totag -side top -padx 2
1476  foreach w {m2 totag fromtag bottom.ok} {
1477    .reminder.$w configure -state disabled
1478  }
1479}
1480
1481# Keep a log of commit log messages.  We want to do this whether the
1482# history has ever been examined by the user or not
1483proc commit_history {comment} {
1484  global cvsglb
1485
1486  set comment [string trimright $comment]
1487  set c 0
1488  foreach ch [array names cvsglb commit_comment,*] {
1489    if {$comment eq $cvsglb($ch)} {
1490      # We already have this one.  We don't have to
1491      # do anything else.
1492      gen_log:log D "Comment is a duplicate"
1493      return
1494    }
1495    incr c
1496  }
1497  # We don't have this one yet
1498  set cvsglb(commit_comment,$c) $comment
1499  gen_log:log D "New comment $c"
1500  if [winfo exists .ci_history] {
1501    .ci_history.text insert end "$comment"
1502    .ci_history.text insert end "\n"
1503    .ci_history.text insert end "================================================================================\n"
1504  }
1505}
1506
1507# See the previous log messages
1508proc history_browser {} {
1509  global cvsglb
1510
1511  gen_log:log T "ENTER history_browser"
1512
1513  if {! [winfo exists .ci_history]} {
1514    toplevel .ci_history
1515    wm protocol .ci_history WM_DELETE_WINDOW { wm withdraw .ci_history }
1516    wm title .ci_history "Commit Log History for Session"
1517
1518    text .ci_history.text -setgrid yes -relief sunken -border 2 \
1519      -exportselection 1 -yscroll ".ci_history.scroll set"
1520    scrollbar .ci_history.scroll -relief sunken \
1521      -command ".ci_history.text yview"
1522    frame .ci_history.bottom
1523    search_textwidget_init
1524    button .ci_history.bottom.srchbtn -text Search \
1525      -command "search_textwidget .ci_history.text"
1526    entry .ci_history.bottom.entry -width 20 -textvariable cvsglb(searchstr)
1527    bind .ci_history.bottom.entry <Return> \
1528        "search_textwidget .ci_history.text"
1529    button .ci_history.bottom.close -text "Close" \
1530       -command { wm withdraw .ci_history }
1531
1532    pack .ci_history.bottom -side bottom -fill x
1533    pack .ci_history.scroll -side right -fill y
1534    pack .ci_history.text -fill both -expand 1
1535    pack .ci_history.bottom.srchbtn -side left
1536    pack .ci_history.bottom.entry -side left
1537    pack .ci_history.bottom.close -side right
1538
1539    # If this is the first time we've built the window, add the history we have so far
1540    foreach ch [array names cvsglb commit_comment,*] {
1541      .ci_history.text insert end $cvsglb($ch)
1542      .ci_history.text insert end "\n"
1543      .ci_history.text insert end "================================================================================\n"
1544    }
1545  }
1546
1547  wm deiconify .ci_history
1548  gen_log:log T "LEAVE"
1549}
1550