blob: b5c9e7a1b4165d34d7aec1beb670a6b268ff8375 [file] [log] [blame]
Paul Mackerras1db95b02005-05-09 04:08:39 +00001#!/bin/sh
2# Tcl ignores the next line -*- tcl -*- \
Paul Mackerras9e026d32005-09-27 10:29:41 +10003exec wish "$0" -- "$@"
Paul Mackerras1db95b02005-05-09 04:08:39 +00004
Paul Mackerrase1a7c812006-07-18 01:52:14 +10005# Copyright (C) 2005-2006 Paul Mackerras. All rights reserved.
Paul Mackerras1db95b02005-05-09 04:08:39 +00006# This program is free software; it may be used, copied, modified
7# and distributed under the terms of the GNU General Public Licence,
8# either version 2, or (at your option) any later version.
9
Junio C Hamano73b6a6c2005-07-28 00:28:44 -070010proc gitdir {} {
11 global env
12 if {[info exists env(GIT_DIR)]} {
13 return $env(GIT_DIR)
14 } else {
Peter Baumann5024baa2007-01-09 15:30:19 +010015 return [exec git rev-parse --git-dir]
Junio C Hamano73b6a6c2005-07-28 00:28:44 -070016 }
17}
18
Paul Mackerras7eb3cb92007-06-17 14:45:00 +100019# A simple scheduler for compute-intensive stuff.
20# The aim is to make sure that event handlers for GUI actions can
21# run at least every 50-100 ms. Unfortunately fileevent handlers are
22# run before X event handlers, so reading from a fast source can
23# make the GUI completely unresponsive.
24proc run args {
25 global isonrunq runq
26
27 set script $args
28 if {[info exists isonrunq($script)]} return
29 if {$runq eq {}} {
30 after idle dorunq
31 }
32 lappend runq [list {} $script]
33 set isonrunq($script) 1
34}
35
36proc filerun {fd script} {
37 fileevent $fd readable [list filereadable $fd $script]
38}
39
40proc filereadable {fd script} {
41 global runq
42
43 fileevent $fd readable {}
44 if {$runq eq {}} {
45 after idle dorunq
46 }
47 lappend runq [list $fd $script]
48}
49
Paul Mackerras7fcc92b2007-12-03 10:33:01 +110050proc nukefile {fd} {
51 global runq
52
53 for {set i 0} {$i < [llength $runq]} {} {
54 if {[lindex $runq $i 0] eq $fd} {
55 set runq [lreplace $runq $i $i]
56 } else {
57 incr i
58 }
59 }
60}
61
Paul Mackerras7eb3cb92007-06-17 14:45:00 +100062proc dorunq {} {
63 global isonrunq runq
64
65 set tstart [clock clicks -milliseconds]
66 set t0 $tstart
Paul Mackerras7fcc92b2007-12-03 10:33:01 +110067 while {[llength $runq] > 0} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +100068 set fd [lindex $runq 0 0]
69 set script [lindex $runq 0 1]
70 set repeat [eval $script]
71 set t1 [clock clicks -milliseconds]
72 set t [expr {$t1 - $t0}]
73 set runq [lrange $runq 1 end]
74 if {$repeat ne {} && $repeat} {
75 if {$fd eq {} || $repeat == 2} {
76 # script returns 1 if it wants to be readded
77 # file readers return 2 if they could do more straight away
78 lappend runq [list $fd $script]
79 } else {
80 fileevent $fd readable [list filereadable $fd $script]
81 }
82 } elseif {$fd eq {}} {
83 unset isonrunq($script)
84 }
85 set t0 $t1
86 if {$t1 - $tstart >= 80} break
87 }
88 if {$runq ne {}} {
89 after idle dorunq
90 }
91}
92
93# Start off a git rev-list process and arrange to read its output
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100094proc start_rev_list {view} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +100095 global startmsecs
Paul Mackerras9f1afe02006-02-19 22:44:47 +110096 global commfd leftover tclencoding datemode
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +100097 global viewargs viewfiles commitidx viewcomplete vnextroot
Paul Mackerras3e6b8932007-09-15 09:33:39 +100098 global showlocalchanges commitinterest mainheadid
Paul Mackerrasbb3edc82007-09-27 11:00:25 +100099 global progressdirn progresscoords proglastnc curview
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100100 global viewincl viewactive loginstance viewinstances
Paul Mackerras38ad0912005-12-01 22:42:46 +1100101
102 set startmsecs [clock clicks -milliseconds]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000103 set commitidx($view) 0
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +1000104 set viewcomplete($view) 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100105 set viewactive($view) 1
Paul Mackerras6e8c8702007-07-31 21:03:06 +1000106 set vnextroot($view) 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100107 varcinit $view
108
Paul Mackerrasf78e7ab2007-12-07 20:50:09 +1100109 set commits [eval exec git rev-parse --default HEAD --revs-only \
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100110 $viewargs($view)]
111 set viewincl($view) {}
112 foreach c $commits {
113 if {![string match "^*" $c]} {
114 lappend viewincl($view) $c
115 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100116 }
Paul Mackerras418c4c72006-02-07 09:10:18 +1100117 if {[catch {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100118 set fd [open [concat | git log --no-color -z --pretty=raw --parents \
119 --boundary $commits "--" $viewfiles($view)] r]
Paul Mackerras418c4c72006-02-07 09:10:18 +1100120 } err]} {
Paul Mackerras00abadb2007-12-20 10:25:50 +1100121 error_popup "[mc "Error executing git log:"] $err"
Paul Mackerras38ad0912005-12-01 22:42:46 +1100122 exit 1
123 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100124 set i [incr loginstance]
125 set viewinstances($view) [list $i]
126 set commfd($i) $fd
127 set leftover($i) {}
Paul Mackerras3e6b8932007-09-15 09:33:39 +1000128 if {$showlocalchanges} {
129 lappend commitinterest($mainheadid) {dodiffindex}
130 }
Mark Levedahl86da5b62007-07-17 18:42:04 -0400131 fconfigure $fd -blocking 0 -translation lf -eofchar {}
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100132 if {$tclencoding != {}} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000133 fconfigure $fd -encoding $tclencoding
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100134 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100135 filerun $fd [list getcommitlines $fd $i $view]
Christian Stimmingd990ced2007-11-07 18:42:55 +0100136 nowbusy $view [mc "Reading"]
Paul Mackerrasbb3edc82007-09-27 11:00:25 +1000137 if {$view == $curview} {
138 set progressdirn 1
139 set progresscoords {0 0}
140 set proglastnc 0
141 }
Paul Mackerras38ad0912005-12-01 22:42:46 +1100142}
143
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100144proc stop_rev_list {view} {
145 global commfd viewinstances leftover
Paul Mackerras22626ef2006-04-17 09:56:02 +1000146
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100147 foreach inst $viewinstances($view) {
148 set fd $commfd($inst)
149 catch {
150 set pid [pid $fd]
151 exec kill $pid
152 }
153 catch {close $fd}
154 nukefile $fd
155 unset commfd($inst)
156 unset leftover($inst)
Paul Mackerras22626ef2006-04-17 09:56:02 +1000157 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100158 set viewinstances($view) {}
Paul Mackerras22626ef2006-04-17 09:56:02 +1000159}
160
Paul Mackerrasa8aaf192006-04-23 22:45:55 +1000161proc getcommits {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100162 global canv curview
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100163
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000164 initlayout
165 start_rev_list $curview
Christian Stimmingd990ced2007-11-07 18:42:55 +0100166 show_status [mc "Reading commits..."]
Paul Mackerras1d10f362005-05-15 12:55:47 +0000167}
168
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100169proc updatecommits {} {
170 global curview viewargs viewfiles viewincl viewinstances
Paul Mackerras24f7a662007-12-19 09:35:33 +1100171 global viewactive viewcomplete loginstance tclencoding mainheadid
172 global varcid startmsecs commfd showneartags showlocalchanges leftover
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100173
Paul Mackerras24f7a662007-12-19 09:35:33 +1100174 if {$showlocalchanges && [commitinview $mainheadid $curview]} {
175 dodiffindex
176 }
Paul Mackerrasfc2a2562007-12-26 23:03:43 +1100177 rereadrefs
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100178 set view $curview
179 set commits [exec git rev-parse --default HEAD --revs-only \
180 $viewargs($view)]
181 set pos {}
182 set neg {}
183 foreach c $commits {
184 if {[string match "^*" $c]} {
185 lappend neg $c
186 } else {
187 if {!([info exists varcid($view,$c)] ||
188 [lsearch -exact $viewincl($view) $c] >= 0)} {
189 lappend pos $c
190 }
191 }
192 }
193 if {$pos eq {}} {
194 return
195 }
196 foreach id $viewincl($view) {
197 lappend neg "^$id"
198 }
199 set viewincl($view) [concat $viewincl($view) $pos]
200 if {[catch {
201 set fd [open [concat | git log --no-color -z --pretty=raw --parents \
202 --boundary $pos $neg "--" $viewfiles($view)] r]
203 } err]} {
204 error_popup "Error executing git log: $err"
205 exit 1
206 }
207 if {$viewactive($view) == 0} {
208 set startmsecs [clock clicks -milliseconds]
209 }
210 set i [incr loginstance]
211 lappend viewinstances($view) $i
212 set commfd($i) $fd
213 set leftover($i) {}
214 fconfigure $fd -blocking 0 -translation lf -eofchar {}
215 if {$tclencoding != {}} {
216 fconfigure $fd -encoding $tclencoding
217 }
218 filerun $fd [list getcommitlines $fd $i $view]
219 incr viewactive($view)
220 set viewcomplete($view) 0
221 nowbusy $view "Reading"
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100222 if {$showneartags} {
223 getallcommits
224 }
225}
226
227proc reloadcommits {} {
228 global curview viewcomplete selectedline currentid thickerline
229 global showneartags treediffs commitinterest cached_commitrow
230 global progresscoords
231
232 if {!$viewcomplete($curview)} {
233 stop_rev_list $curview
234 set progresscoords {0 0}
235 adjustprogress
236 }
237 resetvarcs $curview
238 catch {unset selectedline}
239 catch {unset currentid}
240 catch {unset thickerline}
241 catch {unset treediffs}
242 readrefs
243 changedrefs
244 if {$showneartags} {
245 getallcommits
246 }
247 clear_display
248 catch {unset commitinterest}
249 catch {unset cached_commitrow}
250 setcanvscroll
251 getcommits
252}
253
Paul Mackerras6e8c8702007-07-31 21:03:06 +1000254# This makes a string representation of a positive integer which
255# sorts as a string in numerical order
256proc strrep {n} {
257 if {$n < 16} {
258 return [format "%x" $n]
259 } elseif {$n < 256} {
260 return [format "x%.2x" $n]
261 } elseif {$n < 65536} {
262 return [format "y%.4x" $n]
263 }
264 return [format "z%.8x" $n]
265}
266
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100267# Procedures used in reordering commits from git log (without
268# --topo-order) into the order for display.
269
270proc varcinit {view} {
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100271 global varcstart vupptr vdownptr vleftptr vbackptr varctok varcrow
272 global vtokmod varcmod vrowmod varcix vlastins
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100273
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100274 set varcstart($view) {{}}
275 set vupptr($view) {0}
276 set vdownptr($view) {0}
277 set vleftptr($view) {0}
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100278 set vbackptr($view) {0}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100279 set varctok($view) {{}}
280 set varcrow($view) {{}}
281 set vtokmod($view) {}
282 set varcmod($view) 0
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100283 set vrowmod($view) 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100284 set varcix($view) {{}}
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100285 set vlastins($view) {0}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100286}
287
288proc resetvarcs {view} {
289 global varcid varccommits parents children vseedcount ordertok
290
291 foreach vid [array names varcid $view,*] {
292 unset varcid($vid)
293 unset children($vid)
294 unset parents($vid)
295 }
296 # some commits might have children but haven't been seen yet
297 foreach vid [array names children $view,*] {
298 unset children($vid)
299 }
300 foreach va [array names varccommits $view,*] {
301 unset varccommits($va)
302 }
303 foreach vd [array names vseedcount $view,*] {
304 unset vseedcount($vd)
305 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100306 catch {unset ordertok}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100307}
308
309proc newvarc {view id} {
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100310 global varcid varctok parents children datemode
311 global vupptr vdownptr vleftptr vbackptr varcrow varcix varcstart
312 global commitdata commitinfo vseedcount varccommits vlastins
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100313
314 set a [llength $varctok($view)]
315 set vid $view,$id
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100316 if {[llength $children($vid)] == 0 || $datemode} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100317 if {![info exists commitinfo($id)]} {
318 parsecommit $id $commitdata($id) 1
319 }
320 set cdate [lindex $commitinfo($id) 4]
321 if {![string is integer -strict $cdate]} {
322 set cdate 0
323 }
324 if {![info exists vseedcount($view,$cdate)]} {
325 set vseedcount($view,$cdate) -1
326 }
327 set c [incr vseedcount($view,$cdate)]
328 set cdate [expr {$cdate ^ 0xffffffff}]
329 set tok "s[strrep $cdate][strrep $c]"
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100330 } else {
331 set tok {}
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100332 }
333 set ka 0
334 if {[llength $children($vid)] > 0} {
335 set kid [lindex $children($vid) end]
336 set k $varcid($view,$kid)
337 if {[string compare [lindex $varctok($view) $k] $tok] > 0} {
338 set ki $kid
339 set ka $k
340 set tok [lindex $varctok($view) $k]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100341 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100342 }
343 if {$ka != 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100344 set i [lsearch -exact $parents($view,$ki) $id]
345 set j [expr {[llength $parents($view,$ki)] - 1 - $i}]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100346 append tok [strrep $j]
347 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100348 set c [lindex $vlastins($view) $ka]
349 if {$c == 0 || [string compare $tok [lindex $varctok($view) $c]] < 0} {
350 set c $ka
351 set b [lindex $vdownptr($view) $ka]
352 } else {
353 set b [lindex $vleftptr($view) $c]
354 }
355 while {$b != 0 && [string compare $tok [lindex $varctok($view) $b]] >= 0} {
356 set c $b
357 set b [lindex $vleftptr($view) $c]
358 }
359 if {$c == $ka} {
360 lset vdownptr($view) $ka $a
361 lappend vbackptr($view) 0
362 } else {
363 lset vleftptr($view) $c $a
364 lappend vbackptr($view) $c
365 }
366 lset vlastins($view) $ka $a
367 lappend vupptr($view) $ka
368 lappend vleftptr($view) $b
369 if {$b != 0} {
370 lset vbackptr($view) $b $a
371 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100372 lappend varctok($view) $tok
373 lappend varcstart($view) $id
374 lappend vdownptr($view) 0
375 lappend varcrow($view) {}
376 lappend varcix($view) {}
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100377 set varccommits($view,$a) {}
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100378 lappend vlastins($view) 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100379 return $a
380}
381
382proc splitvarc {p v} {
383 global varcid varcstart varccommits varctok
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100384 global vupptr vdownptr vleftptr vbackptr varcix varcrow vlastins
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100385
386 set oa $varcid($v,$p)
387 set ac $varccommits($v,$oa)
388 set i [lsearch -exact $varccommits($v,$oa) $p]
389 if {$i <= 0} return
390 set na [llength $varctok($v)]
391 # "%" sorts before "0"...
392 set tok "[lindex $varctok($v) $oa]%[strrep $i]"
393 lappend varctok($v) $tok
394 lappend varcrow($v) {}
395 lappend varcix($v) {}
396 set varccommits($v,$oa) [lrange $ac 0 [expr {$i - 1}]]
397 set varccommits($v,$na) [lrange $ac $i end]
398 lappend varcstart($v) $p
399 foreach id $varccommits($v,$na) {
400 set varcid($v,$id) $na
401 }
402 lappend vdownptr($v) [lindex $vdownptr($v) $oa]
403 lset vdownptr($v) $oa $na
404 lappend vupptr($v) $oa
405 lappend vleftptr($v) 0
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100406 lappend vbackptr($v) 0
407 lappend vlastins($v) 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100408 for {set b [lindex $vdownptr($v) $na]} {$b != 0} {set b [lindex $vleftptr($v) $b]} {
409 lset vupptr($v) $b $na
410 }
411}
412
413proc renumbervarc {a v} {
414 global parents children varctok varcstart varccommits
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100415 global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod datemode
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100416
417 set t1 [clock clicks -milliseconds]
418 set todo {}
419 set isrelated($a) 1
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100420 set kidchanged($a) 1
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100421 set ntot 0
422 while {$a != 0} {
423 if {[info exists isrelated($a)]} {
424 lappend todo $a
425 set id [lindex $varccommits($v,$a) end]
426 foreach p $parents($v,$id) {
427 if {[info exists varcid($v,$p)]} {
428 set isrelated($varcid($v,$p)) 1
429 }
430 }
431 }
432 incr ntot
433 set b [lindex $vdownptr($v) $a]
434 if {$b == 0} {
435 while {$a != 0} {
436 set b [lindex $vleftptr($v) $a]
437 if {$b != 0} break
438 set a [lindex $vupptr($v) $a]
439 }
440 }
441 set a $b
442 }
443 foreach a $todo {
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100444 if {![info exists kidchanged($a)]} continue
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100445 set id [lindex $varcstart($v) $a]
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100446 if {[llength $children($v,$id)] > 1} {
447 set children($v,$id) [lsort -command [list vtokcmp $v] \
448 $children($v,$id)]
449 }
450 set oldtok [lindex $varctok($v) $a]
451 if {!$datemode} {
452 set tok {}
453 } else {
454 set tok $oldtok
455 }
456 set ka 0
457 if {[llength $children($v,$id)] > 0} {
458 set kid [lindex $children($v,$id) end]
459 set k $varcid($v,$kid)
460 if {[string compare [lindex $varctok($v) $k] $tok] > 0} {
461 set ki $kid
462 set ka $k
463 set tok [lindex $varctok($v) $k]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100464 }
465 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100466 if {$ka != 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100467 set i [lsearch -exact $parents($v,$ki) $id]
468 set j [expr {[llength $parents($v,$ki)] - 1 - $i}]
469 append tok [strrep $j]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100470 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100471 if {$tok eq $oldtok} {
472 continue
473 }
474 set id [lindex $varccommits($v,$a) end]
475 foreach p $parents($v,$id) {
476 if {[info exists varcid($v,$p)]} {
477 set kidchanged($varcid($v,$p)) 1
478 } else {
479 set sortkids($p) 1
480 }
481 }
482 lset varctok($v) $a $tok
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100483 set b [lindex $vupptr($v) $a]
484 if {$b != $ka} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100485 if {[string compare [lindex $varctok($v) $ka] $vtokmod($v)] < 0} {
486 modify_arc $v $ka
Paul Mackerras38dfe932007-12-06 20:50:31 +1100487 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100488 if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
489 modify_arc $v $b
Paul Mackerras38dfe932007-12-06 20:50:31 +1100490 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100491 set c [lindex $vbackptr($v) $a]
492 set d [lindex $vleftptr($v) $a]
493 if {$c == 0} {
494 lset vdownptr($v) $b $d
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100495 } else {
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100496 lset vleftptr($v) $c $d
497 }
498 if {$d != 0} {
499 lset vbackptr($v) $d $c
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100500 }
501 lset vupptr($v) $a $ka
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100502 set c [lindex $vlastins($v) $ka]
503 if {$c == 0 || \
504 [string compare $tok [lindex $varctok($v) $c]] < 0} {
505 set c $ka
506 set b [lindex $vdownptr($v) $ka]
507 } else {
508 set b [lindex $vleftptr($v) $c]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100509 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100510 while {$b != 0 && \
511 [string compare $tok [lindex $varctok($v) $b]] >= 0} {
512 set c $b
513 set b [lindex $vleftptr($v) $c]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100514 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100515 if {$c == $ka} {
516 lset vdownptr($v) $ka $a
517 lset vbackptr($v) $a 0
518 } else {
519 lset vleftptr($v) $c $a
520 lset vbackptr($v) $a $c
521 }
522 lset vleftptr($v) $a $b
523 if {$b != 0} {
524 lset vbackptr($v) $b $a
525 }
526 lset vlastins($v) $ka $a
527 }
528 }
529 foreach id [array names sortkids] {
530 if {[llength $children($v,$id)] > 1} {
531 set children($v,$id) [lsort -command [list vtokcmp $v] \
532 $children($v,$id)]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100533 }
534 }
535 set t2 [clock clicks -milliseconds]
536 #puts "renumbervarc did [llength $todo] of $ntot arcs in [expr {$t2-$t1}]ms"
537}
538
539proc fix_reversal {p a v} {
Paul Mackerras24f7a662007-12-19 09:35:33 +1100540 global varcid varcstart varctok vupptr
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100541
542 set pa $varcid($v,$p)
543 if {$p ne [lindex $varcstart($v) $pa]} {
544 splitvarc $p $v
545 set pa $varcid($v,$p)
546 }
Paul Mackerras24f7a662007-12-19 09:35:33 +1100547 # seeds always need to be renumbered
548 if {[lindex $vupptr($v) $pa] == 0 ||
549 [string compare [lindex $varctok($v) $a] \
550 [lindex $varctok($v) $pa]] > 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100551 renumbervarc $pa $v
552 }
553}
554
555proc insertrow {id p v} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100556 global varcid varccommits parents children cmitlisted
557 global commitidx varctok vtokmod
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100558
559 set a $varcid($v,$p)
560 set i [lsearch -exact $varccommits($v,$a) $p]
561 if {$i < 0} {
562 puts "oops: insertrow can't find [shortids $p] on arc $a"
563 return
564 }
565 set children($v,$id) {}
566 set parents($v,$id) [list $p]
567 set varcid($v,$id) $a
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100568 lappend children($v,$p) $id
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100569 set cmitlisted($v,$id) 1
570 incr commitidx($v)
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100571 # note we deliberately don't update varcstart($v) even if $i == 0
572 set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id]
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100573 if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100574 modify_arc $v $a $i
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100575 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100576 drawvisible
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100577}
578
579proc removerow {id v} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100580 global varcid varccommits parents children commitidx
Paul Mackerrasfc2a2562007-12-26 23:03:43 +1100581 global varctok vtokmod cmitlisted currentid selectedline
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100582
583 if {[llength $parents($v,$id)] != 1} {
584 puts "oops: removerow [shortids $id] has [llength $parents($v,$id)] parents"
585 return
586 }
587 set p [lindex $parents($v,$id) 0]
588 set a $varcid($v,$id)
589 set i [lsearch -exact $varccommits($v,$a) $id]
590 if {$i < 0} {
591 puts "oops: removerow can't find [shortids $id] on arc $a"
592 return
593 }
594 unset varcid($v,$id)
595 set varccommits($v,$a) [lreplace $varccommits($v,$a) $i $i]
596 unset parents($v,$id)
597 unset children($v,$id)
598 unset cmitlisted($v,$id)
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100599 incr commitidx($v) -1
600 set j [lsearch -exact $children($v,$p) $id]
601 if {$j >= 0} {
602 set children($v,$p) [lreplace $children($v,$p) $j $j]
603 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100604 if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100605 modify_arc $v $a $i
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100606 }
Paul Mackerrasfc2a2562007-12-26 23:03:43 +1100607 if {[info exist currentid] && $id eq $currentid} {
608 unset currentid
609 unset selectedline
610 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100611 drawvisible
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100612}
613
614proc vtokcmp {v a b} {
615 global varctok varcid
616
617 return [string compare [lindex $varctok($v) $varcid($v,$a)] \
618 [lindex $varctok($v) $varcid($v,$b)]]
619}
620
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100621proc modify_arc {v a {lim {}}} {
622 global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits
Paul Mackerras24f7a662007-12-19 09:35:33 +1100623 global vhighlights nhighlights fhighlights rhighlights
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100624
625 set vtokmod($v) [lindex $varctok($v) $a]
626 set varcmod($v) $a
627 if {$v == $curview} {
628 while {$a != 0 && [lindex $varcrow($v) $a] eq {}} {
629 set a [lindex $vupptr($v) $a]
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100630 set lim {}
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100631 }
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100632 set r 0
633 if {$a != 0} {
634 if {$lim eq {}} {
635 set lim [llength $varccommits($v,$a)]
636 }
637 set r [expr {[lindex $varcrow($v) $a] + $lim}]
638 }
639 set vrowmod($v) $r
Paul Mackerras0c278862007-12-11 20:09:53 +1100640 undolayout $r
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100641 }
Paul Mackerras24f7a662007-12-19 09:35:33 +1100642 catch {unset nhighlights}
643 catch {unset fhighlights}
644 catch {unset vhighlights}
645 catch {unset rhighlights}
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100646}
647
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100648proc update_arcrows {v} {
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100649 global vtokmod varcmod vrowmod varcrow commitidx currentid selectedline
Paul Mackerras24f7a662007-12-19 09:35:33 +1100650 global varcid vrownum varcorder varcix varccommits
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100651 global vupptr vdownptr vleftptr varctok
Paul Mackerras24f7a662007-12-19 09:35:33 +1100652 global displayorder parentlist curview cached_commitrow
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100653
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100654 set narctot [expr {[llength $varctok($v)] - 1}]
655 set a $varcmod($v)
656 while {$a != 0 && [lindex $varcix($v) $a] eq {}} {
657 # go up the tree until we find something that has a row number,
658 # or we get to a seed
659 set a [lindex $vupptr($v) $a]
660 }
661 if {$a == 0} {
662 set a [lindex $vdownptr($v) 0]
663 if {$a == 0} return
664 set vrownum($v) {0}
665 set varcorder($v) [list $a]
666 lset varcix($v) $a 0
667 lset varcrow($v) $a 0
668 set arcn 0
669 set row 0
670 } else {
671 set arcn [lindex $varcix($v) $a]
672 # see if a is the last arc; if so, nothing to do
673 if {$arcn == $narctot - 1} {
674 return
675 }
676 if {[llength $vrownum($v)] > $arcn + 1} {
677 set vrownum($v) [lrange $vrownum($v) 0 $arcn]
678 set varcorder($v) [lrange $varcorder($v) 0 $arcn]
679 }
680 set row [lindex $varcrow($v) $a]
681 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100682 if {$v == $curview} {
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100683 if {[llength $displayorder] > $vrowmod($v)} {
684 set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]]
685 set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]]
686 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100687 catch {unset cached_commitrow}
688 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100689 while {1} {
690 set p $a
691 incr row [llength $varccommits($v,$a)]
692 # go down if possible
693 set b [lindex $vdownptr($v) $a]
694 if {$b == 0} {
695 # if not, go left, or go up until we can go left
696 while {$a != 0} {
697 set b [lindex $vleftptr($v) $a]
698 if {$b != 0} break
699 set a [lindex $vupptr($v) $a]
700 }
701 if {$a == 0} break
702 }
703 set a $b
704 incr arcn
705 lappend vrownum($v) $row
706 lappend varcorder($v) $a
707 lset varcix($v) $a $arcn
708 lset varcrow($v) $a $row
709 }
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100710 set vtokmod($v) [lindex $varctok($v) $p]
711 set varcmod($v) $p
712 set vrowmod($v) $row
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100713 if {[info exists currentid]} {
714 set selectedline [rowofcommit $currentid]
715 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100716}
717
718# Test whether view $v contains commit $id
719proc commitinview {id v} {
720 global varcid
721
722 return [info exists varcid($v,$id)]
723}
724
725# Return the row number for commit $id in the current view
726proc rowofcommit {id} {
727 global varcid varccommits varcrow curview cached_commitrow
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100728 global varctok vtokmod
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100729
730 if {[info exists cached_commitrow($id)]} {
731 return $cached_commitrow($id)
732 }
733 set v $curview
734 if {![info exists varcid($v,$id)]} {
735 puts "oops rowofcommit no arc for [shortids $id]"
736 return {}
737 }
738 set a $varcid($v,$id)
Paul Mackerrasfc2a2562007-12-26 23:03:43 +1100739 if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] >= 0} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100740 update_arcrows $v
741 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100742 set i [lsearch -exact $varccommits($v,$a) $id]
743 if {$i < 0} {
744 puts "oops didn't find commit [shortids $id] in arc $a"
745 return {}
746 }
747 incr i [lindex $varcrow($v) $a]
748 set cached_commitrow($id) $i
749 return $i
750}
751
752proc bsearch {l elt} {
753 if {[llength $l] == 0 || $elt <= [lindex $l 0]} {
754 return 0
755 }
756 set lo 0
757 set hi [llength $l]
758 while {$hi - $lo > 1} {
759 set mid [expr {int(($lo + $hi) / 2)}]
760 set t [lindex $l $mid]
761 if {$elt < $t} {
762 set hi $mid
763 } elseif {$elt > $t} {
764 set lo $mid
765 } else {
766 return $mid
767 }
768 }
769 return $lo
770}
771
772# Make sure rows $start..$end-1 are valid in displayorder and parentlist
773proc make_disporder {start end} {
774 global vrownum curview commitidx displayorder parentlist
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100775 global varccommits varcorder parents vrowmod varcrow
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100776 global d_valid_start d_valid_end
777
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100778 if {$end > $vrowmod($curview)} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100779 update_arcrows $curview
780 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100781 set ai [bsearch $vrownum($curview) $start]
782 set start [lindex $vrownum($curview) $ai]
783 set narc [llength $vrownum($curview)]
784 for {set r $start} {$ai < $narc && $r < $end} {incr ai} {
785 set a [lindex $varcorder($curview) $ai]
786 set l [llength $displayorder]
787 set al [llength $varccommits($curview,$a)]
788 if {$l < $r + $al} {
789 if {$l < $r} {
790 set pad [ntimes [expr {$r - $l}] {}]
791 set displayorder [concat $displayorder $pad]
792 set parentlist [concat $parentlist $pad]
793 } elseif {$l > $r} {
794 set displayorder [lrange $displayorder 0 [expr {$r - 1}]]
795 set parentlist [lrange $parentlist 0 [expr {$r - 1}]]
796 }
797 foreach id $varccommits($curview,$a) {
798 lappend displayorder $id
799 lappend parentlist $parents($curview,$id)
800 }
801 } elseif {[lindex $displayorder $r] eq {}} {
802 set i $r
803 foreach id $varccommits($curview,$a) {
804 lset displayorder $i $id
805 lset parentlist $i $parents($curview,$id)
806 incr i
807 }
808 }
809 incr r $al
810 }
811}
812
813proc commitonrow {row} {
814 global displayorder
815
816 set id [lindex $displayorder $row]
817 if {$id eq {}} {
818 make_disporder $row [expr {$row + 1}]
819 set id [lindex $displayorder $row]
820 }
821 return $id
822}
823
824proc closevarcs {v} {
825 global varctok varccommits varcid parents children
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100826 global cmitlisted commitidx commitinterest vtokmod
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100827
828 set missing_parents 0
829 set scripts {}
830 set narcs [llength $varctok($v)]
831 for {set a 1} {$a < $narcs} {incr a} {
832 set id [lindex $varccommits($v,$a) end]
833 foreach p $parents($v,$id) {
834 if {[info exists varcid($v,$p)]} continue
835 # add p as a new commit
836 incr missing_parents
837 set cmitlisted($v,$p) 0
838 set parents($v,$p) {}
839 if {[llength $children($v,$p)] == 1 &&
840 [llength $parents($v,$id)] == 1} {
841 set b $a
842 } else {
843 set b [newvarc $v $p]
844 }
845 set varcid($v,$p) $b
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100846 if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
847 modify_arc $v $b
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100848 }
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100849 lappend varccommits($v,$b) $p
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100850 incr commitidx($v)
851 if {[info exists commitinterest($p)]} {
852 foreach script $commitinterest($p) {
853 lappend scripts [string map [list "%I" $p] $script]
854 }
855 unset commitinterest($id)
856 }
857 }
858 }
859 if {$missing_parents > 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100860 foreach s $scripts {
861 eval $s
862 }
863 }
864}
865
866proc getcommitlines {fd inst view} {
Paul Mackerras24f7a662007-12-19 09:35:33 +1100867 global cmitlisted commitinterest leftover
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100868 global commitidx commitdata datemode
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100869 global parents children curview hlview
Paul Mackerras9257d8f2007-12-11 10:45:38 +1100870 global vnextroot idpending ordertok
871 global varccommits varcid varctok vtokmod
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000872
Paul Mackerrasd1e46752006-08-16 20:02:32 +1000873 set stuff [read $fd 500000]
Paul Mackerras005a2f42007-07-26 22:36:39 +1000874 # git log doesn't terminate the last commit with a null...
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100875 if {$stuff == {} && $leftover($inst) ne {} && [eof $fd]} {
Paul Mackerras005a2f42007-07-26 22:36:39 +1000876 set stuff "\0"
877 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000878 if {$stuff == {}} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +1000879 if {![eof $fd]} {
880 return 1
881 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100882 global commfd viewcomplete viewactive viewname progresscoords
883 global viewinstances
884 unset commfd($inst)
885 set i [lsearch -exact $viewinstances($view) $inst]
886 if {$i >= 0} {
887 set viewinstances($view) [lreplace $viewinstances($view) $i $i]
Paul Mackerrasb0cdca92007-08-23 19:35:51 +1000888 }
Paul Mackerrasf0654862005-07-18 14:29:03 -0400889 # set it blocking so we wait for the process to terminate
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000890 fconfigure $fd -blocking 1
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000891 if {[catch {close $fd} err]} {
892 set fv {}
893 if {$view != $curview} {
894 set fv " for the \"$viewname($view)\" view"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000895 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000896 if {[string range $err 0 4] == "usage"} {
897 set err "Gitk: error reading commits$fv:\
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300898 bad arguments to git rev-list."
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000899 if {$viewname($view) eq "Command line"} {
900 append err \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300901 " (Note: arguments to gitk are passed to git rev-list\
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000902 to allow selection of commits to be displayed.)"
903 }
904 } else {
905 set err "Error reading commits$fv: $err"
906 }
907 error_popup $err
Paul Mackerras1d10f362005-05-15 12:55:47 +0000908 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100909 if {[incr viewactive($view) -1] <= 0} {
910 set viewcomplete($view) 1
911 # Check if we have seen any ids listed as parents that haven't
912 # appeared in the list
913 closevarcs $view
914 notbusy $view
915 set progresscoords {0 0}
916 adjustprogress
917 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000918 if {$view == $curview} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +1000919 run chewcommits $view
Paul Mackerras9a40c502005-05-12 23:46:16 +0000920 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +1000921 return 0
Paul Mackerras9a40c502005-05-12 23:46:16 +0000922 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000923 set start 0
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100924 set gotsome 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100925 set scripts {}
Paul Mackerrasb490a992005-06-22 10:25:38 +1000926 while 1 {
927 set i [string first "\0" $stuff $start]
928 if {$i < 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100929 append leftover($inst) [string range $stuff $start end]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100930 break
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000931 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000932 if {$start == 0} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100933 set cmit $leftover($inst)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100934 append cmit [string range $stuff 0 [expr {$i - 1}]]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100935 set leftover($inst) {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100936 } else {
937 set cmit [string range $stuff $start [expr {$i - 1}]]
Paul Mackerrasb490a992005-06-22 10:25:38 +1000938 }
939 set start [expr {$i + 1}]
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000940 set j [string first "\n" $cmit]
941 set ok 0
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100942 set listed 1
Paul Mackerrasc961b222007-07-09 22:45:47 +1000943 if {$j >= 0 && [string match "commit *" $cmit]} {
944 set ids [string range $cmit 7 [expr {$j - 1}]]
945 if {[string match {[-<>]*} $ids]} {
946 switch -- [string index $ids 0] {
947 "-" {set listed 0}
948 "<" {set listed 2}
949 ">" {set listed 3}
950 }
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100951 set ids [string range $ids 1 end]
952 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000953 set ok 1
954 foreach id $ids {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100955 if {[string length $id] != 40} {
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000956 set ok 0
957 break
958 }
959 }
960 }
961 if {!$ok} {
Paul Mackerras7e952e72005-06-27 20:04:26 +1000962 set shortcmit $cmit
963 if {[string length $shortcmit] > 80} {
964 set shortcmit "[string range $shortcmit 0 80]..."
965 }
Christian Stimmingd990ced2007-11-07 18:42:55 +0100966 error_popup "[mc "Can't parse git log output:"] {$shortcmit}"
Paul Mackerrasb490a992005-06-22 10:25:38 +1000967 exit 1
968 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000969 set id [lindex $ids 0]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100970 set vid $view,$id
971 if {!$listed && [info exists parents($vid)]} continue
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100972 if {$listed} {
973 set olds [lrange $ids 1 end]
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100974 } else {
975 set olds {}
976 }
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +1100977 set commitdata($id) [string range $cmit [expr {$j + 1}] end]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100978 set cmitlisted($vid) $listed
979 set parents($vid) $olds
980 set a 0
981 if {![info exists children($vid)]} {
982 set children($vid) {}
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +1100983 } elseif {[llength $children($vid)] == 1} {
984 set k [lindex $children($vid) 0]
985 if {[llength $parents($view,$k)] == 1 &&
986 (!$datemode ||
987 $varcid($view,$k) == [llength $varctok($view)] - 1)} {
988 set a $varcid($view,$k)
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100989 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000990 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100991 if {$a == 0} {
992 # new arc
993 set a [newvarc $view $id]
994 }
995 set varcid($vid) $a
Paul Mackerrase5b37ac2007-12-12 18:13:51 +1100996 if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
997 modify_arc $view $a
998 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +1100999 lappend varccommits($view,$a) $id
Paul Mackerrase5b37ac2007-12-12 18:13:51 +11001000
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001001 set i 0
1002 foreach p $olds {
1003 if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
1004 set vp $view,$p
1005 if {[llength [lappend children($vp) $id]] > 1 &&
1006 [vtokcmp $view [lindex $children($vp) end-1] $id] > 0} {
1007 set children($vp) [lsort -command [list vtokcmp $view] \
1008 $children($vp)]
Paul Mackerras9257d8f2007-12-11 10:45:38 +11001009 catch {unset ordertok}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001010 }
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +11001011 if {[info exists varcid($view,$p)]} {
1012 fix_reversal $p $a $view
1013 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001014 }
1015 incr i
1016 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001017
1018 incr commitidx($view)
Paul Mackerras3e6b8932007-09-15 09:33:39 +10001019 if {[info exists commitinterest($id)]} {
1020 foreach script $commitinterest($id) {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001021 lappend scripts [string map [list "%I" $id] $script]
Paul Mackerras3e6b8932007-09-15 09:33:39 +10001022 }
1023 unset commitinterest($id)
1024 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001025 set gotsome 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001026 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001027 if {$gotsome} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001028 run chewcommits $view
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001029 foreach s $scripts {
1030 eval $s
1031 }
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001032 if {$view == $curview} {
1033 # update progress bar
1034 global progressdirn progresscoords proglastnc
1035 set inc [expr {($commitidx($view) - $proglastnc) * 0.0002}]
1036 set proglastnc $commitidx($view)
1037 set l [lindex $progresscoords 0]
1038 set r [lindex $progresscoords 1]
1039 if {$progressdirn} {
1040 set r [expr {$r + $inc}]
1041 if {$r >= 1.0} {
1042 set r 1.0
1043 set progressdirn 0
1044 }
1045 if {$r > 0.2} {
1046 set l [expr {$r - 0.2}]
1047 }
1048 } else {
1049 set l [expr {$l - $inc}]
1050 if {$l <= 0.0} {
1051 set l 0.0
1052 set progressdirn 1
1053 }
1054 set r [expr {$l + 0.2}]
1055 }
1056 set progresscoords [list $l $r]
1057 adjustprogress
1058 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001059 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001060 return 2
Paul Mackerrascfb45632005-05-31 12:14:42 +00001061}
1062
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001063proc chewcommits {view} {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10001064 global curview hlview viewcomplete
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001065 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001066
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001067 if {$view == $curview} {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10001068 layoutmore
1069 if {$viewcomplete($view)} {
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +11001070 global commitidx varctok
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001071 global numcommits startmsecs
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001072 global mainheadid commitinfo nullid
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001073
1074 if {[info exists pending_select]} {
Paul Mackerras8f489362007-07-13 19:49:37 +10001075 set row [first_real_row]
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001076 selectline $row 1
1077 }
1078 if {$commitidx($curview) > 0} {
1079 #set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
1080 #puts "overall $ms ms for $numcommits commits"
Paul Mackerrasf3ea5ed2007-12-20 10:03:35 +11001081 #puts "[llength $varctok($view)] arcs, $commitidx($view) commits"
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001082 } else {
Christian Stimmingd990ced2007-11-07 18:42:55 +01001083 show_status [mc "No commits selected"]
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001084 }
1085 notbusy layout
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001086 }
Paul Mackerrasb6645502005-08-11 09:56:23 +10001087 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10001088 if {[info exists hlview] && $view == $hlview} {
1089 vhighlightmore
Paul Mackerrasb6645502005-08-11 09:56:23 +10001090 }
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10001091 return 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00001092}
1093
1094proc readcommit {id} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03001095 if {[catch {set contents [exec git cat-file commit $id]}]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001096 parsecommit $id $contents 0
Paul Mackerrasb490a992005-06-22 10:25:38 +10001097}
1098
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001099proc parsecommit {id contents listed} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01001100 global commitinfo cdate
1101
1102 set inhdr 1
1103 set comment {}
1104 set headline {}
1105 set auname {}
1106 set audate {}
1107 set comname {}
1108 set comdate {}
Paul Mackerras232475d2005-11-15 10:34:03 +11001109 set hdrend [string first "\n\n" $contents]
1110 if {$hdrend < 0} {
1111 # should never happen...
1112 set hdrend [string length $contents]
1113 }
1114 set header [string range $contents 0 [expr {$hdrend - 1}]]
1115 set comment [string range $contents [expr {$hdrend + 2}] end]
1116 foreach line [split $header "\n"] {
1117 set tag [lindex $line 0]
1118 if {$tag == "author"} {
1119 set audate [lindex $line end-1]
1120 set auname [lrange $line 1 end-2]
1121 } elseif {$tag == "committer"} {
1122 set comdate [lindex $line end-1]
1123 set comname [lrange $line 1 end-2]
Paul Mackerras1db95b02005-05-09 04:08:39 +00001124 }
1125 }
Paul Mackerras232475d2005-11-15 10:34:03 +11001126 set headline {}
Paul Mackerras43c25072006-09-27 10:56:02 +10001127 # take the first non-blank line of the comment as the headline
1128 set headline [string trimleft $comment]
1129 set i [string first "\n" $headline]
Paul Mackerras232475d2005-11-15 10:34:03 +11001130 if {$i >= 0} {
Paul Mackerras43c25072006-09-27 10:56:02 +10001131 set headline [string range $headline 0 $i]
1132 }
1133 set headline [string trimright $headline]
1134 set i [string first "\r" $headline]
1135 if {$i >= 0} {
1136 set headline [string trimright [string range $headline 0 $i]]
Paul Mackerras232475d2005-11-15 10:34:03 +11001137 }
1138 if {!$listed} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03001139 # git rev-list indents the comment by 4 spaces;
1140 # if we got this via git cat-file, add the indentation
Paul Mackerras232475d2005-11-15 10:34:03 +11001141 set newcomment {}
1142 foreach line [split $comment "\n"] {
1143 append newcomment " "
1144 append newcomment $line
Paul Mackerrasf6e28692005-11-20 23:08:22 +11001145 append newcomment "\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11001146 }
1147 set comment $newcomment
Paul Mackerras1db95b02005-05-09 04:08:39 +00001148 }
1149 if {$comdate != {}} {
Paul Mackerrascfb45632005-05-31 12:14:42 +00001150 set cdate($id) $comdate
Paul Mackerras1db95b02005-05-09 04:08:39 +00001151 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001152 set commitinfo($id) [list $headline $auname $audate \
1153 $comname $comdate $comment]
Paul Mackerras1db95b02005-05-09 04:08:39 +00001154}
1155
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11001156proc getcommit {id} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10001157 global commitdata commitinfo
Paul Mackerras8ed16482006-03-02 22:56:44 +11001158
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11001159 if {[info exists commitdata($id)]} {
1160 parsecommit $id $commitdata($id) 1
Paul Mackerras8ed16482006-03-02 22:56:44 +11001161 } else {
1162 readcommit $id
1163 if {![info exists commitinfo($id)]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01001164 set commitinfo($id) [list [mc "No commit information available"]]
Paul Mackerras8ed16482006-03-02 22:56:44 +11001165 }
1166 }
1167 return 1
1168}
1169
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001170proc readrefs {} {
Paul Mackerras62d3ea62006-09-11 10:36:53 +10001171 global tagids idtags headids idheads tagobjid
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001172 global otherrefids idotherrefs mainhead mainheadid
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001173
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01001174 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
1175 catch {unset $v}
1176 }
Paul Mackerras62d3ea62006-09-11 10:36:53 +10001177 set refd [open [list | git show-ref -d] r]
1178 while {[gets $refd line] >= 0} {
1179 if {[string index $line 40] ne " "} continue
1180 set id [string range $line 0 39]
1181 set ref [string range $line 41 end]
1182 if {![string match "refs/*" $ref]} continue
1183 set name [string range $ref 5 end]
1184 if {[string match "remotes/*" $name]} {
1185 if {![string match "*/HEAD" $name]} {
1186 set headids($name) $id
1187 lappend idheads($id) $name
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001188 }
Paul Mackerras62d3ea62006-09-11 10:36:53 +10001189 } elseif {[string match "heads/*" $name]} {
1190 set name [string range $name 6 end]
Junio C Hamano36a7cad2005-11-18 23:54:17 -08001191 set headids($name) $id
1192 lappend idheads($id) $name
Paul Mackerras62d3ea62006-09-11 10:36:53 +10001193 } elseif {[string match "tags/*" $name]} {
1194 # this lets refs/tags/foo^{} overwrite refs/tags/foo,
1195 # which is what we want since the former is the commit ID
1196 set name [string range $name 5 end]
1197 if {[string match "*^{}" $name]} {
1198 set name [string range $name 0 end-3]
1199 } else {
1200 set tagobjid($name) $id
1201 }
1202 set tagids($name) $id
1203 lappend idtags($id) $name
Junio C Hamano36a7cad2005-11-18 23:54:17 -08001204 } else {
1205 set otherrefids($name) $id
1206 lappend idotherrefs($id) $name
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001207 }
1208 }
Alex Riesen062d6712007-07-29 22:28:40 +02001209 catch {close $refd}
Paul Mackerras8a485712006-07-06 10:21:23 +10001210 set mainhead {}
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001211 set mainheadid {}
Paul Mackerras8a485712006-07-06 10:21:23 +10001212 catch {
1213 set thehead [exec git symbolic-ref HEAD]
1214 if {[string match "refs/heads/*" $thehead]} {
1215 set mainhead [string range $thehead 11 end]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001216 if {[info exists headids($mainhead)]} {
1217 set mainheadid $headids($mainhead)
1218 }
Paul Mackerras8a485712006-07-06 10:21:23 +10001219 }
1220 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001221}
1222
Paul Mackerras8f489362007-07-13 19:49:37 +10001223# skip over fake commits
1224proc first_real_row {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001225 global nullid nullid2 numcommits
Paul Mackerras8f489362007-07-13 19:49:37 +10001226
1227 for {set row 0} {$row < $numcommits} {incr row} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11001228 set id [commitonrow $row]
Paul Mackerras8f489362007-07-13 19:49:37 +10001229 if {$id ne $nullid && $id ne $nullid2} {
1230 break
1231 }
1232 }
1233 return $row
1234}
1235
Paul Mackerrase11f1232007-06-16 20:29:25 +10001236# update things for a head moved to a child of its previous location
1237proc movehead {id name} {
1238 global headids idheads
1239
1240 removehead $headids($name) $name
1241 set headids($name) $id
1242 lappend idheads($id) $name
1243}
1244
1245# update things when a head has been removed
1246proc removehead {id name} {
1247 global headids idheads
1248
1249 if {$idheads($id) eq $name} {
1250 unset idheads($id)
1251 } else {
1252 set i [lsearch -exact $idheads($id) $name]
1253 if {$i >= 0} {
1254 set idheads($id) [lreplace $idheads($id) $i $i]
1255 }
1256 }
1257 unset headids($name)
1258}
1259
Paul Mackerrase54be9e2006-05-26 22:34:30 +10001260proc show_error {w top msg} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001261 message $w.m -text $msg -justify center -aspect 400
1262 pack $w.m -side top -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 18:42:55 +01001263 button $w.ok -text [mc OK] -command "destroy $top"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001264 pack $w.ok -side bottom -fill x
Paul Mackerrase54be9e2006-05-26 22:34:30 +10001265 bind $top <Visibility> "grab $top; focus $top"
1266 bind $top <Key-Return> "destroy $top"
1267 tkwait window $top
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001268}
1269
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001270proc error_popup msg {
1271 set w .error
1272 toplevel $w
1273 wm transient $w .
Paul Mackerrase54be9e2006-05-26 22:34:30 +10001274 show_error $w $w $msg
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001275}
1276
Paul Mackerras10299152006-08-02 09:52:01 +10001277proc confirm_popup msg {
1278 global confirm_ok
1279 set confirm_ok 0
1280 set w .confirm
1281 toplevel $w
1282 wm transient $w .
1283 message $w.m -text $msg -justify center -aspect 400
1284 pack $w.m -side top -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 18:42:55 +01001285 button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
Paul Mackerras10299152006-08-02 09:52:01 +10001286 pack $w.ok -side left -fill x
Christian Stimmingd990ced2007-11-07 18:42:55 +01001287 button $w.cancel -text [mc Cancel] -command "destroy $w"
Paul Mackerras10299152006-08-02 09:52:01 +10001288 pack $w.cancel -side right -fill x
1289 bind $w <Visibility> "grab $w; focus $w"
1290 tkwait window $w
1291 return $confirm_ok
1292}
1293
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001294proc makewindow {} {
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10001295 global canv canv2 canv3 linespc charspc ctext cflist
Paul Mackerras9c311b32007-10-04 22:27:13 +10001296 global tabstop
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001297 global findtype findtypemenu findloc findstring fstring geometry
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001298 global entries sha1entry sha1string sha1but
Steffen Prohaska890fae72007-08-12 12:05:46 +02001299 global diffcontextstring diffcontext
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001300 global maincursor textcursor curtextcursor
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001301 global rowctxmenu fakerowmenu mergemax wrapcomment
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001302 global highlight_files gdttype
Paul Mackerras3ea06f92006-05-24 10:16:03 +10001303 global searchstring sstring
Mark Levedahl60378c02007-05-20 12:12:48 -04001304 global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001305 global headctxmenu progresscanv progressitem progresscoords statusw
1306 global fprogitem fprogcoord lastprogupdate progupdatepending
Paul Mackerrasa137a902007-10-23 21:12:49 +10001307 global rprogitem rprogcoord
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10001308 global have_tk85
Paul Mackerras9a40c502005-05-12 23:46:16 +00001309
1310 menu .bar
Christian Stimmingd990ced2007-11-07 18:42:55 +01001311 .bar add cascade -label [mc "File"] -menu .bar.file
Paul Mackerras9c311b32007-10-04 22:27:13 +10001312 .bar configure -font uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +00001313 menu .bar.file
Christian Stimmingd990ced2007-11-07 18:42:55 +01001314 .bar.file add command -label [mc "Update"] -command updatecommits
Paul Mackerras00abadb2007-12-20 10:25:50 +11001315 .bar.file add command -label [mc "Reload"] -command reloadcommits
Christian Stimmingd990ced2007-11-07 18:42:55 +01001316 .bar.file add command -label [mc "Reread references"] -command rereadrefs
1317 .bar.file add command -label [mc "List references"] -command showrefs
1318 .bar.file add command -label [mc "Quit"] -command doquit
Paul Mackerras9c311b32007-10-04 22:27:13 +10001319 .bar.file configure -font uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11001320 menu .bar.edit
Christian Stimmingd990ced2007-11-07 18:42:55 +01001321 .bar add cascade -label [mc "Edit"] -menu .bar.edit
1322 .bar.edit add command -label [mc "Preferences"] -command doprefs
Paul Mackerras9c311b32007-10-04 22:27:13 +10001323 .bar.edit configure -font uifont
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001324
Paul Mackerras9c311b32007-10-04 22:27:13 +10001325 menu .bar.view -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01001326 .bar add cascade -label [mc "View"] -menu .bar.view
1327 .bar.view add command -label [mc "New view..."] -command {newview 0}
1328 .bar.view add command -label [mc "Edit view..."] -command editview \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001329 -state disabled
Christian Stimmingd990ced2007-11-07 18:42:55 +01001330 .bar.view add command -label [mc "Delete view"] -command delview -state disabled
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001331 .bar.view add separator
Christian Stimmingd990ced2007-11-07 18:42:55 +01001332 .bar.view add radiobutton -label [mc "All files"] -command {showview 0} \
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001333 -variable selectedview -value 0
Mark Levedahl40b87ff2007-02-01 08:44:46 -05001334
Paul Mackerras9a40c502005-05-12 23:46:16 +00001335 menu .bar.help
Christian Stimmingd990ced2007-11-07 18:42:55 +01001336 .bar add cascade -label [mc "Help"] -menu .bar.help
1337 .bar.help add command -label [mc "About gitk"] -command about
1338 .bar.help add command -label [mc "Key bindings"] -command keys
Paul Mackerras9c311b32007-10-04 22:27:13 +10001339 .bar.help configure -font uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +00001340 . configure -menu .bar
1341
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001342 # the gui has upper and lower half, parts of a paned window.
Paul Mackerras0327d272005-05-10 00:23:42 +00001343 panedwindow .ctop -orient vertical
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001344
1345 # possibly use assumed geometry
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001346 if {![info exists geometry(pwsash0)]} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001347 set geometry(topheight) [expr {15 * $linespc}]
1348 set geometry(topwidth) [expr {80 * $charspc}]
1349 set geometry(botheight) [expr {15 * $linespc}]
1350 set geometry(botwidth) [expr {50 * $charspc}]
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001351 set geometry(pwsash0) "[expr {40 * $charspc}] 2"
1352 set geometry(pwsash1) "[expr {60 * $charspc}] 2"
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001353 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001354
1355 # the upper half will have a paned window, a scroll bar to the right, and some stuff below
1356 frame .tf -height $geometry(topheight) -width $geometry(topwidth)
1357 frame .tf.histframe
1358 panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
1359
1360 # create three canvases
1361 set cscroll .tf.histframe.csb
1362 set canv .tf.histframe.pwclist.canv
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001363 canvas $canv \
Mark Levedahl60378c02007-05-20 12:12:48 -04001364 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001365 -background $bgcolor -bd 0 \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001366 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001367 .tf.histframe.pwclist add $canv
1368 set canv2 .tf.histframe.pwclist.canv2
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001369 canvas $canv2 \
Mark Levedahl60378c02007-05-20 12:12:48 -04001370 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001371 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001372 .tf.histframe.pwclist add $canv2
1373 set canv3 .tf.histframe.pwclist.canv3
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001374 canvas $canv3 \
Mark Levedahl60378c02007-05-20 12:12:48 -04001375 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001376 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001377 .tf.histframe.pwclist add $canv3
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001378 eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
1379 eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
Paul Mackerras98f350e2005-05-15 05:56:51 +00001380
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001381 # a scroll bar to rule them
1382 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
1383 pack $cscroll -side right -fill y
1384 bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
1385 lappend bglist $canv $canv2 $canv3
1386 pack .tf.histframe.pwclist -fill both -expand 1 -side left
1387
1388 # we have two button bars at bottom of top frame. Bar 1
1389 frame .tf.bar
1390 frame .tf.lbar -height 15
1391
1392 set sha1entry .tf.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001393 set entries $sha1entry
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001394 set sha1but .tf.bar.sha1label
Christian Stimmingd990ced2007-11-07 18:42:55 +01001395 button $sha1but -text [mc "SHA1 ID: "] -state disabled -relief flat \
Paul Mackerras9c311b32007-10-04 22:27:13 +10001396 -command gotocommit -width 8 -font uifont
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001397 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001398 pack .tf.bar.sha1label -side left
Paul Mackerras9c311b32007-10-04 22:27:13 +10001399 entry $sha1entry -width 40 -font textfont -textvariable sha1string
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001400 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51 +00001401 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 22:06:06 +10001402
1403 image create bitmap bm-left -data {
1404 #define left_width 16
1405 #define left_height 16
1406 static unsigned char left_bits[] = {
1407 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
1408 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
1409 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
1410 }
1411 image create bitmap bm-right -data {
1412 #define right_width 16
1413 #define right_height 16
1414 static unsigned char right_bits[] = {
1415 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
1416 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
1417 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
1418 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001419 button .tf.bar.leftbut -image bm-left -command goback \
Paul Mackerrasd6982062005-08-06 22:06:06 +10001420 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001421 pack .tf.bar.leftbut -side left -fill y
1422 button .tf.bar.rightbut -image bm-right -command goforw \
Paul Mackerrasd6982062005-08-06 22:06:06 +10001423 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001424 pack .tf.bar.rightbut -side left -fill y
Paul Mackerrasd6982062005-08-06 22:06:06 +10001425
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001426 # Status label and progress bar
1427 set statusw .tf.bar.status
Paul Mackerras9c311b32007-10-04 22:27:13 +10001428 label $statusw -width 15 -relief sunken -font uifont
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001429 pack $statusw -side left -padx 5
Paul Mackerras9c311b32007-10-04 22:27:13 +10001430 set h [expr {[font metrics uifont -linespace] + 2}]
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001431 set progresscanv .tf.bar.progress
1432 canvas $progresscanv -relief sunken -height $h -borderwidth 2
1433 set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
1434 set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
Paul Mackerrasa137a902007-10-23 21:12:49 +10001435 set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001436 pack $progresscanv -side right -expand 1 -fill x
1437 set progresscoords {0 0}
1438 set fprogcoord 0
Paul Mackerrasa137a902007-10-23 21:12:49 +10001439 set rprogcoord 0
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001440 bind $progresscanv <Configure> adjustprogress
1441 set lastprogupdate [clock clicks -milliseconds]
1442 set progupdatepending 0
Paul Mackerrasb5721c72005-05-10 12:08:22 +00001443
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001444 # build up the bottom bar of upper window
Christian Stimmingd990ced2007-11-07 18:42:55 +01001445 label .tf.lbar.flabel -text "[mc "Find"] " -font uifont
1446 button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1} -font uifont
1447 button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1} -font uifont
1448 label .tf.lbar.flab2 -text " [mc "commit"] " -font uifont
Paul Mackerras687c8762007-09-22 12:49:33 +10001449 pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
1450 -side left -fill y
Christian Stimmingb007ee22007-11-07 18:44:35 +01001451 set gdttype [mc "containing:"]
Paul Mackerras687c8762007-09-22 12:49:33 +10001452 set gm [tk_optionMenu .tf.lbar.gdttype gdttype \
Christian Stimmingb007ee22007-11-07 18:44:35 +01001453 [mc "containing:"] \
1454 [mc "touching paths:"] \
1455 [mc "adding/removing string:"]]
Paul Mackerras687c8762007-09-22 12:49:33 +10001456 trace add variable gdttype write gdttype_change
Paul Mackerras9c311b32007-10-04 22:27:13 +10001457 $gm conf -font uifont
1458 .tf.lbar.gdttype conf -font uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001459 pack .tf.lbar.gdttype -side left -fill y
Paul Mackerras687c8762007-09-22 12:49:33 +10001460
1461 set findstring {}
1462 set fstring .tf.lbar.findstring
1463 lappend entries $fstring
Paul Mackerras9c311b32007-10-04 22:27:13 +10001464 entry $fstring -width 30 -font textfont -textvariable findstring
Paul Mackerras687c8762007-09-22 12:49:33 +10001465 trace add variable findstring write find_change
Christian Stimmingb007ee22007-11-07 18:44:35 +01001466 set findtype [mc "Exact"]
Paul Mackerras687c8762007-09-22 12:49:33 +10001467 set findtypemenu [tk_optionMenu .tf.lbar.findtype \
Christian Stimmingb007ee22007-11-07 18:44:35 +01001468 findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
Paul Mackerras687c8762007-09-22 12:49:33 +10001469 trace add variable findtype write findcom_change
Paul Mackerras9c311b32007-10-04 22:27:13 +10001470 .tf.lbar.findtype configure -font uifont
1471 .tf.lbar.findtype.menu configure -font uifont
Christian Stimmingb007ee22007-11-07 18:44:35 +01001472 set findloc [mc "All fields"]
1473 tk_optionMenu .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \
1474 [mc "Comments"] [mc "Author"] [mc "Committer"]
Paul Mackerras687c8762007-09-22 12:49:33 +10001475 trace add variable findloc write find_change
Paul Mackerras9c311b32007-10-04 22:27:13 +10001476 .tf.lbar.findloc configure -font uifont
1477 .tf.lbar.findloc.menu configure -font uifont
Paul Mackerras687c8762007-09-22 12:49:33 +10001478 pack .tf.lbar.findloc -side right
1479 pack .tf.lbar.findtype -side right
1480 pack $fstring -side left -expand 1 -fill x
Paul Mackerras908c3582006-05-20 09:38:11 +10001481
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001482 # Finish putting the upper half of the viewer together
1483 pack .tf.lbar -in .tf -side bottom -fill x
1484 pack .tf.bar -in .tf -side bottom -fill x
1485 pack .tf.histframe -fill both -side top -expand 1
1486 .ctop add .tf
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001487 .ctop paneconfigure .tf -height $geometry(topheight)
1488 .ctop paneconfigure .tf -width $geometry(topwidth)
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001489
1490 # now build up the bottom
1491 panedwindow .pwbottom -orient horizontal
1492
1493 # lower left, a text box over search bar, scroll bar to the right
1494 # if we know window height, then that will set the lower text height, otherwise
1495 # we set lower text height which will drive window height
1496 if {[info exists geometry(main)]} {
1497 frame .bleft -width $geometry(botwidth)
1498 } else {
1499 frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
1500 }
1501 frame .bleft.top
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001502 frame .bleft.mid
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001503
Christian Stimmingd990ced2007-11-07 18:42:55 +01001504 button .bleft.top.search -text [mc "Search"] -command dosearch \
Paul Mackerras9c311b32007-10-04 22:27:13 +10001505 -font uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001506 pack .bleft.top.search -side left -padx 5
1507 set sstring .bleft.top.sstring
Paul Mackerras9c311b32007-10-04 22:27:13 +10001508 entry $sstring -width 20 -font textfont -textvariable searchstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +10001509 lappend entries $sstring
1510 trace add variable searchstring write incrsearch
1511 pack $sstring -side left -expand 1 -fill x
Christian Stimmingd990ced2007-11-07 18:42:55 +01001512 radiobutton .bleft.mid.diff -text [mc "Diff"] -font uifont \
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001513 -command changediffdisp -variable diffelide -value {0 0}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001514 radiobutton .bleft.mid.old -text [mc "Old version"] -font uifont \
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001515 -command changediffdisp -variable diffelide -value {0 1}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001516 radiobutton .bleft.mid.new -text [mc "New version"] -font uifont \
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001517 -command changediffdisp -variable diffelide -value {1 0}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001518 label .bleft.mid.labeldiffcontext -text " [mc "Lines of context"]: " \
Paul Mackerras9c311b32007-10-04 22:27:13 +10001519 -font uifont
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001520 pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
Paul Mackerras9c311b32007-10-04 22:27:13 +10001521 spinbox .bleft.mid.diffcontext -width 5 -font textfont \
Steffen Prohaska890fae72007-08-12 12:05:46 +02001522 -from 1 -increment 1 -to 10000000 \
1523 -validate all -validatecommand "diffcontextvalidate %P" \
1524 -textvariable diffcontextstring
1525 .bleft.mid.diffcontext set $diffcontext
1526 trace add variable diffcontextstring write diffcontextchange
1527 lappend entries .bleft.mid.diffcontext
1528 pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001529 set ctext .bleft.ctext
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001530 text $ctext -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 22:27:13 +10001531 -state disabled -font textfont \
Paul Mackerras3ea06f92006-05-24 10:16:03 +10001532 -yscrollcommand scrolltext -wrap none
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10001533 if {$have_tk85} {
1534 $ctext conf -tabstyle wordprocessor
1535 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001536 scrollbar .bleft.sb -command "$ctext yview"
1537 pack .bleft.top -side top -fill x
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10001538 pack .bleft.mid -side top -fill x
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001539 pack .bleft.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +00001540 pack $ctext -side left -fill both -expand 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001541 lappend bglist $ctext
1542 lappend fglist $ctext
Paul Mackerrasd2610d12005-05-11 00:45:38 +00001543
Sergey Vlasovf1b86292006-05-15 19:13:14 +04001544 $ctext tag conf comment -wrap $wrapcomment
Paul Mackerras9c311b32007-10-04 22:27:13 +10001545 $ctext tag conf filesep -font textfontbold -back "#aaaaaa"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001546 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
1547 $ctext tag conf d0 -fore [lindex $diffcolors 0]
1548 $ctext tag conf d1 -fore [lindex $diffcolors 1]
Paul Mackerras712fcc02005-11-30 09:28:16 +11001549 $ctext tag conf m0 -fore red
1550 $ctext tag conf m1 -fore blue
1551 $ctext tag conf m2 -fore green
1552 $ctext tag conf m3 -fore purple
1553 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-07 09:13:52 +11001554 $ctext tag conf m5 -fore "#009090"
1555 $ctext tag conf m6 -fore magenta
1556 $ctext tag conf m7 -fore "#808000"
1557 $ctext tag conf m8 -fore "#009000"
1558 $ctext tag conf m9 -fore "#ff0080"
1559 $ctext tag conf m10 -fore cyan
1560 $ctext tag conf m11 -fore "#b07070"
1561 $ctext tag conf m12 -fore "#70b0f0"
1562 $ctext tag conf m13 -fore "#70f0b0"
1563 $ctext tag conf m14 -fore "#f0b070"
1564 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-30 09:28:16 +11001565 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-07 09:13:52 +11001566 set mergemax 16
Paul Mackerras9c311b32007-10-04 22:27:13 +10001567 $ctext tag conf mresult -font textfontbold
1568 $ctext tag conf msep -font textfontbold
Paul Mackerras712fcc02005-11-30 09:28:16 +11001569 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001570
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001571 .pwbottom add .bleft
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001572 .pwbottom paneconfigure .bleft -width $geometry(botwidth)
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001573
1574 # lower right
1575 frame .bright
1576 frame .bright.mode
Christian Stimmingd990ced2007-11-07 18:42:55 +01001577 radiobutton .bright.mode.patch -text [mc "Patch"] \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001578 -command reselectline -variable cmitmode -value "patch"
Paul Mackerras9c311b32007-10-04 22:27:13 +10001579 .bright.mode.patch configure -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01001580 radiobutton .bright.mode.tree -text [mc "Tree"] \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001581 -command reselectline -variable cmitmode -value "tree"
Paul Mackerras9c311b32007-10-04 22:27:13 +10001582 .bright.mode.tree configure -font uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001583 grid .bright.mode.patch .bright.mode.tree -sticky ew
1584 pack .bright.mode -side top -fill x
1585 set cflist .bright.cfiles
Paul Mackerras9c311b32007-10-04 22:27:13 +10001586 set indent [font measure mainfont "nn"]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001587 text $cflist \
Mark Levedahl60378c02007-05-20 12:12:48 -04001588 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001589 -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 22:27:13 +10001590 -font mainfont \
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001591 -tabs [list $indent [expr {2 * $indent}]] \
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001592 -yscrollcommand ".bright.sb set" \
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001593 -cursor [. cget -cursor] \
1594 -spacing1 1 -spacing3 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001595 lappend bglist $cflist
1596 lappend fglist $cflist
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001597 scrollbar .bright.sb -command "$cflist yview"
1598 pack .bright.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +00001599 pack $cflist -side left -fill both -expand 1
Paul Mackerras89b11d32006-05-02 19:55:31 +10001600 $cflist tag configure highlight \
1601 -background [$cflist cget -selectbackground]
Paul Mackerras9c311b32007-10-04 22:27:13 +10001602 $cflist tag configure bold -font mainfontbold
Paul Mackerrasd2610d12005-05-11 00:45:38 +00001603
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001604 .pwbottom add .bright
1605 .ctop add .pwbottom
Paul Mackerras1db95b02005-05-09 04:08:39 +00001606
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001607 # restore window position if known
1608 if {[info exists geometry(main)]} {
1609 wm geometry . "$geometry(main)"
1610 }
1611
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001612 if {[tk windowingsystem] eq {aqua}} {
1613 set M1B M1
1614 } else {
1615 set M1B Control
1616 }
1617
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001618 bind .pwbottom <Configure> {resizecdetpanes %W %w}
1619 pack .ctop -fill both -expand 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10001620 bindall <1> {selcanvline %W %x %y}
1621 #bindall <B1-Motion> {selcanvline %W %x %y}
Mark Levedahl314c3092007-08-07 21:40:35 -04001622 if {[tk windowingsystem] == "win32"} {
1623 bind . <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D }
1624 bind $ctext <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D ; break }
1625 } else {
1626 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
1627 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Jonathan del Strother5dd57d52007-10-15 10:33:07 +01001628 if {[tk windowingsystem] eq "aqua"} {
1629 bindall <MouseWheel> {
1630 set delta [expr {- (%D)}]
1631 allcanvs yview scroll $delta units
1632 }
1633 }
Mark Levedahl314c3092007-08-07 21:40:35 -04001634 }
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11001635 bindall <2> "canvscan mark %W %x %y"
1636 bindall <B2-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10001637 bindkey <Home> selfirstline
1638 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:00 +00001639 bind . <Key-Up> "selnextline -1"
1640 bind . <Key-Down> "selnextline 1"
Paul Mackerrascca5d942007-10-27 21:16:56 +10001641 bind . <Shift-Key-Up> "dofind -1 0"
1642 bind . <Shift-Key-Down> "dofind 1 0"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10001643 bindkey <Key-Right> "goforw"
1644 bindkey <Key-Left> "goback"
1645 bind . <Key-Prior> "selnextpage -1"
1646 bind . <Key-Next> "selnextpage 1"
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001647 bind . <$M1B-Home> "allcanvs yview moveto 0.0"
1648 bind . <$M1B-End> "allcanvs yview moveto 1.0"
1649 bind . <$M1B-Key-Up> "allcanvs yview scroll -1 units"
1650 bind . <$M1B-Key-Down> "allcanvs yview scroll 1 units"
1651 bind . <$M1B-Key-Prior> "allcanvs yview scroll -1 pages"
1652 bind . <$M1B-Key-Next> "allcanvs yview scroll 1 pages"
Paul Mackerrascfb45632005-05-31 12:14:42 +00001653 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
1654 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
1655 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001656 bindkey p "selnextline -1"
1657 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +10001658 bindkey z "goback"
1659 bindkey x "goforw"
1660 bindkey i "selnextline -1"
1661 bindkey k "selnextline 1"
1662 bindkey j "goback"
1663 bindkey l "goforw"
Paul Mackerrascfb45632005-05-31 12:14:42 +00001664 bindkey b "$ctext yview scroll -1 pages"
1665 bindkey d "$ctext yview scroll 18 units"
1666 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrascca5d942007-10-27 21:16:56 +10001667 bindkey / {dofind 1 1}
1668 bindkey <Key-Return> {dofind 1 1}
1669 bindkey ? {dofind -1 1}
Paul Mackerras39ad8572005-05-19 12:35:53 +00001670 bindkey f nextfile
Eric Wonge7a09192007-02-23 12:36:34 -08001671 bindkey <F5> updatecommits
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001672 bind . <$M1B-q> doquit
Paul Mackerrascca5d942007-10-27 21:16:56 +10001673 bind . <$M1B-f> {dofind 1 1}
1674 bind . <$M1B-g> {dofind 1 0}
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001675 bind . <$M1B-r> dosearchback
1676 bind . <$M1B-s> dosearch
1677 bind . <$M1B-equal> {incrfont 1}
1678 bind . <$M1B-KP_Add> {incrfont 1}
1679 bind . <$M1B-minus> {incrfont -1}
1680 bind . <$M1B-KP_Subtract> {incrfont -1}
Mark Levedahlb6047c52007-02-08 22:22:24 -05001681 wm protocol . WM_DELETE_WINDOW doquit
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001682 bind . <Button-1> "click %W"
Paul Mackerrascca5d942007-10-27 21:16:56 +10001683 bind $fstring <Key-Return> {dofind 1 1}
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001684 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 16:37:13 +10001685 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001686 bind $cflist <1> {sel_flist %W %x %y; break}
1687 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001688 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
Paul Mackerras32447292007-07-27 22:30:15 +10001689 bind $cflist <Button-3> {pop_flist_menu %W %X %Y %x %y}
Paul Mackerrasea13cba2005-06-16 10:54:04 +00001690
1691 set maincursor [. cget -cursor]
1692 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001693 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26 +00001694
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10001695 set rowctxmenu .rowctxmenu
1696 menu $rowctxmenu -tearoff 0
Christian Stimmingd990ced2007-11-07 18:42:55 +01001697 $rowctxmenu add command -label [mc "Diff this -> selected"] \
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10001698 -command {diffvssel 0}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001699 $rowctxmenu add command -label [mc "Diff selected -> this"] \
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10001700 -command {diffvssel 1}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001701 $rowctxmenu add command -label [mc "Make patch"] -command mkpatch
1702 $rowctxmenu add command -label [mc "Create tag"] -command mktag
1703 $rowctxmenu add command -label [mc "Write commit to file"] -command writecommit
1704 $rowctxmenu add command -label [mc "Create new branch"] -command mkbranch
1705 $rowctxmenu add command -label [mc "Cherry-pick this commit"] \
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10001706 -command cherrypick
Christian Stimmingd990ced2007-11-07 18:42:55 +01001707 $rowctxmenu add command -label [mc "Reset HEAD branch to here"] \
Paul Mackerras6fb735a2006-10-19 10:09:06 +10001708 -command resethead
Paul Mackerras10299152006-08-02 09:52:01 +10001709
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001710 set fakerowmenu .fakerowmenu
1711 menu $fakerowmenu -tearoff 0
Christian Stimmingd990ced2007-11-07 18:42:55 +01001712 $fakerowmenu add command -label [mc "Diff this -> selected"] \
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001713 -command {diffvssel 0}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001714 $fakerowmenu add command -label [mc "Diff selected -> this"] \
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001715 -command {diffvssel 1}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001716 $fakerowmenu add command -label [mc "Make patch"] -command mkpatch
1717# $fakerowmenu add command -label [mc "Commit"] -command {mkcommit 0}
1718# $fakerowmenu add command -label [mc "Commit all"] -command {mkcommit 1}
1719# $fakerowmenu add command -label [mc "Revert local changes"] -command revertlocal
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001720
Paul Mackerras10299152006-08-02 09:52:01 +10001721 set headctxmenu .headctxmenu
1722 menu $headctxmenu -tearoff 0
Christian Stimmingd990ced2007-11-07 18:42:55 +01001723 $headctxmenu add command -label [mc "Check out this branch"] \
Paul Mackerras10299152006-08-02 09:52:01 +10001724 -command cobranch
Christian Stimmingd990ced2007-11-07 18:42:55 +01001725 $headctxmenu add command -label [mc "Remove this branch"] \
Paul Mackerras10299152006-08-02 09:52:01 +10001726 -command rmbranch
Paul Mackerras32447292007-07-27 22:30:15 +10001727
1728 global flist_menu
1729 set flist_menu .flistctxmenu
1730 menu $flist_menu -tearoff 0
Christian Stimmingd990ced2007-11-07 18:42:55 +01001731 $flist_menu add command -label [mc "Highlight this too"] \
Paul Mackerras32447292007-07-27 22:30:15 +10001732 -command {flist_hl 0}
Christian Stimmingd990ced2007-11-07 18:42:55 +01001733 $flist_menu add command -label [mc "Highlight this only"] \
Paul Mackerras32447292007-07-27 22:30:15 +10001734 -command {flist_hl 1}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001735}
1736
Mark Levedahl314c3092007-08-07 21:40:35 -04001737# Windows sends all mouse wheel events to the current focused window, not
1738# the one where the mouse hovers, so bind those events here and redirect
1739# to the correct window
1740proc windows_mousewheel_redirector {W X Y D} {
1741 global canv canv2 canv3
1742 set w [winfo containing -displayof $W $X $Y]
1743 if {$w ne ""} {
1744 set u [expr {$D < 0 ? 5 : -5}]
1745 if {$w == $canv || $w == $canv2 || $w == $canv3} {
1746 allcanvs yview scroll $u units
1747 } else {
1748 catch {
1749 $w yview scroll $u units
1750 }
1751 }
1752 }
1753}
1754
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11001755# mouse-2 makes all windows scan vertically, but only the one
1756# the cursor is in scans horizontally
1757proc canvscan {op w x y} {
1758 global canv canv2 canv3
1759 foreach c [list $canv $canv2 $canv3] {
1760 if {$c == $w} {
1761 $c scan $op $x $y
1762 } else {
1763 $c scan $op 0 $y
1764 }
1765 }
1766}
1767
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001768proc scrollcanv {cscroll f0 f1} {
1769 $cscroll set $f0 $f1
1770 drawfrac $f0 $f1
Paul Mackerras908c3582006-05-20 09:38:11 +10001771 flushhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001772}
1773
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001774# when we make a key binding for the toplevel, make sure
1775# it doesn't get triggered when that key is pressed in the
1776# find string entry widget.
1777proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001778 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001779 bind . $ev $script
1780 set escript [bind Entry $ev]
1781 if {$escript == {}} {
1782 set escript [bind Entry <Key>]
1783 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001784 foreach e $entries {
1785 bind $e $ev "$escript; break"
1786 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001787}
1788
1789# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001790# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001791proc click {w} {
Mark Levedahlbd441de2007-08-07 21:40:34 -04001792 global ctext entries
1793 foreach e [concat $entries $ctext] {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001794 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001795 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00001796 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001797}
1798
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001799# Adjust the progress bar for a change in requested extent or canvas size
1800proc adjustprogress {} {
1801 global progresscanv progressitem progresscoords
1802 global fprogitem fprogcoord lastprogupdate progupdatepending
Paul Mackerrasa137a902007-10-23 21:12:49 +10001803 global rprogitem rprogcoord
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001804
1805 set w [expr {[winfo width $progresscanv] - 4}]
1806 set x0 [expr {$w * [lindex $progresscoords 0]}]
1807 set x1 [expr {$w * [lindex $progresscoords 1]}]
1808 set h [winfo height $progresscanv]
1809 $progresscanv coords $progressitem $x0 0 $x1 $h
1810 $progresscanv coords $fprogitem 0 0 [expr {$w * $fprogcoord}] $h
Paul Mackerrasa137a902007-10-23 21:12:49 +10001811 $progresscanv coords $rprogitem 0 0 [expr {$w * $rprogcoord}] $h
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10001812 set now [clock clicks -milliseconds]
1813 if {$now >= $lastprogupdate + 100} {
1814 set progupdatepending 0
1815 update
1816 } elseif {!$progupdatepending} {
1817 set progupdatepending 1
1818 after [expr {$lastprogupdate + 100 - $now}] doprogupdate
1819 }
1820}
1821
1822proc doprogupdate {} {
1823 global lastprogupdate progupdatepending
1824
1825 if {$progupdatepending} {
1826 set progupdatepending 0
1827 set lastprogupdate [clock clicks -milliseconds]
1828 update
1829 }
1830}
1831
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001832proc savestuff {w} {
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10001833 global canv canv2 canv3 mainfont textfont uifont tabstop
Paul Mackerras712fcc02005-11-30 09:28:16 +11001834 global stuffsaved findmergefiles maxgraphpct
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001835 global maxwidth showneartags showlocalchanges
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001836 global viewname viewfiles viewargs viewperm nextviewnum
Paul Mackerras7a39a172007-10-23 10:15:11 +10001837 global cmitmode wrapcomment datetimeformat limitdiffs
Steffen Prohaska890fae72007-08-12 12:05:46 +02001838 global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
Paul Mackerras4ef17532005-07-27 22:16:51 -05001839
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001840 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001841 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001842 catch {
1843 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 14:29:03 -04001844 puts $f [list set mainfont $mainfont]
1845 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 00:19:45 -07001846 puts $f [list set uifont $uifont]
Mark Levedahl7e12f1a2007-05-20 11:45:50 -04001847 puts $f [list set tabstop $tabstop]
Paul Mackerrasf0654862005-07-18 14:29:03 -04001848 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-05 09:52:16 +10001849 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 10:22:24 +10001850 puts $f [list set maxwidth $maxwidth]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001851 puts $f [list set cmitmode $cmitmode]
Sergey Vlasovf1b86292006-05-15 19:13:14 +04001852 puts $f [list set wrapcomment $wrapcomment]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10001853 puts $f [list set showneartags $showneartags]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10001854 puts $f [list set showlocalchanges $showlocalchanges]
Arjen Laarhovene8b5f4b2007-08-14 22:02:04 +02001855 puts $f [list set datetimeformat $datetimeformat]
Paul Mackerras7a39a172007-10-23 10:15:11 +10001856 puts $f [list set limitdiffs $limitdiffs]
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10001857 puts $f [list set bgcolor $bgcolor]
1858 puts $f [list set fgcolor $fgcolor]
1859 puts $f [list set colors $colors]
1860 puts $f [list set diffcolors $diffcolors]
Steffen Prohaska890fae72007-08-12 12:05:46 +02001861 puts $f [list set diffcontext $diffcontext]
Mark Levedahl60378c02007-05-20 12:12:48 -04001862 puts $f [list set selectbgcolor $selectbgcolor]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001863
Mark Levedahlb6047c52007-02-08 22:22:24 -05001864 puts $f "set geometry(main) [wm geometry .]"
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001865 puts $f "set geometry(topwidth) [winfo width .tf]"
1866 puts $f "set geometry(topheight) [winfo height .tf]"
Mark Levedahl9ca72f42007-02-12 19:19:34 -05001867 puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
1868 puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
Junio C Hamanoe9937d22007-02-01 08:46:38 -05001869 puts $f "set geometry(botwidth) [winfo width .bleft]"
1870 puts $f "set geometry(botheight) [winfo height .bleft]"
1871
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001872 puts -nonewline $f "set permviews {"
1873 for {set v 0} {$v < $nextviewnum} {incr v} {
1874 if {$viewperm($v)} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001875 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001876 }
1877 }
1878 puts $f "}"
Paul Mackerras0fba86b2005-05-16 23:54:58 +00001879 close $f
1880 file rename -force "~/.gitk-new" "~/.gitk"
1881 }
1882 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:39 +00001883}
1884
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001885proc resizeclistpanes {win w} {
1886 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +11001887 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001888 set s0 [$win sash coord 0]
1889 set s1 [$win sash coord 1]
1890 if {$w < 60} {
1891 set sash0 [expr {int($w/2 - 2)}]
1892 set sash1 [expr {int($w*5/6 - 2)}]
1893 } else {
1894 set factor [expr {1.0 * $w / $oldwidth($win)}]
1895 set sash0 [expr {int($factor * [lindex $s0 0])}]
1896 set sash1 [expr {int($factor * [lindex $s1 0])}]
1897 if {$sash0 < 30} {
1898 set sash0 30
1899 }
1900 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001901 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001902 }
1903 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001904 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001905 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001906 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001907 }
1908 }
1909 }
1910 $win sash place 0 $sash0 [lindex $s0 1]
1911 $win sash place 1 $sash1 [lindex $s1 1]
1912 }
1913 set oldwidth($win) $w
1914}
1915
1916proc resizecdetpanes {win w} {
1917 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +11001918 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001919 set s0 [$win sash coord 0]
1920 if {$w < 60} {
1921 set sash0 [expr {int($w*3/4 - 2)}]
1922 } else {
1923 set factor [expr {1.0 * $w / $oldwidth($win)}]
1924 set sash0 [expr {int($factor * [lindex $s0 0])}]
1925 if {$sash0 < 45} {
1926 set sash0 45
1927 }
1928 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001929 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +00001930 }
1931 }
1932 $win sash place 0 $sash0 [lindex $s0 1]
1933 }
1934 set oldwidth($win) $w
1935}
1936
Paul Mackerrasb5721c72005-05-10 12:08:22 +00001937proc allcanvs args {
1938 global canv canv2 canv3
1939 eval $canv $args
1940 eval $canv2 $args
1941 eval $canv3 $args
1942}
1943
1944proc bindall {event action} {
1945 global canv canv2 canv3
1946 bind $canv $event $action
1947 bind $canv2 $event $action
1948 bind $canv3 $event $action
1949}
1950
Paul Mackerras9a40c502005-05-12 23:46:16 +00001951proc about {} {
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001952 global uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +00001953 set w .about
1954 if {[winfo exists $w]} {
1955 raise $w
1956 return
1957 }
1958 toplevel $w
Christian Stimmingd990ced2007-11-07 18:42:55 +01001959 wm title $w [mc "About gitk"]
1960 message $w.m -text [mc "
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001961Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16 +00001962
Christian Stimmingeadcac92007-11-07 18:47:04 +01001963Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16 +00001964
Christian Stimmingd990ced2007-11-07 18:42:55 +01001965Use and redistribute under the terms of the GNU General Public License"] \
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04001966 -justify center -aspect 400 -border 2 -bg white -relief groove
1967 pack $w.m -side top -fill x -padx 2 -pady 2
Paul Mackerras9c311b32007-10-04 22:27:13 +10001968 $w.m configure -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01001969 button $w.ok -text [mc "Close"] -command "destroy $w" -default active
Paul Mackerras9a40c502005-05-12 23:46:16 +00001970 pack $w.ok -side bottom
Paul Mackerras9c311b32007-10-04 22:27:13 +10001971 $w.ok configure -font uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04001972 bind $w <Visibility> "focus $w.ok"
1973 bind $w <Key-Escape> "destroy $w"
1974 bind $w <Key-Return> "destroy $w"
Paul Mackerras9a40c502005-05-12 23:46:16 +00001975}
1976
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001977proc keys {} {
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001978 global uifont
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001979 set w .keys
1980 if {[winfo exists $w]} {
1981 raise $w
1982 return
1983 }
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001984 if {[tk windowingsystem] eq {aqua}} {
1985 set M1T Cmd
1986 } else {
1987 set M1T Ctrl
1988 }
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001989 toplevel $w
Christian Stimmingd990ced2007-11-07 18:42:55 +01001990 wm title $w [mc "Gitk key bindings"]
1991 message $w.m -text [mc "
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001992Gitk key bindings:
1993
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04001994<$M1T-Q> Quit
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10001995<Home> Move to first commit
1996<End> Move to last commit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001997<Up>, p, i Move up one commit
1998<Down>, n, k Move down one commit
1999<Left>, z, j Go back in history list
2000<Right>, x, l Go forward in history list
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10002001<PageUp> Move up one page in commit list
2002<PageDown> Move down one page in commit list
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04002003<$M1T-Home> Scroll to top of commit list
2004<$M1T-End> Scroll to bottom of commit list
2005<$M1T-Up> Scroll commit list up one line
2006<$M1T-Down> Scroll commit list down one line
2007<$M1T-PageUp> Scroll commit list up one page
2008<$M1T-PageDown> Scroll commit list down one page
Paul Mackerrascca5d942007-10-27 21:16:56 +10002009<Shift-Up> Find backwards (upwards, later commits)
2010<Shift-Down> Find forwards (downwards, earlier commits)
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10002011<Delete>, b Scroll diff view up one page
2012<Backspace> Scroll diff view up one page
2013<Space> Scroll diff view down one page
2014u Scroll diff view up 18 lines
2015d Scroll diff view down 18 lines
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04002016<$M1T-F> Find
2017<$M1T-G> Move to next find hit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10002018<Return> Move to next find hit
2019/ Move to next find hit, or redo find
2020? Move to previous find hit
2021f Scroll diff view to next file
Shawn O. Pearced23d98d2007-07-19 00:37:58 -04002022<$M1T-S> Search for next hit in diff view
2023<$M1T-R> Search for previous hit in diff view
2024<$M1T-KP+> Increase font size
2025<$M1T-plus> Increase font size
2026<$M1T-KP-> Decrease font size
2027<$M1T-minus> Decrease font size
Eric Wonge7a09192007-02-23 12:36:34 -08002028<F5> Update
Christian Stimmingd990ced2007-11-07 18:42:55 +01002029"] \
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04002030 -justify left -bg white -border 2 -relief groove
2031 pack $w.m -side top -fill both -padx 2 -pady 2
Paul Mackerras9c311b32007-10-04 22:27:13 +10002032 $w.m configure -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01002033 button $w.ok -text [mc "Close"] -command "destroy $w" -default active
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10002034 pack $w.ok -side bottom
Paul Mackerras9c311b32007-10-04 22:27:13 +10002035 $w.ok configure -font uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04002036 bind $w <Visibility> "focus $w.ok"
2037 bind $w <Key-Escape> "destroy $w"
2038 bind $w <Key-Return> "destroy $w"
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10002039}
2040
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002041# Procedures for manipulating the file list window at the
2042# bottom right of the overall window.
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002043
2044proc treeview {w l openlevs} {
2045 global treecontents treediropen treeheight treeparent treeindex
2046
2047 set ix 0
2048 set treeindex() 0
2049 set lev 0
2050 set prefix {}
2051 set prefixend -1
2052 set prefendstack {}
2053 set htstack {}
2054 set ht 0
2055 set treecontents() {}
2056 $w conf -state normal
2057 foreach f $l {
2058 while {[string range $f 0 $prefixend] ne $prefix} {
2059 if {$lev <= $openlevs} {
2060 $w mark set e:$treeindex($prefix) "end -1c"
2061 $w mark gravity e:$treeindex($prefix) left
2062 }
2063 set treeheight($prefix) $ht
2064 incr ht [lindex $htstack end]
2065 set htstack [lreplace $htstack end end]
2066 set prefixend [lindex $prefendstack end]
2067 set prefendstack [lreplace $prefendstack end end]
2068 set prefix [string range $prefix 0 $prefixend]
2069 incr lev -1
2070 }
2071 set tail [string range $f [expr {$prefixend+1}] end]
2072 while {[set slash [string first "/" $tail]] >= 0} {
2073 lappend htstack $ht
2074 set ht 0
2075 lappend prefendstack $prefixend
2076 incr prefixend [expr {$slash + 1}]
2077 set d [string range $tail 0 $slash]
2078 lappend treecontents($prefix) $d
2079 set oldprefix $prefix
2080 append prefix $d
2081 set treecontents($prefix) {}
2082 set treeindex($prefix) [incr ix]
2083 set treeparent($prefix) $oldprefix
2084 set tail [string range $tail [expr {$slash+1}] end]
2085 if {$lev <= $openlevs} {
2086 set ht 1
2087 set treediropen($prefix) [expr {$lev < $openlevs}]
2088 set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
2089 $w mark set d:$ix "end -1c"
2090 $w mark gravity d:$ix left
2091 set str "\n"
2092 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
2093 $w insert end $str
2094 $w image create end -align center -image $bm -padx 1 \
2095 -name a:$ix
Paul Mackerras45a9d502006-05-20 22:56:27 +10002096 $w insert end $d [highlight_tag $prefix]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002097 $w mark set s:$ix "end -1c"
2098 $w mark gravity s:$ix left
2099 }
2100 incr lev
2101 }
2102 if {$tail ne {}} {
2103 if {$lev <= $openlevs} {
2104 incr ht
2105 set str "\n"
2106 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
2107 $w insert end $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10002108 $w insert end $tail [highlight_tag $f]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002109 }
2110 lappend treecontents($prefix) $tail
2111 }
2112 }
2113 while {$htstack ne {}} {
2114 set treeheight($prefix) $ht
2115 incr ht [lindex $htstack end]
2116 set htstack [lreplace $htstack end end]
Brian Downing096e96b2007-07-05 06:33:02 -05002117 set prefixend [lindex $prefendstack end]
2118 set prefendstack [lreplace $prefendstack end end]
2119 set prefix [string range $prefix 0 $prefixend]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002120 }
2121 $w conf -state disabled
2122}
2123
2124proc linetoelt {l} {
2125 global treeheight treecontents
2126
2127 set y 2
2128 set prefix {}
2129 while {1} {
2130 foreach e $treecontents($prefix) {
2131 if {$y == $l} {
2132 return "$prefix$e"
2133 }
2134 set n 1
2135 if {[string index $e end] eq "/"} {
2136 set n $treeheight($prefix$e)
2137 if {$y + $n > $l} {
2138 append prefix $e
2139 incr y
2140 break
2141 }
2142 }
2143 incr y $n
2144 }
2145 }
2146}
2147
Paul Mackerras45a9d502006-05-20 22:56:27 +10002148proc highlight_tree {y prefix} {
2149 global treeheight treecontents cflist
2150
2151 foreach e $treecontents($prefix) {
2152 set path $prefix$e
2153 if {[highlight_tag $path] ne {}} {
2154 $cflist tag add bold $y.0 "$y.0 lineend"
2155 }
2156 incr y
2157 if {[string index $e end] eq "/" && $treeheight($path) > 1} {
2158 set y [highlight_tree $y $path]
2159 }
2160 }
2161 return $y
2162}
2163
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002164proc treeclosedir {w dir} {
2165 global treediropen treeheight treeparent treeindex
2166
2167 set ix $treeindex($dir)
2168 $w conf -state normal
2169 $w delete s:$ix e:$ix
2170 set treediropen($dir) 0
2171 $w image configure a:$ix -image tri-rt
2172 $w conf -state disabled
2173 set n [expr {1 - $treeheight($dir)}]
2174 while {$dir ne {}} {
2175 incr treeheight($dir) $n
2176 set dir $treeparent($dir)
2177 }
2178}
2179
2180proc treeopendir {w dir} {
2181 global treediropen treeheight treeparent treecontents treeindex
2182
2183 set ix $treeindex($dir)
2184 $w conf -state normal
2185 $w image configure a:$ix -image tri-dn
2186 $w mark set e:$ix s:$ix
2187 $w mark gravity e:$ix right
2188 set lev 0
2189 set str "\n"
2190 set n [llength $treecontents($dir)]
2191 for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
2192 incr lev
2193 append str "\t"
2194 incr treeheight($x) $n
2195 }
2196 foreach e $treecontents($dir) {
Paul Mackerras45a9d502006-05-20 22:56:27 +10002197 set de $dir$e
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002198 if {[string index $e end] eq "/"} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002199 set iy $treeindex($de)
2200 $w mark set d:$iy e:$ix
2201 $w mark gravity d:$iy left
2202 $w insert e:$ix $str
2203 set treediropen($de) 0
2204 $w image create e:$ix -align center -image tri-rt -padx 1 \
2205 -name a:$iy
Paul Mackerras45a9d502006-05-20 22:56:27 +10002206 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002207 $w mark set s:$iy e:$ix
2208 $w mark gravity s:$iy left
2209 set treeheight($de) 1
2210 } else {
2211 $w insert e:$ix $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10002212 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002213 }
2214 }
2215 $w mark gravity e:$ix left
2216 $w conf -state disabled
2217 set treediropen($dir) 1
2218 set top [lindex [split [$w index @0,0] .] 0]
2219 set ht [$w cget -height]
2220 set l [lindex [split [$w index s:$ix] .] 0]
2221 if {$l < $top} {
2222 $w yview $l.0
2223 } elseif {$l + $n + 1 > $top + $ht} {
2224 set top [expr {$l + $n + 2 - $ht}]
2225 if {$l < $top} {
2226 set top $l
2227 }
2228 $w yview $top.0
2229 }
2230}
2231
2232proc treeclick {w x y} {
2233 global treediropen cmitmode ctext cflist cflist_top
2234
2235 if {$cmitmode ne "tree"} return
2236 if {![info exists cflist_top]} return
2237 set l [lindex [split [$w index "@$x,$y"] "."] 0]
2238 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
2239 $cflist tag add highlight $l.0 "$l.0 lineend"
2240 set cflist_top $l
2241 if {$l == 1} {
2242 $ctext yview 1.0
2243 return
2244 }
2245 set e [linetoelt $l]
2246 if {[string index $e end] ne "/"} {
2247 showfile $e
2248 } elseif {$treediropen($e)} {
2249 treeclosedir $w $e
2250 } else {
2251 treeopendir $w $e
2252 }
2253}
2254
2255proc setfilelist {id} {
2256 global treefilelist cflist
2257
2258 treeview $cflist $treefilelist($id) 0
2259}
2260
2261image create bitmap tri-rt -background black -foreground blue -data {
2262 #define tri-rt_width 13
2263 #define tri-rt_height 13
2264 static unsigned char tri-rt_bits[] = {
2265 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x70, 0x00, 0xf0, 0x00,
2266 0xf0, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00,
2267 0x00, 0x00};
2268} -maskdata {
2269 #define tri-rt-mask_width 13
2270 #define tri-rt-mask_height 13
2271 static unsigned char tri-rt-mask_bits[] = {
2272 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
2273 0xf8, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00,
2274 0x08, 0x00};
2275}
2276image create bitmap tri-dn -background black -foreground blue -data {
2277 #define tri-dn_width 13
2278 #define tri-dn_height 13
2279 static unsigned char tri-dn_bits[] = {
2280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf8, 0x03,
2281 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2282 0x00, 0x00};
2283} -maskdata {
2284 #define tri-dn-mask_width 13
2285 #define tri-dn-mask_height 13
2286 static unsigned char tri-dn-mask_bits[] = {
2287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07,
2288 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
2289 0x00, 0x00};
2290}
2291
Paul Mackerras887c9962007-08-20 19:36:20 +10002292image create bitmap reficon-T -background black -foreground yellow -data {
2293 #define tagicon_width 13
2294 #define tagicon_height 9
2295 static unsigned char tagicon_bits[] = {
2296 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x07,
2297 0xfc, 0x07, 0xf8, 0x07, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00};
2298} -maskdata {
2299 #define tagicon-mask_width 13
2300 #define tagicon-mask_height 9
2301 static unsigned char tagicon-mask_bits[] = {
2302 0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0xfc, 0x0f,
2303 0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf0, 0x0f, 0x00, 0x00};
2304}
2305set rectdata {
2306 #define headicon_width 13
2307 #define headicon_height 9
2308 static unsigned char headicon_bits[] = {
2309 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf8, 0x07,
2310 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00};
2311}
2312set rectmask {
2313 #define headicon-mask_width 13
2314 #define headicon-mask_height 9
2315 static unsigned char headicon-mask_bits[] = {
2316 0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
2317 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
2318}
2319image create bitmap reficon-H -background black -foreground green \
2320 -data $rectdata -maskdata $rectmask
2321image create bitmap reficon-o -background black -foreground "#ddddff" \
2322 -data $rectdata -maskdata $rectmask
2323
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002324proc init_flist {first} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002325 global cflist cflist_top difffilestart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002326
2327 $cflist conf -state normal
2328 $cflist delete 0.0 end
2329 if {$first ne {}} {
2330 $cflist insert end $first
2331 set cflist_top 1
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002332 $cflist tag add highlight 1.0 "1.0 lineend"
2333 } else {
2334 catch {unset cflist_top}
2335 }
2336 $cflist conf -state disabled
2337 set difffilestart {}
2338}
2339
Paul Mackerras63b79192006-05-20 21:31:52 +10002340proc highlight_tag {f} {
2341 global highlight_paths
2342
2343 foreach p $highlight_paths {
2344 if {[string match $p $f]} {
2345 return "bold"
2346 }
2347 }
2348 return {}
2349}
2350
2351proc highlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10002352 global cmitmode cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10002353
Paul Mackerras45a9d502006-05-20 22:56:27 +10002354 $cflist conf -state normal
2355 if {$cmitmode ne "tree"} {
Paul Mackerras63b79192006-05-20 21:31:52 +10002356 set end [lindex [split [$cflist index end] .] 0]
2357 for {set l 2} {$l < $end} {incr l} {
2358 set line [$cflist get $l.0 "$l.0 lineend"]
2359 if {[highlight_tag $line] ne {}} {
2360 $cflist tag add bold $l.0 "$l.0 lineend"
2361 }
2362 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10002363 } else {
2364 highlight_tree 2 {}
Paul Mackerras63b79192006-05-20 21:31:52 +10002365 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10002366 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10002367}
2368
2369proc unhighlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10002370 global cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10002371
Paul Mackerras45a9d502006-05-20 22:56:27 +10002372 $cflist conf -state normal
2373 $cflist tag remove bold 1.0 end
2374 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10002375}
2376
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002377proc add_flist {fl} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10002378 global cflist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002379
Paul Mackerras45a9d502006-05-20 22:56:27 +10002380 $cflist conf -state normal
2381 foreach f $fl {
2382 $cflist insert end "\n"
2383 $cflist insert end $f [highlight_tag $f]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002384 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10002385 $cflist conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002386}
2387
2388proc sel_flist {w x y} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10002389 global ctext difffilestart cflist cflist_top cmitmode
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002390
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002391 if {$cmitmode eq "tree"} return
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002392 if {![info exists cflist_top]} return
2393 set l [lindex [split [$w index "@$x,$y"] "."] 0]
Paul Mackerras89b11d32006-05-02 19:55:31 +10002394 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
2395 $cflist tag add highlight $l.0 "$l.0 lineend"
2396 set cflist_top $l
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10002397 if {$l == 1} {
2398 $ctext yview 1.0
2399 } else {
2400 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002401 }
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002402}
2403
Paul Mackerras32447292007-07-27 22:30:15 +10002404proc pop_flist_menu {w X Y x y} {
2405 global ctext cflist cmitmode flist_menu flist_menu_file
2406 global treediffs diffids
2407
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002408 stopfinding
Paul Mackerras32447292007-07-27 22:30:15 +10002409 set l [lindex [split [$w index "@$x,$y"] "."] 0]
2410 if {$l <= 1} return
2411 if {$cmitmode eq "tree"} {
2412 set e [linetoelt $l]
2413 if {[string index $e end] eq "/"} return
2414 } else {
2415 set e [lindex $treediffs($diffids) [expr {$l-2}]]
2416 }
2417 set flist_menu_file $e
2418 tk_popup $flist_menu $X $Y
2419}
2420
2421proc flist_hl {only} {
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002422 global flist_menu_file findstring gdttype
Paul Mackerras32447292007-07-27 22:30:15 +10002423
2424 set x [shellquote $flist_menu_file]
Christian Stimmingb007ee22007-11-07 18:44:35 +01002425 if {$only || $findstring eq {} || $gdttype ne [mc "touching paths:"]} {
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002426 set findstring $x
Paul Mackerras32447292007-07-27 22:30:15 +10002427 } else {
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002428 append findstring " " $x
Paul Mackerras32447292007-07-27 22:30:15 +10002429 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01002430 set gdttype [mc "touching paths:"]
Paul Mackerras32447292007-07-27 22:30:15 +10002431}
2432
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002433# Functions for adding and removing shell-type quoting
2434
2435proc shellquote {str} {
2436 if {![string match "*\['\"\\ \t]*" $str]} {
2437 return $str
2438 }
2439 if {![string match "*\['\"\\]*" $str]} {
2440 return "\"$str\""
2441 }
2442 if {![string match "*'*" $str]} {
2443 return "'$str'"
2444 }
2445 return "\"[string map {\" \\\" \\ \\\\} $str]\""
2446}
2447
2448proc shellarglist {l} {
2449 set str {}
2450 foreach a $l {
2451 if {$str ne {}} {
2452 append str " "
2453 }
2454 append str [shellquote $a]
2455 }
2456 return $str
2457}
2458
2459proc shelldequote {str} {
2460 set ret {}
2461 set used -1
2462 while {1} {
2463 incr used
2464 if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
2465 append ret [string range $str $used end]
2466 set used [string length $str]
2467 break
2468 }
2469 set first [lindex $first 0]
2470 set ch [string index $str $first]
2471 if {$first > $used} {
2472 append ret [string range $str $used [expr {$first - 1}]]
2473 set used $first
2474 }
2475 if {$ch eq " " || $ch eq "\t"} break
2476 incr used
2477 if {$ch eq "'"} {
2478 set first [string first "'" $str $used]
2479 if {$first < 0} {
2480 error "unmatched single-quote"
2481 }
2482 append ret [string range $str $used [expr {$first - 1}]]
2483 set used $first
2484 continue
2485 }
2486 if {$ch eq "\\"} {
2487 if {$used >= [string length $str]} {
2488 error "trailing backslash"
2489 }
2490 append ret [string index $str $used]
2491 continue
2492 }
2493 # here ch == "\""
2494 while {1} {
2495 if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
2496 error "unmatched double-quote"
2497 }
2498 set first [lindex $first 0]
2499 set ch [string index $str $first]
2500 if {$first > $used} {
2501 append ret [string range $str $used [expr {$first - 1}]]
2502 set used $first
2503 }
2504 if {$ch eq "\""} break
2505 incr used
2506 append ret [string index $str $used]
2507 incr used
2508 }
2509 }
2510 return [list $used $ret]
2511}
2512
2513proc shellsplit {str} {
2514 set l {}
2515 while {1} {
2516 set str [string trimleft $str]
2517 if {$str eq {}} break
2518 set dq [shelldequote $str]
2519 set n [lindex $dq 0]
2520 set word [lindex $dq 1]
2521 set str [string range $str $n end]
2522 lappend l $word
2523 }
2524 return $l
2525}
2526
Paul Mackerras7fcceed2006-04-27 19:21:49 +10002527# Code to implement multiple views
2528
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002529proc newview {ishighlight} {
2530 global nextviewnum newviewname newviewperm uifont newishighlight
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002531 global newviewargs revtreeargs
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002532
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002533 set newishighlight $ishighlight
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002534 set top .gitkview
2535 if {[winfo exists $top]} {
2536 raise $top
2537 return
2538 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002539 set newviewname($nextviewnum) "View $nextviewnum"
2540 set newviewperm($nextviewnum) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002541 set newviewargs($nextviewnum) [shellarglist $revtreeargs]
Christian Stimmingd990ced2007-11-07 18:42:55 +01002542 vieweditor $top $nextviewnum [mc "Gitk view definition"]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002543}
2544
2545proc editview {} {
2546 global curview
2547 global viewname viewperm newviewname newviewperm
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002548 global viewargs newviewargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002549
2550 set top .gitkvedit-$curview
2551 if {[winfo exists $top]} {
2552 raise $top
2553 return
2554 }
2555 set newviewname($curview) $viewname($curview)
2556 set newviewperm($curview) $viewperm($curview)
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002557 set newviewargs($curview) [shellarglist $viewargs($curview)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002558 vieweditor $top $curview "Gitk: edit view $viewname($curview)"
2559}
2560
2561proc vieweditor {top n title} {
2562 global newviewname newviewperm viewfiles
2563 global uifont
2564
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002565 toplevel $top
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002566 wm title $top $title
Christian Stimmingd990ced2007-11-07 18:42:55 +01002567 label $top.nl -text [mc "Name"] -font uifont
Paul Mackerras9c311b32007-10-04 22:27:13 +10002568 entry $top.name -width 20 -textvariable newviewname($n) -font uifont
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10002569 grid $top.nl $top.name -sticky w -pady 5
Christian Stimmingd990ced2007-11-07 18:42:55 +01002570 checkbutton $top.perm -text [mc "Remember this view"] -variable newviewperm($n) \
Paul Mackerras9c311b32007-10-04 22:27:13 +10002571 -font uifont
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10002572 grid $top.perm - -pady 5 -sticky w
Paul Mackerras9c311b32007-10-04 22:27:13 +10002573 message $top.al -aspect 1000 -font uifont \
Christian Stimmingd990ced2007-11-07 18:42:55 +01002574 -text [mc "Commits to include (arguments to git rev-list):"]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002575 grid $top.al - -sticky w -pady 5
2576 entry $top.args -width 50 -textvariable newviewargs($n) \
Paul Mackerras9c311b32007-10-04 22:27:13 +10002577 -background white -font uifont
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002578 grid $top.args - -sticky ew -padx 5
Paul Mackerras9c311b32007-10-04 22:27:13 +10002579 message $top.l -aspect 1000 -font uifont \
Christian Stimmingd990ced2007-11-07 18:42:55 +01002580 -text [mc "Enter files and directories to include, one per line:"]
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10002581 grid $top.l - -sticky w
Paul Mackerras9c311b32007-10-04 22:27:13 +10002582 text $top.t -width 40 -height 10 -background white -font uifont
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002583 if {[info exists viewfiles($n)]} {
2584 foreach f $viewfiles($n) {
2585 $top.t insert end $f
2586 $top.t insert end "\n"
2587 }
2588 $top.t delete {end - 1c} end
2589 $top.t mark set insert 0.0
2590 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002591 grid $top.t - -sticky ew -padx 5
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002592 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01002593 button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n] \
Paul Mackerras9c311b32007-10-04 22:27:13 +10002594 -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01002595 button $top.buts.can -text [mc "Cancel"] -command [list destroy $top] \
Paul Mackerras9c311b32007-10-04 22:27:13 +10002596 -font uifont
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002597 grid $top.buts.ok $top.buts.can
2598 grid columnconfigure $top.buts 0 -weight 1 -uniform a
2599 grid columnconfigure $top.buts 1 -weight 1 -uniform a
2600 grid $top.buts - -pady 10 -sticky ew
2601 focus $top.t
2602}
2603
Paul Mackerras908c3582006-05-20 09:38:11 +10002604proc doviewmenu {m first cmd op argv} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002605 set nmenu [$m index end]
2606 for {set i $first} {$i <= $nmenu} {incr i} {
2607 if {[$m entrycget $i -command] eq $cmd} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002608 eval $m $op $i $argv
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002609 break
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002610 }
2611 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002612}
2613
2614proc allviewmenus {n op args} {
Paul Mackerras687c8762007-09-22 12:49:33 +10002615 # global viewhlmenu
Paul Mackerras908c3582006-05-20 09:38:11 +10002616
Paul Mackerras3cd204e2006-11-23 21:06:16 +11002617 doviewmenu .bar.view 5 [list showview $n] $op $args
Paul Mackerras687c8762007-09-22 12:49:33 +10002618 # doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002619}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002620
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002621proc newviewok {top n} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002622 global nextviewnum newviewperm newviewname newishighlight
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002623 global viewname viewfiles viewperm selectedview curview
Paul Mackerras908c3582006-05-20 09:38:11 +10002624 global viewargs newviewargs viewhlmenu
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002625
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002626 if {[catch {
2627 set newargs [shellsplit $newviewargs($n)]
2628 } err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01002629 error_popup "[mc "Error in commit selection arguments:"] $err"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002630 wm raise $top
2631 focus $top
2632 return
2633 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002634 set files {}
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002635 foreach f [split [$top.t get 0.0 end] "\n"] {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002636 set ft [string trim $f]
2637 if {$ft ne {}} {
2638 lappend files $ft
2639 }
2640 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002641 if {![info exists viewfiles($n)]} {
2642 # creating a new view
2643 incr nextviewnum
2644 set viewname($n) $newviewname($n)
2645 set viewperm($n) $newviewperm($n)
2646 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002647 set viewargs($n) $newargs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002648 addviewmenu $n
2649 if {!$newishighlight} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10002650 run showview $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002651 } else {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10002652 run addvhighlight $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002653 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002654 } else {
2655 # editing an existing view
2656 set viewperm($n) $newviewperm($n)
2657 if {$newviewname($n) ne $viewname($n)} {
2658 set viewname($n) $newviewname($n)
Paul Mackerras3cd204e2006-11-23 21:06:16 +11002659 doviewmenu .bar.view 5 [list showview $n] \
Paul Mackerras908c3582006-05-20 09:38:11 +10002660 entryconf [list -label $viewname($n)]
Paul Mackerras687c8762007-09-22 12:49:33 +10002661 # doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
2662 # entryconf [list -label $viewname($n) -value $viewname($n)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002663 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002664 if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002665 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002666 set viewargs($n) $newargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002667 if {$curview == $n} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002668 run reloadcommits
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002669 }
2670 }
2671 }
2672 catch {destroy $top}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002673}
2674
2675proc delview {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002676 global curview viewperm hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002677
2678 if {$curview == 0} return
Paul Mackerras908c3582006-05-20 09:38:11 +10002679 if {[info exists hlview] && $hlview == $curview} {
Christian Stimmingb007ee22007-11-07 18:44:35 +01002680 set selectedhlview [mc "None"]
Paul Mackerras908c3582006-05-20 09:38:11 +10002681 unset hlview
2682 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002683 allviewmenus $curview delete
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10002684 set viewperm($curview) 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002685 showview 0
2686}
2687
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002688proc addviewmenu {n} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002689 global viewname viewhlmenu
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002690
2691 .bar.view add radiobutton -label $viewname($n) \
2692 -command [list showview $n] -variable selectedview -value $n
Paul Mackerras687c8762007-09-22 12:49:33 +10002693 #$viewhlmenu add radiobutton -label $viewname($n) \
2694 # -command [list addvhighlight $n] -variable selectedhlview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002695}
2696
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002697proc showview {n} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11002698 global curview viewfiles cached_commitrow ordertok
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10002699 global displayorder parentlist rowidlist rowisopt rowfinal
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002700 global colormap rowtextx nextcolor canvxmax
2701 global numcommits viewcomplete
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002702 global selectedline currentid canv canvy0
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10002703 global treediffs
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002704 global pending_select
Paul Mackerras03800812007-08-29 21:45:21 +10002705 global commitidx
Paul Mackerrase507fd42007-06-16 21:51:08 +10002706 global selectedview selectfirst
Paul Mackerras97645682007-08-23 22:24:38 +10002707 global hlview selectedhlview commitinterest
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002708
2709 if {$n == $curview} return
2710 set selid {}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002711 set ymax [lindex [$canv cget -scrollregion] 3]
2712 set span [$canv yview]
2713 set ytop [expr {[lindex $span 0] * $ymax}]
2714 set ybot [expr {[lindex $span 1] * $ymax}]
2715 set yscreen [expr {($ybot - $ytop) / 2}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002716 if {[info exists selectedline]} {
2717 set selid $currentid
2718 set y [yc $selectedline]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002719 if {$ytop < $y && $y < $ybot} {
2720 set yscreen [expr {$y - $ytop}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002721 }
Paul Mackerrase507fd42007-06-16 21:51:08 +10002722 } elseif {[info exists pending_select]} {
2723 set selid $pending_select
2724 unset pending_select
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002725 }
2726 unselectline
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002727 normalline
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002728 catch {unset treediffs}
2729 clear_display
Paul Mackerras908c3582006-05-20 09:38:11 +10002730 if {[info exists hlview] && $hlview == $n} {
2731 unset hlview
Christian Stimmingb007ee22007-11-07 18:44:35 +01002732 set selectedhlview [mc "None"]
Paul Mackerras908c3582006-05-20 09:38:11 +10002733 }
Paul Mackerras97645682007-08-23 22:24:38 +10002734 catch {unset commitinterest}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002735 catch {unset cached_commitrow}
Paul Mackerras9257d8f2007-12-11 10:45:38 +11002736 catch {unset ordertok}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002737
2738 set curview $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10002739 set selectedview $n
Christian Stimmingd990ced2007-11-07 18:42:55 +01002740 .bar.view entryconf [mc "Edit view..."] -state [expr {$n == 0? "disabled": "normal"}]
2741 .bar.view entryconf [mc "Delete view"] -state [expr {$n == 0? "disabled": "normal"}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002742
Paul Mackerrasdf904492007-08-29 22:03:07 +10002743 run refill_reflist
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002744 if {![info exists viewcomplete($n)]} {
Paul Mackerrase507fd42007-06-16 21:51:08 +10002745 if {$selid ne {}} {
2746 set pending_select $selid
2747 }
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10002748 getcommits
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002749 return
2750 }
2751
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002752 set displayorder {}
2753 set parentlist {}
2754 set rowidlist {}
2755 set rowisopt {}
2756 set rowfinal {}
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10002757 set numcommits $commitidx($n)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002758
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002759 catch {unset colormap}
2760 catch {unset rowtextx}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002761 set nextcolor 0
2762 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002763 set curview $n
2764 set row 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002765 setcanvscroll
2766 set yf 0
Paul Mackerrase507fd42007-06-16 21:51:08 +10002767 set row {}
2768 set selectfirst 0
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002769 if {$selid ne {} && [commitinview $selid $n]} {
2770 set row [rowofcommit $selid]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002771 # try to get the selected row in the same position on the screen
2772 set ymax [lindex [$canv cget -scrollregion] 3]
2773 set ytop [expr {[yc $row] - $yscreen}]
2774 if {$ytop < 0} {
2775 set ytop 0
2776 }
2777 set yf [expr {$ytop * 1.0 / $ymax}]
2778 }
2779 allcanvs yview moveto $yf
2780 drawvisible
Paul Mackerrase507fd42007-06-16 21:51:08 +10002781 if {$row ne {}} {
2782 selectline $row 0
2783 } elseif {$selid ne {}} {
2784 set pending_select $selid
2785 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10002786 set row [first_real_row]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10002787 if {$row < $numcommits} {
2788 selectline $row 0
Paul Mackerrase507fd42007-06-16 21:51:08 +10002789 } else {
2790 set selectfirst 1
2791 }
2792 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002793 if {!$viewcomplete($n)} {
2794 if {$numcommits == 0} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01002795 show_status [mc "Reading commits..."]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10002796 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10002797 } elseif {$numcommits == 0} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01002798 show_status [mc "No commits selected"]
Paul Mackerras2516dae2006-04-21 10:35:31 +10002799 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002800}
2801
Paul Mackerras908c3582006-05-20 09:38:11 +10002802# Stuff relating to the highlighting facility
2803
2804proc ishighlighted {row} {
Paul Mackerras164ff272006-05-29 19:50:02 +10002805 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10002806
2807 if {[info exists nhighlights($row)] && $nhighlights($row) > 0} {
2808 return $nhighlights($row)
2809 }
2810 if {[info exists vhighlights($row)] && $vhighlights($row) > 0} {
2811 return $vhighlights($row)
2812 }
2813 if {[info exists fhighlights($row)] && $fhighlights($row) > 0} {
2814 return $fhighlights($row)
2815 }
Paul Mackerras164ff272006-05-29 19:50:02 +10002816 if {[info exists rhighlights($row)] && $rhighlights($row) > 0} {
2817 return $rhighlights($row)
2818 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002819 return 0
2820}
2821
2822proc bolden {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002823 global canv linehtag selectedline boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10002824
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002825 lappend boldrows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10002826 $canv itemconf $linehtag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10002827 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002828 $canv delete secsel
2829 set t [eval $canv create rect [$canv bbox $linehtag($row)] \
2830 -outline {{}} -tags secsel \
2831 -fill [$canv cget -selectbackground]]
2832 $canv lower $t
2833 }
2834}
2835
2836proc bolden_name {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002837 global canv2 linentag selectedline boldnamerows
Paul Mackerras908c3582006-05-20 09:38:11 +10002838
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002839 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10002840 $canv2 itemconf $linentag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10002841 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002842 $canv2 delete secsel
2843 set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
2844 -outline {{}} -tags secsel \
2845 -fill [$canv2 cget -selectbackground]]
2846 $canv2 lower $t
2847 }
2848}
2849
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002850proc unbolden {} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002851 global boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10002852
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002853 set stillbold {}
2854 foreach row $boldrows {
Paul Mackerras908c3582006-05-20 09:38:11 +10002855 if {![ishighlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002856 bolden $row mainfont
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002857 } else {
2858 lappend stillbold $row
Paul Mackerras908c3582006-05-20 09:38:11 +10002859 }
2860 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002861 set boldrows $stillbold
Paul Mackerras908c3582006-05-20 09:38:11 +10002862}
2863
2864proc addvhighlight {n} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002865 global hlview viewcomplete curview vhl_done vhighlights commitidx
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002866
2867 if {[info exists hlview]} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002868 delvhighlight
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002869 }
2870 set hlview $n
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002871 if {$n != $curview && ![info exists viewcomplete($n)]} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002872 start_rev_list $n
Paul Mackerras908c3582006-05-20 09:38:11 +10002873 }
2874 set vhl_done $commitidx($hlview)
2875 if {$vhl_done > 0} {
2876 drawvisible
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002877 }
2878}
2879
Paul Mackerras908c3582006-05-20 09:38:11 +10002880proc delvhighlight {} {
2881 global hlview vhighlights
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002882
2883 if {![info exists hlview]} return
2884 unset hlview
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002885 catch {unset vhighlights}
2886 unbolden
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002887}
2888
Paul Mackerras908c3582006-05-20 09:38:11 +10002889proc vhighlightmore {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002890 global hlview vhl_done commitidx vhighlights curview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002891
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002892 set max $commitidx($hlview)
Paul Mackerras908c3582006-05-20 09:38:11 +10002893 set vr [visiblerows]
2894 set r0 [lindex $vr 0]
2895 set r1 [lindex $vr 1]
2896 for {set i $vhl_done} {$i < $max} {incr i} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002897 set id [commitonrow $i $hlview]
2898 if {[commitinview $id $curview]} {
2899 set row [rowofcommit $id]
Paul Mackerras908c3582006-05-20 09:38:11 +10002900 if {$r0 <= $row && $row <= $r1} {
2901 if {![highlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002902 bolden $row mainfontbold
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002903 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002904 set vhighlights($row) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002905 }
2906 }
2907 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002908 set vhl_done $max
2909}
2910
2911proc askvhighlight {row id} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002912 global hlview vhighlights iddrawn
Paul Mackerras908c3582006-05-20 09:38:11 +10002913
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11002914 if {[commitinview $id $hlview]} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002915 if {[info exists iddrawn($id)] && ![ishighlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002916 bolden $row mainfontbold
Paul Mackerras908c3582006-05-20 09:38:11 +10002917 }
2918 set vhighlights($row) 1
2919 } else {
2920 set vhighlights($row) 0
2921 }
2922}
2923
Paul Mackerras687c8762007-09-22 12:49:33 +10002924proc hfiles_change {} {
Paul Mackerras908c3582006-05-20 09:38:11 +10002925 global highlight_files filehighlight fhighlights fh_serial
Paul Mackerras9c311b32007-10-04 22:27:13 +10002926 global highlight_paths gdttype
Paul Mackerras908c3582006-05-20 09:38:11 +10002927
2928 if {[info exists filehighlight]} {
2929 # delete previous highlights
2930 catch {close $filehighlight}
2931 unset filehighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002932 catch {unset fhighlights}
2933 unbolden
Paul Mackerras63b79192006-05-20 21:31:52 +10002934 unhighlight_filelist
Paul Mackerras908c3582006-05-20 09:38:11 +10002935 }
Paul Mackerras63b79192006-05-20 21:31:52 +10002936 set highlight_paths {}
Paul Mackerras908c3582006-05-20 09:38:11 +10002937 after cancel do_file_hl $fh_serial
2938 incr fh_serial
2939 if {$highlight_files ne {}} {
2940 after 300 do_file_hl $fh_serial
2941 }
2942}
2943
Paul Mackerras687c8762007-09-22 12:49:33 +10002944proc gdttype_change {name ix op} {
2945 global gdttype highlight_files findstring findpattern
2946
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002947 stopfinding
Paul Mackerras687c8762007-09-22 12:49:33 +10002948 if {$findstring ne {}} {
Christian Stimmingb007ee22007-11-07 18:44:35 +01002949 if {$gdttype eq [mc "containing:"]} {
Paul Mackerras687c8762007-09-22 12:49:33 +10002950 if {$highlight_files ne {}} {
2951 set highlight_files {}
2952 hfiles_change
2953 }
2954 findcom_change
2955 } else {
2956 if {$findpattern ne {}} {
2957 set findpattern {}
2958 findcom_change
2959 }
2960 set highlight_files $findstring
2961 hfiles_change
2962 }
2963 drawvisible
2964 }
2965 # enable/disable findtype/findloc menus too
2966}
2967
2968proc find_change {name ix op} {
2969 global gdttype findstring highlight_files
2970
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002971 stopfinding
Christian Stimmingb007ee22007-11-07 18:44:35 +01002972 if {$gdttype eq [mc "containing:"]} {
Paul Mackerras687c8762007-09-22 12:49:33 +10002973 findcom_change
2974 } else {
2975 if {$highlight_files ne $findstring} {
2976 set highlight_files $findstring
2977 hfiles_change
2978 }
2979 }
2980 drawvisible
2981}
2982
Paul Mackerras64b5f142007-10-04 22:19:24 +10002983proc findcom_change args {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002984 global nhighlights boldnamerows
Paul Mackerras687c8762007-09-22 12:49:33 +10002985 global findpattern findtype findstring gdttype
2986
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10002987 stopfinding
Paul Mackerras687c8762007-09-22 12:49:33 +10002988 # delete previous highlights, if any
2989 foreach row $boldnamerows {
Paul Mackerras9c311b32007-10-04 22:27:13 +10002990 bolden_name $row mainfont
Paul Mackerras687c8762007-09-22 12:49:33 +10002991 }
2992 set boldnamerows {}
2993 catch {unset nhighlights}
2994 unbolden
2995 unmarkmatches
Christian Stimmingb007ee22007-11-07 18:44:35 +01002996 if {$gdttype ne [mc "containing:"] || $findstring eq {}} {
Paul Mackerras687c8762007-09-22 12:49:33 +10002997 set findpattern {}
Christian Stimmingb007ee22007-11-07 18:44:35 +01002998 } elseif {$findtype eq [mc "Regexp"]} {
Paul Mackerras687c8762007-09-22 12:49:33 +10002999 set findpattern $findstring
3000 } else {
3001 set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
3002 $findstring]
3003 set findpattern "*$e*"
3004 }
3005}
3006
Paul Mackerras63b79192006-05-20 21:31:52 +10003007proc makepatterns {l} {
3008 set ret {}
3009 foreach e $l {
3010 set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
3011 if {[string index $ee end] eq "/"} {
3012 lappend ret "$ee*"
3013 } else {
3014 lappend ret $ee
3015 lappend ret "$ee/*"
3016 }
3017 }
3018 return $ret
3019}
3020
Paul Mackerras908c3582006-05-20 09:38:11 +10003021proc do_file_hl {serial} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003022 global highlight_files filehighlight highlight_paths gdttype fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10003023
Christian Stimmingb007ee22007-11-07 18:44:35 +01003024 if {$gdttype eq [mc "touching paths:"]} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003025 if {[catch {set paths [shellsplit $highlight_files]}]} return
3026 set highlight_paths [makepatterns $paths]
3027 highlight_filelist
3028 set gdtargs [concat -- $paths]
Christian Stimmingb007ee22007-11-07 18:44:35 +01003029 } elseif {$gdttype eq [mc "adding/removing string:"]} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003030 set gdtargs [list "-S$highlight_files"]
Paul Mackerras687c8762007-09-22 12:49:33 +10003031 } else {
3032 # must be "containing:", i.e. we're searching commit info
3033 return
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003034 }
Brandon Casey1ce09dd2007-03-19 18:00:37 -05003035 set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
Paul Mackerras908c3582006-05-20 09:38:11 +10003036 set filehighlight [open $cmd r+]
3037 fconfigure $filehighlight -blocking 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003038 filerun $filehighlight readfhighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003039 set fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10003040 drawvisible
3041 flushhighlights
3042}
3043
3044proc flushhighlights {} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003045 global filehighlight fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10003046
3047 if {[info exists filehighlight]} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003048 lappend fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10003049 puts $filehighlight ""
3050 flush $filehighlight
3051 }
3052}
3053
3054proc askfilehighlight {row id} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003055 global filehighlight fhighlights fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10003056
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003057 lappend fhl_list $id
3058 set fhighlights($row) -1
Paul Mackerras908c3582006-05-20 09:38:11 +10003059 puts $filehighlight $id
3060}
3061
3062proc readfhighlight {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003063 global filehighlight fhighlights curview iddrawn
Paul Mackerras687c8762007-09-22 12:49:33 +10003064 global fhl_list find_dirn
Paul Mackerras908c3582006-05-20 09:38:11 +10003065
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003066 if {![info exists filehighlight]} {
3067 return 0
3068 }
3069 set nr 0
3070 while {[incr nr] <= 100 && [gets $filehighlight line] >= 0} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003071 set line [string trim $line]
3072 set i [lsearch -exact $fhl_list $line]
3073 if {$i < 0} continue
3074 for {set j 0} {$j < $i} {incr j} {
3075 set id [lindex $fhl_list $j]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003076 if {[commitinview $id $curview]} {
3077 set fhighlights([rowofcommit $id]) 0
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003078 }
Paul Mackerras908c3582006-05-20 09:38:11 +10003079 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003080 set fhl_list [lrange $fhl_list [expr {$i+1}] end]
3081 if {$line eq {}} continue
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003082 if {![commitinview $line $curview]} continue
3083 set row [rowofcommit $line]
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003084 if {[info exists iddrawn($line)] && ![ishighlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003085 bolden $row mainfontbold
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003086 }
3087 set fhighlights($row) 1
Paul Mackerras908c3582006-05-20 09:38:11 +10003088 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003089 if {[eof $filehighlight]} {
3090 # strange...
Brandon Casey1ce09dd2007-03-19 18:00:37 -05003091 puts "oops, git diff-tree died"
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003092 catch {close $filehighlight}
3093 unset filehighlight
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003094 return 0
Paul Mackerras908c3582006-05-20 09:38:11 +10003095 }
Paul Mackerras687c8762007-09-22 12:49:33 +10003096 if {[info exists find_dirn]} {
Paul Mackerrascca5d942007-10-27 21:16:56 +10003097 run findmore
Paul Mackerras687c8762007-09-22 12:49:33 +10003098 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003099 return 1
Paul Mackerras908c3582006-05-20 09:38:11 +10003100}
3101
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003102proc doesmatch {f} {
Paul Mackerras687c8762007-09-22 12:49:33 +10003103 global findtype findpattern
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003104
Christian Stimmingb007ee22007-11-07 18:44:35 +01003105 if {$findtype eq [mc "Regexp"]} {
Paul Mackerras687c8762007-09-22 12:49:33 +10003106 return [regexp $findpattern $f]
Christian Stimmingb007ee22007-11-07 18:44:35 +01003107 } elseif {$findtype eq [mc "IgnCase"]} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003108 return [string match -nocase $findpattern $f]
3109 } else {
3110 return [string match $findpattern $f]
3111 }
3112}
3113
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003114proc askfindhighlight {row id} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003115 global nhighlights commitinfo iddrawn
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003116 global findloc
3117 global markingmatches
Paul Mackerras908c3582006-05-20 09:38:11 +10003118
3119 if {![info exists commitinfo($id)]} {
3120 getcommit $id
3121 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003122 set info $commitinfo($id)
Paul Mackerras908c3582006-05-20 09:38:11 +10003123 set isbold 0
Christian Stimmingb007ee22007-11-07 18:44:35 +01003124 set fldtypes [list [mc Headline] [mc Author] [mc Date] [mc Committer] [mc CDate] [mc Comments]]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003125 foreach f $info ty $fldtypes {
Christian Stimmingb007ee22007-11-07 18:44:35 +01003126 if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003127 [doesmatch $f]} {
Christian Stimmingb007ee22007-11-07 18:44:35 +01003128 if {$ty eq [mc "Author"]} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003129 set isbold 2
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003130 break
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003131 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003132 set isbold 1
Paul Mackerras908c3582006-05-20 09:38:11 +10003133 }
3134 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003135 if {$isbold && [info exists iddrawn($id)]} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003136 if {![ishighlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003137 bolden $row mainfontbold
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003138 if {$isbold > 1} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003139 bolden_name $row mainfontbold
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003140 }
Paul Mackerras908c3582006-05-20 09:38:11 +10003141 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003142 if {$markingmatches} {
Paul Mackerras005a2f42007-07-26 22:36:39 +10003143 markrowmatches $row $id
Paul Mackerras908c3582006-05-20 09:38:11 +10003144 }
3145 }
3146 set nhighlights($row) $isbold
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003147}
3148
Paul Mackerras005a2f42007-07-26 22:36:39 +10003149proc markrowmatches {row id} {
3150 global canv canv2 linehtag linentag commitinfo findloc
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003151
Paul Mackerras005a2f42007-07-26 22:36:39 +10003152 set headline [lindex $commitinfo($id) 0]
3153 set author [lindex $commitinfo($id) 1]
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003154 $canv delete match$row
3155 $canv2 delete match$row
Christian Stimmingb007ee22007-11-07 18:44:35 +01003156 if {$findloc eq [mc "All fields"] || $findloc eq [mc "Headline"]} {
Paul Mackerras005a2f42007-07-26 22:36:39 +10003157 set m [findmatches $headline]
3158 if {$m ne {}} {
3159 markmatches $canv $row $headline $linehtag($row) $m \
3160 [$canv itemcget $linehtag($row) -font] $row
3161 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003162 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01003163 if {$findloc eq [mc "All fields"] || $findloc eq [mc "Author"]} {
Paul Mackerras005a2f42007-07-26 22:36:39 +10003164 set m [findmatches $author]
3165 if {$m ne {}} {
3166 markmatches $canv2 $row $author $linentag($row) $m \
3167 [$canv2 itemcget $linentag($row) -font] $row
3168 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10003169 }
3170}
3171
Paul Mackerras164ff272006-05-29 19:50:02 +10003172proc vrel_change {name ix op} {
3173 global highlight_related
3174
3175 rhighlight_none
Christian Stimmingb007ee22007-11-07 18:44:35 +01003176 if {$highlight_related ne [mc "None"]} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003177 run drawvisible
Paul Mackerras164ff272006-05-29 19:50:02 +10003178 }
3179}
3180
3181# prepare for testing whether commits are descendents or ancestors of a
3182proc rhighlight_sel {a} {
3183 global descendent desc_todo ancestor anc_todo
3184 global highlight_related rhighlights
3185
3186 catch {unset descendent}
3187 set desc_todo [list $a]
3188 catch {unset ancestor}
3189 set anc_todo [list $a]
Christian Stimmingb007ee22007-11-07 18:44:35 +01003190 if {$highlight_related ne [mc "None"]} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003191 rhighlight_none
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10003192 run drawvisible
Paul Mackerras164ff272006-05-29 19:50:02 +10003193 }
3194}
3195
3196proc rhighlight_none {} {
3197 global rhighlights
3198
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003199 catch {unset rhighlights}
3200 unbolden
Paul Mackerras164ff272006-05-29 19:50:02 +10003201}
3202
3203proc is_descendent {a} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003204 global curview children descendent desc_todo
Paul Mackerras164ff272006-05-29 19:50:02 +10003205
3206 set v $curview
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003207 set la [rowofcommit $a]
Paul Mackerras164ff272006-05-29 19:50:02 +10003208 set todo $desc_todo
3209 set leftover {}
3210 set done 0
3211 for {set i 0} {$i < [llength $todo]} {incr i} {
3212 set do [lindex $todo $i]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003213 if {[rowofcommit $do] < $la} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003214 lappend leftover $do
3215 continue
3216 }
3217 foreach nk $children($v,$do) {
3218 if {![info exists descendent($nk)]} {
3219 set descendent($nk) 1
3220 lappend todo $nk
3221 if {$nk eq $a} {
3222 set done 1
3223 }
3224 }
3225 }
3226 if {$done} {
3227 set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
3228 return
3229 }
3230 }
3231 set descendent($a) 0
3232 set desc_todo $leftover
3233}
3234
3235proc is_ancestor {a} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003236 global curview parents ancestor anc_todo
Paul Mackerras164ff272006-05-29 19:50:02 +10003237
3238 set v $curview
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003239 set la [rowofcommit $a]
Paul Mackerras164ff272006-05-29 19:50:02 +10003240 set todo $anc_todo
3241 set leftover {}
3242 set done 0
3243 for {set i 0} {$i < [llength $todo]} {incr i} {
3244 set do [lindex $todo $i]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003245 if {![commitinview $do $v] || [rowofcommit $do] > $la} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003246 lappend leftover $do
3247 continue
3248 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003249 foreach np $parents($v,$do) {
Paul Mackerras164ff272006-05-29 19:50:02 +10003250 if {![info exists ancestor($np)]} {
3251 set ancestor($np) 1
3252 lappend todo $np
3253 if {$np eq $a} {
3254 set done 1
3255 }
3256 }
3257 }
3258 if {$done} {
3259 set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
3260 return
3261 }
3262 }
3263 set ancestor($a) 0
3264 set anc_todo $leftover
3265}
3266
3267proc askrelhighlight {row id} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003268 global descendent highlight_related iddrawn rhighlights
Paul Mackerras164ff272006-05-29 19:50:02 +10003269 global selectedline ancestor
3270
3271 if {![info exists selectedline]} return
3272 set isbold 0
Christian Stimmingb007ee22007-11-07 18:44:35 +01003273 if {$highlight_related eq [mc "Descendent"] ||
3274 $highlight_related eq [mc "Not descendent"]} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003275 if {![info exists descendent($id)]} {
3276 is_descendent $id
3277 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01003278 if {$descendent($id) == ($highlight_related eq [mc "Descendent"])} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003279 set isbold 1
3280 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01003281 } elseif {$highlight_related eq [mc "Ancestor"] ||
3282 $highlight_related eq [mc "Not ancestor"]} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003283 if {![info exists ancestor($id)]} {
3284 is_ancestor $id
3285 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01003286 if {$ancestor($id) == ($highlight_related eq [mc "Ancestor"])} {
Paul Mackerras164ff272006-05-29 19:50:02 +10003287 set isbold 1
3288 }
3289 }
3290 if {[info exists iddrawn($id)]} {
3291 if {$isbold && ![ishighlighted $row]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10003292 bolden $row mainfontbold
Paul Mackerras164ff272006-05-29 19:50:02 +10003293 }
3294 }
3295 set rhighlights($row) $isbold
3296}
3297
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003298# Graph layout functions
3299
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003300proc shortids {ids} {
3301 set res {}
3302 foreach id $ids {
3303 if {[llength $id] > 1} {
3304 lappend res [shortids $id]
3305 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
3306 lappend res [string range $id 0 7]
3307 } else {
3308 lappend res $id
3309 }
3310 }
3311 return $res
3312}
3313
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003314proc ntimes {n o} {
3315 set ret {}
Paul Mackerras03800812007-08-29 21:45:21 +10003316 set o [list $o]
3317 for {set mask 1} {$mask <= $n} {incr mask $mask} {
3318 if {($n & $mask) != 0} {
3319 set ret [concat $ret $o]
3320 }
3321 set o [concat $o $o]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003322 }
3323 return $ret
3324}
3325
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003326proc ordertoken {id} {
3327 global ordertok curview varcid varcstart varctok curview parents children
3328 global nullid nullid2
3329
3330 if {[info exists ordertok($id)]} {
3331 return $ordertok($id)
3332 }
3333 set origid $id
3334 set todo {}
3335 while {1} {
3336 if {[info exists varcid($curview,$id)]} {
3337 set a $varcid($curview,$id)
3338 set p [lindex $varcstart($curview) $a]
3339 } else {
3340 set p [lindex $children($curview,$id) 0]
3341 }
3342 if {[info exists ordertok($p)]} {
3343 set tok $ordertok($p)
3344 break
3345 }
3346 if {[llength $children($curview,$p)] == 0} {
3347 # it's a root
3348 set tok [lindex $varctok($curview) $a]
3349 break
3350 }
3351 set id [lindex $children($curview,$p) 0]
3352 if {$id eq $nullid || $id eq $nullid2} {
3353 # XXX treat it as a root
3354 set tok [lindex $varctok($curview) $a]
3355 break
3356 }
3357 if {[llength $parents($curview,$id)] == 1} {
3358 lappend todo [list $p {}]
3359 } else {
3360 set j [lsearch -exact $parents($curview,$id) $p]
3361 if {$j < 0} {
3362 puts "oops didn't find [shortids $p] in parents of [shortids $id]"
3363 }
3364 lappend todo [list $p [strrep $j]]
3365 }
3366 }
3367 for {set i [llength $todo]} {[incr i -1] >= 0} {} {
3368 set p [lindex $todo $i 0]
3369 append tok [lindex $todo $i 1]
3370 set ordertok($p) $tok
3371 }
3372 set ordertok($origid) $tok
3373 return $tok
3374}
3375
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003376# Work out where id should go in idlist so that order-token
3377# values increase from left to right
3378proc idcol {idlist id {i 0}} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003379 set t [ordertoken $id]
Paul Mackerrase5b37ac2007-12-12 18:13:51 +11003380 if {$i < 0} {
3381 set i 0
3382 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003383 if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003384 if {$i > [llength $idlist]} {
3385 set i [llength $idlist]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003386 }
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003387 while {[incr i -1] >= 0 && $t < [ordertoken [lindex $idlist $i]]} {}
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003388 incr i
3389 } else {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003390 if {$t > [ordertoken [lindex $idlist $i]]} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003391 while {[incr i] < [llength $idlist] &&
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003392 $t >= [ordertoken [lindex $idlist $i]]} {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003393 }
3394 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003395 return $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003396}
3397
3398proc initlayout {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003399 global rowidlist rowisopt rowfinal displayorder parentlist
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003400 global numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003401 global nextcolor
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003402 global colormap rowtextx
Paul Mackerras322a8cc2006-10-15 18:03:46 +10003403 global selectfirst
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003404
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003405 set numcommits 0
3406 set displayorder {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10003407 set parentlist {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003408 set nextcolor 0
Paul Mackerras03800812007-08-29 21:45:21 +10003409 set rowidlist {}
3410 set rowisopt {}
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003411 set rowfinal {}
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11003412 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003413 catch {unset colormap}
3414 catch {unset rowtextx}
Paul Mackerrase507fd42007-06-16 21:51:08 +10003415 set selectfirst 1
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11003416}
3417
3418proc setcanvscroll {} {
3419 global canv canv2 canv3 numcommits linespc canvxmax canvy0
3420
3421 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
3422 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
3423 $canv2 conf -scrollregion [list 0 0 0 $ymax]
3424 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003425}
3426
3427proc visiblerows {} {
3428 global canv numcommits linespc
3429
3430 set ymax [lindex [$canv cget -scrollregion] 3]
3431 if {$ymax eq {} || $ymax == 0} return
3432 set f [$canv yview]
3433 set y0 [expr {int([lindex $f 0] * $ymax)}]
3434 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
3435 if {$r0 < 0} {
3436 set r0 0
3437 }
3438 set y1 [expr {int([lindex $f 1] * $ymax)}]
3439 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
3440 if {$r1 >= $numcommits} {
3441 set r1 [expr {$numcommits - 1}]
3442 }
3443 return [list $r0 $r1]
3444}
3445
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003446proc layoutmore {} {
Paul Mackerras38dfe932007-12-06 20:50:31 +11003447 global commitidx viewcomplete curview
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003448 global numcommits pending_select selectedline curview
Paul Mackerras38dfe932007-12-06 20:50:31 +11003449 global selectfirst lastscrollset commitinterest
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003450
Paul Mackerras38dfe932007-12-06 20:50:31 +11003451 set canshow $commitidx($curview)
3452 if {$canshow <= $numcommits && !$viewcomplete($curview)} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003453 if {$numcommits == 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003454 allcanvs delete all
3455 }
Paul Mackerras322a8cc2006-10-15 18:03:46 +10003456 set r0 $numcommits
Paul Mackerrasa2c22362006-10-31 15:00:53 +11003457 set prev $numcommits
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003458 set numcommits $canshow
Paul Mackerrasa2c22362006-10-31 15:00:53 +11003459 set t [clock clicks -milliseconds]
Paul Mackerras38dfe932007-12-06 20:50:31 +11003460 if {$prev < 100 || $viewcomplete($curview) || $t - $lastscrollset > 500} {
Paul Mackerrasa2c22362006-10-31 15:00:53 +11003461 set lastscrollset $t
3462 setcanvscroll
3463 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003464 set rows [visiblerows]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003465 set r1 [lindex $rows 1]
Paul Mackerras322a8cc2006-10-15 18:03:46 +10003466 if {$r1 >= $canshow} {
3467 set r1 [expr {$canshow - 1}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003468 }
Paul Mackerras322a8cc2006-10-15 18:03:46 +10003469 if {$r0 <= $r1} {
3470 drawcommits $r0 $r1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003471 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003472 if {[info exists pending_select] &&
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003473 [commitinview $pending_select $curview]} {
3474 selectline [rowofcommit $pending_select] 1
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003475 }
Paul Mackerrase507fd42007-06-16 21:51:08 +10003476 if {$selectfirst} {
3477 if {[info exists selectedline] || [info exists pending_select]} {
3478 set selectfirst 0
3479 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10003480 set l [first_real_row]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003481 selectline $l 1
Paul Mackerrase507fd42007-06-16 21:51:08 +10003482 set selectfirst 0
3483 }
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003484 }
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003485}
3486
3487proc doshowlocalchanges {} {
Paul Mackerras38dfe932007-12-06 20:50:31 +11003488 global curview mainheadid
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003489
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003490 if {[commitinview $mainheadid $curview]} {
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003491 dodiffindex
Paul Mackerras38dfe932007-12-06 20:50:31 +11003492 } else {
3493 lappend commitinterest($mainheadid) {dodiffindex}
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003494 }
3495}
3496
3497proc dohidelocalchanges {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003498 global nullid nullid2 lserial curview
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003499
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003500 if {[commitinview $nullid $curview]} {
3501 removerow $nullid $curview
Paul Mackerras8f489362007-07-13 19:49:37 +10003502 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003503 if {[commitinview $nullid2 $curview]} {
3504 removerow $nullid2 $curview
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003505 }
3506 incr lserial
3507}
3508
Paul Mackerras8f489362007-07-13 19:49:37 +10003509# spawn off a process to do git diff-index --cached HEAD
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003510proc dodiffindex {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003511 global lserial showlocalchanges
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003512
Paul Mackerras3e6b8932007-09-15 09:33:39 +10003513 if {!$showlocalchanges} return
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003514 incr lserial
Paul Mackerras8f489362007-07-13 19:49:37 +10003515 set fd [open "|git diff-index --cached HEAD" r]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003516 fconfigure $fd -blocking 0
3517 filerun $fd [list readdiffindex $fd $lserial]
3518}
3519
3520proc readdiffindex {fd serial} {
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11003521 global mainheadid nullid nullid2 curview commitinfo commitdata lserial
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003522
Paul Mackerras8f489362007-07-13 19:49:37 +10003523 set isdiff 1
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003524 if {[gets $fd line] < 0} {
Paul Mackerras8f489362007-07-13 19:49:37 +10003525 if {![eof $fd]} {
3526 return 1
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003527 }
Paul Mackerras8f489362007-07-13 19:49:37 +10003528 set isdiff 0
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003529 }
3530 # we only need to see one line and we don't really care what it says...
3531 close $fd
3532
Paul Mackerras24f7a662007-12-19 09:35:33 +11003533 if {$serial != $lserial} {
3534 return 0
Paul Mackerras8f489362007-07-13 19:49:37 +10003535 }
3536
Paul Mackerras24f7a662007-12-19 09:35:33 +11003537 # now see if there are any local changes not checked in to the index
3538 set fd [open "|git diff-files" r]
3539 fconfigure $fd -blocking 0
3540 filerun $fd [list readdifffiles $fd $serial]
3541
3542 if {$isdiff && ![commitinview $nullid2 $curview]} {
Paul Mackerras8f489362007-07-13 19:49:37 +10003543 # add the line for the changes in the index to the graph
Christian Stimmingd990ced2007-11-07 18:42:55 +01003544 set hl [mc "Local changes checked in to index but not committed"]
Paul Mackerras8f489362007-07-13 19:49:37 +10003545 set commitinfo($nullid2) [list $hl {} {} {} {} " $hl\n"]
3546 set commitdata($nullid2) "\n $hl\n"
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11003547 if {[commitinview $nullid $curview]} {
3548 removerow $nullid $curview
3549 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003550 insertrow $nullid2 $mainheadid $curview
Paul Mackerras24f7a662007-12-19 09:35:33 +11003551 } elseif {!$isdiff && [commitinview $nullid2 $curview]} {
3552 removerow $nullid2 $curview
Paul Mackerras8f489362007-07-13 19:49:37 +10003553 }
3554 return 0
3555}
3556
3557proc readdifffiles {fd serial} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003558 global mainheadid nullid nullid2 curview
Paul Mackerras8f489362007-07-13 19:49:37 +10003559 global commitinfo commitdata lserial
3560
3561 set isdiff 1
3562 if {[gets $fd line] < 0} {
3563 if {![eof $fd]} {
3564 return 1
3565 }
3566 set isdiff 0
3567 }
3568 # we only need to see one line and we don't really care what it says...
3569 close $fd
3570
Paul Mackerras24f7a662007-12-19 09:35:33 +11003571 if {$serial != $lserial} {
3572 return 0
3573 }
3574
3575 if {$isdiff && ![commitinview $nullid $curview]} {
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003576 # add the line for the local diff to the graph
Christian Stimmingd990ced2007-11-07 18:42:55 +01003577 set hl [mc "Local uncommitted changes, not checked in to index"]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003578 set commitinfo($nullid) [list $hl {} {} {} {} " $hl\n"]
3579 set commitdata($nullid) "\n $hl\n"
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003580 if {[commitinview $nullid2 $curview]} {
3581 set p $nullid2
3582 } else {
3583 set p $mainheadid
3584 }
3585 insertrow $nullid $p $curview
Paul Mackerras24f7a662007-12-19 09:35:33 +11003586 } elseif {!$isdiff && [commitinview $nullid $curview]} {
3587 removerow $nullid $curview
Paul Mackerras219ea3a2006-09-07 10:21:39 +10003588 }
3589 return 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003590}
3591
Paul Mackerras8f0bc7e2007-08-24 22:16:42 +10003592proc nextuse {id row} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003593 global curview children
Paul Mackerras8f0bc7e2007-08-24 22:16:42 +10003594
3595 if {[info exists children($curview,$id)]} {
3596 foreach kid $children($curview,$id) {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003597 if {![commitinview $kid $curview]} {
Paul Mackerras03800812007-08-29 21:45:21 +10003598 return -1
3599 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003600 if {[rowofcommit $kid] > $row} {
3601 return [rowofcommit $kid]
Paul Mackerras8f0bc7e2007-08-24 22:16:42 +10003602 }
3603 }
3604 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003605 if {[commitinview $id $curview]} {
3606 return [rowofcommit $id]
Paul Mackerras8f0bc7e2007-08-24 22:16:42 +10003607 }
3608 return -1
3609}
3610
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003611proc prevuse {id row} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003612 global curview children
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003613
3614 set ret -1
3615 if {[info exists children($curview,$id)]} {
3616 foreach kid $children($curview,$id) {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003617 if {![commitinview $kid $curview]} break
3618 if {[rowofcommit $kid] < $row} {
3619 set ret [rowofcommit $kid]
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003620 }
3621 }
3622 }
3623 return $ret
3624}
3625
Paul Mackerras03800812007-08-29 21:45:21 +10003626proc make_idlist {row} {
3627 global displayorder parentlist uparrowlen downarrowlen mingaplen
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003628 global commitidx curview children
Paul Mackerras03800812007-08-29 21:45:21 +10003629
3630 set r [expr {$row - $mingaplen - $downarrowlen - 1}]
3631 if {$r < 0} {
3632 set r 0
3633 }
3634 set ra [expr {$row - $downarrowlen}]
3635 if {$ra < 0} {
3636 set ra 0
3637 }
3638 set rb [expr {$row + $uparrowlen}]
3639 if {$rb > $commitidx($curview)} {
3640 set rb $commitidx($curview)
3641 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003642 make_disporder $r [expr {$rb + 1}]
Paul Mackerras03800812007-08-29 21:45:21 +10003643 set ids {}
3644 for {} {$r < $ra} {incr r} {
3645 set nextid [lindex $displayorder [expr {$r + 1}]]
3646 foreach p [lindex $parentlist $r] {
3647 if {$p eq $nextid} continue
3648 set rn [nextuse $p $r]
3649 if {$rn >= $row &&
3650 $rn <= $r + $downarrowlen + $mingaplen + $uparrowlen} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003651 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 21:45:21 +10003652 }
3653 }
3654 }
3655 for {} {$r < $row} {incr r} {
3656 set nextid [lindex $displayorder [expr {$r + 1}]]
3657 foreach p [lindex $parentlist $r] {
3658 if {$p eq $nextid} continue
3659 set rn [nextuse $p $r]
3660 if {$rn < 0 || $rn >= $row} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003661 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 21:45:21 +10003662 }
3663 }
3664 }
3665 set id [lindex $displayorder $row]
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003666 lappend ids [list [ordertoken $id] $id]
Paul Mackerras03800812007-08-29 21:45:21 +10003667 while {$r < $rb} {
3668 foreach p [lindex $parentlist $r] {
3669 set firstkid [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003670 if {[rowofcommit $firstkid] < $row} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003671 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 21:45:21 +10003672 }
3673 }
3674 incr r
3675 set id [lindex $displayorder $r]
3676 if {$id ne {}} {
3677 set firstkid [lindex $children($curview,$id) 0]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003678 if {$firstkid ne {} && [rowofcommit $firstkid] < $row} {
Paul Mackerras9257d8f2007-12-11 10:45:38 +11003679 lappend ids [list [ordertoken $id] $id]
Paul Mackerras03800812007-08-29 21:45:21 +10003680 }
3681 }
3682 }
3683 set idlist {}
3684 foreach idx [lsort -unique $ids] {
3685 lappend idlist [lindex $idx 1]
3686 }
3687 return $idlist
3688}
3689
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003690proc rowsequal {a b} {
3691 while {[set i [lsearch -exact $a {}]] >= 0} {
3692 set a [lreplace $a $i $i]
3693 }
3694 while {[set i [lsearch -exact $b {}]] >= 0} {
3695 set b [lreplace $b $i $i]
3696 }
3697 return [expr {$a eq $b}]
3698}
3699
3700proc makeupline {id row rend col} {
3701 global rowidlist uparrowlen downarrowlen mingaplen
3702
3703 for {set r $rend} {1} {set r $rstart} {
3704 set rstart [prevuse $id $r]
3705 if {$rstart < 0} return
3706 if {$rstart < $row} break
3707 }
3708 if {$rstart + $uparrowlen + $mingaplen + $downarrowlen < $rend} {
3709 set rstart [expr {$rend - $uparrowlen - 1}]
3710 }
3711 for {set r $rstart} {[incr r] <= $row} {} {
3712 set idlist [lindex $rowidlist $r]
3713 if {$idlist ne {} && [lsearch -exact $idlist $id] < 0} {
3714 set col [idcol $idlist $id $col]
3715 lset rowidlist $r [linsert $idlist $col $id]
3716 changedrow $r
3717 }
3718 }
3719}
3720
Paul Mackerras03800812007-08-29 21:45:21 +10003721proc layoutrows {row endrow} {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003722 global rowidlist rowisopt rowfinal displayorder
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003723 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras6a90bff2007-06-18 09:48:23 +10003724 global children parentlist
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003725 global commitidx viewcomplete curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003726
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003727 make_disporder [expr {$row - 1}] [expr {$endrow + $uparrowlen}]
Paul Mackerras03800812007-08-29 21:45:21 +10003728 set idlist {}
3729 if {$row > 0} {
Paul Mackerrasf56782a2007-09-15 09:04:11 +10003730 set rm1 [expr {$row - 1}]
3731 foreach id [lindex $rowidlist $rm1] {
Paul Mackerras03800812007-08-29 21:45:21 +10003732 if {$id ne {}} {
3733 lappend idlist $id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003734 }
3735 }
Paul Mackerrasf56782a2007-09-15 09:04:11 +10003736 set final [lindex $rowfinal $rm1]
Paul Mackerras8f0bc7e2007-08-24 22:16:42 +10003737 }
Paul Mackerras03800812007-08-29 21:45:21 +10003738 for {} {$row < $endrow} {incr row} {
3739 set rm1 [expr {$row - 1}]
Paul Mackerrasf56782a2007-09-15 09:04:11 +10003740 if {$rm1 < 0 || $idlist eq {}} {
Paul Mackerras03800812007-08-29 21:45:21 +10003741 set idlist [make_idlist $row]
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003742 set final 1
Paul Mackerras03800812007-08-29 21:45:21 +10003743 } else {
3744 set id [lindex $displayorder $rm1]
3745 set col [lsearch -exact $idlist $id]
3746 set idlist [lreplace $idlist $col $col]
3747 foreach p [lindex $parentlist $rm1] {
3748 if {[lsearch -exact $idlist $p] < 0} {
3749 set col [idcol $idlist $p $col]
3750 set idlist [linsert $idlist $col $p]
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003751 # if not the first child, we have to insert a line going up
3752 if {$id ne [lindex $children($curview,$p) 0]} {
3753 makeupline $p $rm1 $row $col
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003754 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003755 }
3756 }
Paul Mackerras03800812007-08-29 21:45:21 +10003757 set id [lindex $displayorder $row]
3758 if {$row > $downarrowlen} {
3759 set termrow [expr {$row - $downarrowlen - 1}]
3760 foreach p [lindex $parentlist $termrow] {
3761 set i [lsearch -exact $idlist $p]
3762 if {$i < 0} continue
3763 set nr [nextuse $p $termrow]
3764 if {$nr < 0 || $nr >= $row + $mingaplen + $uparrowlen} {
3765 set idlist [lreplace $idlist $i $i]
3766 }
3767 }
3768 }
3769 set col [lsearch -exact $idlist $id]
3770 if {$col < 0} {
3771 set col [idcol $idlist $id]
3772 set idlist [linsert $idlist $col $id]
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003773 if {$children($curview,$id) ne {}} {
3774 makeupline $id $rm1 $row $col
3775 }
Paul Mackerras03800812007-08-29 21:45:21 +10003776 }
3777 set r [expr {$row + $uparrowlen - 1}]
3778 if {$r < $commitidx($curview)} {
3779 set x $col
3780 foreach p [lindex $parentlist $r] {
3781 if {[lsearch -exact $idlist $p] >= 0} continue
3782 set fk [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003783 if {[rowofcommit $fk] < $row} {
Paul Mackerras03800812007-08-29 21:45:21 +10003784 set x [idcol $idlist $p $x]
3785 set idlist [linsert $idlist $x $p]
3786 }
3787 }
3788 if {[incr r] < $commitidx($curview)} {
3789 set p [lindex $displayorder $r]
3790 if {[lsearch -exact $idlist $p] < 0} {
3791 set fk [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11003792 if {$fk ne {} && [rowofcommit $fk] < $row} {
Paul Mackerras03800812007-08-29 21:45:21 +10003793 set x [idcol $idlist $p $x]
3794 set idlist [linsert $idlist $x $p]
3795 }
3796 }
3797 }
Paul Mackerras7b459a12007-08-13 14:52:00 +10003798 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003799 }
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003800 if {$final && !$viewcomplete($curview) &&
3801 $row + $uparrowlen + $mingaplen + $downarrowlen
3802 >= $commitidx($curview)} {
3803 set final 0
Paul Mackerras7b459a12007-08-13 14:52:00 +10003804 }
Paul Mackerras03800812007-08-29 21:45:21 +10003805 set l [llength $rowidlist]
3806 if {$row == $l} {
3807 lappend rowidlist $idlist
3808 lappend rowisopt 0
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003809 lappend rowfinal $final
Paul Mackerras03800812007-08-29 21:45:21 +10003810 } elseif {$row < $l} {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003811 if {![rowsequal $idlist [lindex $rowidlist $row]]} {
Paul Mackerras03800812007-08-29 21:45:21 +10003812 lset rowidlist $row $idlist
3813 changedrow $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003814 }
Paul Mackerrasf56782a2007-09-15 09:04:11 +10003815 lset rowfinal $row $final
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003816 } else {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003817 set pad [ntimes [expr {$row - $l}] {}]
3818 set rowidlist [concat $rowidlist $pad]
Paul Mackerras03800812007-08-29 21:45:21 +10003819 lappend rowidlist $idlist
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10003820 set rowfinal [concat $rowfinal $pad]
3821 lappend rowfinal $final
Paul Mackerras03800812007-08-29 21:45:21 +10003822 set rowisopt [concat $rowisopt [ntimes [expr {$row - $l + 1}] 0]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003823 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003824 }
3825 return $row
3826}
3827
Paul Mackerras03800812007-08-29 21:45:21 +10003828proc changedrow {row} {
3829 global displayorder iddrawn rowisopt need_redisplay
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003830
Paul Mackerras03800812007-08-29 21:45:21 +10003831 set l [llength $rowisopt]
3832 if {$row < $l} {
3833 lset rowisopt $row 0
3834 if {$row + 1 < $l} {
3835 lset rowisopt [expr {$row + 1}] 0
3836 if {$row + 2 < $l} {
3837 lset rowisopt [expr {$row + 2}] 0
3838 }
3839 }
Paul Mackerras79b2c752006-04-02 20:47:40 +10003840 }
Paul Mackerras03800812007-08-29 21:45:21 +10003841 set id [lindex $displayorder $row]
3842 if {[info exists iddrawn($id)]} {
3843 set need_redisplay 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003844 }
3845}
3846
3847proc insert_pad {row col npad} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003848 global rowidlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003849
3850 set pad [ntimes $npad {}]
Paul Mackerrase341c062007-08-12 12:42:57 +10003851 set idlist [lindex $rowidlist $row]
3852 set bef [lrange $idlist 0 [expr {$col - 1}]]
3853 set aft [lrange $idlist $col end]
3854 set i [lsearch -exact $aft {}]
3855 if {$i > 0} {
3856 set aft [lreplace $aft $i $i]
3857 }
3858 lset rowidlist $row [concat $bef $pad $aft]
Paul Mackerras03800812007-08-29 21:45:21 +10003859 changedrow $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003860}
3861
3862proc optimize_rows {row col endrow} {
Paul Mackerras03800812007-08-29 21:45:21 +10003863 global rowidlist rowisopt displayorder curview children
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003864
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003865 if {$row < 1} {
3866 set row 1
3867 }
Paul Mackerras03800812007-08-29 21:45:21 +10003868 for {} {$row < $endrow} {incr row; set col 0} {
3869 if {[lindex $rowisopt $row]} continue
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003870 set haspad 0
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003871 set y0 [expr {$row - 1}]
3872 set ym [expr {$row - 2}]
Paul Mackerras03800812007-08-29 21:45:21 +10003873 set idlist [lindex $rowidlist $row]
3874 set previdlist [lindex $rowidlist $y0]
3875 if {$idlist eq {} || $previdlist eq {}} continue
3876 if {$ym >= 0} {
3877 set pprevidlist [lindex $rowidlist $ym]
3878 if {$pprevidlist eq {}} continue
3879 } else {
3880 set pprevidlist {}
3881 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003882 set x0 -1
3883 set xm -1
3884 for {} {$col < [llength $idlist]} {incr col} {
3885 set id [lindex $idlist $col]
3886 if {[lindex $previdlist $col] eq $id} continue
3887 if {$id eq {}} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003888 set haspad 1
3889 continue
3890 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003891 set x0 [lsearch -exact $previdlist $id]
3892 if {$x0 < 0} continue
3893 set z [expr {$x0 - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003894 set isarrow 0
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003895 set z0 {}
3896 if {$ym >= 0} {
3897 set xm [lsearch -exact $pprevidlist $id]
3898 if {$xm >= 0} {
3899 set z0 [expr {$xm - $x0}]
3900 }
3901 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003902 if {$z0 eq {}} {
Paul Mackerras92ed6662007-08-22 22:35:28 +10003903 # if row y0 is the first child of $id then it's not an arrow
3904 if {[lindex $children($curview,$id) 0] ne
3905 [lindex $displayorder $y0]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003906 set isarrow 1
3907 }
3908 }
Paul Mackerrase341c062007-08-12 12:42:57 +10003909 if {!$isarrow && $id ne [lindex $displayorder $row] &&
3910 [lsearch -exact [lindex $rowidlist [expr {$row+1}]] $id] < 0} {
3911 set isarrow 1
3912 }
Paul Mackerras3fc42792006-09-15 09:45:23 +10003913 # Looking at lines from this row to the previous row,
3914 # make them go straight up if they end in an arrow on
3915 # the previous row; otherwise make them go straight up
3916 # or at 45 degrees.
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003917 if {$z < -1 || ($z < 0 && $isarrow)} {
Paul Mackerras3fc42792006-09-15 09:45:23 +10003918 # Line currently goes left too much;
3919 # insert pads in the previous row, then optimize it
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003920 set npad [expr {-1 - $z + $isarrow}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003921 insert_pad $y0 $x0 $npad
3922 if {$y0 > 0} {
3923 optimize_rows $y0 $x0 $row
3924 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003925 set previdlist [lindex $rowidlist $y0]
3926 set x0 [lsearch -exact $previdlist $id]
3927 set z [expr {$x0 - $col}]
3928 if {$z0 ne {}} {
3929 set pprevidlist [lindex $rowidlist $ym]
3930 set xm [lsearch -exact $pprevidlist $id]
3931 set z0 [expr {$xm - $x0}]
3932 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003933 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
Paul Mackerras3fc42792006-09-15 09:45:23 +10003934 # Line currently goes right too much;
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003935 # insert pads in this line
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003936 set npad [expr {$z - 1 + $isarrow}]
Paul Mackerrase341c062007-08-12 12:42:57 +10003937 insert_pad $row $col $npad
3938 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003939 incr col $npad
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003940 set z [expr {$x0 - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003941 set haspad 1
3942 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003943 if {$z0 eq {} && !$isarrow && $ym >= 0} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11003944 # this line links to its first child on row $row-2
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003945 set id [lindex $displayorder $ym]
3946 set xc [lsearch -exact $pprevidlist $id]
Paul Mackerraseb447a12006-03-18 23:11:37 +11003947 if {$xc >= 0} {
3948 set z0 [expr {$xc - $x0}]
3949 }
3950 }
Paul Mackerras3fc42792006-09-15 09:45:23 +10003951 # avoid lines jigging left then immediately right
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003952 if {$z0 ne {} && $z < 0 && $z0 > 0} {
3953 insert_pad $y0 $x0 1
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003954 incr x0
3955 optimize_rows $y0 $x0 $row
3956 set previdlist [lindex $rowidlist $y0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003957 }
3958 }
3959 if {!$haspad} {
Paul Mackerras3fc42792006-09-15 09:45:23 +10003960 # Find the first column that doesn't have a line going right
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003961 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003962 set id [lindex $idlist $col]
3963 if {$id eq {}} break
3964 set x0 [lsearch -exact $previdlist $id]
3965 if {$x0 < 0} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11003966 # check if this is the link to the first child
Paul Mackerras92ed6662007-08-22 22:35:28 +10003967 set kid [lindex $displayorder $y0]
3968 if {[lindex $children($curview,$id) 0] eq $kid} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11003969 # it is, work out offset to child
Paul Mackerras92ed6662007-08-22 22:35:28 +10003970 set x0 [lsearch -exact $previdlist $kid]
Paul Mackerraseb447a12006-03-18 23:11:37 +11003971 }
3972 }
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003973 if {$x0 <= $col} break
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003974 }
Paul Mackerras3fc42792006-09-15 09:45:23 +10003975 # Insert a pad at that column as long as it has a line and
Paul Mackerras6e8c8702007-07-31 21:03:06 +10003976 # isn't the last column
3977 if {$x0 >= 0 && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003978 set idlist [linsert $idlist $col {}]
Paul Mackerras03800812007-08-29 21:45:21 +10003979 lset rowidlist $row $idlist
3980 changedrow $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003981 }
3982 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003983 }
3984}
3985
3986proc xc {row col} {
3987 global canvx0 linespc
3988 return [expr {$canvx0 + $col * $linespc}]
3989}
3990
3991proc yc {row} {
3992 global canvy0 linespc
3993 return [expr {$canvy0 + $row * $linespc}]
3994}
3995
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11003996proc linewidth {id} {
3997 global thickerline lthickness
3998
3999 set wid $lthickness
4000 if {[info exists thickerline] && $id eq $thickerline} {
4001 set wid [expr {2 * $lthickness}]
4002 }
4003 return $wid
4004}
4005
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004006proc rowranges {id} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004007 global curview children uparrowlen downarrowlen
Paul Mackerras92ed6662007-08-22 22:35:28 +10004008 global rowidlist
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004009
Paul Mackerras92ed6662007-08-22 22:35:28 +10004010 set kids $children($curview,$id)
4011 if {$kids eq {}} {
4012 return {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004013 }
Paul Mackerras92ed6662007-08-22 22:35:28 +10004014 set ret {}
4015 lappend kids $id
4016 foreach child $kids {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004017 if {![commitinview $child $curview]} break
4018 set row [rowofcommit $child]
Paul Mackerras92ed6662007-08-22 22:35:28 +10004019 if {![info exists prev]} {
4020 lappend ret [expr {$row + 1}]
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004021 } else {
Paul Mackerras92ed6662007-08-22 22:35:28 +10004022 if {$row <= $prevrow} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004023 puts "oops children of [shortids $id] out of order [shortids $child] $row <= [shortids $prev] $prevrow"
Paul Mackerras92ed6662007-08-22 22:35:28 +10004024 }
4025 # see if the line extends the whole way from prevrow to row
4026 if {$row > $prevrow + $uparrowlen + $downarrowlen &&
4027 [lsearch -exact [lindex $rowidlist \
4028 [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
4029 # it doesn't, see where it ends
4030 set r [expr {$prevrow + $downarrowlen}]
4031 if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
4032 while {[incr r -1] > $prevrow &&
4033 [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
4034 } else {
4035 while {[incr r] <= $row &&
4036 [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
4037 incr r -1
4038 }
4039 lappend ret $r
4040 # see where it starts up again
4041 set r [expr {$row - $uparrowlen}]
4042 if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
4043 while {[incr r] < $row &&
4044 [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
4045 } else {
4046 while {[incr r -1] >= $prevrow &&
4047 [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
4048 incr r
4049 }
4050 lappend ret $r
4051 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11004052 }
Paul Mackerras92ed6662007-08-22 22:35:28 +10004053 if {$child eq $id} {
4054 lappend ret $row
4055 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004056 set prev $child
Paul Mackerras92ed6662007-08-22 22:35:28 +10004057 set prevrow $row
Paul Mackerraseb447a12006-03-18 23:11:37 +11004058 }
Paul Mackerras92ed6662007-08-22 22:35:28 +10004059 return $ret
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004060}
4061
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004062proc drawlineseg {id row endrow arrowlow} {
4063 global rowidlist displayorder iddrawn linesegs
Paul Mackerrase341c062007-08-12 12:42:57 +10004064 global canv colormap linespc curview maxlinelen parentlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004065
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004066 set cols [list [lsearch -exact [lindex $rowidlist $row] $id]]
4067 set le [expr {$row + 1}]
4068 set arrowhigh 1
4069 while {1} {
4070 set c [lsearch -exact [lindex $rowidlist $le] $id]
4071 if {$c < 0} {
4072 incr le -1
4073 break
4074 }
4075 lappend cols $c
4076 set x [lindex $displayorder $le]
4077 if {$x eq $id} {
4078 set arrowhigh 0
4079 break
4080 }
4081 if {[info exists iddrawn($x)] || $le == $endrow} {
4082 set c [lsearch -exact [lindex $rowidlist [expr {$le+1}]] $id]
4083 if {$c >= 0} {
4084 lappend cols $c
4085 set arrowhigh 0
4086 }
4087 break
4088 }
4089 incr le
4090 }
4091 if {$le <= $row} {
4092 return $row
4093 }
4094
4095 set lines {}
4096 set i 0
4097 set joinhigh 0
4098 if {[info exists linesegs($id)]} {
4099 set lines $linesegs($id)
4100 foreach li $lines {
4101 set r0 [lindex $li 0]
4102 if {$r0 > $row} {
4103 if {$r0 == $le && [lindex $li 1] - $row <= $maxlinelen} {
4104 set joinhigh 1
4105 }
4106 break
4107 }
4108 incr i
4109 }
4110 }
4111 set joinlow 0
4112 if {$i > 0} {
4113 set li [lindex $lines [expr {$i-1}]]
4114 set r1 [lindex $li 1]
4115 if {$r1 == $row && $le - [lindex $li 0] <= $maxlinelen} {
4116 set joinlow 1
4117 }
4118 }
4119
4120 set x [lindex $cols [expr {$le - $row}]]
4121 set xp [lindex $cols [expr {$le - 1 - $row}]]
4122 set dir [expr {$xp - $x}]
4123 if {$joinhigh} {
4124 set ith [lindex $lines $i 2]
4125 set coords [$canv coords $ith]
4126 set ah [$canv itemcget $ith -arrow]
4127 set arrowhigh [expr {$ah eq "first" || $ah eq "both"}]
4128 set x2 [lindex $cols [expr {$le + 1 - $row}]]
4129 if {$x2 ne {} && $x - $x2 == $dir} {
4130 set coords [lrange $coords 0 end-2]
4131 }
4132 } else {
4133 set coords [list [xc $le $x] [yc $le]]
4134 }
4135 if {$joinlow} {
4136 set itl [lindex $lines [expr {$i-1}] 2]
4137 set al [$canv itemcget $itl -arrow]
4138 set arrowlow [expr {$al eq "last" || $al eq "both"}]
Paul Mackerrase341c062007-08-12 12:42:57 +10004139 } elseif {$arrowlow} {
4140 if {[lsearch -exact [lindex $rowidlist [expr {$row-1}]] $id] >= 0 ||
4141 [lsearch -exact [lindex $parentlist [expr {$row-1}]] $id] >= 0} {
4142 set arrowlow 0
4143 }
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004144 }
4145 set arrow [lindex {none first last both} [expr {$arrowhigh + 2*$arrowlow}]]
4146 for {set y $le} {[incr y -1] > $row} {} {
4147 set x $xp
4148 set xp [lindex $cols [expr {$y - 1 - $row}]]
4149 set ndir [expr {$xp - $x}]
4150 if {$dir != $ndir || $xp < 0} {
4151 lappend coords [xc $y $x] [yc $y]
4152 }
4153 set dir $ndir
4154 }
4155 if {!$joinlow} {
4156 if {$xp < 0} {
4157 # join parent line to first child
4158 set ch [lindex $displayorder $row]
4159 set xc [lsearch -exact [lindex $rowidlist $row] $ch]
4160 if {$xc < 0} {
4161 puts "oops: drawlineseg: child $ch not on row $row"
Paul Mackerrase341c062007-08-12 12:42:57 +10004162 } elseif {$xc != $x} {
4163 if {($arrowhigh && $le == $row + 1) || $dir == 0} {
4164 set d [expr {int(0.5 * $linespc)}]
4165 set x1 [xc $row $x]
4166 if {$xc < $x} {
4167 set x2 [expr {$x1 - $d}]
4168 } else {
4169 set x2 [expr {$x1 + $d}]
4170 }
4171 set y2 [yc $row]
4172 set y1 [expr {$y2 + $d}]
4173 lappend coords $x1 $y1 $x2 $y2
4174 } elseif {$xc < $x - 1} {
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004175 lappend coords [xc $row [expr {$x-1}]] [yc $row]
4176 } elseif {$xc > $x + 1} {
4177 lappend coords [xc $row [expr {$x+1}]] [yc $row]
4178 }
4179 set x $xc
4180 }
4181 lappend coords [xc $row $x] [yc $row]
4182 } else {
4183 set xn [xc $row $xp]
4184 set yn [yc $row]
Paul Mackerrase341c062007-08-12 12:42:57 +10004185 lappend coords $xn $yn
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004186 }
4187 if {!$joinhigh} {
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004188 assigncolor $id
4189 set t [$canv create line $coords -width [linewidth $id] \
4190 -fill $colormap($id) -tags lines.$id -arrow $arrow]
4191 $canv lower $t
4192 bindline $t $id
4193 set lines [linsert $lines $i [list $row $le $t]]
4194 } else {
4195 $canv coords $ith $coords
4196 if {$arrow ne $ah} {
4197 $canv itemconf $ith -arrow $arrow
4198 }
4199 lset lines $i 0 $row
4200 }
4201 } else {
4202 set xo [lsearch -exact [lindex $rowidlist [expr {$row - 1}]] $id]
4203 set ndir [expr {$xo - $xp}]
4204 set clow [$canv coords $itl]
4205 if {$dir == $ndir} {
4206 set clow [lrange $clow 2 end]
4207 }
4208 set coords [concat $coords $clow]
4209 if {!$joinhigh} {
4210 lset lines [expr {$i-1}] 1 $le
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004211 } else {
4212 # coalesce two pieces
4213 $canv delete $ith
4214 set b [lindex $lines [expr {$i-1}] 0]
4215 set e [lindex $lines $i 1]
4216 set lines [lreplace $lines [expr {$i-1}] $i [list $b $e $itl]]
4217 }
4218 $canv coords $itl $coords
4219 if {$arrow ne $al} {
4220 $canv itemconf $itl -arrow $arrow
4221 }
4222 }
4223
4224 set linesegs($id) $lines
4225 return $le
4226}
4227
4228proc drawparentlinks {id row} {
4229 global rowidlist canv colormap curview parentlist
Paul Mackerras513a54d2007-08-01 22:27:57 +10004230 global idpos linespc
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004231
4232 set rowids [lindex $rowidlist $row]
4233 set col [lsearch -exact $rowids $id]
4234 if {$col < 0} return
4235 set olds [lindex $parentlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004236 set row2 [expr {$row + 1}]
4237 set x [xc $row $col]
4238 set y [yc $row]
4239 set y2 [yc $row2]
Paul Mackerrase341c062007-08-12 12:42:57 +10004240 set d [expr {int(0.5 * $linespc)}]
Paul Mackerras513a54d2007-08-01 22:27:57 +10004241 set ymid [expr {$y + $d}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004242 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004243 # rmx = right-most X coord used
4244 set rmx 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004245 foreach p $olds {
Paul Mackerrasf3408442006-03-31 09:54:24 +11004246 set i [lsearch -exact $ids $p]
4247 if {$i < 0} {
4248 puts "oops, parent $p of $id not in list"
4249 continue
4250 }
4251 set x2 [xc $row2 $i]
4252 if {$x2 > $rmx} {
4253 set rmx $x2
4254 }
Paul Mackerras513a54d2007-08-01 22:27:57 +10004255 set j [lsearch -exact $rowids $p]
4256 if {$j < 0} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11004257 # drawlineseg will do this one for us
4258 continue
4259 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004260 assigncolor $p
4261 # should handle duplicated parents here...
4262 set coords [list $x $y]
Paul Mackerras513a54d2007-08-01 22:27:57 +10004263 if {$i != $col} {
4264 # if attaching to a vertical segment, draw a smaller
4265 # slant for visual distinctness
4266 if {$i == $j} {
4267 if {$i < $col} {
4268 lappend coords [expr {$x2 + $d}] $y $x2 $ymid
4269 } else {
4270 lappend coords [expr {$x2 - $d}] $y $x2 $ymid
4271 }
4272 } elseif {$i < $col && $i < $j} {
4273 # segment slants towards us already
4274 lappend coords [xc $row $j] $y
4275 } else {
4276 if {$i < $col - 1} {
4277 lappend coords [expr {$x2 + $linespc}] $y
4278 } elseif {$i > $col + 1} {
4279 lappend coords [expr {$x2 - $linespc}] $y
4280 }
4281 lappend coords $x2 $y2
4282 }
4283 } else {
4284 lappend coords $x2 $y2
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004285 }
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004286 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004287 -fill $colormap($p) -tags lines.$p]
4288 $canv lower $t
4289 bindline $t $p
4290 }
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004291 if {$rmx > [lindex $idpos($id) 1]} {
4292 lset idpos($id) 1 $rmx
4293 redrawtags $id
4294 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004295}
4296
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004297proc drawlines {id} {
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004298 global canv
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004299
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004300 $canv itemconf lines.$id -width [linewidth $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004301}
4302
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004303proc drawcmittext {id row col} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004304 global linespc canv canv2 canv3 fgcolor curview
4305 global cmitlisted commitinfo rowidlist parentlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004306 global rowtextx idpos idtags idheads idotherrefs
Paul Mackerras03800812007-08-29 21:45:21 +10004307 global linehtag linentag linedtag selectedline
Paul Mackerras9c311b32007-10-04 22:27:13 +10004308 global canvxmax boldrows boldnamerows fgcolor nullid nullid2
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004309
Paul Mackerrasc961b222007-07-09 22:45:47 +10004310 # listed is 0 for boundary, 1 for normal, 2 for left, 3 for right
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004311 set listed $cmitlisted($curview,$id)
Paul Mackerras219ea3a2006-09-07 10:21:39 +10004312 if {$id eq $nullid} {
4313 set ofill red
Paul Mackerras8f489362007-07-13 19:49:37 +10004314 } elseif {$id eq $nullid2} {
Paul Mackerrasef3192b2007-07-22 22:05:30 +10004315 set ofill green
Paul Mackerras219ea3a2006-09-07 10:21:39 +10004316 } else {
Paul Mackerrasc961b222007-07-09 22:45:47 +10004317 set ofill [expr {$listed != 0? "blue": "white"}]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10004318 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004319 set x [xc $row $col]
4320 set y [yc $row]
4321 set orad [expr {$linespc / 3}]
Paul Mackerrasc961b222007-07-09 22:45:47 +10004322 if {$listed <= 1} {
4323 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
4324 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
4325 -fill $ofill -outline $fgcolor -width 1 -tags circle]
4326 } elseif {$listed == 2} {
4327 # triangle pointing left for left-side commits
4328 set t [$canv create polygon \
4329 [expr {$x - $orad}] $y \
4330 [expr {$x + $orad - 1}] [expr {$y - $orad}] \
4331 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
4332 -fill $ofill -outline $fgcolor -width 1 -tags circle]
4333 } else {
4334 # triangle pointing right for right-side commits
4335 set t [$canv create polygon \
4336 [expr {$x + $orad - 1}] $y \
4337 [expr {$x - $orad}] [expr {$y - $orad}] \
4338 [expr {$x - $orad}] [expr {$y + $orad - 1}] \
4339 -fill $ofill -outline $fgcolor -width 1 -tags circle]
4340 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004341 $canv raise $t
4342 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004343 set rmx [llength [lindex $rowidlist $row]]
4344 set olds [lindex $parentlist $row]
4345 if {$olds ne {}} {
4346 set nextids [lindex $rowidlist [expr {$row + 1}]]
4347 foreach p $olds {
4348 set i [lsearch -exact $nextids $p]
4349 if {$i > $rmx} {
4350 set rmx $i
4351 }
4352 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004353 }
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004354 set xt [xc $row $rmx]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004355 set rowtextx($row) $xt
4356 set idpos($id) [list $x $xt $y]
4357 if {[info exists idtags($id)] || [info exists idheads($id)]
4358 || [info exists idotherrefs($id)]} {
4359 set xt [drawtags $id $x $xt $y]
4360 }
4361 set headline [lindex $commitinfo($id) 0]
4362 set name [lindex $commitinfo($id) 1]
4363 set date [lindex $commitinfo($id) 2]
4364 set date [formatdate $date]
Paul Mackerras9c311b32007-10-04 22:27:13 +10004365 set font mainfont
4366 set nfont mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10004367 set isbold [ishighlighted $row]
4368 if {$isbold > 0} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10004369 lappend boldrows $row
Paul Mackerras9c311b32007-10-04 22:27:13 +10004370 set font mainfontbold
Paul Mackerras908c3582006-05-20 09:38:11 +10004371 if {$isbold > 1} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10004372 lappend boldnamerows $row
Paul Mackerras9c311b32007-10-04 22:27:13 +10004373 set nfont mainfontbold
Paul Mackerras908c3582006-05-20 09:38:11 +10004374 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004375 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004376 set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
4377 -text $headline -font $font -tags text]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004378 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004379 set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
4380 -text $name -font $nfont -tags text]
4381 set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
Paul Mackerras9c311b32007-10-04 22:27:13 +10004382 -text $date -font mainfont -tags text]
Paul Mackerras03800812007-08-29 21:45:21 +10004383 if {[info exists selectedline] && $selectedline == $row} {
4384 make_secsel $row
4385 }
Paul Mackerras9c311b32007-10-04 22:27:13 +10004386 set xr [expr {$xt + [font measure $font $headline]}]
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004387 if {$xr > $canvxmax} {
4388 set canvxmax $xr
4389 setcanvscroll
4390 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004391}
4392
4393proc drawcmitrow {row} {
Paul Mackerras03800812007-08-29 21:45:21 +10004394 global displayorder rowidlist nrows_drawn
Paul Mackerras005a2f42007-07-26 22:36:39 +10004395 global iddrawn markingmatches
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004396 global commitinfo numcommits
Paul Mackerras687c8762007-09-22 12:49:33 +10004397 global filehighlight fhighlights findpattern nhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10004398 global hlview vhighlights
Paul Mackerras164ff272006-05-29 19:50:02 +10004399 global highlight_related rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004400
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004401 if {$row >= $numcommits} return
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004402
4403 set id [lindex $displayorder $row]
Paul Mackerras908c3582006-05-20 09:38:11 +10004404 if {[info exists hlview] && ![info exists vhighlights($row)]} {
4405 askvhighlight $row $id
4406 }
4407 if {[info exists filehighlight] && ![info exists fhighlights($row)]} {
4408 askfilehighlight $row $id
4409 }
Paul Mackerras687c8762007-09-22 12:49:33 +10004410 if {$findpattern ne {} && ![info exists nhighlights($row)]} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10004411 askfindhighlight $row $id
Paul Mackerras908c3582006-05-20 09:38:11 +10004412 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01004413 if {$highlight_related ne [mc "None"] && ![info exists rhighlights($row)]} {
Paul Mackerras164ff272006-05-29 19:50:02 +10004414 askrelhighlight $row $id
4415 }
Paul Mackerras005a2f42007-07-26 22:36:39 +10004416 if {![info exists iddrawn($id)]} {
4417 set col [lsearch -exact [lindex $rowidlist $row] $id]
4418 if {$col < 0} {
4419 puts "oops, row $row id $id not in list"
4420 return
4421 }
4422 if {![info exists commitinfo($id)]} {
4423 getcommit $id
4424 }
4425 assigncolor $id
4426 drawcmittext $id $row $col
4427 set iddrawn($id) 1
Paul Mackerras03800812007-08-29 21:45:21 +10004428 incr nrows_drawn
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004429 }
Paul Mackerras005a2f42007-07-26 22:36:39 +10004430 if {$markingmatches} {
4431 markrowmatches $row $id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004432 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004433}
4434
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004435proc drawcommits {row {endrow {}}} {
Paul Mackerras03800812007-08-29 21:45:21 +10004436 global numcommits iddrawn displayorder curview need_redisplay
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10004437 global parentlist rowidlist rowfinal uparrowlen downarrowlen nrows_drawn
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004438
4439 if {$row < 0} {
4440 set row 0
4441 }
4442 if {$endrow eq {}} {
4443 set endrow $row
4444 }
4445 if {$endrow >= $numcommits} {
4446 set endrow [expr {$numcommits - 1}]
4447 }
4448
Paul Mackerras03800812007-08-29 21:45:21 +10004449 set rl1 [expr {$row - $downarrowlen - 3}]
4450 if {$rl1 < 0} {
4451 set rl1 0
4452 }
4453 set ro1 [expr {$row - 3}]
4454 if {$ro1 < 0} {
4455 set ro1 0
4456 }
4457 set r2 [expr {$endrow + $uparrowlen + 3}]
4458 if {$r2 > $numcommits} {
4459 set r2 $numcommits
4460 }
4461 for {set r $rl1} {$r < $r2} {incr r} {
Paul Mackerrasf5f3c2e2007-09-05 02:19:56 +10004462 if {[lindex $rowidlist $r] ne {} && [lindex $rowfinal $r]} {
Paul Mackerras03800812007-08-29 21:45:21 +10004463 if {$rl1 < $r} {
4464 layoutrows $rl1 $r
4465 }
4466 set rl1 [expr {$r + 1}]
4467 }
4468 }
4469 if {$rl1 < $r} {
4470 layoutrows $rl1 $r
4471 }
4472 optimize_rows $ro1 0 $r2
4473 if {$need_redisplay || $nrows_drawn > 2000} {
4474 clear_display
4475 drawvisible
4476 }
4477
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004478 # make the lines join to already-drawn rows either side
4479 set r [expr {$row - 1}]
4480 if {$r < 0 || ![info exists iddrawn([lindex $displayorder $r])]} {
4481 set r $row
4482 }
4483 set er [expr {$endrow + 1}]
4484 if {$er >= $numcommits ||
4485 ![info exists iddrawn([lindex $displayorder $er])]} {
4486 set er $endrow
4487 }
4488 for {} {$r <= $er} {incr r} {
4489 set id [lindex $displayorder $r]
4490 set wasdrawn [info exists iddrawn($id)]
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004491 drawcmitrow $r
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004492 if {$r == $er} break
4493 set nextid [lindex $displayorder [expr {$r + 1}]]
Paul Mackerrase5ef6f92007-10-21 12:58:42 +10004494 if {$wasdrawn && [info exists iddrawn($nextid)]} continue
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004495 drawparentlinks $id $r
4496
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004497 set rowids [lindex $rowidlist $r]
4498 foreach lid $rowids {
4499 if {$lid eq {}} continue
Paul Mackerrase5ef6f92007-10-21 12:58:42 +10004500 if {[info exists lineend($lid)] && $lineend($lid) > $r} continue
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004501 if {$lid eq $id} {
4502 # see if this is the first child of any of its parents
4503 foreach p [lindex $parentlist $r] {
4504 if {[lsearch -exact $rowids $p] < 0} {
4505 # make this line extend up to the child
Paul Mackerrase5ef6f92007-10-21 12:58:42 +10004506 set lineend($p) [drawlineseg $p $r $er 0]
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004507 }
4508 }
Paul Mackerrase5ef6f92007-10-21 12:58:42 +10004509 } else {
4510 set lineend($lid) [drawlineseg $lid $r $er 1]
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004511 }
4512 }
4513 }
4514}
4515
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004516proc undolayout {row} {
4517 global uparrowlen mingaplen downarrowlen
4518 global rowidlist rowisopt rowfinal need_redisplay
4519
4520 set r [expr {$row - ($uparrowlen + $mingaplen + $downarrowlen)}]
4521 if {$r < 0} {
4522 set r 0
4523 }
4524 if {[llength $rowidlist] > $r} {
4525 incr r -1
4526 set rowidlist [lrange $rowidlist 0 $r]
4527 set rowfinal [lrange $rowfinal 0 $r]
4528 set rowisopt [lrange $rowisopt 0 $r]
4529 set need_redisplay 1
4530 run drawvisible
4531 }
4532}
4533
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004534proc drawfrac {f0 f1} {
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004535 global canv linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004536
4537 set ymax [lindex [$canv cget -scrollregion] 3]
4538 if {$ymax eq {} || $ymax == 0} return
4539 set y0 [expr {int($f0 * $ymax)}]
4540 set row [expr {int(($y0 - 3) / $linespc) - 1}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004541 set y1 [expr {int($f1 * $ymax)}]
4542 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004543 drawcommits $row $endrow
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004544}
4545
4546proc drawvisible {} {
4547 global canv
4548 eval drawfrac [$canv yview]
4549}
4550
4551proc clear_display {} {
Paul Mackerras03800812007-08-29 21:45:21 +10004552 global iddrawn linesegs need_redisplay nrows_drawn
Paul Mackerras164ff272006-05-29 19:50:02 +10004553 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004554
4555 allcanvs delete all
4556 catch {unset iddrawn}
Paul Mackerras322a8cc2006-10-15 18:03:46 +10004557 catch {unset linesegs}
Paul Mackerras908c3582006-05-20 09:38:11 +10004558 catch {unset vhighlights}
4559 catch {unset fhighlights}
4560 catch {unset nhighlights}
Paul Mackerras164ff272006-05-29 19:50:02 +10004561 catch {unset rhighlights}
Paul Mackerras03800812007-08-29 21:45:21 +10004562 set need_redisplay 0
4563 set nrows_drawn 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004564}
4565
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004566proc findcrossings {id} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10004567 global rowidlist parentlist numcommits displayorder
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004568
4569 set cross {}
4570 set ccross {}
4571 foreach {s e} [rowranges $id] {
4572 if {$e >= $numcommits} {
4573 set e [expr {$numcommits - 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004574 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10004575 if {$e <= $s} continue
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004576 for {set row $e} {[incr row -1] >= $s} {} {
Paul Mackerras6e8c8702007-07-31 21:03:06 +10004577 set x [lsearch -exact [lindex $rowidlist $row] $id]
4578 if {$x < 0} break
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004579 set olds [lindex $parentlist $row]
4580 set kid [lindex $displayorder $row]
4581 set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
4582 if {$kidx < 0} continue
4583 set nextrow [lindex $rowidlist [expr {$row + 1}]]
4584 foreach p $olds {
4585 set px [lsearch -exact $nextrow $p]
4586 if {$px < 0} continue
4587 if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
4588 if {[lsearch -exact $ccross $p] >= 0} continue
4589 if {$x == $px + ($kidx < $px? -1: 1)} {
4590 lappend ccross $p
4591 } elseif {[lsearch -exact $cross $p] < 0} {
4592 lappend cross $p
4593 }
4594 }
4595 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004596 }
4597 }
4598 return [concat $ccross {{}} $cross]
4599}
4600
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004601proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +11004602 global colormap colors nextcolor
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004603 global parents children children curview
Paul Mackerras6c20ff32005-06-22 19:53:32 +10004604
Paul Mackerras418c4c72006-02-07 09:10:18 +11004605 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004606 set ncolors [llength $colors]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004607 if {[info exists children($curview,$id)]} {
4608 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10004609 } else {
4610 set kids {}
4611 }
4612 if {[llength $kids] == 1} {
4613 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004614 if {[info exists colormap($child)]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004615 && [llength $parents($curview,$child)] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004616 set colormap($id) $colormap($child)
4617 return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004618 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004619 }
4620 set badcolors {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004621 set origbad {}
4622 foreach x [findcrossings $id] {
4623 if {$x eq {}} {
4624 # delimiter between corner crossings and other crossings
4625 if {[llength $badcolors] >= $ncolors - 1} break
4626 set origbad $badcolors
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004627 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004628 if {[info exists colormap($x)]
4629 && [lsearch -exact $badcolors $colormap($x)] < 0} {
4630 lappend badcolors $colormap($x)
Paul Mackerras6c20ff32005-06-22 19:53:32 +10004631 }
4632 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004633 if {[llength $badcolors] >= $ncolors} {
4634 set badcolors $origbad
4635 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10004636 set origbad $badcolors
4637 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004638 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 19:53:32 +10004639 if {[info exists colormap($child)]
4640 && [lsearch -exact $badcolors $colormap($child)] < 0} {
4641 lappend badcolors $colormap($child)
4642 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004643 foreach p $parents($curview,$child) {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004644 if {[info exists colormap($p)]
4645 && [lsearch -exact $badcolors $colormap($p)] < 0} {
4646 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004647 }
4648 }
4649 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10004650 if {[llength $badcolors] >= $ncolors} {
4651 set badcolors $origbad
4652 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004653 }
4654 for {set i 0} {$i <= $ncolors} {incr i} {
4655 set c [lindex $colors $nextcolor]
4656 if {[incr nextcolor] >= $ncolors} {
4657 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004658 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004659 if {[lsearch -exact $badcolors $c]} break
4660 }
4661 set colormap($id) $c
4662}
4663
Paul Mackerrasa823a912005-06-21 10:01:38 +10004664proc bindline {t id} {
4665 global canv
4666
Paul Mackerrasa823a912005-06-21 10:01:38 +10004667 $canv bind $t <Enter> "lineenter %x %y $id"
4668 $canv bind $t <Motion> "linemotion %x %y $id"
4669 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004670 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 10:01:38 +10004671}
4672
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004673proc drawtags {id x xt y1} {
Paul Mackerras8a485712006-07-06 10:21:23 +10004674 global idtags idheads idotherrefs mainhead
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004675 global linespc lthickness
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004676 global canv rowtextx curview fgcolor bgcolor
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004677
4678 set marks {}
4679 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10004680 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004681 if {[info exists idtags($id)]} {
4682 set marks $idtags($id)
4683 set ntags [llength $marks]
4684 }
4685 if {[info exists idheads($id)]} {
4686 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10004687 set nheads [llength $idheads($id)]
4688 }
4689 if {[info exists idotherrefs($id)]} {
4690 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004691 }
4692 if {$marks eq {}} {
4693 return $xt
4694 }
4695
4696 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004697 set yt [expr {$y1 - 0.5 * $linespc}]
4698 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004699 set xvals {}
4700 set wvals {}
Paul Mackerras8a485712006-07-06 10:21:23 +10004701 set i -1
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004702 foreach tag $marks {
Paul Mackerras8a485712006-07-06 10:21:23 +10004703 incr i
4704 if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10004705 set wid [font measure mainfontbold $tag]
Paul Mackerras8a485712006-07-06 10:21:23 +10004706 } else {
Paul Mackerras9c311b32007-10-04 22:27:13 +10004707 set wid [font measure mainfont $tag]
Paul Mackerras8a485712006-07-06 10:21:23 +10004708 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004709 lappend xvals $xt
4710 lappend wvals $wid
4711 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
4712 }
4713 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
4714 -width $lthickness -fill black -tags tag.$id]
4715 $canv lower $t
4716 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004717 set xl [expr {$x + $delta}]
4718 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerras9c311b32007-10-04 22:27:13 +10004719 set font mainfont
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004720 if {[incr ntags -1] >= 0} {
4721 # draw a tag
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004722 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
4723 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 23:11:39 +10004724 -width 1 -outline black -fill yellow -tags tag.$id]
4725 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004726 set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004727 } else {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10004728 # draw a head or other ref
4729 if {[incr nheads -1] >= 0} {
4730 set col green
Paul Mackerras8a485712006-07-06 10:21:23 +10004731 if {$tag eq $mainhead} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10004732 set font mainfontbold
Paul Mackerras8a485712006-07-06 10:21:23 +10004733 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10004734 } else {
4735 set col "#ddddff"
4736 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004737 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004738 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10004739 -width 1 -outline black -fill $col -tags tag.$id
Josef Weidendorfera970fcf2006-04-18 23:53:07 +02004740 if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10004741 set rwid [font measure mainfont $remoteprefix]
Josef Weidendorfera970fcf2006-04-18 23:53:07 +02004742 set xi [expr {$x + 1}]
4743 set yti [expr {$yt + 1}]
4744 set xri [expr {$x + $rwid}]
4745 $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
4746 -width 0 -fill "#ffddaa" -tags tag.$id
4747 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004748 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004749 set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
Paul Mackerras8a485712006-07-06 10:21:23 +10004750 -font $font -tags [list tag.$id text]]
Paul Mackerras106288c2005-08-19 23:11:39 +10004751 if {$ntags >= 0} {
4752 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras10299152006-08-02 09:52:01 +10004753 } elseif {$nheads >= 0} {
4754 $canv bind $t <Button-3> [list headmenu %X %Y $id $tag]
Paul Mackerras106288c2005-08-19 23:11:39 +10004755 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10004756 }
4757 return $xt
4758}
4759
Paul Mackerras8d858d12005-08-05 09:52:16 +10004760proc xcoord {i level ln} {
4761 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004762
Paul Mackerras8d858d12005-08-05 09:52:16 +10004763 set x [expr {$canvx0 + $i * $xspc1($ln)}]
4764 if {$i > 0 && $i == $level} {
4765 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
4766 } elseif {$i > $level} {
4767 set x [expr {$x + $xspc2 - $xspc1($ln)}]
4768 }
4769 return $x
4770}
4771
Paul Mackerras098dd8a2006-05-03 09:32:53 +10004772proc show_status {msg} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10004773 global canv fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10004774
4775 clear_display
Paul Mackerras9c311b32007-10-04 22:27:13 +10004776 $canv create text 3 3 -anchor nw -text $msg -font mainfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004777 -tags text -fill $fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10004778}
4779
Paul Mackerras94a2eed2005-08-07 15:27:57 +10004780# Don't change the text pane cursor if it is currently the hand cursor,
4781# showing that we are over a sha1 ID link.
4782proc settextcursor {c} {
4783 global ctext curtextcursor
4784
4785 if {[$ctext cget -cursor] == $curtextcursor} {
4786 $ctext config -cursor $c
4787 }
4788 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00004789}
4790
Paul Mackerrasa137a902007-10-23 21:12:49 +10004791proc nowbusy {what {name {}}} {
4792 global isbusy busyname statusw
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004793
4794 if {[array names isbusy] eq {}} {
4795 . config -cursor watch
4796 settextcursor watch
4797 }
4798 set isbusy($what) 1
Paul Mackerrasa137a902007-10-23 21:12:49 +10004799 set busyname($what) $name
4800 if {$name ne {}} {
4801 $statusw conf -text $name
4802 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004803}
4804
4805proc notbusy {what} {
Paul Mackerrasa137a902007-10-23 21:12:49 +10004806 global isbusy maincursor textcursor busyname statusw
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004807
Paul Mackerrasa137a902007-10-23 21:12:49 +10004808 catch {
4809 unset isbusy($what)
4810 if {$busyname($what) ne {} &&
4811 [$statusw cget -text] eq $busyname($what)} {
4812 $statusw conf -text {}
4813 }
4814 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004815 if {[array names isbusy] eq {}} {
4816 . config -cursor $maincursor
4817 settextcursor $textcursor
4818 }
4819}
4820
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004821proc findmatches {f} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004822 global findtype findstring
Christian Stimmingb007ee22007-11-07 18:44:35 +01004823 if {$findtype == [mc "Regexp"]} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004824 set matches [regexp -indices -all -inline $findstring $f]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004825 } else {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004826 set fs $findstring
Christian Stimmingb007ee22007-11-07 18:44:35 +01004827 if {$findtype == [mc "IgnCase"]} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004828 set f [string tolower $f]
4829 set fs [string tolower $fs]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004830 }
4831 set matches {}
4832 set i 0
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004833 set l [string length $fs]
4834 while {[set j [string first $fs $f $i]] >= 0} {
4835 lappend matches [list $j [expr {$j+$l-1}]]
4836 set i [expr {$j + $l}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004837 }
4838 }
4839 return $matches
4840}
4841
Paul Mackerrascca5d942007-10-27 21:16:56 +10004842proc dofind {{dirn 1} {wrap 1}} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004843 global findstring findstartline findcurline selectedline numcommits
Paul Mackerrascca5d942007-10-27 21:16:56 +10004844 global gdttype filehighlight fh_serial find_dirn findallowwrap
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004845
Paul Mackerrascca5d942007-10-27 21:16:56 +10004846 if {[info exists find_dirn]} {
4847 if {$find_dirn == $dirn} return
4848 stopfinding
4849 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004850 focus .
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004851 if {$findstring eq {} || $numcommits == 0} return
Paul Mackerras98f350e2005-05-15 05:56:51 +00004852 if {![info exists selectedline]} {
Paul Mackerrascca5d942007-10-27 21:16:56 +10004853 set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
Paul Mackerras98f350e2005-05-15 05:56:51 +00004854 } else {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004855 set findstartline $selectedline
Paul Mackerras98f350e2005-05-15 05:56:51 +00004856 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004857 set findcurline $findstartline
Christian Stimmingb007ee22007-11-07 18:44:35 +01004858 nowbusy finding [mc "Searching"]
4859 if {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} {
Paul Mackerras687c8762007-09-22 12:49:33 +10004860 after cancel do_file_hl $fh_serial
4861 do_file_hl $fh_serial
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004862 }
Paul Mackerrascca5d942007-10-27 21:16:56 +10004863 set find_dirn $dirn
4864 set findallowwrap $wrap
4865 run findmore
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004866}
4867
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004868proc stopfinding {} {
4869 global find_dirn findcurline fprogcoord
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004870
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004871 if {[info exists find_dirn]} {
4872 unset find_dirn
4873 unset findcurline
4874 notbusy finding
4875 set fprogcoord 0
4876 adjustprogress
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004877 }
4878}
4879
4880proc findmore {} {
Paul Mackerras687c8762007-09-22 12:49:33 +10004881 global commitdata commitinfo numcommits findpattern findloc
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004882 global findstartline findcurline findallowwrap
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004883 global find_dirn gdttype fhighlights fprogcoord
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004884 global curview varcorder vrownum varccommits
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004885
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004886 if {![info exists find_dirn]} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004887 return 0
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004888 }
Christian Stimmingb007ee22007-11-07 18:44:35 +01004889 set fldtypes [list [mc "Headline"] [mc "Author"] [mc "Date"] [mc "Committer"] [mc "CDate"] [mc "Comments"]]
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004890 set l $findcurline
Paul Mackerrascca5d942007-10-27 21:16:56 +10004891 set moretodo 0
4892 if {$find_dirn > 0} {
4893 incr l
4894 if {$l >= $numcommits} {
4895 set l 0
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004896 }
Paul Mackerrascca5d942007-10-27 21:16:56 +10004897 if {$l <= $findstartline} {
4898 set lim [expr {$findstartline + 1}]
4899 } else {
4900 set lim $numcommits
4901 set moretodo $findallowwrap
4902 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00004903 } else {
Paul Mackerrascca5d942007-10-27 21:16:56 +10004904 if {$l == 0} {
4905 set l $numcommits
4906 }
4907 incr l -1
4908 if {$l >= $findstartline} {
4909 set lim [expr {$findstartline - 1}]
4910 } else {
4911 set lim -1
4912 set moretodo $findallowwrap
4913 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00004914 }
Paul Mackerrascca5d942007-10-27 21:16:56 +10004915 set n [expr {($lim - $l) * $find_dirn}]
4916 if {$n > 500} {
4917 set n 500
4918 set moretodo 1
Paul Mackerras98f350e2005-05-15 05:56:51 +00004919 }
Paul Mackerras687c8762007-09-22 12:49:33 +10004920 set found 0
4921 set domore 1
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004922 set ai [bsearch $vrownum($curview) $l]
4923 set a [lindex $varcorder($curview) $ai]
4924 set arow [lindex $vrownum($curview) $ai]
4925 set ids [lindex $varccommits($curview,$a)]
4926 set arowend [expr {$arow + [llength $ids]}]
Christian Stimmingb007ee22007-11-07 18:44:35 +01004927 if {$gdttype eq [mc "containing:"]} {
Paul Mackerrascca5d942007-10-27 21:16:56 +10004928 for {} {$n > 0} {incr n -1; incr l $find_dirn} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004929 if {$l < $arow || $l >= $arowend} {
4930 incr ai $find_dirn
4931 set a [lindex $varcorder($curview) $ai]
4932 set arow [lindex $vrownum($curview) $ai]
4933 set ids [lindex $varccommits($curview,$a)]
4934 set arowend [expr {$arow + [llength $ids]}]
4935 }
4936 set id [lindex $ids [expr {$l - $arow}]]
Paul Mackerras687c8762007-09-22 12:49:33 +10004937 # shouldn't happen unless git log doesn't give all the commits...
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004938 if {![info exists commitdata($id)] ||
4939 ![doesmatch $commitdata($id)]} {
4940 continue
4941 }
Paul Mackerras687c8762007-09-22 12:49:33 +10004942 if {![info exists commitinfo($id)]} {
4943 getcommit $id
4944 }
4945 set info $commitinfo($id)
4946 foreach f $info ty $fldtypes {
Christian Stimmingb007ee22007-11-07 18:44:35 +01004947 if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
Paul Mackerras687c8762007-09-22 12:49:33 +10004948 [doesmatch $f]} {
4949 set found 1
4950 break
4951 }
4952 }
4953 if {$found} break
Paul Mackerras98f350e2005-05-15 05:56:51 +00004954 }
Paul Mackerras687c8762007-09-22 12:49:33 +10004955 } else {
Paul Mackerrascca5d942007-10-27 21:16:56 +10004956 for {} {$n > 0} {incr n -1; incr l $find_dirn} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11004957 if {$l < $arow || $l >= $arowend} {
4958 incr ai $find_dirn
4959 set a [lindex $varcorder($curview) $ai]
4960 set arow [lindex $vrownum($curview) $ai]
4961 set ids [lindex $varccommits($curview,$a)]
4962 set arowend [expr {$arow + [llength $ids]}]
4963 }
4964 set id [lindex $ids [expr {$l - $arow}]]
Paul Mackerras687c8762007-09-22 12:49:33 +10004965 if {![info exists fhighlights($l)]} {
4966 askfilehighlight $l $id
4967 if {$domore} {
4968 set domore 0
Paul Mackerrascca5d942007-10-27 21:16:56 +10004969 set findcurline [expr {$l - $find_dirn}]
Paul Mackerras687c8762007-09-22 12:49:33 +10004970 }
4971 } elseif {$fhighlights($l)} {
4972 set found $domore
4973 break
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004974 }
4975 }
4976 }
Paul Mackerrascca5d942007-10-27 21:16:56 +10004977 if {$found || ($domore && !$moretodo)} {
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004978 unset findcurline
Paul Mackerras687c8762007-09-22 12:49:33 +10004979 unset find_dirn
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004980 notbusy finding
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004981 set fprogcoord 0
4982 adjustprogress
4983 if {$found} {
4984 findselectline $l
4985 } else {
4986 bell
4987 }
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004988 return 0
4989 }
Paul Mackerras687c8762007-09-22 12:49:33 +10004990 if {!$domore} {
4991 flushhighlights
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004992 } else {
Paul Mackerrascca5d942007-10-27 21:16:56 +10004993 set findcurline [expr {$l - $find_dirn}]
Paul Mackerras687c8762007-09-22 12:49:33 +10004994 }
Paul Mackerrascca5d942007-10-27 21:16:56 +10004995 set n [expr {($findcurline - $findstartline) * $find_dirn - 1}]
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004996 if {$n < 0} {
4997 incr n $numcommits
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10004998 }
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10004999 set fprogcoord [expr {$n * 1.0 / $numcommits}]
5000 adjustprogress
5001 return $domore
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00005002}
5003
5004proc findselectline {l} {
Paul Mackerras687c8762007-09-22 12:49:33 +10005005 global findloc commentend ctext findcurline markingmatches gdttype
Paul Mackerras005a2f42007-07-26 22:36:39 +10005006
5007 set markingmatches 1
5008 set findcurline $l
Paul Mackerrasd6982062005-08-06 22:06:06 +10005009 selectline $l 1
Christian Stimmingb007ee22007-11-07 18:44:35 +01005010 if {$findloc == [mc "All fields"] || $findloc == [mc "Comments"]} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00005011 # highlight the matches in the comments
5012 set f [$ctext get 1.0 $commentend]
5013 set matches [findmatches $f]
5014 foreach match $matches {
5015 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08005016 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00005017 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
5018 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00005019 }
Paul Mackerras005a2f42007-07-26 22:36:39 +10005020 drawvisible
Paul Mackerras98f350e2005-05-15 05:56:51 +00005021}
5022
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10005023# mark the bits of a headline or author that match a find string
Paul Mackerras005a2f42007-07-26 22:36:39 +10005024proc markmatches {canv l str tag matches font row} {
5025 global selectedline
5026
Paul Mackerras98f350e2005-05-15 05:56:51 +00005027 set bbox [$canv bbox $tag]
5028 set x0 [lindex $bbox 0]
5029 set y0 [lindex $bbox 1]
5030 set y1 [lindex $bbox 3]
5031 foreach match $matches {
5032 set start [lindex $match 0]
5033 set end [lindex $match 1]
5034 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08005035 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
5036 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
5037 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
5038 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10005039 -outline {} -tags [list match$l matches] -fill yellow]
Paul Mackerras98f350e2005-05-15 05:56:51 +00005040 $canv lower $t
Paul Mackerras005a2f42007-07-26 22:36:39 +10005041 if {[info exists selectedline] && $row == $selectedline} {
5042 $canv raise $t secsel
5043 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00005044 }
5045}
5046
5047proc unmarkmatches {} {
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10005048 global markingmatches
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10005049
Paul Mackerras98f350e2005-05-15 05:56:51 +00005050 allcanvs delete matches
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10005051 set markingmatches 0
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10005052 stopfinding
Paul Mackerras98f350e2005-05-15 05:56:51 +00005053}
5054
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005055proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005056 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11005057 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:39 +00005058 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:42 +00005059 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:39 +00005060 set yfrac [lindex [$canv yview] 0]
5061 set y [expr {$y + $yfrac * $ymax}]
5062 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
5063 if {$l < 0} {
5064 set l 0
5065 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005066 if {$w eq $canv} {
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11005067 set xmax [lindex [$canv cget -scrollregion] 2]
5068 set xleft [expr {[lindex [$canv xview] 0] * $xmax}]
5069 if {![info exists rowtextx($l)] || $xleft + $x < $rowtextx($l)} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005070 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00005071 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10005072 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005073}
5074
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07005075proc commit_descriptor {p} {
5076 global commitinfo
Paul Mackerrasb0934482006-05-15 09:56:08 +10005077 if {![info exists commitinfo($p)]} {
5078 getcommit $p
5079 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07005080 set l "..."
Paul Mackerrasb0934482006-05-15 09:56:08 +10005081 if {[llength $commitinfo($p)] > 1} {
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07005082 set l [lindex $commitinfo($p) 0]
5083 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005084 return "$p ($l)\n"
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07005085}
5086
Paul Mackerras106288c2005-08-19 23:11:39 +10005087# append some text to the ctext widget, and make any SHA1 ID
5088# that we know about be a clickable link.
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005089proc appendwithlinks {text tags} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005090 global ctext linknum curview pendinglinks
Paul Mackerras106288c2005-08-19 23:11:39 +10005091
5092 set start [$ctext index "end - 1c"]
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005093 $ctext insert end $text $tags
Paul Mackerras106288c2005-08-19 23:11:39 +10005094 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
5095 foreach l $links {
5096 set s [lindex $l 0]
5097 set e [lindex $l 1]
5098 set linkid [string range $text $s $e]
Paul Mackerras106288c2005-08-19 23:11:39 +10005099 incr e
Paul Mackerrasc73adce2007-09-27 10:35:05 +10005100 $ctext tag delete link$linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10005101 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerras97645682007-08-23 22:24:38 +10005102 setlink $linkid link$linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10005103 incr linknum
5104 }
Paul Mackerras97645682007-08-23 22:24:38 +10005105}
5106
5107proc setlink {id lk} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005108 global curview ctext pendinglinks commitinterest
Paul Mackerras97645682007-08-23 22:24:38 +10005109
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005110 if {[commitinview $id $curview]} {
Paul Mackerras97645682007-08-23 22:24:38 +10005111 $ctext tag conf $lk -foreground blue -underline 1
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005112 $ctext tag bind $lk <1> [list selectline [rowofcommit $id] 1]
Paul Mackerras97645682007-08-23 22:24:38 +10005113 $ctext tag bind $lk <Enter> {linkcursor %W 1}
5114 $ctext tag bind $lk <Leave> {linkcursor %W -1}
5115 } else {
5116 lappend pendinglinks($id) $lk
5117 lappend commitinterest($id) {makelink %I}
5118 }
5119}
5120
5121proc makelink {id} {
5122 global pendinglinks
5123
5124 if {![info exists pendinglinks($id)]} return
5125 foreach lk $pendinglinks($id) {
5126 setlink $id $lk
5127 }
5128 unset pendinglinks($id)
5129}
5130
5131proc linkcursor {w inc} {
5132 global linkentercount curtextcursor
5133
5134 if {[incr linkentercount $inc] > 0} {
5135 $w configure -cursor hand2
5136 } else {
5137 $w configure -cursor $curtextcursor
5138 if {$linkentercount < 0} {
5139 set linkentercount 0
5140 }
5141 }
Paul Mackerras106288c2005-08-19 23:11:39 +10005142}
5143
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10005144proc viewnextline {dir} {
5145 global canv linespc
5146
5147 $canv delete hover
5148 set ymax [lindex [$canv cget -scrollregion] 3]
5149 set wnow [$canv yview]
5150 set wtop [expr {[lindex $wnow 0] * $ymax}]
5151 set newtop [expr {$wtop + $dir * $linespc}]
5152 if {$newtop < 0} {
5153 set newtop 0
5154 } elseif {$newtop > $ymax} {
5155 set newtop $ymax
5156 }
5157 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
5158}
5159
Paul Mackerrasef030b82006-06-04 11:50:38 +10005160# add a list of tag or branch names at position pos
5161# returns the number of names inserted
Paul Mackerrase11f1232007-06-16 20:29:25 +10005162proc appendrefs {pos ids var} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005163 global ctext linknum curview $var maxrefs
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005164
Paul Mackerrasef030b82006-06-04 11:50:38 +10005165 if {[catch {$ctext index $pos}]} {
5166 return 0
5167 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10005168 $ctext conf -state normal
5169 $ctext delete $pos "$pos lineend"
5170 set tags {}
5171 foreach id $ids {
5172 foreach tag [set $var\($id\)] {
5173 lappend tags [list $tag $id]
5174 }
5175 }
Paul Mackerras0a4dd8b2007-06-16 21:21:57 +10005176 if {[llength $tags] > $maxrefs} {
5177 $ctext insert $pos "many ([llength $tags])"
5178 } else {
5179 set tags [lsort -index 0 -decreasing $tags]
5180 set sep {}
5181 foreach ti $tags {
5182 set id [lindex $ti 1]
5183 set lk link$linknum
5184 incr linknum
5185 $ctext tag delete $lk
5186 $ctext insert $pos $sep
5187 $ctext insert $pos [lindex $ti 0] $lk
Paul Mackerras97645682007-08-23 22:24:38 +10005188 setlink $id $lk
Paul Mackerras0a4dd8b2007-06-16 21:21:57 +10005189 set sep ", "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005190 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005191 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10005192 $ctext conf -state disabled
Paul Mackerrasef030b82006-06-04 11:50:38 +10005193 return [llength $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005194}
5195
5196# called when we have finished computing the nearby tags
Paul Mackerrase11f1232007-06-16 20:29:25 +10005197proc dispneartags {delay} {
5198 global selectedline currentid showneartags tagphase
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005199
5200 if {![info exists selectedline] || !$showneartags} return
Paul Mackerrase11f1232007-06-16 20:29:25 +10005201 after cancel dispnexttag
5202 if {$delay} {
5203 after 200 dispnexttag
5204 set tagphase -1
5205 } else {
5206 after idle dispnexttag
5207 set tagphase 0
5208 }
5209}
5210
5211proc dispnexttag {} {
5212 global selectedline currentid showneartags tagphase ctext
5213
5214 if {![info exists selectedline] || !$showneartags} return
5215 switch -- $tagphase {
5216 0 {
5217 set dtags [desctags $currentid]
5218 if {$dtags ne {}} {
5219 appendrefs precedes $dtags idtags
5220 }
5221 }
5222 1 {
5223 set atags [anctags $currentid]
5224 if {$atags ne {}} {
5225 appendrefs follows $atags idtags
5226 }
5227 }
5228 2 {
5229 set dheads [descheads $currentid]
5230 if {$dheads ne {}} {
5231 if {[appendrefs branch $dheads idheads] > 1
5232 && [$ctext get "branch -3c"] eq "h"} {
5233 # turn "Branch" into "Branches"
5234 $ctext conf -state normal
5235 $ctext insert "branch -2c" "es"
5236 $ctext conf -state disabled
5237 }
5238 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10005239 }
5240 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10005241 if {[incr tagphase] <= 2} {
5242 after idle dispnexttag
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005243 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005244}
5245
Paul Mackerras03800812007-08-29 21:45:21 +10005246proc make_secsel {l} {
5247 global linehtag linentag linedtag canv canv2 canv3
5248
5249 if {![info exists linehtag($l)]} return
5250 $canv delete secsel
5251 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
5252 -tags secsel -fill [$canv cget -selectbackground]]
5253 $canv lower $t
5254 $canv2 delete secsel
5255 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
5256 -tags secsel -fill [$canv2 cget -selectbackground]]
5257 $canv2 lower $t
5258 $canv3 delete secsel
5259 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
5260 -tags secsel -fill [$canv3 cget -selectbackground]]
5261 $canv3 lower $t
5262}
5263
Paul Mackerrasd6982062005-08-06 22:06:06 +10005264proc selectline {l isnew} {
Paul Mackerras03800812007-08-29 21:45:21 +10005265 global canv ctext commitinfo selectedline
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005266 global canvy0 linespc parents children curview
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005267 global currentid sha1entry
Paul Mackerras9f1afe02006-02-19 22:44:47 +11005268 global commentend idtags linknum
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10005269 global mergemax numcommits pending_select
Paul Mackerrase11f1232007-06-16 20:29:25 +10005270 global cmitmode showneartags allcommits
Paul Mackerrasd6982062005-08-06 22:06:06 +10005271
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10005272 catch {unset pending_select}
Paul Mackerras84ba7342005-06-17 00:12:26 +00005273 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10005274 normalline
Paul Mackerras887c9962007-08-20 19:36:20 +10005275 unsel_reflist
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10005276 stopfinding
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11005277 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005278 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:00 +00005279 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:42 +00005280 set ytop [expr {$y - $linespc - 1}]
5281 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005282 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08005283 set wtop [expr {[lindex $wnow 0] * $ymax}]
5284 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:42 +00005285 set wh [expr {$wbot - $wtop}]
5286 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:00 +00005287 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:42 +00005288 if {$ybot < $wtop} {
5289 set newtop [expr {$y - $wh / 2.0}]
5290 } else {
5291 set newtop $ytop
5292 if {$newtop > $wtop - $linespc} {
5293 set newtop [expr {$wtop - $linespc}]
5294 }
Paul Mackerras17386062005-05-18 22:51:00 +00005295 }
Paul Mackerras58422152005-05-19 10:56:42 +00005296 } elseif {$ybot > $wbot} {
5297 if {$ytop > $wbot} {
5298 set newtop [expr {$y - $wh / 2.0}]
5299 } else {
5300 set newtop [expr {$ybot - $wh}]
5301 if {$newtop < $wtop + $linespc} {
5302 set newtop [expr {$wtop + $linespc}]
5303 }
Paul Mackerras17386062005-05-18 22:51:00 +00005304 }
Paul Mackerras58422152005-05-19 10:56:42 +00005305 }
5306 if {$newtop != $wtop} {
5307 if {$newtop < 0} {
5308 set newtop 0
5309 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08005310 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11005311 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005312 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10005313
Paul Mackerras03800812007-08-29 21:45:21 +10005314 make_secsel $l
Paul Mackerras9f1afe02006-02-19 22:44:47 +11005315
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11005316 set id [commitonrow $l]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005317 if {$isnew} {
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11005318 addtohistory [list selbyid $id]
Paul Mackerrasd6982062005-08-06 22:06:06 +10005319 }
5320
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005321 set selectedline $l
Paul Mackerras887fe3c2005-05-21 07:35:37 +00005322 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00005323 $sha1entry delete 0 end
5324 $sha1entry insert 0 $id
5325 $sha1entry selection from 0
5326 $sha1entry selection to end
Paul Mackerras164ff272006-05-29 19:50:02 +10005327 rhighlight_sel $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00005328
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005329 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10005330 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10005331 set linknum 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00005332 set info $commitinfo($id)
Paul Mackerras232475d2005-11-15 10:34:03 +11005333 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 18:42:55 +01005334 $ctext insert end "[mc "Author"]: [lindex $info 1] $date\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11005335 set date [formatdate [lindex $info 4]]
Christian Stimmingd990ced2007-11-07 18:42:55 +01005336 $ctext insert end "[mc "Committer"]: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00005337 if {[info exists idtags($id)]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01005338 $ctext insert end [mc "Tags:"]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00005339 foreach tag $idtags($id) {
5340 $ctext insert end " $tag"
5341 }
5342 $ctext insert end "\n"
5343 }
Mark Levedahl40b87ff2007-02-01 08:44:46 -05005344
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005345 set headers {}
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005346 set olds $parents($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10005347 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005348 set np 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10005349 foreach p $olds {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005350 if {$np >= $mergemax} {
5351 set tag mmax
5352 } else {
5353 set tag m$np
5354 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01005355 $ctext insert end "[mc "Parent"]: " $tag
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005356 appendwithlinks [commit_descriptor $p] {}
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005357 incr np
5358 }
5359 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10005360 foreach p $olds {
Christian Stimmingd990ced2007-11-07 18:42:55 +01005361 append headers "[mc "Parent"]: [commit_descriptor $p]"
Linus Torvalds8b192802005-08-07 13:58:56 -07005362 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07005363 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005364
Paul Mackerras6a90bff2007-06-18 09:48:23 +10005365 foreach c $children($curview,$id) {
Christian Stimmingd990ced2007-11-07 18:42:55 +01005366 append headers "[mc "Child"]: [commit_descriptor $c]"
Linus Torvalds8b192802005-08-07 13:58:56 -07005367 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10005368
5369 # make anything that looks like a SHA1 ID be a clickable link
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005370 appendwithlinks $headers {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005371 if {$showneartags} {
5372 if {![info exists allcommits]} {
5373 getallcommits
5374 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01005375 $ctext insert end "[mc "Branch"]: "
Paul Mackerrasef030b82006-06-04 11:50:38 +10005376 $ctext mark set branch "end -1c"
5377 $ctext mark gravity branch left
Christian Stimmingd990ced2007-11-07 18:42:55 +01005378 $ctext insert end "\n[mc "Follows"]: "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005379 $ctext mark set follows "end -1c"
5380 $ctext mark gravity follows left
Christian Stimmingd990ced2007-11-07 18:42:55 +01005381 $ctext insert end "\n[mc "Precedes"]: "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005382 $ctext mark set precedes "end -1c"
5383 $ctext mark gravity precedes left
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005384 $ctext insert end "\n"
Paul Mackerrase11f1232007-06-16 20:29:25 +10005385 dispneartags 1
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005386 }
5387 $ctext insert end "\n"
Paul Mackerras43c25072006-09-27 10:56:02 +10005388 set comment [lindex $info 5]
5389 if {[string first "\r" $comment] >= 0} {
5390 set comment [string map {"\r" "\n "} $comment]
5391 }
5392 appendwithlinks $comment {comment}
Paul Mackerrasd6982062005-08-06 22:06:06 +10005393
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00005394 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005395 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00005396 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005397
Christian Stimmingb007ee22007-11-07 18:44:35 +01005398 init_flist [mc "Comments"]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005399 if {$cmitmode eq "tree"} {
5400 gettree $id
5401 } elseif {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 20:41:56 +11005402 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 20:50:40 +11005403 } else {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005404 mergediff $id
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005405 }
5406}
5407
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10005408proc selfirstline {} {
5409 unmarkmatches
5410 selectline 0 1
5411}
5412
5413proc sellastline {} {
5414 global numcommits
5415 unmarkmatches
5416 set l [expr {$numcommits - 1}]
5417 selectline $l 1
5418}
5419
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005420proc selnextline {dir} {
5421 global selectedline
Mark Levedahlbd441de2007-08-07 21:40:34 -04005422 focus .
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005423 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08005424 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:51 +00005425 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10005426 selectline $l 1
5427}
5428
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10005429proc selnextpage {dir} {
5430 global canv linespc selectedline numcommits
5431
5432 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
5433 if {$lpp < 1} {
5434 set lpp 1
5435 }
5436 allcanvs yview scroll [expr {$dir * $lpp}] units
Paul Mackerrase72ee5e2006-05-20 09:58:49 +10005437 drawvisible
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10005438 if {![info exists selectedline]} return
5439 set l [expr {$selectedline + $dir * $lpp}]
5440 if {$l < 0} {
5441 set l 0
5442 } elseif {$l >= $numcommits} {
5443 set l [expr $numcommits - 1]
5444 }
5445 unmarkmatches
Mark Levedahl40b87ff2007-02-01 08:44:46 -05005446 selectline $l 1
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10005447}
5448
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005449proc unselectline {} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10005450 global selectedline currentid
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005451
5452 catch {unset selectedline}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10005453 catch {unset currentid}
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005454 allcanvs delete secsel
Paul Mackerras164ff272006-05-29 19:50:02 +10005455 rhighlight_none
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005456}
5457
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005458proc reselectline {} {
5459 global selectedline
5460
5461 if {[info exists selectedline]} {
5462 selectline $selectedline 0
5463 }
5464}
5465
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005466proc addtohistory {cmd} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10005467 global history historyindex curview
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005468
Paul Mackerras2516dae2006-04-21 10:35:31 +10005469 set elt [list $curview $cmd]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005470 if {$historyindex > 0
Paul Mackerras2516dae2006-04-21 10:35:31 +10005471 && [lindex $history [expr {$historyindex - 1}]] == $elt} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005472 return
5473 }
5474
5475 if {$historyindex < [llength $history]} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10005476 set history [lreplace $history $historyindex end $elt]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005477 } else {
Paul Mackerras2516dae2006-04-21 10:35:31 +10005478 lappend history $elt
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005479 }
5480 incr historyindex
5481 if {$historyindex > 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005482 .tf.bar.leftbut conf -state normal
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005483 } else {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005484 .tf.bar.leftbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005485 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005486 .tf.bar.rightbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005487}
5488
Paul Mackerras2516dae2006-04-21 10:35:31 +10005489proc godo {elt} {
5490 global curview
5491
5492 set view [lindex $elt 0]
5493 set cmd [lindex $elt 1]
5494 if {$curview != $view} {
5495 showview $view
5496 }
5497 eval $cmd
5498}
5499
Paul Mackerrasd6982062005-08-06 22:06:06 +10005500proc goback {} {
5501 global history historyindex
Mark Levedahlbd441de2007-08-07 21:40:34 -04005502 focus .
Paul Mackerrasd6982062005-08-06 22:06:06 +10005503
5504 if {$historyindex > 1} {
5505 incr historyindex -1
Paul Mackerras2516dae2006-04-21 10:35:31 +10005506 godo [lindex $history [expr {$historyindex - 1}]]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005507 .tf.bar.rightbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10005508 }
5509 if {$historyindex <= 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005510 .tf.bar.leftbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10005511 }
5512}
5513
5514proc goforw {} {
5515 global history historyindex
Mark Levedahlbd441de2007-08-07 21:40:34 -04005516 focus .
Paul Mackerrasd6982062005-08-06 22:06:06 +10005517
5518 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10005519 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 22:06:06 +10005520 incr historyindex
Paul Mackerras2516dae2006-04-21 10:35:31 +10005521 godo $cmd
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005522 .tf.bar.leftbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10005523 }
5524 if {$historyindex >= [llength $history]} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05005525 .tf.bar.rightbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10005526 }
Paul Mackerras5ad588d2005-05-10 01:02:55 +00005527}
5528
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005529proc gettree {id} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005530 global treefilelist treeidlist diffids diffmergeid treepending
5531 global nullid nullid2
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005532
5533 set diffids $id
5534 catch {unset diffmergeid}
5535 if {![info exists treefilelist($id)]} {
5536 if {![info exists treepending]} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005537 if {$id eq $nullid} {
5538 set cmd [list | git ls-files]
5539 } elseif {$id eq $nullid2} {
5540 set cmd [list | git ls-files --stage -t]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005541 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10005542 set cmd [list | git ls-tree -r $id]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005543 }
5544 if {[catch {set gtf [open $cmd r]}]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005545 return
5546 }
5547 set treepending $id
5548 set treefilelist($id) {}
5549 set treeidlist($id) {}
5550 fconfigure $gtf -blocking 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005551 filerun $gtf [list gettreeline $gtf $id]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005552 }
5553 } else {
5554 setfilelist $id
5555 }
5556}
5557
5558proc gettreeline {gtf id} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005559 global treefilelist treeidlist treepending cmitmode diffids nullid nullid2
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005560
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005561 set nl 0
5562 while {[incr nl] <= 1000 && [gets $gtf line] >= 0} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005563 if {$diffids eq $nullid} {
5564 set fname $line
5565 } else {
5566 if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
Paul Mackerras9396cd32007-06-23 20:28:15 +10005567 set i [string first "\t" $line]
5568 if {$i < 0} continue
5569 set sha1 [lindex $line 2]
5570 set fname [string range $line [expr {$i+1}] end]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005571 if {[string index $fname 0] eq "\""} {
5572 set fname [lindex $fname 0]
5573 }
5574 lappend treeidlist($id) $sha1
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005575 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005576 lappend treefilelist($id) $fname
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005577 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005578 if {![eof $gtf]} {
5579 return [expr {$nl >= 1000? 2: 1}]
5580 }
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005581 close $gtf
5582 unset treepending
5583 if {$cmitmode ne "tree"} {
5584 if {![info exists diffmergeid]} {
5585 gettreediffs $diffids
5586 }
5587 } elseif {$id ne $diffids} {
5588 gettree $diffids
5589 } else {
5590 setfilelist $id
5591 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005592 return 0
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005593}
5594
5595proc showfile {f} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005596 global treefilelist treeidlist diffids nullid nullid2
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005597 global ctext commentend
5598
5599 set i [lsearch -exact $treefilelist($diffids) $f]
5600 if {$i < 0} {
5601 puts "oops, $f not in list for id $diffids"
5602 return
5603 }
Paul Mackerras8f489362007-07-13 19:49:37 +10005604 if {$diffids eq $nullid} {
5605 if {[catch {set bf [open $f r]} err]} {
5606 puts "oops, can't read $f: $err"
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005607 return
5608 }
5609 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10005610 set blob [lindex $treeidlist($diffids) $i]
5611 if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
5612 puts "oops, error reading blob $blob: $err"
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005613 return
5614 }
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005615 }
5616 fconfigure $bf -blocking 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005617 filerun $bf [list getblobline $bf $diffids]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005618 $ctext config -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10005619 clear_ctext $commentend
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005620 $ctext insert end "\n"
5621 $ctext insert end "$f\n" filesep
5622 $ctext config -state disabled
5623 $ctext yview $commentend
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10005624 settabs 0
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005625}
5626
5627proc getblobline {bf id} {
5628 global diffids cmitmode ctext
5629
5630 if {$id ne $diffids || $cmitmode ne "tree"} {
5631 catch {close $bf}
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005632 return 0
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005633 }
5634 $ctext config -state normal
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005635 set nl 0
5636 while {[incr nl] <= 1000 && [gets $bf line] >= 0} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005637 $ctext insert end "$line\n"
5638 }
5639 if {[eof $bf]} {
5640 # delete last newline
5641 $ctext delete "end - 2c" "end - 1c"
5642 close $bf
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005643 return 0
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005644 }
5645 $ctext config -state disabled
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005646 return [expr {$nl >= 1000? 2: 1}]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10005647}
5648
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005649proc mergediff {id} {
Paul Mackerras8d73b242007-10-06 20:22:00 +10005650 global diffmergeid mdifffd
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005651 global diffids
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005652 global parents
Paul Mackerrasbd8f6772007-10-23 22:37:23 +10005653 global limitdiffs viewfiles curview
Paul Mackerrase2ed4322005-07-17 03:39:44 -04005654
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005655 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11005656 set diffids $id
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005657 # this doesn't seem to actually affect anything...
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03005658 set cmd [concat | git diff-tree --no-commit-id --cc $id]
Paul Mackerrasbd8f6772007-10-23 22:37:23 +10005659 if {$limitdiffs && $viewfiles($curview) ne {}} {
5660 set cmd [concat $cmd -- $viewfiles($curview)]
5661 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005662 if {[catch {set mdf [open $cmd r]} err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01005663 error_popup "[mc "Error getting merge diffs:"] $err"
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005664 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005665 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11005666 fconfigure $mdf -blocking 0
5667 set mdifffd($id) $mdf
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11005668 set np [llength $parents($curview,$id)]
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10005669 settabs $np
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005670 filerun $mdf [list getmergediffline $mdf $id $np]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005671}
5672
Paul Mackerras79b2c752006-04-02 20:47:40 +10005673proc getmergediffline {mdf id np} {
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005674 global diffmergeid ctext cflist mergemax
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11005675 global difffilestart mdifffd
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005676
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005677 $ctext conf -state normal
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005678 set nr 0
5679 while {[incr nr] <= 1000 && [gets $mdf line] >= 0} {
5680 if {![info exists diffmergeid] || $id != $diffmergeid
5681 || $mdf != $mdifffd($id)} {
5682 close $mdf
5683 return 0
5684 }
5685 if {[regexp {^diff --cc (.*)} $line match fname]} {
5686 # start of a new file
5687 $ctext insert end "\n"
5688 set here [$ctext index "end - 1c"]
5689 lappend difffilestart $here
5690 add_flist [list $fname]
5691 set l [expr {(78 - [string length $fname]) / 2}]
5692 set pad [string range "----------------------------------------" 1 $l]
5693 $ctext insert end "$pad $fname $pad\n" filesep
5694 } elseif {[regexp {^@@} $line]} {
5695 $ctext insert end "$line\n" hunksep
5696 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
5697 # do nothing
5698 } else {
5699 # parse the prefix - one ' ', '-' or '+' for each parent
5700 set spaces {}
5701 set minuses {}
5702 set pluses {}
5703 set isbad 0
5704 for {set j 0} {$j < $np} {incr j} {
5705 set c [string range $line $j $j]
5706 if {$c == " "} {
5707 lappend spaces $j
5708 } elseif {$c == "-"} {
5709 lappend minuses $j
5710 } elseif {$c == "+"} {
5711 lappend pluses $j
5712 } else {
5713 set isbad 1
5714 break
5715 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005716 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005717 set tags {}
5718 set num {}
5719 if {!$isbad && $minuses ne {} && $pluses eq {}} {
5720 # line doesn't appear in result, parents in $minuses have the line
5721 set num [lindex $minuses 0]
5722 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
5723 # line appears in result, parents in $pluses don't have the line
5724 lappend tags mresult
5725 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005726 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005727 if {$num ne {}} {
5728 if {$num >= $mergemax} {
5729 set num "max"
5730 }
5731 lappend tags m$num
5732 }
5733 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005734 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05005735 }
5736 $ctext conf -state disabled
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005737 if {[eof $mdf]} {
5738 close $mdf
5739 return 0
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05005740 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005741 return [expr {$nr >= 1000? 2: 1}]
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05005742}
5743
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005744proc startdiff {ids} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005745 global treediffs diffids treepending diffmergeid nullid nullid2
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005746
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10005747 settabs 1
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005748 set diffids $ids
5749 catch {unset diffmergeid}
Paul Mackerras8f489362007-07-13 19:49:37 +10005750 if {![info exists treediffs($ids)] ||
5751 [lsearch -exact $ids $nullid] >= 0 ||
5752 [lsearch -exact $ids $nullid2] >= 0} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005753 if {![info exists treepending]} {
5754 gettreediffs $ids
5755 }
5756 } else {
5757 addtocflist $ids
5758 }
5759}
5760
Paul Mackerras7a39a172007-10-23 10:15:11 +10005761proc path_filter {filter name} {
5762 foreach p $filter {
5763 set l [string length $p]
Paul Mackerras74a40c72007-10-24 10:16:56 +10005764 if {[string index $p end] eq "/"} {
5765 if {[string compare -length $l $p $name] == 0} {
5766 return 1
5767 }
5768 } else {
5769 if {[string compare -length $l $p $name] == 0 &&
5770 ([string length $name] == $l ||
5771 [string index $name $l] eq "/")} {
5772 return 1
5773 }
Paul Mackerras7a39a172007-10-23 10:15:11 +10005774 }
5775 }
5776 return 0
5777}
5778
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005779proc addtocflist {ids} {
Paul Mackerras74a40c72007-10-24 10:16:56 +10005780 global treediffs
Paul Mackerras7a39a172007-10-23 10:15:11 +10005781
Paul Mackerras74a40c72007-10-24 10:16:56 +10005782 add_flist $treediffs($ids)
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005783 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:38 +00005784}
5785
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005786proc diffcmd {ids flags} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005787 global nullid nullid2
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005788
5789 set i [lsearch -exact $ids $nullid]
Paul Mackerras8f489362007-07-13 19:49:37 +10005790 set j [lsearch -exact $ids $nullid2]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005791 if {$i >= 0} {
Paul Mackerras8f489362007-07-13 19:49:37 +10005792 if {[llength $ids] > 1 && $j < 0} {
5793 # comparing working directory with some specific revision
5794 set cmd [concat | git diff-index $flags]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005795 if {$i == 0} {
5796 lappend cmd -R [lindex $ids 1]
5797 } else {
5798 lappend cmd [lindex $ids 0]
5799 }
5800 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10005801 # comparing working directory with index
5802 set cmd [concat | git diff-files $flags]
5803 if {$j == 1} {
5804 lappend cmd -R
5805 }
5806 }
5807 } elseif {$j >= 0} {
5808 set cmd [concat | git diff-index --cached $flags]
5809 if {[llength $ids] > 1} {
5810 # comparing index with specific revision
5811 if {$i == 0} {
5812 lappend cmd -R [lindex $ids 1]
5813 } else {
5814 lappend cmd [lindex $ids 0]
5815 }
5816 } else {
5817 # comparing index with HEAD
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005818 lappend cmd HEAD
5819 }
5820 } else {
Paul Mackerras8f489362007-07-13 19:49:37 +10005821 set cmd [concat | git diff-tree -r $flags $ids]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005822 }
5823 return $cmd
5824}
5825
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005826proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10005827 global treediff treepending
Paul Mackerras219ea3a2006-09-07 10:21:39 +10005828
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005829 set treepending $ids
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005830 set treediff {}
Paul Mackerras8f489362007-07-13 19:49:37 +10005831 if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return
Paul Mackerrasd2610d12005-05-11 00:45:38 +00005832 fconfigure $gdtf -blocking 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005833 filerun $gdtf [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:38 +00005834}
5835
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005836proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005837 global treediff treediffs treepending diffids diffmergeid
Paul Mackerras74a40c72007-10-24 10:16:56 +10005838 global cmitmode viewfiles curview limitdiffs
Paul Mackerras3c461ff2005-07-20 09:13:46 -04005839
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005840 set nr 0
5841 while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
Paul Mackerras9396cd32007-06-23 20:28:15 +10005842 set i [string first "\t" $line]
5843 if {$i >= 0} {
5844 set file [string range $line [expr {$i+1}] end]
5845 if {[string index $file 0] eq "\""} {
5846 set file [lindex $file 0]
5847 }
5848 lappend treediff $file
5849 }
Paul Mackerrasd2610d12005-05-11 00:45:38 +00005850 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005851 if {![eof $gdtf]} {
5852 return [expr {$nr >= 1000? 2: 1}]
5853 }
5854 close $gdtf
Paul Mackerras74a40c72007-10-24 10:16:56 +10005855 if {$limitdiffs && $viewfiles($curview) ne {}} {
5856 set flist {}
5857 foreach f $treediff {
5858 if {[path_filter $viewfiles($curview) $f]} {
5859 lappend flist $f
5860 }
5861 }
5862 set treediffs($ids) $flist
5863 } else {
5864 set treediffs($ids) $treediff
5865 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005866 unset treepending
5867 if {$cmitmode eq "tree"} {
5868 gettree $diffids
5869 } elseif {$ids != $diffids} {
5870 if {![info exists diffmergeid]} {
5871 gettreediffs $diffids
5872 }
5873 } else {
5874 addtocflist $ids
5875 }
5876 return 0
Paul Mackerrasd2610d12005-05-11 00:45:38 +00005877}
5878
Steffen Prohaska890fae72007-08-12 12:05:46 +02005879# empty string or positive integer
5880proc diffcontextvalidate {v} {
5881 return [regexp {^(|[1-9][0-9]*)$} $v]
5882}
5883
5884proc diffcontextchange {n1 n2 op} {
5885 global diffcontextstring diffcontext
5886
5887 if {[string is integer -strict $diffcontextstring]} {
5888 if {$diffcontextstring > 0} {
5889 set diffcontext $diffcontextstring
5890 reselectline
5891 }
5892 }
5893}
5894
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005895proc getblobdiffs {ids} {
Paul Mackerras8d73b242007-10-06 20:22:00 +10005896 global blobdifffd diffids env
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005897 global diffinhdr treediffs
Steffen Prohaska890fae72007-08-12 12:05:46 +02005898 global diffcontext
Paul Mackerras7a39a172007-10-23 10:15:11 +10005899 global limitdiffs viewfiles curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005900
Paul Mackerras7a39a172007-10-23 10:15:11 +10005901 set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
5902 if {$limitdiffs && $viewfiles($curview) ne {}} {
Paul Mackerrasbd8f6772007-10-23 22:37:23 +10005903 set cmd [concat $cmd -- $viewfiles($curview)]
Paul Mackerras7a39a172007-10-23 10:15:11 +10005904 }
5905 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005906 puts "error getting diffs: $err"
5907 return
5908 }
Paul Mackerras4f2c2642005-07-17 11:11:44 -04005909 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005910 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005911 set blobdifffd($ids) $bdf
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005912 filerun $bdf [list getblobdiffline $bdf $diffids]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005913}
5914
Paul Mackerras89b11d32006-05-02 19:55:31 +10005915proc setinlist {var i val} {
5916 global $var
5917
5918 while {[llength [set $var]] < $i} {
5919 lappend $var {}
5920 }
5921 if {[llength [set $var]] == $i} {
5922 lappend $var $val
5923 } else {
5924 lset $var $i $val
5925 }
5926}
5927
Paul Mackerras9396cd32007-06-23 20:28:15 +10005928proc makediffhdr {fname ids} {
5929 global ctext curdiffstart treediffs
5930
5931 set i [lsearch -exact $treediffs($ids) $fname]
5932 if {$i >= 0} {
5933 setinlist difffilestart $i $curdiffstart
5934 }
5935 set l [expr {(78 - [string length $fname]) / 2}]
5936 set pad [string range "----------------------------------------" 1 $l]
5937 $ctext insert $curdiffstart "$pad $fname $pad" filesep
5938}
5939
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005940proc getblobdiffline {bdf ids} {
Paul Mackerras9396cd32007-06-23 20:28:15 +10005941 global diffids blobdifffd ctext curdiffstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04005942 global diffnexthead diffnextnote difffilestart
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005943 global diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10005944
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005945 set nr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005946 $ctext conf -state normal
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005947 while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
5948 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
5949 close $bdf
5950 return 0
Paul Mackerras89b11d32006-05-02 19:55:31 +10005951 }
Paul Mackerras9396cd32007-06-23 20:28:15 +10005952 if {![string compare -length 11 "diff --git " $line]} {
5953 # trim off "diff --git "
5954 set line [string range $line 11 end]
5955 set diffinhdr 1
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005956 # start of a new file
5957 $ctext insert end "\n"
Paul Mackerras9396cd32007-06-23 20:28:15 +10005958 set curdiffstart [$ctext index "end - 1c"]
5959 $ctext insert end "\n" filesep
5960 # If the name hasn't changed the length will be odd,
5961 # the middle char will be a space, and the two bits either
5962 # side will be a/name and b/name, or "a/name" and "b/name".
5963 # If the name has changed we'll get "rename from" and
Johannes Sixtd1cb2982007-08-16 14:32:29 +02005964 # "rename to" or "copy from" and "copy to" lines following this,
5965 # and we'll use them to get the filenames.
Paul Mackerras9396cd32007-06-23 20:28:15 +10005966 # This complexity is necessary because spaces in the filename(s)
5967 # don't get escaped.
5968 set l [string length $line]
5969 set i [expr {$l / 2}]
5970 if {!(($l & 1) && [string index $line $i] eq " " &&
5971 [string range $line 2 [expr {$i - 1}]] eq \
5972 [string range $line [expr {$i + 3}] end])} {
5973 continue
Paul Mackerras89b11d32006-05-02 19:55:31 +10005974 }
Paul Mackerras9396cd32007-06-23 20:28:15 +10005975 # unescape if quoted and chop off the a/ from the front
5976 if {[string index $line 0] eq "\""} {
5977 set fname [string range [lindex $line 0] 2 end]
5978 } else {
5979 set fname [string range $line 2 [expr {$i - 1}]]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00005980 }
Paul Mackerras9396cd32007-06-23 20:28:15 +10005981 makediffhdr $fname $ids
5982
5983 } elseif {[regexp {^@@ -([0-9]+)(,[0-9]+)? \+([0-9]+)(,[0-9]+)? @@(.*)} \
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10005984 $line match f1l f1c f2l f2c rest]} {
5985 $ctext insert end "$line\n" hunksep
5986 set diffinhdr 0
Paul Mackerras9396cd32007-06-23 20:28:15 +10005987
5988 } elseif {$diffinhdr} {
Johannes Sixt5e85ec42007-10-02 16:16:54 +02005989 if {![string compare -length 12 "rename from " $line]} {
Johannes Sixtd1cb2982007-08-16 14:32:29 +02005990 set fname [string range $line [expr 6 + [string first " from " $line] ] end]
Paul Mackerras9396cd32007-06-23 20:28:15 +10005991 if {[string index $fname 0] eq "\""} {
5992 set fname [lindex $fname 0]
5993 }
5994 set i [lsearch -exact $treediffs($ids) $fname]
5995 if {$i >= 0} {
5996 setinlist difffilestart $i $curdiffstart
5997 }
Johannes Sixtd1cb2982007-08-16 14:32:29 +02005998 } elseif {![string compare -length 10 $line "rename to "] ||
5999 ![string compare -length 8 $line "copy to "]} {
6000 set fname [string range $line [expr 4 + [string first " to " $line] ] end]
Paul Mackerras9396cd32007-06-23 20:28:15 +10006001 if {[string index $fname 0] eq "\""} {
6002 set fname [lindex $fname 0]
6003 }
6004 makediffhdr $fname $ids
6005 } elseif {[string compare -length 3 $line "---"] == 0} {
6006 # do nothing
6007 continue
6008 } elseif {[string compare -length 3 $line "+++"] == 0} {
6009 set diffinhdr 0
6010 continue
6011 }
6012 $ctext insert end "$line\n" filesep
6013
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006014 } else {
6015 set x [string range $line 0 0]
6016 if {$x == "-" || $x == "+"} {
6017 set tag [expr {$x == "+"}]
6018 $ctext insert end "$line\n" d$tag
6019 } elseif {$x == " "} {
6020 $ctext insert end "$line\n"
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006021 } else {
Paul Mackerras9396cd32007-06-23 20:28:15 +10006022 # "\ No newline at end of file",
6023 # or something else we don't recognize
6024 $ctext insert end "$line\n" hunksep
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006025 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00006026 }
6027 }
6028 $ctext conf -state disabled
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006029 if {[eof $bdf]} {
6030 close $bdf
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006031 return 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006032 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10006033 return [expr {$nr >= 1000? 2: 1}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00006034}
6035
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10006036proc changediffdisp {} {
6037 global ctext diffelide
6038
6039 $ctext tag conf d0 -elide [lindex $diffelide 0]
6040 $ctext tag conf d1 -elide [lindex $diffelide 1]
6041}
6042
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09006043proc prevfile {} {
6044 global difffilestart ctext
6045 set prev [lindex $difffilestart 0]
6046 set here [$ctext index @0,0]
6047 foreach loc $difffilestart {
6048 if {[$ctext compare $loc >= $here]} {
6049 $ctext yview $prev
6050 return
6051 }
6052 set prev $loc
6053 }
6054 $ctext yview $prev
6055}
6056
Paul Mackerras39ad8572005-05-19 12:35:53 +00006057proc nextfile {} {
6058 global difffilestart ctext
6059 set here [$ctext index @0,0]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10006060 foreach loc $difffilestart {
6061 if {[$ctext compare $loc > $here]} {
6062 $ctext yview $loc
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09006063 return
Paul Mackerras39ad8572005-05-19 12:35:53 +00006064 }
6065 }
Paul Mackerras1db95b02005-05-09 04:08:39 +00006066}
6067
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006068proc clear_ctext {{first 1.0}} {
6069 global ctext smarktop smarkbot
Paul Mackerras97645682007-08-23 22:24:38 +10006070 global pendinglinks
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006071
Paul Mackerras1902c272006-05-25 21:25:13 +10006072 set l [lindex [split $first .] 0]
6073 if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
6074 set smarktop $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006075 }
Paul Mackerras1902c272006-05-25 21:25:13 +10006076 if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
6077 set smarkbot $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006078 }
6079 $ctext delete $first end
Paul Mackerras97645682007-08-23 22:24:38 +10006080 if {$first eq "1.0"} {
6081 catch {unset pendinglinks}
6082 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006083}
6084
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006085proc settabs {{firstab {}}} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10006086 global firsttabstop tabstop ctext have_tk85
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006087
6088 if {$firstab ne {} && $have_tk85} {
6089 set firsttabstop $firstab
6090 }
Paul Mackerras9c311b32007-10-04 22:27:13 +10006091 set w [font measure textfont "0"]
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006092 if {$firsttabstop != 0} {
Paul Mackerras64b5f142007-10-04 22:19:24 +10006093 $ctext conf -tabs [list [expr {($firsttabstop + $tabstop) * $w}] \
6094 [expr {($firsttabstop + 2 * $tabstop) * $w}]]
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006095 } elseif {$have_tk85 || $tabstop != 8} {
6096 $ctext conf -tabs [expr {$tabstop * $w}]
6097 } else {
6098 $ctext conf -tabs {}
6099 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006100}
6101
6102proc incrsearch {name ix op} {
Paul Mackerras1902c272006-05-25 21:25:13 +10006103 global ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006104
6105 $ctext tag remove found 1.0 end
Paul Mackerras1902c272006-05-25 21:25:13 +10006106 if {[catch {$ctext index anchor}]} {
6107 # no anchor set, use start of selection, or of visible area
6108 set sel [$ctext tag ranges sel]
6109 if {$sel ne {}} {
6110 $ctext mark set anchor [lindex $sel 0]
6111 } elseif {$searchdirn eq "-forwards"} {
6112 $ctext mark set anchor @0,0
6113 } else {
6114 $ctext mark set anchor @0,[winfo height $ctext]
6115 }
6116 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006117 if {$searchstring ne {}} {
Paul Mackerras1902c272006-05-25 21:25:13 +10006118 set here [$ctext search $searchdirn -- $searchstring anchor]
6119 if {$here ne {}} {
6120 $ctext see $here
6121 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006122 searchmarkvisible 1
6123 }
6124}
6125
6126proc dosearch {} {
Paul Mackerras1902c272006-05-25 21:25:13 +10006127 global sstring ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006128
6129 focus $sstring
6130 $sstring icursor end
Paul Mackerras1902c272006-05-25 21:25:13 +10006131 set searchdirn -forwards
6132 if {$searchstring ne {}} {
6133 set sel [$ctext tag ranges sel]
6134 if {$sel ne {}} {
6135 set start "[lindex $sel 0] + 1c"
6136 } elseif {[catch {set start [$ctext index anchor]}]} {
6137 set start "@0,0"
6138 }
6139 set match [$ctext search -count mlen -- $searchstring $start]
6140 $ctext tag remove sel 1.0 end
6141 if {$match eq {}} {
6142 bell
6143 return
6144 }
6145 $ctext see $match
6146 set mend "$match + $mlen c"
6147 $ctext tag add sel $match $mend
6148 $ctext mark unset anchor
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006149 }
Paul Mackerras1902c272006-05-25 21:25:13 +10006150}
6151
6152proc dosearchback {} {
6153 global sstring ctext searchstring searchdirn
6154
6155 focus $sstring
6156 $sstring icursor end
6157 set searchdirn -backwards
6158 if {$searchstring ne {}} {
6159 set sel [$ctext tag ranges sel]
6160 if {$sel ne {}} {
6161 set start [lindex $sel 0]
6162 } elseif {[catch {set start [$ctext index anchor]}]} {
6163 set start @0,[winfo height $ctext]
6164 }
6165 set match [$ctext search -backwards -count ml -- $searchstring $start]
6166 $ctext tag remove sel 1.0 end
6167 if {$match eq {}} {
6168 bell
6169 return
6170 }
6171 $ctext see $match
6172 set mend "$match + $ml c"
6173 $ctext tag add sel $match $mend
6174 $ctext mark unset anchor
6175 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006176}
6177
6178proc searchmark {first last} {
6179 global ctext searchstring
6180
6181 set mend $first.0
6182 while {1} {
6183 set match [$ctext search -count mlen -- $searchstring $mend $last.end]
6184 if {$match eq {}} break
6185 set mend "$match + $mlen c"
6186 $ctext tag add found $match $mend
6187 }
6188}
6189
6190proc searchmarkvisible {doall} {
6191 global ctext smarktop smarkbot
6192
6193 set topline [lindex [split [$ctext index @0,0] .] 0]
6194 set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
6195 if {$doall || $botline < $smarktop || $topline > $smarkbot} {
6196 # no overlap with previous
6197 searchmark $topline $botline
6198 set smarktop $topline
6199 set smarkbot $botline
6200 } else {
6201 if {$topline < $smarktop} {
6202 searchmark $topline [expr {$smarktop-1}]
6203 set smarktop $topline
6204 }
6205 if {$botline > $smarkbot} {
6206 searchmark [expr {$smarkbot+1}] $botline
6207 set smarkbot $botline
6208 }
6209 }
6210}
6211
6212proc scrolltext {f0 f1} {
Paul Mackerras1902c272006-05-25 21:25:13 +10006213 global searchstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006214
Junio C Hamanoe9937d22007-02-01 08:46:38 -05006215 .bleft.sb set $f0 $f1
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006216 if {$searchstring ne {}} {
6217 searchmarkvisible 0
6218 }
6219}
6220
Paul Mackerras1d10f362005-05-15 12:55:47 +00006221proc setcoords {} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10006222 global linespc charspc canvx0 canvy0
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10006223 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-05 09:52:16 +10006224
Paul Mackerras9c311b32007-10-04 22:27:13 +10006225 set linespc [font metrics mainfont -linespace]
6226 set charspc [font measure mainfont "m"]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006227 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
6228 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10006229 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-05 09:52:16 +10006230 set xspc1(0) $linespc
6231 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:16 +00006232}
Paul Mackerras1db95b02005-05-09 04:08:39 +00006233
Paul Mackerras1d10f362005-05-15 12:55:47 +00006234proc redisplay {} {
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11006235 global canv
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006236 global selectedline
6237
6238 set ymax [lindex [$canv cget -scrollregion] 3]
6239 if {$ymax eq {} || $ymax == 0} return
6240 set span [$canv yview]
6241 clear_display
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11006242 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006243 allcanvs yview moveto [lindex $span 0]
6244 drawvisible
6245 if {[info exists selectedline]} {
6246 selectline $selectedline 0
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006247 allcanvs yview moveto [lindex $span 0]
Paul Mackerras1db95b02005-05-09 04:08:39 +00006248 }
6249}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006250
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006251proc parsefont {f n} {
6252 global fontattr
6253
6254 set fontattr($f,family) [lindex $n 0]
6255 set s [lindex $n 1]
6256 if {$s eq {} || $s == 0} {
6257 set s 10
6258 } elseif {$s < 0} {
6259 set s [expr {int(-$s / [winfo fpixels . 1p] + 0.5)}]
Paul Mackerras9c311b32007-10-04 22:27:13 +10006260 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006261 set fontattr($f,size) $s
6262 set fontattr($f,weight) normal
6263 set fontattr($f,slant) roman
6264 foreach style [lrange $n 2 end] {
6265 switch -- $style {
6266 "normal" -
6267 "bold" {set fontattr($f,weight) $style}
6268 "roman" -
6269 "italic" {set fontattr($f,slant) $style}
6270 }
Paul Mackerras9c311b32007-10-04 22:27:13 +10006271 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006272}
6273
6274proc fontflags {f {isbold 0}} {
6275 global fontattr
6276
6277 return [list -family $fontattr($f,family) -size $fontattr($f,size) \
6278 -weight [expr {$isbold? "bold": $fontattr($f,weight)}] \
6279 -slant $fontattr($f,slant)]
6280}
6281
6282proc fontname {f} {
6283 global fontattr
6284
6285 set n [list $fontattr($f,family) $fontattr($f,size)]
6286 if {$fontattr($f,weight) eq "bold"} {
6287 lappend n "bold"
Paul Mackerras9c311b32007-10-04 22:27:13 +10006288 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006289 if {$fontattr($f,slant) eq "italic"} {
6290 lappend n "italic"
Paul Mackerras9c311b32007-10-04 22:27:13 +10006291 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006292 return $n
Paul Mackerras9c311b32007-10-04 22:27:13 +10006293}
6294
Paul Mackerras1d10f362005-05-15 12:55:47 +00006295proc incrfont {inc} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006296 global mainfont textfont ctext canv cflist showrefstop
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006297 global stopped entries fontattr
6298
Paul Mackerras1d10f362005-05-15 12:55:47 +00006299 unmarkmatches
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006300 set s $fontattr(mainfont,size)
Paul Mackerras9c311b32007-10-04 22:27:13 +10006301 incr s $inc
6302 if {$s < 1} {
6303 set s 1
6304 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006305 set fontattr(mainfont,size) $s
Paul Mackerras9c311b32007-10-04 22:27:13 +10006306 font config mainfont -size $s
6307 font config mainfontbold -size $s
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006308 set mainfont [fontname mainfont]
6309 set s $fontattr(textfont,size)
Paul Mackerras9c311b32007-10-04 22:27:13 +10006310 incr s $inc
6311 if {$s < 1} {
6312 set s 1
6313 }
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006314 set fontattr(textfont,size) $s
Paul Mackerras9c311b32007-10-04 22:27:13 +10006315 font config textfont -size $s
6316 font config textfontbold -size $s
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10006317 set textfont [fontname textfont]
Paul Mackerras1d10f362005-05-15 12:55:47 +00006318 setcoords
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006319 settabs
Paul Mackerras1d10f362005-05-15 12:55:47 +00006320 redisplay
Paul Mackerras1db95b02005-05-09 04:08:39 +00006321}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006322
Paul Mackerrasee3dc722005-06-25 16:37:13 +10006323proc clearsha1 {} {
6324 global sha1entry sha1string
6325 if {[string length $sha1string] == 40} {
6326 $sha1entry delete 0 end
6327 }
6328}
6329
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006330proc sha1change {n1 n2 op} {
6331 global sha1string currentid sha1but
6332 if {$sha1string == {}
6333 || ([info exists currentid] && $sha1string == $currentid)} {
6334 set state disabled
6335 } else {
6336 set state normal
6337 }
6338 if {[$sha1but cget -state] == $state} return
6339 if {$state == "normal"} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006340 $sha1but conf -state normal -relief raised -text "[mc "Goto:"] "
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006341 } else {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006342 $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] "
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006343 }
6344}
6345
6346proc gotocommit {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006347 global sha1string tagids headids curview varcid
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006348
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006349 if {$sha1string == {}
6350 || ([info exists currentid] && $sha1string == $currentid)} return
6351 if {[info exists tagids($sha1string)]} {
6352 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 16:13:12 +11006353 } elseif {[info exists headids($sha1string)]} {
6354 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006355 } else {
6356 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006357 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006358 set matches [array names varcid "$curview,$id*"]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006359 if {$matches ne {}} {
6360 if {[llength $matches] > 1} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006361 error_popup [mc "Short SHA1 id %s is ambiguous" $id]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006362 return
6363 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006364 set id [lindex [split [lindex $matches 0] ","] 1]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006365 }
6366 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006367 }
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006368 if {[commitinview $id $curview]} {
6369 selectline [rowofcommit $id] 1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006370 return
6371 }
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04006372 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006373 set msg [mc "SHA1 id %s is not known" $sha1string]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006374 } else {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006375 set msg [mc "Tag/Head %s is not known" $sha1string]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006376 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01006377 error_popup $msg
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006378}
6379
Paul Mackerras84ba7342005-06-17 00:12:26 +00006380proc lineenter {x y id} {
6381 global hoverx hovery hoverid hovertimer
6382 global commitinfo canv
6383
Paul Mackerras8ed16482006-03-02 22:56:44 +11006384 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:26 +00006385 set hoverx $x
6386 set hovery $y
6387 set hoverid $id
6388 if {[info exists hovertimer]} {
6389 after cancel $hovertimer
6390 }
6391 set hovertimer [after 500 linehover]
6392 $canv delete hover
6393}
6394
6395proc linemotion {x y id} {
6396 global hoverx hovery hoverid hovertimer
6397
6398 if {[info exists hoverid] && $id == $hoverid} {
6399 set hoverx $x
6400 set hovery $y
6401 if {[info exists hovertimer]} {
6402 after cancel $hovertimer
6403 }
6404 set hovertimer [after 500 linehover]
6405 }
6406}
6407
6408proc lineleave {id} {
6409 global hoverid hovertimer canv
6410
6411 if {[info exists hoverid] && $id == $hoverid} {
6412 $canv delete hover
6413 if {[info exists hovertimer]} {
6414 after cancel $hovertimer
6415 unset hovertimer
6416 }
6417 unset hoverid
6418 }
6419}
6420
6421proc linehover {} {
6422 global hoverx hovery hoverid hovertimer
6423 global canv linespc lthickness
Paul Mackerras9c311b32007-10-04 22:27:13 +10006424 global commitinfo
Paul Mackerras84ba7342005-06-17 00:12:26 +00006425
6426 set text [lindex $commitinfo($hoverid) 0]
6427 set ymax [lindex [$canv cget -scrollregion] 3]
6428 if {$ymax == {}} return
6429 set yfrac [lindex [$canv yview] 0]
6430 set x [expr {$hoverx + 2 * $linespc}]
6431 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
6432 set x0 [expr {$x - 2 * $lthickness}]
6433 set y0 [expr {$y - 2 * $lthickness}]
Paul Mackerras9c311b32007-10-04 22:27:13 +10006434 set x1 [expr {$x + [font measure mainfont $text] + 2 * $lthickness}]
Paul Mackerras84ba7342005-06-17 00:12:26 +00006435 set y1 [expr {$y + $linespc + 2 * $lthickness}]
6436 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
6437 -fill \#ffff80 -outline black -width 1 -tags hover]
6438 $canv raise $t
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10006439 set t [$canv create text $x $y -anchor nw -text $text -tags hover \
Paul Mackerras9c311b32007-10-04 22:27:13 +10006440 -font mainfont]
Paul Mackerras84ba7342005-06-17 00:12:26 +00006441 $canv raise $t
6442}
6443
Paul Mackerras9843c302005-08-30 10:57:11 +10006444proc clickisonarrow {id y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006445 global lthickness
Paul Mackerras9843c302005-08-30 10:57:11 +10006446
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006447 set ranges [rowranges $id]
Paul Mackerras9843c302005-08-30 10:57:11 +10006448 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006449 set n [expr {[llength $ranges] - 1}]
Paul Mackerrasf6342482006-02-28 10:02:03 +11006450 for {set i 1} {$i < $n} {incr i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006451 set row [lindex $ranges $i]
Paul Mackerrasf6342482006-02-28 10:02:03 +11006452 if {abs([yc $row] - $y) < $thresh} {
6453 return $i
Paul Mackerras9843c302005-08-30 10:57:11 +10006454 }
6455 }
6456 return {}
6457}
6458
Paul Mackerrasf6342482006-02-28 10:02:03 +11006459proc arrowjump {id n y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006460 global canv
Paul Mackerras9843c302005-08-30 10:57:11 +10006461
Paul Mackerrasf6342482006-02-28 10:02:03 +11006462 # 1 <-> 2, 3 <-> 4, etc...
6463 set n [expr {(($n - 1) ^ 1) + 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006464 set row [lindex [rowranges $id] $n]
Paul Mackerrasf6342482006-02-28 10:02:03 +11006465 set yt [yc $row]
Paul Mackerras9843c302005-08-30 10:57:11 +10006466 set ymax [lindex [$canv cget -scrollregion] 3]
6467 if {$ymax eq {} || $ymax <= 0} return
6468 set view [$canv yview]
6469 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
6470 set yfrac [expr {$yt / $ymax - $yspan / 2}]
6471 if {$yfrac < 0} {
6472 set yfrac 0
6473 }
Paul Mackerrasf6342482006-02-28 10:02:03 +11006474 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 10:57:11 +10006475}
6476
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006477proc lineclick {x y id isnew} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006478 global ctext commitinfo children canv thickerline curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006479
Paul Mackerras8ed16482006-03-02 22:56:44 +11006480 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006481 unmarkmatches
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006482 unselectline
Paul Mackerras9843c302005-08-30 10:57:11 +10006483 normalline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006484 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10006485 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 10:57:11 +10006486 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11006487 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10006488 if {$isnew} {
6489 set ymax [lindex [$canv cget -scrollregion] 3]
6490 if {$ymax eq {}} return
6491 set yfrac [lindex [$canv yview] 0]
6492 set y [expr {$y + $yfrac * $ymax}]
6493 }
6494 set dirn [clickisonarrow $id $y]
6495 if {$dirn ne {}} {
6496 arrowjump $id $dirn $y
6497 return
6498 }
6499
6500 if {$isnew} {
6501 addtohistory [list lineclick $x $y $id 0]
6502 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006503 # fill the details pane with info about this line
6504 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006505 clear_ctext
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10006506 settabs 0
Christian Stimmingd990ced2007-11-07 18:42:55 +01006507 $ctext insert end "[mc "Parent"]:\t"
Paul Mackerras97645682007-08-23 22:24:38 +10006508 $ctext insert end $id link0
6509 setlink $id link0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006510 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006511 $ctext insert end "\n\t[lindex $info 0]\n"
Christian Stimmingd990ced2007-11-07 18:42:55 +01006512 $ctext insert end "\t[mc "Author"]:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11006513 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 18:42:55 +01006514 $ctext insert end "\t[mc "Date"]:\t$date\n"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006515 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10006516 if {$kids ne {}} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006517 $ctext insert end "\n[mc "Children"]:"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006518 set i 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10006519 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006520 incr i
Paul Mackerras8ed16482006-03-02 22:56:44 +11006521 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006522 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006523 $ctext insert end "\n\t"
Paul Mackerras97645682007-08-23 22:24:38 +10006524 $ctext insert end $child link$i
6525 setlink $child link$i
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006526 $ctext insert end "\n\t[lindex $info 0]"
Christian Stimmingd990ced2007-11-07 18:42:55 +01006527 $ctext insert end "\n\t[mc "Author"]:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-15 10:34:03 +11006528 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 18:42:55 +01006529 $ctext insert end "\n\t[mc "Date"]:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006530 }
6531 }
6532 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10006533 init_flist {}
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006534}
6535
Paul Mackerras9843c302005-08-30 10:57:11 +10006536proc normalline {} {
6537 global thickerline
6538 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11006539 set id $thickerline
Paul Mackerras9843c302005-08-30 10:57:11 +10006540 unset thickerline
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11006541 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10006542 }
6543}
6544
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006545proc selbyid {id} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006546 global curview
6547 if {[commitinview $id $curview]} {
6548 selectline [rowofcommit $id] 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006549 }
6550}
6551
6552proc mstime {} {
6553 global startmstime
6554 if {![info exists startmstime]} {
6555 set startmstime [clock clicks -milliseconds]
6556 }
6557 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
6558}
6559
6560proc rowmenu {x y id} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006561 global rowctxmenu selectedline rowmenuid curview
Paul Mackerras8f489362007-07-13 19:49:37 +10006562 global nullid nullid2 fakerowmenu mainhead
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006563
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10006564 stopfinding
Paul Mackerras219ea3a2006-09-07 10:21:39 +10006565 set rowmenuid $id
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006566 if {![info exists selectedline]
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006567 || [rowofcommit $id] eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006568 set state disabled
6569 } else {
6570 set state normal
6571 }
Paul Mackerras8f489362007-07-13 19:49:37 +10006572 if {$id ne $nullid && $id ne $nullid2} {
Paul Mackerras219ea3a2006-09-07 10:21:39 +10006573 set menu $rowctxmenu
Christian Stimmingd990ced2007-11-07 18:42:55 +01006574 $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10006575 } else {
6576 set menu $fakerowmenu
6577 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01006578 $menu entryconfigure [mc "Diff this -> selected"] -state $state
6579 $menu entryconfigure [mc "Diff selected -> this"] -state $state
6580 $menu entryconfigure [mc "Make patch"] -state $state
Paul Mackerras219ea3a2006-09-07 10:21:39 +10006581 tk_popup $menu $x $y
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006582}
6583
6584proc diffvssel {dirn} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006585 global rowmenuid selectedline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006586
6587 if {![info exists selectedline]} return
6588 if {$dirn} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006589 set oldid [commitonrow $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006590 set newid $rowmenuid
6591 } else {
6592 set oldid $rowmenuid
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006593 set newid [commitonrow $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006594 }
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006595 addtohistory [list doseldiff $oldid $newid]
6596 doseldiff $oldid $newid
6597}
6598
6599proc doseldiff {oldid newid} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10006600 global ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006601 global commitinfo
6602
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006603 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10006604 clear_ctext
Christian Stimmingd990ced2007-11-07 18:42:55 +01006605 init_flist [mc "Top"]
6606 $ctext insert end "[mc "From"] "
Paul Mackerras97645682007-08-23 22:24:38 +10006607 $ctext insert end $oldid link0
6608 setlink $oldid link0
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006609 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006610 $ctext insert end [lindex $commitinfo($oldid) 0]
Christian Stimmingd990ced2007-11-07 18:42:55 +01006611 $ctext insert end "\n\n[mc "To"] "
Paul Mackerras97645682007-08-23 22:24:38 +10006612 $ctext insert end $newid link1
6613 setlink $newid link1
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10006614 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006615 $ctext insert end [lindex $commitinfo($newid) 0]
6616 $ctext insert end "\n"
6617 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006618 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 20:41:56 +11006619 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10006620}
6621
Paul Mackerras74daedb2005-06-27 19:27:32 +10006622proc mkpatch {} {
6623 global rowmenuid currentid commitinfo patchtop patchnum
6624
6625 if {![info exists currentid]} return
6626 set oldid $currentid
6627 set oldhead [lindex $commitinfo($oldid) 0]
6628 set newid $rowmenuid
6629 set newhead [lindex $commitinfo($newid) 0]
6630 set top .patch
6631 set patchtop $top
6632 catch {destroy $top}
6633 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01006634 label $top.title -text [mc "Generate patch"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006635 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006636 label $top.from -text [mc "From:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006637 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10006638 $top.fromsha1 insert 0 $oldid
6639 $top.fromsha1 conf -state readonly
6640 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006641 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10006642 $top.fromhead insert 0 $oldhead
6643 $top.fromhead conf -state readonly
6644 grid x $top.fromhead -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01006645 label $top.to -text [mc "To:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006646 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10006647 $top.tosha1 insert 0 $newid
6648 $top.tosha1 conf -state readonly
6649 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006650 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10006651 $top.tohead insert 0 $newhead
6652 $top.tohead conf -state readonly
6653 grid x $top.tohead -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01006654 button $top.rev -text [mc "Reverse"] -command mkpatchrev -padx 5
Paul Mackerras74daedb2005-06-27 19:27:32 +10006655 grid $top.rev x -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006656 label $top.flab -text [mc "Output file:"]
Paul Mackerras74daedb2005-06-27 19:27:32 +10006657 entry $top.fname -width 60
6658 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
6659 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006660 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 19:27:32 +10006661 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01006662 button $top.buts.gen -text [mc "Generate"] -command mkpatchgo
6663 button $top.buts.can -text [mc "Cancel"] -command mkpatchcan
Paul Mackerras74daedb2005-06-27 19:27:32 +10006664 grid $top.buts.gen $top.buts.can
6665 grid columnconfigure $top.buts 0 -weight 1 -uniform a
6666 grid columnconfigure $top.buts 1 -weight 1 -uniform a
6667 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006668 focus $top.fname
Paul Mackerras74daedb2005-06-27 19:27:32 +10006669}
6670
6671proc mkpatchrev {} {
6672 global patchtop
6673
6674 set oldid [$patchtop.fromsha1 get]
6675 set oldhead [$patchtop.fromhead get]
6676 set newid [$patchtop.tosha1 get]
6677 set newhead [$patchtop.tohead get]
6678 foreach e [list fromsha1 fromhead tosha1 tohead] \
6679 v [list $newid $newhead $oldid $oldhead] {
6680 $patchtop.$e conf -state normal
6681 $patchtop.$e delete 0 end
6682 $patchtop.$e insert 0 $v
6683 $patchtop.$e conf -state readonly
6684 }
6685}
6686
6687proc mkpatchgo {} {
Paul Mackerras8f489362007-07-13 19:49:37 +10006688 global patchtop nullid nullid2
Paul Mackerras74daedb2005-06-27 19:27:32 +10006689
6690 set oldid [$patchtop.fromsha1 get]
6691 set newid [$patchtop.tosha1 get]
6692 set fname [$patchtop.fname get]
Paul Mackerras8f489362007-07-13 19:49:37 +10006693 set cmd [diffcmd [list $oldid $newid] -p]
Paul Mackerrasd372e212007-09-15 12:08:38 +10006694 # trim off the initial "|"
6695 set cmd [lrange $cmd 1 end]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10006696 lappend cmd >$fname &
6697 if {[catch {eval exec $cmd} err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006698 error_popup "[mc "Error creating patch:"] $err"
Paul Mackerras74daedb2005-06-27 19:27:32 +10006699 }
6700 catch {destroy $patchtop}
6701 unset patchtop
6702}
6703
6704proc mkpatchcan {} {
6705 global patchtop
6706
6707 catch {destroy $patchtop}
6708 unset patchtop
6709}
6710
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006711proc mktag {} {
6712 global rowmenuid mktagtop commitinfo
6713
6714 set top .maketag
6715 set mktagtop $top
6716 catch {destroy $top}
6717 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01006718 label $top.title -text [mc "Create tag"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006719 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006720 label $top.id -text [mc "ID:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006721 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006722 $top.sha1 insert 0 $rowmenuid
6723 $top.sha1 conf -state readonly
6724 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006725 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006726 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
6727 $top.head conf -state readonly
6728 grid x $top.head -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01006729 label $top.tlab -text [mc "Tag name:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006730 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006731 grid $top.tlab $top.tag -sticky w
6732 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01006733 button $top.buts.gen -text [mc "Create"] -command mktaggo
6734 button $top.buts.can -text [mc "Cancel"] -command mktagcan
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006735 grid $top.buts.gen $top.buts.can
6736 grid columnconfigure $top.buts 0 -weight 1 -uniform a
6737 grid columnconfigure $top.buts 1 -weight 1 -uniform a
6738 grid $top.buts - -pady 10 -sticky ew
6739 focus $top.tag
6740}
6741
6742proc domktag {} {
6743 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006744
6745 set id [$mktagtop.sha1 get]
6746 set tag [$mktagtop.tag get]
6747 if {$tag == {}} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006748 error_popup [mc "No tag name specified"]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006749 return
6750 }
6751 if {[info exists tagids($tag)]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006752 error_popup [mc "Tag \"%s\" already exists" $tag]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006753 return
6754 }
6755 if {[catch {
Junio C Hamano73b6a6c2005-07-28 00:28:44 -07006756 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006757 set fname [file join $dir "refs/tags" $tag]
6758 set f [open $fname w]
6759 puts $f $id
6760 close $f
6761 } err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006762 error_popup "[mc "Error creating tag:"] $err"
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006763 return
6764 }
6765
6766 set tagids($tag) $id
6767 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10006768 redrawtags $id
Paul Mackerrasceadfe92006-08-08 20:55:36 +10006769 addedtag $id
Paul Mackerras887c9962007-08-20 19:36:20 +10006770 dispneartags 0
6771 run refill_reflist
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10006772}
6773
6774proc redrawtags {id} {
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11006775 global canv linehtag idpos currentid curview
Paul Mackerras9c311b32007-10-04 22:27:13 +10006776 global canvxmax iddrawn
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10006777
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006778 if {![commitinview $id $curview]} return
Paul Mackerras322a8cc2006-10-15 18:03:46 +10006779 if {![info exists iddrawn($id)]} return
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11006780 set row [rowofcommit $id]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006781 $canv delete tag.$id
6782 set xt [eval drawtags $id $idpos($id)]
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11006783 $canv coords $linehtag($row) $xt [lindex $idpos($id) 2]
6784 set text [$canv itemcget $linehtag($row) -text]
6785 set font [$canv itemcget $linehtag($row) -font]
6786 set xr [expr {$xt + [font measure $font $text]}]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10006787 if {$xr > $canvxmax} {
6788 set canvxmax $xr
6789 setcanvscroll
6790 }
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11006791 if {[info exists currentid] && $currentid == $id} {
6792 make_secsel $row
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10006793 }
6794}
6795
6796proc mktagcan {} {
6797 global mktagtop
6798
6799 catch {destroy $mktagtop}
6800 unset mktagtop
6801}
6802
6803proc mktaggo {} {
6804 domktag
6805 mktagcan
6806}
6807
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006808proc writecommit {} {
6809 global rowmenuid wrcomtop commitinfo wrcomcmd
6810
6811 set top .writecommit
6812 set wrcomtop $top
6813 catch {destroy $top}
6814 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01006815 label $top.title -text [mc "Write commit to file"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006816 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006817 label $top.id -text [mc "ID:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006818 entry $top.sha1 -width 40 -relief flat
6819 $top.sha1 insert 0 $rowmenuid
6820 $top.sha1 conf -state readonly
6821 grid $top.id $top.sha1 -sticky w
6822 entry $top.head -width 60 -relief flat
6823 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
6824 $top.head conf -state readonly
6825 grid x $top.head -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01006826 label $top.clab -text [mc "Command:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006827 entry $top.cmd -width 60 -textvariable wrcomcmd
6828 grid $top.clab $top.cmd -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006829 label $top.flab -text [mc "Output file:"]
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006830 entry $top.fname -width 60
6831 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
6832 grid $top.flab $top.fname -sticky w
6833 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01006834 button $top.buts.gen -text [mc "Write"] -command wrcomgo
6835 button $top.buts.can -text [mc "Cancel"] -command wrcomcan
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006836 grid $top.buts.gen $top.buts.can
6837 grid columnconfigure $top.buts 0 -weight 1 -uniform a
6838 grid columnconfigure $top.buts 1 -weight 1 -uniform a
6839 grid $top.buts - -pady 10 -sticky ew
6840 focus $top.fname
6841}
6842
6843proc wrcomgo {} {
6844 global wrcomtop
6845
6846 set id [$wrcomtop.sha1 get]
6847 set cmd "echo $id | [$wrcomtop.cmd get]"
6848 set fname [$wrcomtop.fname get]
6849 if {[catch {exec sh -c $cmd >$fname &} err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006850 error_popup "[mc "Error writing commit:"] $err"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10006851 }
6852 catch {destroy $wrcomtop}
6853 unset wrcomtop
6854}
6855
6856proc wrcomcan {} {
6857 global wrcomtop
6858
6859 catch {destroy $wrcomtop}
6860 unset wrcomtop
6861}
6862
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006863proc mkbranch {} {
6864 global rowmenuid mkbrtop
6865
6866 set top .makebranch
6867 catch {destroy $top}
6868 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01006869 label $top.title -text [mc "Create new branch"]
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006870 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01006871 label $top.id -text [mc "ID:"]
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006872 entry $top.sha1 -width 40 -relief flat
6873 $top.sha1 insert 0 $rowmenuid
6874 $top.sha1 conf -state readonly
6875 grid $top.id $top.sha1 -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01006876 label $top.nlab -text [mc "Name:"]
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006877 entry $top.name -width 40
6878 grid $top.nlab $top.name -sticky w
6879 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01006880 button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
6881 button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}"
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006882 grid $top.buts.go $top.buts.can
6883 grid columnconfigure $top.buts 0 -weight 1 -uniform a
6884 grid columnconfigure $top.buts 1 -weight 1 -uniform a
6885 grid $top.buts - -pady 10 -sticky ew
6886 focus $top.name
6887}
6888
6889proc mkbrgo {top} {
6890 global headids idheads
6891
6892 set name [$top.name get]
6893 set id [$top.sha1 get]
6894 if {$name eq {}} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006895 error_popup [mc "Please specify a name for the new branch"]
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006896 return
6897 }
6898 catch {destroy $top}
6899 nowbusy newbranch
6900 update
6901 if {[catch {
6902 exec git branch $name $id
6903 } err]} {
6904 notbusy newbranch
6905 error_popup $err
6906 } else {
Paul Mackerrase11f1232007-06-16 20:29:25 +10006907 set headids($name) $id
6908 lappend idheads($id) $name
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006909 addedhead $id $name
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006910 notbusy newbranch
6911 redrawtags $id
Paul Mackerrase11f1232007-06-16 20:29:25 +10006912 dispneartags 0
Paul Mackerras887c9962007-08-20 19:36:20 +10006913 run refill_reflist
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10006914 }
6915}
6916
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006917proc cherrypick {} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006918 global rowmenuid curview
Paul Mackerrase11f1232007-06-16 20:29:25 +10006919 global mainhead
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006920
Paul Mackerrase11f1232007-06-16 20:29:25 +10006921 set oldhead [exec git rev-parse HEAD]
6922 set dheads [descheads $rowmenuid]
6923 if {$dheads ne {} && [lsearch -exact $dheads $oldhead] >= 0} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01006924 set ok [confirm_popup [mc "Commit %s is already\
6925 included in branch %s -- really re-apply it?" \
6926 [string range $rowmenuid 0 7] $mainhead]]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006927 if {!$ok} return
6928 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01006929 nowbusy cherrypick [mc "Cherry-picking"]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006930 update
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006931 # Unfortunately git-cherry-pick writes stuff to stderr even when
6932 # no error occurs, and exec takes that as an indication of error...
6933 if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
6934 notbusy cherrypick
6935 error_popup $err
6936 return
6937 }
6938 set newhead [exec git rev-parse HEAD]
6939 if {$newhead eq $oldhead} {
6940 notbusy cherrypick
Christian Stimmingd990ced2007-11-07 18:42:55 +01006941 error_popup [mc "No changes committed"]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006942 return
6943 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10006944 addnewchild $newhead $oldhead
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11006945 if {[commitinview $oldhead $curview]} {
6946 insertrow $newhead $oldhead $curview
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006947 if {$mainhead ne {}} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10006948 movehead $newhead $mainhead
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10006949 movedhead $newhead $mainhead
6950 }
6951 redrawtags $oldhead
6952 redrawtags $newhead
6953 }
6954 notbusy cherrypick
6955}
6956
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006957proc resethead {} {
6958 global mainheadid mainhead rowmenuid confirm_ok resettype
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006959
6960 set confirm_ok 0
6961 set w ".confirmreset"
6962 toplevel $w
6963 wm transient $w .
Christian Stimmingd990ced2007-11-07 18:42:55 +01006964 wm title $w [mc "Confirm reset"]
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006965 message $w.m -text \
Christian Stimmingd990ced2007-11-07 18:42:55 +01006966 [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]] \
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006967 -justify center -aspect 1000
6968 pack $w.m -side top -fill x -padx 20 -pady 20
6969 frame $w.f -relief sunken -border 2
Christian Stimmingd990ced2007-11-07 18:42:55 +01006970 message $w.f.rt -text [mc "Reset type:"] -aspect 1000
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006971 grid $w.f.rt -sticky w
6972 set resettype mixed
6973 radiobutton $w.f.soft -value soft -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 18:42:55 +01006974 -text [mc "Soft: Leave working tree and index untouched"]
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006975 grid $w.f.soft -sticky w
6976 radiobutton $w.f.mixed -value mixed -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 18:42:55 +01006977 -text [mc "Mixed: Leave working tree untouched, reset index"]
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006978 grid $w.f.mixed -sticky w
6979 radiobutton $w.f.hard -value hard -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 18:42:55 +01006980 -text [mc "Hard: Reset working tree and index\n(discard ALL local changes)"]
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006981 grid $w.f.hard -sticky w
6982 pack $w.f -side top -fill x
Christian Stimmingd990ced2007-11-07 18:42:55 +01006983 button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006984 pack $w.ok -side left -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 18:42:55 +01006985 button $w.cancel -text [mc Cancel] -command "destroy $w"
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006986 pack $w.cancel -side right -fill x -padx 20 -pady 20
6987 bind $w <Visibility> "grab $w; focus $w"
6988 tkwait window $w
6989 if {!$confirm_ok} return
Paul Mackerras706d6c32007-06-26 11:09:49 +10006990 if {[catch {set fd [open \
6991 [list | sh -c "git reset --$resettype $rowmenuid 2>&1"] r]} err]} {
Paul Mackerras6fb735a2006-10-19 10:09:06 +10006992 error_popup $err
6993 } else {
Paul Mackerras706d6c32007-06-26 11:09:49 +10006994 dohidelocalchanges
Paul Mackerrasa137a902007-10-23 21:12:49 +10006995 filerun $fd [list readresetstat $fd]
Christian Stimmingd990ced2007-11-07 18:42:55 +01006996 nowbusy reset [mc "Resetting"]
Paul Mackerras706d6c32007-06-26 11:09:49 +10006997 }
6998}
6999
Paul Mackerrasa137a902007-10-23 21:12:49 +10007000proc readresetstat {fd} {
7001 global mainhead mainheadid showlocalchanges rprogcoord
Paul Mackerras706d6c32007-06-26 11:09:49 +10007002
7003 if {[gets $fd line] >= 0} {
7004 if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
Paul Mackerrasa137a902007-10-23 21:12:49 +10007005 set rprogcoord [expr {1.0 * $m / $n}]
7006 adjustprogress
Paul Mackerras706d6c32007-06-26 11:09:49 +10007007 }
7008 return 1
7009 }
Paul Mackerrasa137a902007-10-23 21:12:49 +10007010 set rprogcoord 0
7011 adjustprogress
Paul Mackerras706d6c32007-06-26 11:09:49 +10007012 notbusy reset
7013 if {[catch {close $fd} err]} {
7014 error_popup $err
7015 }
7016 set oldhead $mainheadid
7017 set newhead [exec git rev-parse HEAD]
7018 if {$newhead ne $oldhead} {
7019 movehead $newhead $mainhead
7020 movedhead $newhead $mainhead
7021 set mainheadid $newhead
Paul Mackerras6fb735a2006-10-19 10:09:06 +10007022 redrawtags $oldhead
Paul Mackerras706d6c32007-06-26 11:09:49 +10007023 redrawtags $newhead
Paul Mackerras6fb735a2006-10-19 10:09:06 +10007024 }
7025 if {$showlocalchanges} {
7026 doshowlocalchanges
7027 }
Paul Mackerras706d6c32007-06-26 11:09:49 +10007028 return 0
Paul Mackerras6fb735a2006-10-19 10:09:06 +10007029}
7030
Paul Mackerras10299152006-08-02 09:52:01 +10007031# context menu for a head
7032proc headmenu {x y id head} {
Paul Mackerras00609462007-06-17 17:08:35 +10007033 global headmenuid headmenuhead headctxmenu mainhead
Paul Mackerras10299152006-08-02 09:52:01 +10007034
Paul Mackerrasbb3edc82007-09-27 11:00:25 +10007035 stopfinding
Paul Mackerras10299152006-08-02 09:52:01 +10007036 set headmenuid $id
7037 set headmenuhead $head
Paul Mackerras00609462007-06-17 17:08:35 +10007038 set state normal
7039 if {$head eq $mainhead} {
7040 set state disabled
7041 }
7042 $headctxmenu entryconfigure 0 -state $state
7043 $headctxmenu entryconfigure 1 -state $state
Paul Mackerras10299152006-08-02 09:52:01 +10007044 tk_popup $headctxmenu $x $y
7045}
7046
7047proc cobranch {} {
7048 global headmenuid headmenuhead mainhead headids
Paul Mackerras219ea3a2006-09-07 10:21:39 +10007049 global showlocalchanges mainheadid
Paul Mackerras10299152006-08-02 09:52:01 +10007050
7051 # check the tree is clean first??
7052 set oldmainhead $mainhead
Christian Stimmingd990ced2007-11-07 18:42:55 +01007053 nowbusy checkout [mc "Checking out"]
Paul Mackerras10299152006-08-02 09:52:01 +10007054 update
Paul Mackerras219ea3a2006-09-07 10:21:39 +10007055 dohidelocalchanges
Paul Mackerras10299152006-08-02 09:52:01 +10007056 if {[catch {
Paul Mackerras696cf492007-05-22 09:52:00 +10007057 exec git checkout -q $headmenuhead
Paul Mackerras10299152006-08-02 09:52:01 +10007058 } err]} {
7059 notbusy checkout
7060 error_popup $err
7061 } else {
7062 notbusy checkout
Paul Mackerras53cda8d2006-08-02 19:43:34 +10007063 set mainhead $headmenuhead
Paul Mackerras219ea3a2006-09-07 10:21:39 +10007064 set mainheadid $headmenuid
Paul Mackerras10299152006-08-02 09:52:01 +10007065 if {[info exists headids($oldmainhead)]} {
7066 redrawtags $headids($oldmainhead)
7067 }
7068 redrawtags $headmenuid
Paul Mackerras6fb735a2006-10-19 10:09:06 +10007069 }
7070 if {$showlocalchanges} {
7071 dodiffindex
Paul Mackerras10299152006-08-02 09:52:01 +10007072 }
7073}
7074
7075proc rmbranch {} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10007076 global headmenuid headmenuhead mainhead
Paul Mackerrasb1054ac2007-08-15 10:09:47 +10007077 global idheads
Paul Mackerras10299152006-08-02 09:52:01 +10007078
7079 set head $headmenuhead
7080 set id $headmenuid
Paul Mackerras00609462007-06-17 17:08:35 +10007081 # this check shouldn't be needed any more...
Paul Mackerras10299152006-08-02 09:52:01 +10007082 if {$head eq $mainhead} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01007083 error_popup [mc "Cannot delete the currently checked-out branch"]
Paul Mackerras10299152006-08-02 09:52:01 +10007084 return
7085 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007086 set dheads [descheads $id]
Paul Mackerrasd7b16112007-08-17 17:57:31 +10007087 if {[llength $dheads] == 1 && $idheads($dheads) eq $head} {
Paul Mackerras10299152006-08-02 09:52:01 +10007088 # the stuff on this branch isn't on any other branch
Christian Stimmingd990ced2007-11-07 18:42:55 +01007089 if {![confirm_popup [mc "The commits on branch %s aren't on any other\
7090 branch.\nReally delete branch %s?" $head $head]]} return
Paul Mackerras10299152006-08-02 09:52:01 +10007091 }
7092 nowbusy rmbranch
7093 update
7094 if {[catch {exec git branch -D $head} err]} {
7095 notbusy rmbranch
7096 error_popup $err
7097 return
7098 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007099 removehead $id $head
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10007100 removedhead $id $head
Paul Mackerras10299152006-08-02 09:52:01 +10007101 redrawtags $id
7102 notbusy rmbranch
Paul Mackerrase11f1232007-06-16 20:29:25 +10007103 dispneartags 0
Paul Mackerras887c9962007-08-20 19:36:20 +10007104 run refill_reflist
7105}
7106
7107# Display a list of tags and heads
7108proc showrefs {} {
Paul Mackerras9c311b32007-10-04 22:27:13 +10007109 global showrefstop bgcolor fgcolor selectbgcolor
7110 global bglist fglist reflistfilter reflist maincursor
Paul Mackerras887c9962007-08-20 19:36:20 +10007111
7112 set top .showrefs
7113 set showrefstop $top
7114 if {[winfo exists $top]} {
7115 raise $top
7116 refill_reflist
7117 return
7118 }
7119 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01007120 wm title $top [mc "Tags and heads: %s" [file tail [pwd]]]
Paul Mackerras887c9962007-08-20 19:36:20 +10007121 text $top.list -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 22:27:13 +10007122 -selectbackground $selectbgcolor -font mainfont \
Paul Mackerras887c9962007-08-20 19:36:20 +10007123 -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
7124 -width 30 -height 20 -cursor $maincursor \
7125 -spacing1 1 -spacing3 1 -state disabled
7126 $top.list tag configure highlight -background $selectbgcolor
7127 lappend bglist $top.list
7128 lappend fglist $top.list
7129 scrollbar $top.ysb -command "$top.list yview" -orient vertical
7130 scrollbar $top.xsb -command "$top.list xview" -orient horizontal
7131 grid $top.list $top.ysb -sticky nsew
7132 grid $top.xsb x -sticky ew
7133 frame $top.f
Christian Stimmingd990ced2007-11-07 18:42:55 +01007134 label $top.f.l -text "[mc "Filter"]: " -font uifont
Paul Mackerras9c311b32007-10-04 22:27:13 +10007135 entry $top.f.e -width 20 -textvariable reflistfilter -font uifont
Paul Mackerras887c9962007-08-20 19:36:20 +10007136 set reflistfilter "*"
7137 trace add variable reflistfilter write reflistfilter_change
7138 pack $top.f.e -side right -fill x -expand 1
7139 pack $top.f.l -side left
7140 grid $top.f - -sticky ew -pady 2
Christian Stimmingd990ced2007-11-07 18:42:55 +01007141 button $top.close -command [list destroy $top] -text [mc "Close"] \
Paul Mackerras9c311b32007-10-04 22:27:13 +10007142 -font uifont
Paul Mackerras887c9962007-08-20 19:36:20 +10007143 grid $top.close -
7144 grid columnconfigure $top 0 -weight 1
7145 grid rowconfigure $top 0 -weight 1
7146 bind $top.list <1> {break}
7147 bind $top.list <B1-Motion> {break}
7148 bind $top.list <ButtonRelease-1> {sel_reflist %W %x %y; break}
7149 set reflist {}
7150 refill_reflist
7151}
7152
7153proc sel_reflist {w x y} {
7154 global showrefstop reflist headids tagids otherrefids
7155
7156 if {![winfo exists $showrefstop]} return
7157 set l [lindex [split [$w index "@$x,$y"] "."] 0]
7158 set ref [lindex $reflist [expr {$l-1}]]
7159 set n [lindex $ref 0]
7160 switch -- [lindex $ref 1] {
7161 "H" {selbyid $headids($n)}
7162 "T" {selbyid $tagids($n)}
7163 "o" {selbyid $otherrefids($n)}
7164 }
7165 $showrefstop.list tag add highlight $l.0 "$l.0 lineend"
7166}
7167
7168proc unsel_reflist {} {
7169 global showrefstop
7170
7171 if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
7172 $showrefstop.list tag remove highlight 0.0 end
7173}
7174
7175proc reflistfilter_change {n1 n2 op} {
7176 global reflistfilter
7177
7178 after cancel refill_reflist
7179 after 200 refill_reflist
7180}
7181
7182proc refill_reflist {} {
7183 global reflist reflistfilter showrefstop headids tagids otherrefids
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11007184 global curview commitinterest
Paul Mackerras887c9962007-08-20 19:36:20 +10007185
7186 if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
7187 set refs {}
7188 foreach n [array names headids] {
7189 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11007190 if {[commitinview $headids($n) $curview]} {
Paul Mackerras887c9962007-08-20 19:36:20 +10007191 lappend refs [list $n H]
7192 } else {
7193 set commitinterest($headids($n)) {run refill_reflist}
7194 }
7195 }
7196 }
7197 foreach n [array names tagids] {
7198 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11007199 if {[commitinview $tagids($n) $curview]} {
Paul Mackerras887c9962007-08-20 19:36:20 +10007200 lappend refs [list $n T]
7201 } else {
7202 set commitinterest($tagids($n)) {run refill_reflist}
7203 }
7204 }
7205 }
7206 foreach n [array names otherrefids] {
7207 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11007208 if {[commitinview $otherrefids($n) $curview]} {
Paul Mackerras887c9962007-08-20 19:36:20 +10007209 lappend refs [list $n o]
7210 } else {
7211 set commitinterest($otherrefids($n)) {run refill_reflist}
7212 }
7213 }
7214 }
7215 set refs [lsort -index 0 $refs]
7216 if {$refs eq $reflist} return
7217
7218 # Update the contents of $showrefstop.list according to the
7219 # differences between $reflist (old) and $refs (new)
7220 $showrefstop.list conf -state normal
7221 $showrefstop.list insert end "\n"
7222 set i 0
7223 set j 0
7224 while {$i < [llength $reflist] || $j < [llength $refs]} {
7225 if {$i < [llength $reflist]} {
7226 if {$j < [llength $refs]} {
7227 set cmp [string compare [lindex $reflist $i 0] \
7228 [lindex $refs $j 0]]
7229 if {$cmp == 0} {
7230 set cmp [string compare [lindex $reflist $i 1] \
7231 [lindex $refs $j 1]]
7232 }
7233 } else {
7234 set cmp -1
7235 }
7236 } else {
7237 set cmp 1
7238 }
7239 switch -- $cmp {
7240 -1 {
7241 $showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
7242 incr i
7243 }
7244 0 {
7245 incr i
7246 incr j
7247 }
7248 1 {
7249 set l [expr {$j + 1}]
7250 $showrefstop.list image create $l.0 -align baseline \
7251 -image reficon-[lindex $refs $j 1] -padx 2
7252 $showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
7253 incr j
7254 }
7255 }
7256 }
7257 set reflist $refs
7258 # delete last newline
7259 $showrefstop.list delete end-2c end-1c
7260 $showrefstop.list conf -state disabled
Paul Mackerras10299152006-08-02 09:52:01 +10007261}
7262
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007263# Stuff for finding nearby tags
7264proc getallcommits {} {
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007265 global allcommits nextarc seeds allccache allcwait cachedarcs allcupdate
7266 global idheads idtags idotherrefs allparents tagobjid
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10007267
Paul Mackerrasa69b2d12007-08-13 15:02:02 +10007268 if {![info exists allcommits]} {
Paul Mackerrasa69b2d12007-08-13 15:02:02 +10007269 set nextarc 0
7270 set allcommits 0
7271 set seeds {}
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007272 set allcwait 0
7273 set cachedarcs 0
7274 set allccache [file join [gitdir] "gitk.cache"]
7275 if {![catch {
7276 set f [open $allccache r]
7277 set allcwait 1
7278 getcache $f
7279 }]} return
Paul Mackerrasa69b2d12007-08-13 15:02:02 +10007280 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007281
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007282 if {$allcwait} {
7283 return
Paul Mackerrase11f1232007-06-16 20:29:25 +10007284 }
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007285 set cmd [list | git rev-list --parents]
7286 set allcupdate [expr {$seeds ne {}}]
7287 if {!$allcupdate} {
7288 set ids "--all"
7289 } else {
7290 set refs [concat [array names idheads] [array names idtags] \
7291 [array names idotherrefs]]
7292 set ids {}
7293 set tagobjs {}
7294 foreach name [array names tagobjid] {
7295 lappend tagobjs $tagobjid($name)
7296 }
7297 foreach id [lsort -unique $refs] {
7298 if {![info exists allparents($id)] &&
7299 [lsearch -exact $tagobjs $id] < 0} {
7300 lappend ids $id
7301 }
7302 }
7303 if {$ids ne {}} {
7304 foreach id $seeds {
7305 lappend ids "^$id"
7306 }
7307 }
7308 }
7309 if {$ids ne {}} {
7310 set fd [open [concat $cmd $ids] r]
7311 fconfigure $fd -blocking 0
7312 incr allcommits
7313 nowbusy allcommits
7314 filerun $fd [list getallclines $fd]
7315 } else {
7316 dispneartags 0
7317 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007318}
7319
Paul Mackerrase11f1232007-06-16 20:29:25 +10007320# Since most commits have 1 parent and 1 child, we group strings of
7321# such commits into "arcs" joining branch/merge points (BMPs), which
7322# are commits that either don't have 1 parent or don't have 1 child.
7323#
7324# arcnos(id) - incoming arcs for BMP, arc we're on for other nodes
7325# arcout(id) - outgoing arcs for BMP
7326# arcids(a) - list of IDs on arc including end but not start
7327# arcstart(a) - BMP ID at start of arc
7328# arcend(a) - BMP ID at end of arc
7329# growing(a) - arc a is still growing
7330# arctags(a) - IDs out of arcids (excluding end) that have tags
7331# archeads(a) - IDs out of arcids (excluding end) that have heads
7332# The start of an arc is at the descendent end, so "incoming" means
7333# coming from descendents, and "outgoing" means going towards ancestors.
Paul Mackerrascec7bec2006-08-02 09:38:10 +10007334
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007335proc getallclines {fd} {
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007336 global allparents allchildren idtags idheads nextarc
Paul Mackerrase11f1232007-06-16 20:29:25 +10007337 global arcnos arcids arctags arcout arcend arcstart archeads growing
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007338 global seeds allcommits cachedarcs allcupdate
7339
Paul Mackerrase11f1232007-06-16 20:29:25 +10007340 set nid 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10007341 while {[incr nid] <= 1000 && [gets $fd line] >= 0} {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007342 set id [lindex $line 0]
Paul Mackerrase11f1232007-06-16 20:29:25 +10007343 if {[info exists allparents($id)]} {
7344 # seen it already
7345 continue
7346 }
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007347 set cachedarcs 0
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007348 set olds [lrange $line 1 end]
7349 set allparents($id) $olds
7350 if {![info exists allchildren($id)]} {
7351 set allchildren($id) {}
Paul Mackerrase11f1232007-06-16 20:29:25 +10007352 set arcnos($id) {}
7353 lappend seeds $id
7354 } else {
7355 set a $arcnos($id)
7356 if {[llength $olds] == 1 && [llength $a] == 1} {
7357 lappend arcids($a) $id
7358 if {[info exists idtags($id)]} {
7359 lappend arctags($a) $id
7360 }
7361 if {[info exists idheads($id)]} {
7362 lappend archeads($a) $id
7363 }
7364 if {[info exists allparents($olds)]} {
7365 # seen parent already
7366 if {![info exists arcout($olds)]} {
7367 splitarc $olds
7368 }
7369 lappend arcids($a) $olds
7370 set arcend($a) $olds
7371 unset growing($a)
7372 }
7373 lappend allchildren($olds) $id
7374 lappend arcnos($olds) $a
7375 continue
7376 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007377 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007378 foreach a $arcnos($id) {
7379 lappend arcids($a) $id
7380 set arcend($a) $id
7381 unset growing($a)
7382 }
7383
7384 set ao {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007385 foreach p $olds {
7386 lappend allchildren($p) $id
Paul Mackerrase11f1232007-06-16 20:29:25 +10007387 set a [incr nextarc]
7388 set arcstart($a) $id
7389 set archeads($a) {}
7390 set arctags($a) {}
7391 set archeads($a) {}
7392 set arcids($a) {}
7393 lappend ao $a
7394 set growing($a) 1
7395 if {[info exists allparents($p)]} {
7396 # seen it already, may need to make a new branch
7397 if {![info exists arcout($p)]} {
7398 splitarc $p
7399 }
7400 lappend arcids($a) $p
7401 set arcend($a) $p
7402 unset growing($a)
7403 }
7404 lappend arcnos($p) $a
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007405 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007406 set arcout($id) $ao
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10007407 }
Paul Mackerrasf3326b62007-06-18 22:39:21 +10007408 if {$nid > 0} {
7409 global cached_dheads cached_dtags cached_atags
7410 catch {unset cached_dheads}
7411 catch {unset cached_dtags}
7412 catch {unset cached_atags}
7413 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10007414 if {![eof $fd]} {
7415 return [expr {$nid >= 1000? 2: 1}]
7416 }
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007417 set cacheok 1
7418 if {[catch {
7419 fconfigure $fd -blocking 1
7420 close $fd
7421 } err]} {
7422 # got an error reading the list of commits
7423 # if we were updating, try rereading the whole thing again
7424 if {$allcupdate} {
7425 incr allcommits -1
7426 dropcache $err
7427 return
7428 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01007429 error_popup "[mc "Error reading commit topology information;\
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007430 branch and preceding/following tag information\
Christian Stimmingd990ced2007-11-07 18:42:55 +01007431 will be incomplete."]\n($err)"
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007432 set cacheok 0
7433 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007434 if {[incr allcommits -1] == 0} {
7435 notbusy allcommits
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007436 if {$cacheok} {
7437 run savecache
7438 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007439 }
7440 dispneartags 0
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10007441 return 0
Paul Mackerrase11f1232007-06-16 20:29:25 +10007442}
7443
7444proc recalcarc {a} {
7445 global arctags archeads arcids idtags idheads
7446
7447 set at {}
7448 set ah {}
7449 foreach id [lrange $arcids($a) 0 end-1] {
7450 if {[info exists idtags($id)]} {
7451 lappend at $id
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007452 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007453 if {[info exists idheads($id)]} {
7454 lappend ah $id
7455 }
7456 }
7457 set arctags($a) $at
7458 set archeads($a) $ah
7459}
7460
7461proc splitarc {p} {
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007462 global arcnos arcids nextarc arctags archeads idtags idheads
Paul Mackerrase11f1232007-06-16 20:29:25 +10007463 global arcstart arcend arcout allparents growing
7464
7465 set a $arcnos($p)
7466 if {[llength $a] != 1} {
7467 puts "oops splitarc called but [llength $a] arcs already"
7468 return
7469 }
7470 set a [lindex $a 0]
7471 set i [lsearch -exact $arcids($a) $p]
7472 if {$i < 0} {
7473 puts "oops splitarc $p not in arc $a"
7474 return
7475 }
7476 set na [incr nextarc]
7477 if {[info exists arcend($a)]} {
7478 set arcend($na) $arcend($a)
7479 } else {
7480 set l [lindex $allparents([lindex $arcids($a) end]) 0]
7481 set j [lsearch -exact $arcnos($l) $a]
7482 set arcnos($l) [lreplace $arcnos($l) $j $j $na]
7483 }
7484 set tail [lrange $arcids($a) [expr {$i+1}] end]
7485 set arcids($a) [lrange $arcids($a) 0 $i]
7486 set arcend($a) $p
7487 set arcstart($na) $p
7488 set arcout($p) $na
7489 set arcids($na) $tail
7490 if {[info exists growing($a)]} {
7491 set growing($na) 1
7492 unset growing($a)
7493 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007494
7495 foreach id $tail {
7496 if {[llength $arcnos($id)] == 1} {
7497 set arcnos($id) $na
7498 } else {
7499 set j [lsearch -exact $arcnos($id) $a]
7500 set arcnos($id) [lreplace $arcnos($id) $j $j $na]
7501 }
7502 }
7503
7504 # reconstruct tags and heads lists
7505 if {$arctags($a) ne {} || $archeads($a) ne {}} {
7506 recalcarc $a
7507 recalcarc $na
7508 } else {
7509 set arctags($na) {}
7510 set archeads($na) {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007511 }
7512}
7513
Paul Mackerrase11f1232007-06-16 20:29:25 +10007514# Update things for a new commit added that is a child of one
7515# existing commit. Used when cherry-picking.
7516proc addnewchild {id p} {
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007517 global allparents allchildren idtags nextarc
Paul Mackerrase11f1232007-06-16 20:29:25 +10007518 global arcnos arcids arctags arcout arcend arcstart archeads growing
Paul Mackerras719c2b92007-08-29 22:41:34 +10007519 global seeds allcommits
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007520
Paul Mackerras3ebba3c2007-10-20 22:10:52 +10007521 if {![info exists allcommits] || ![info exists arcnos($p)]} return
Paul Mackerrase11f1232007-06-16 20:29:25 +10007522 set allparents($id) [list $p]
7523 set allchildren($id) {}
7524 set arcnos($id) {}
7525 lappend seeds $id
Paul Mackerrase11f1232007-06-16 20:29:25 +10007526 lappend allchildren($p) $id
7527 set a [incr nextarc]
7528 set arcstart($a) $id
7529 set archeads($a) {}
7530 set arctags($a) {}
7531 set arcids($a) [list $p]
7532 set arcend($a) $p
7533 if {![info exists arcout($p)]} {
7534 splitarc $p
7535 }
7536 lappend arcnos($p) $a
7537 set arcout($id) [list $a]
7538}
7539
Paul Mackerras5cd15b62007-08-30 21:54:17 +10007540# This implements a cache for the topology information.
7541# The cache saves, for each arc, the start and end of the arc,
7542# the ids on the arc, and the outgoing arcs from the end.
7543proc readcache {f} {
7544 global arcnos arcids arcout arcstart arcend arctags archeads nextarc
7545 global idtags idheads allparents cachedarcs possible_seeds seeds growing
7546 global allcwait
7547
7548 set a $nextarc
7549 set lim $cachedarcs
7550 if {$lim - $a > 500} {
7551 set lim [expr {$a + 500}]
7552 }
7553 if {[catch {
7554 if {$a == $lim} {
7555 # finish reading the cache and setting up arctags, etc.
7556 set line [gets $f]
7557 if {$line ne "1"} {error "bad final version"}
7558 close $f
7559 foreach id [array names idtags] {
7560 if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
7561 [llength $allparents($id)] == 1} {
7562 set a [lindex $arcnos($id) 0]
7563 if {$arctags($a) eq {}} {
7564 recalcarc $a
7565 }
7566 }
7567 }
7568 foreach id [array names idheads] {
7569 if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
7570 [llength $allparents($id)] == 1} {
7571 set a [lindex $arcnos($id) 0]
7572 if {$archeads($a) eq {}} {
7573 recalcarc $a
7574 }
7575 }
7576 }
7577 foreach id [lsort -unique $possible_seeds] {
7578 if {$arcnos($id) eq {}} {
7579 lappend seeds $id
7580 }
7581 }
7582 set allcwait 0
7583 } else {
7584 while {[incr a] <= $lim} {
7585 set line [gets $f]
7586 if {[llength $line] != 3} {error "bad line"}
7587 set s [lindex $line 0]
7588 set arcstart($a) $s
7589 lappend arcout($s) $a
7590 if {![info exists arcnos($s)]} {
7591 lappend possible_seeds $s
7592 set arcnos($s) {}
7593 }
7594 set e [lindex $line 1]
7595 if {$e eq {}} {
7596 set growing($a) 1
7597 } else {
7598 set arcend($a) $e
7599 if {![info exists arcout($e)]} {
7600 set arcout($e) {}
7601 }
7602 }
7603 set arcids($a) [lindex $line 2]
7604 foreach id $arcids($a) {
7605 lappend allparents($s) $id
7606 set s $id
7607 lappend arcnos($id) $a
7608 }
7609 if {![info exists allparents($s)]} {
7610 set allparents($s) {}
7611 }
7612 set arctags($a) {}
7613 set archeads($a) {}
7614 }
7615 set nextarc [expr {$a - 1}]
7616 }
7617 } err]} {
7618 dropcache $err
7619 return 0
7620 }
7621 if {!$allcwait} {
7622 getallcommits
7623 }
7624 return $allcwait
7625}
7626
7627proc getcache {f} {
7628 global nextarc cachedarcs possible_seeds
7629
7630 if {[catch {
7631 set line [gets $f]
7632 if {[llength $line] != 2 || [lindex $line 0] ne "1"} {error "bad version"}
7633 # make sure it's an integer
7634 set cachedarcs [expr {int([lindex $line 1])}]
7635 if {$cachedarcs < 0} {error "bad number of arcs"}
7636 set nextarc 0
7637 set possible_seeds {}
7638 run readcache $f
7639 } err]} {
7640 dropcache $err
7641 }
7642 return 0
7643}
7644
7645proc dropcache {err} {
7646 global allcwait nextarc cachedarcs seeds
7647
7648 #puts "dropping cache ($err)"
7649 foreach v {arcnos arcout arcids arcstart arcend growing \
7650 arctags archeads allparents allchildren} {
7651 global $v
7652 catch {unset $v}
7653 }
7654 set allcwait 0
7655 set nextarc 0
7656 set cachedarcs 0
7657 set seeds {}
7658 getallcommits
7659}
7660
7661proc writecache {f} {
7662 global cachearc cachedarcs allccache
7663 global arcstart arcend arcnos arcids arcout
7664
7665 set a $cachearc
7666 set lim $cachedarcs
7667 if {$lim - $a > 1000} {
7668 set lim [expr {$a + 1000}]
7669 }
7670 if {[catch {
7671 while {[incr a] <= $lim} {
7672 if {[info exists arcend($a)]} {
7673 puts $f [list $arcstart($a) $arcend($a) $arcids($a)]
7674 } else {
7675 puts $f [list $arcstart($a) {} $arcids($a)]
7676 }
7677 }
7678 } err]} {
7679 catch {close $f}
7680 catch {file delete $allccache}
7681 #puts "writing cache failed ($err)"
7682 return 0
7683 }
7684 set cachearc [expr {$a - 1}]
7685 if {$a > $cachedarcs} {
7686 puts $f "1"
7687 close $f
7688 return 0
7689 }
7690 return 1
7691}
7692
7693proc savecache {} {
7694 global nextarc cachedarcs cachearc allccache
7695
7696 if {$nextarc == $cachedarcs} return
7697 set cachearc 0
7698 set cachedarcs $nextarc
7699 catch {
7700 set f [open $allccache w]
7701 puts $f [list 1 $cachedarcs]
7702 run writecache $f
7703 }
7704}
7705
Paul Mackerrase11f1232007-06-16 20:29:25 +10007706# Returns 1 if a is an ancestor of b, -1 if b is an ancestor of a,
7707# or 0 if neither is true.
7708proc anc_or_desc {a b} {
7709 global arcout arcstart arcend arcnos cached_isanc
7710
7711 if {$arcnos($a) eq $arcnos($b)} {
7712 # Both are on the same arc(s); either both are the same BMP,
7713 # or if one is not a BMP, the other is also not a BMP or is
7714 # the BMP at end of the arc (and it only has 1 incoming arc).
Paul Mackerras69c0b5d2007-07-04 21:57:04 +10007715 # Or both can be BMPs with no incoming arcs.
7716 if {$a eq $b || $arcnos($a) eq {}} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10007717 return 0
7718 }
7719 # assert {[llength $arcnos($a)] == 1}
7720 set arc [lindex $arcnos($a) 0]
7721 set i [lsearch -exact $arcids($arc) $a]
7722 set j [lsearch -exact $arcids($arc) $b]
7723 if {$i < 0 || $i > $j} {
7724 return 1
7725 } else {
7726 return -1
7727 }
7728 }
7729
7730 if {![info exists arcout($a)]} {
7731 set arc [lindex $arcnos($a) 0]
7732 if {[info exists arcend($arc)]} {
7733 set aend $arcend($arc)
7734 } else {
7735 set aend {}
7736 }
7737 set a $arcstart($arc)
7738 } else {
7739 set aend $a
7740 }
7741 if {![info exists arcout($b)]} {
7742 set arc [lindex $arcnos($b) 0]
7743 if {[info exists arcend($arc)]} {
7744 set bend $arcend($arc)
7745 } else {
7746 set bend {}
7747 }
7748 set b $arcstart($arc)
7749 } else {
7750 set bend $b
7751 }
7752 if {$a eq $bend} {
7753 return 1
7754 }
7755 if {$b eq $aend} {
7756 return -1
7757 }
7758 if {[info exists cached_isanc($a,$bend)]} {
7759 if {$cached_isanc($a,$bend)} {
7760 return 1
7761 }
7762 }
7763 if {[info exists cached_isanc($b,$aend)]} {
7764 if {$cached_isanc($b,$aend)} {
7765 return -1
7766 }
7767 if {[info exists cached_isanc($a,$bend)]} {
7768 return 0
7769 }
7770 }
7771
7772 set todo [list $a $b]
7773 set anc($a) a
7774 set anc($b) b
7775 for {set i 0} {$i < [llength $todo]} {incr i} {
7776 set x [lindex $todo $i]
7777 if {$anc($x) eq {}} {
7778 continue
7779 }
7780 foreach arc $arcnos($x) {
7781 set xd $arcstart($arc)
7782 if {$xd eq $bend} {
7783 set cached_isanc($a,$bend) 1
7784 set cached_isanc($b,$aend) 0
7785 return 1
7786 } elseif {$xd eq $aend} {
7787 set cached_isanc($b,$aend) 1
7788 set cached_isanc($a,$bend) 0
7789 return -1
7790 }
7791 if {![info exists anc($xd)]} {
7792 set anc($xd) $anc($x)
7793 lappend todo $xd
7794 } elseif {$anc($xd) ne $anc($x)} {
7795 set anc($xd) {}
7796 }
7797 }
7798 }
7799 set cached_isanc($a,$bend) 0
7800 set cached_isanc($b,$aend) 0
7801 return 0
7802}
7803
7804# This identifies whether $desc has an ancestor that is
7805# a growing tip of the graph and which is not an ancestor of $anc
7806# and returns 0 if so and 1 if not.
7807# If we subsequently discover a tag on such a growing tip, and that
7808# turns out to be a descendent of $anc (which it could, since we
7809# don't necessarily see children before parents), then $desc
7810# isn't a good choice to display as a descendent tag of
7811# $anc (since it is the descendent of another tag which is
7812# a descendent of $anc). Similarly, $anc isn't a good choice to
7813# display as a ancestor tag of $desc.
7814#
7815proc is_certain {desc anc} {
7816 global arcnos arcout arcstart arcend growing problems
7817
7818 set certain {}
7819 if {[llength $arcnos($anc)] == 1} {
7820 # tags on the same arc are certain
7821 if {$arcnos($desc) eq $arcnos($anc)} {
7822 return 1
7823 }
7824 if {![info exists arcout($anc)]} {
7825 # if $anc is partway along an arc, use the start of the arc instead
7826 set a [lindex $arcnos($anc) 0]
7827 set anc $arcstart($a)
7828 }
7829 }
7830 if {[llength $arcnos($desc)] > 1 || [info exists arcout($desc)]} {
7831 set x $desc
7832 } else {
7833 set a [lindex $arcnos($desc) 0]
7834 set x $arcend($a)
7835 }
7836 if {$x == $anc} {
7837 return 1
7838 }
7839 set anclist [list $x]
7840 set dl($x) 1
7841 set nnh 1
7842 set ngrowanc 0
7843 for {set i 0} {$i < [llength $anclist] && ($nnh > 0 || $ngrowanc > 0)} {incr i} {
7844 set x [lindex $anclist $i]
7845 if {$dl($x)} {
7846 incr nnh -1
7847 }
7848 set done($x) 1
7849 foreach a $arcout($x) {
7850 if {[info exists growing($a)]} {
7851 if {![info exists growanc($x)] && $dl($x)} {
7852 set growanc($x) 1
7853 incr ngrowanc
7854 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007855 } else {
Paul Mackerrase11f1232007-06-16 20:29:25 +10007856 set y $arcend($a)
7857 if {[info exists dl($y)]} {
7858 if {$dl($y)} {
7859 if {!$dl($x)} {
7860 set dl($y) 0
7861 if {![info exists done($y)]} {
7862 incr nnh -1
7863 }
7864 if {[info exists growanc($x)]} {
7865 incr ngrowanc -1
7866 }
7867 set xl [list $y]
7868 for {set k 0} {$k < [llength $xl]} {incr k} {
7869 set z [lindex $xl $k]
7870 foreach c $arcout($z) {
7871 if {[info exists arcend($c)]} {
7872 set v $arcend($c)
7873 if {[info exists dl($v)] && $dl($v)} {
7874 set dl($v) 0
7875 if {![info exists done($v)]} {
7876 incr nnh -1
7877 }
7878 if {[info exists growanc($v)]} {
7879 incr ngrowanc -1
7880 }
7881 lappend xl $v
7882 }
7883 }
7884 }
7885 }
7886 }
7887 }
7888 } elseif {$y eq $anc || !$dl($x)} {
7889 set dl($y) 0
7890 lappend anclist $y
7891 } else {
7892 set dl($y) 1
7893 lappend anclist $y
7894 incr nnh
7895 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007896 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10007897 }
7898 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10007899 foreach x [array names growanc] {
7900 if {$dl($x)} {
7901 return 0
7902 }
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10007903 return 0
Paul Mackerrase11f1232007-06-16 20:29:25 +10007904 }
7905 return 1
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10007906}
7907
Paul Mackerrase11f1232007-06-16 20:29:25 +10007908proc validate_arctags {a} {
7909 global arctags idtags
7910
7911 set i -1
7912 set na $arctags($a)
7913 foreach id $arctags($a) {
7914 incr i
7915 if {![info exists idtags($id)]} {
7916 set na [lreplace $na $i $i]
7917 incr i -1
7918 }
7919 }
7920 set arctags($a) $na
7921}
7922
7923proc validate_archeads {a} {
7924 global archeads idheads
7925
7926 set i -1
7927 set na $archeads($a)
7928 foreach id $archeads($a) {
7929 incr i
7930 if {![info exists idheads($id)]} {
7931 set na [lreplace $na $i $i]
7932 incr i -1
7933 }
7934 }
7935 set archeads($a) $na
7936}
7937
7938# Return the list of IDs that have tags that are descendents of id,
7939# ignoring IDs that are descendents of IDs already reported.
7940proc desctags {id} {
7941 global arcnos arcstart arcids arctags idtags allparents
7942 global growing cached_dtags
7943
7944 if {![info exists allparents($id)]} {
7945 return {}
7946 }
7947 set t1 [clock clicks -milliseconds]
7948 set argid $id
7949 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
7950 # part-way along an arc; check that arc first
7951 set a [lindex $arcnos($id) 0]
7952 if {$arctags($a) ne {}} {
7953 validate_arctags $a
7954 set i [lsearch -exact $arcids($a) $id]
7955 set tid {}
7956 foreach t $arctags($a) {
7957 set j [lsearch -exact $arcids($a) $t]
7958 if {$j >= $i} break
7959 set tid $t
7960 }
7961 if {$tid ne {}} {
7962 return $tid
7963 }
7964 }
7965 set id $arcstart($a)
7966 if {[info exists idtags($id)]} {
7967 return $id
7968 }
7969 }
7970 if {[info exists cached_dtags($id)]} {
7971 return $cached_dtags($id)
7972 }
7973
7974 set origid $id
7975 set todo [list $id]
7976 set queued($id) 1
7977 set nc 1
7978 for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
7979 set id [lindex $todo $i]
7980 set done($id) 1
7981 set ta [info exists hastaggedancestor($id)]
7982 if {!$ta} {
7983 incr nc -1
7984 }
7985 # ignore tags on starting node
7986 if {!$ta && $i > 0} {
7987 if {[info exists idtags($id)]} {
7988 set tagloc($id) $id
7989 set ta 1
7990 } elseif {[info exists cached_dtags($id)]} {
7991 set tagloc($id) $cached_dtags($id)
7992 set ta 1
7993 }
7994 }
7995 foreach a $arcnos($id) {
7996 set d $arcstart($a)
7997 if {!$ta && $arctags($a) ne {}} {
7998 validate_arctags $a
7999 if {$arctags($a) ne {}} {
8000 lappend tagloc($id) [lindex $arctags($a) end]
8001 }
8002 }
8003 if {$ta || $arctags($a) ne {}} {
8004 set tomark [list $d]
8005 for {set j 0} {$j < [llength $tomark]} {incr j} {
8006 set dd [lindex $tomark $j]
8007 if {![info exists hastaggedancestor($dd)]} {
8008 if {[info exists done($dd)]} {
8009 foreach b $arcnos($dd) {
8010 lappend tomark $arcstart($b)
8011 }
8012 if {[info exists tagloc($dd)]} {
8013 unset tagloc($dd)
8014 }
8015 } elseif {[info exists queued($dd)]} {
8016 incr nc -1
8017 }
8018 set hastaggedancestor($dd) 1
8019 }
8020 }
8021 }
8022 if {![info exists queued($d)]} {
8023 lappend todo $d
8024 set queued($d) 1
8025 if {![info exists hastaggedancestor($d)]} {
8026 incr nc
8027 }
8028 }
8029 }
8030 }
8031 set tags {}
8032 foreach id [array names tagloc] {
8033 if {![info exists hastaggedancestor($id)]} {
8034 foreach t $tagloc($id) {
8035 if {[lsearch -exact $tags $t] < 0} {
8036 lappend tags $t
8037 }
8038 }
8039 }
8040 }
8041 set t2 [clock clicks -milliseconds]
8042 set loopix $i
8043
8044 # remove tags that are descendents of other tags
8045 for {set i 0} {$i < [llength $tags]} {incr i} {
8046 set a [lindex $tags $i]
8047 for {set j 0} {$j < $i} {incr j} {
8048 set b [lindex $tags $j]
8049 set r [anc_or_desc $a $b]
8050 if {$r == 1} {
8051 set tags [lreplace $tags $j $j]
8052 incr j -1
8053 incr i -1
8054 } elseif {$r == -1} {
8055 set tags [lreplace $tags $i $i]
8056 incr i -1
8057 break
8058 }
8059 }
8060 }
8061
8062 if {[array names growing] ne {}} {
8063 # graph isn't finished, need to check if any tag could get
8064 # eclipsed by another tag coming later. Simply ignore any
8065 # tags that could later get eclipsed.
8066 set ctags {}
8067 foreach t $tags {
8068 if {[is_certain $t $origid]} {
8069 lappend ctags $t
8070 }
8071 }
8072 if {$tags eq $ctags} {
8073 set cached_dtags($origid) $tags
8074 } else {
8075 set tags $ctags
8076 }
8077 } else {
8078 set cached_dtags($origid) $tags
8079 }
8080 set t3 [clock clicks -milliseconds]
8081 if {0 && $t3 - $t1 >= 100} {
8082 puts "iterating descendents ($loopix/[llength $todo] nodes) took\
8083 [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
8084 }
8085 return $tags
8086}
8087
8088proc anctags {id} {
8089 global arcnos arcids arcout arcend arctags idtags allparents
8090 global growing cached_atags
8091
8092 if {![info exists allparents($id)]} {
8093 return {}
8094 }
8095 set t1 [clock clicks -milliseconds]
8096 set argid $id
8097 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
8098 # part-way along an arc; check that arc first
8099 set a [lindex $arcnos($id) 0]
8100 if {$arctags($a) ne {}} {
8101 validate_arctags $a
8102 set i [lsearch -exact $arcids($a) $id]
8103 foreach t $arctags($a) {
8104 set j [lsearch -exact $arcids($a) $t]
8105 if {$j > $i} {
8106 return $t
8107 }
8108 }
8109 }
8110 if {![info exists arcend($a)]} {
8111 return {}
8112 }
8113 set id $arcend($a)
8114 if {[info exists idtags($id)]} {
8115 return $id
8116 }
8117 }
8118 if {[info exists cached_atags($id)]} {
8119 return $cached_atags($id)
8120 }
8121
8122 set origid $id
8123 set todo [list $id]
8124 set queued($id) 1
8125 set taglist {}
8126 set nc 1
8127 for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
8128 set id [lindex $todo $i]
8129 set done($id) 1
8130 set td [info exists hastaggeddescendent($id)]
8131 if {!$td} {
8132 incr nc -1
8133 }
8134 # ignore tags on starting node
8135 if {!$td && $i > 0} {
8136 if {[info exists idtags($id)]} {
8137 set tagloc($id) $id
8138 set td 1
8139 } elseif {[info exists cached_atags($id)]} {
8140 set tagloc($id) $cached_atags($id)
8141 set td 1
8142 }
8143 }
8144 foreach a $arcout($id) {
8145 if {!$td && $arctags($a) ne {}} {
8146 validate_arctags $a
8147 if {$arctags($a) ne {}} {
8148 lappend tagloc($id) [lindex $arctags($a) 0]
8149 }
8150 }
8151 if {![info exists arcend($a)]} continue
8152 set d $arcend($a)
8153 if {$td || $arctags($a) ne {}} {
8154 set tomark [list $d]
8155 for {set j 0} {$j < [llength $tomark]} {incr j} {
8156 set dd [lindex $tomark $j]
8157 if {![info exists hastaggeddescendent($dd)]} {
8158 if {[info exists done($dd)]} {
8159 foreach b $arcout($dd) {
8160 if {[info exists arcend($b)]} {
8161 lappend tomark $arcend($b)
8162 }
8163 }
8164 if {[info exists tagloc($dd)]} {
8165 unset tagloc($dd)
8166 }
8167 } elseif {[info exists queued($dd)]} {
8168 incr nc -1
8169 }
8170 set hastaggeddescendent($dd) 1
8171 }
8172 }
8173 }
8174 if {![info exists queued($d)]} {
8175 lappend todo $d
8176 set queued($d) 1
8177 if {![info exists hastaggeddescendent($d)]} {
8178 incr nc
8179 }
8180 }
8181 }
8182 }
8183 set t2 [clock clicks -milliseconds]
8184 set loopix $i
8185 set tags {}
8186 foreach id [array names tagloc] {
8187 if {![info exists hastaggeddescendent($id)]} {
8188 foreach t $tagloc($id) {
8189 if {[lsearch -exact $tags $t] < 0} {
8190 lappend tags $t
8191 }
8192 }
8193 }
8194 }
8195
8196 # remove tags that are ancestors of other tags
8197 for {set i 0} {$i < [llength $tags]} {incr i} {
8198 set a [lindex $tags $i]
8199 for {set j 0} {$j < $i} {incr j} {
8200 set b [lindex $tags $j]
8201 set r [anc_or_desc $a $b]
8202 if {$r == -1} {
8203 set tags [lreplace $tags $j $j]
8204 incr j -1
8205 incr i -1
8206 } elseif {$r == 1} {
8207 set tags [lreplace $tags $i $i]
8208 incr i -1
8209 break
8210 }
8211 }
8212 }
8213
8214 if {[array names growing] ne {}} {
8215 # graph isn't finished, need to check if any tag could get
8216 # eclipsed by another tag coming later. Simply ignore any
8217 # tags that could later get eclipsed.
8218 set ctags {}
8219 foreach t $tags {
8220 if {[is_certain $origid $t]} {
8221 lappend ctags $t
8222 }
8223 }
8224 if {$tags eq $ctags} {
8225 set cached_atags($origid) $tags
8226 } else {
8227 set tags $ctags
8228 }
8229 } else {
8230 set cached_atags($origid) $tags
8231 }
8232 set t3 [clock clicks -milliseconds]
8233 if {0 && $t3 - $t1 >= 100} {
8234 puts "iterating ancestors ($loopix/[llength $todo] nodes) took\
8235 [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
8236 }
8237 return $tags
8238}
8239
8240# Return the list of IDs that have heads that are descendents of id,
8241# including id itself if it has a head.
8242proc descheads {id} {
8243 global arcnos arcstart arcids archeads idheads cached_dheads
8244 global allparents
8245
8246 if {![info exists allparents($id)]} {
8247 return {}
8248 }
Paul Mackerrasf3326b62007-06-18 22:39:21 +10008249 set aret {}
Paul Mackerrase11f1232007-06-16 20:29:25 +10008250 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
8251 # part-way along an arc; check it first
8252 set a [lindex $arcnos($id) 0]
8253 if {$archeads($a) ne {}} {
8254 validate_archeads $a
8255 set i [lsearch -exact $arcids($a) $id]
8256 foreach t $archeads($a) {
8257 set j [lsearch -exact $arcids($a) $t]
8258 if {$j > $i} break
Paul Mackerrasf3326b62007-06-18 22:39:21 +10008259 lappend aret $t
Paul Mackerrase11f1232007-06-16 20:29:25 +10008260 }
8261 }
8262 set id $arcstart($a)
8263 }
8264 set origid $id
8265 set todo [list $id]
8266 set seen($id) 1
Paul Mackerrasf3326b62007-06-18 22:39:21 +10008267 set ret {}
Paul Mackerrase11f1232007-06-16 20:29:25 +10008268 for {set i 0} {$i < [llength $todo]} {incr i} {
8269 set id [lindex $todo $i]
8270 if {[info exists cached_dheads($id)]} {
8271 set ret [concat $ret $cached_dheads($id)]
8272 } else {
8273 if {[info exists idheads($id)]} {
8274 lappend ret $id
8275 }
8276 foreach a $arcnos($id) {
8277 if {$archeads($a) ne {}} {
Paul Mackerras706d6c32007-06-26 11:09:49 +10008278 validate_archeads $a
8279 if {$archeads($a) ne {}} {
8280 set ret [concat $ret $archeads($a)]
8281 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10008282 }
8283 set d $arcstart($a)
8284 if {![info exists seen($d)]} {
8285 lappend todo $d
8286 set seen($d) 1
8287 }
8288 }
8289 }
8290 }
8291 set ret [lsort -unique $ret]
8292 set cached_dheads($origid) $ret
Paul Mackerrasf3326b62007-06-18 22:39:21 +10008293 return [concat $ret $aret]
Paul Mackerrase11f1232007-06-16 20:29:25 +10008294}
8295
Paul Mackerrasceadfe92006-08-08 20:55:36 +10008296proc addedtag {id} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10008297 global arcnos arcout cached_dtags cached_atags
Paul Mackerrasceadfe92006-08-08 20:55:36 +10008298
Paul Mackerrase11f1232007-06-16 20:29:25 +10008299 if {![info exists arcnos($id)]} return
8300 if {![info exists arcout($id)]} {
8301 recalcarc [lindex $arcnos($id) 0]
Paul Mackerrasceadfe92006-08-08 20:55:36 +10008302 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10008303 catch {unset cached_dtags}
8304 catch {unset cached_atags}
Paul Mackerrasceadfe92006-08-08 20:55:36 +10008305}
8306
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008307proc addedhead {hid head} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10008308 global arcnos arcout cached_dheads
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008309
Paul Mackerrase11f1232007-06-16 20:29:25 +10008310 if {![info exists arcnos($hid)]} return
8311 if {![info exists arcout($hid)]} {
8312 recalcarc [lindex $arcnos($hid) 0]
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10008313 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10008314 catch {unset cached_dheads}
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10008315}
8316
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008317proc removedhead {hid head} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10008318 global cached_dheads
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008319
Paul Mackerrase11f1232007-06-16 20:29:25 +10008320 catch {unset cached_dheads}
Paul Mackerras10299152006-08-02 09:52:01 +10008321}
8322
Paul Mackerrase11f1232007-06-16 20:29:25 +10008323proc movedhead {hid head} {
8324 global arcnos arcout cached_dheads
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008325
Paul Mackerrase11f1232007-06-16 20:29:25 +10008326 if {![info exists arcnos($hid)]} return
8327 if {![info exists arcout($hid)]} {
8328 recalcarc [lindex $arcnos($hid) 0]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008329 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10008330 catch {unset cached_dheads}
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10008331}
8332
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008333proc changedrefs {} {
Paul Mackerrase11f1232007-06-16 20:29:25 +10008334 global cached_dheads cached_dtags cached_atags
8335 global arctags archeads arcnos arcout idheads idtags
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008336
Paul Mackerrase11f1232007-06-16 20:29:25 +10008337 foreach id [concat [array names idheads] [array names idtags]] {
8338 if {[info exists arcnos($id)] && ![info exists arcout($id)]} {
8339 set a [lindex $arcnos($id) 0]
8340 if {![info exists donearc($a)]} {
8341 recalcarc $a
8342 set donearc($a) 1
8343 }
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008344 }
8345 }
Paul Mackerrase11f1232007-06-16 20:29:25 +10008346 catch {unset cached_dtags}
8347 catch {unset cached_atags}
8348 catch {unset cached_dheads}
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008349}
8350
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008351proc rereadrefs {} {
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11008352 global idtags idheads idotherrefs mainheadid
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008353
8354 set refids [concat [array names idtags] \
8355 [array names idheads] [array names idotherrefs]]
8356 foreach id $refids {
8357 if {![info exists ref($id)]} {
8358 set ref($id) [listrefs $id]
8359 }
8360 }
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11008361 set oldmainhead $mainheadid
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008362 readrefs
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008363 changedrefs
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008364 set refids [lsort -unique [concat $refids [array names idtags] \
8365 [array names idheads] [array names idotherrefs]]]
8366 foreach id $refids {
8367 set v [listrefs $id]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10008368 if {![info exists ref($id)] || $ref($id) != $v ||
Paul Mackerrasfc2a2562007-12-26 23:03:43 +11008369 ($id eq $oldmainhead && $id ne $mainheadid) ||
8370 ($id eq $mainheadid && $id ne $oldmainhead)} {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008371 redrawtags $id
8372 }
8373 }
Paul Mackerras887c9962007-08-20 19:36:20 +10008374 run refill_reflist
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10008375}
8376
Junio C Hamano2e1ded42006-06-11 09:50:47 -07008377proc listrefs {id} {
8378 global idtags idheads idotherrefs
8379
8380 set x {}
8381 if {[info exists idtags($id)]} {
8382 set x $idtags($id)
8383 }
8384 set y {}
8385 if {[info exists idheads($id)]} {
8386 set y $idheads($id)
8387 }
8388 set z {}
8389 if {[info exists idotherrefs($id)]} {
8390 set z $idotherrefs($id)
8391 }
8392 return [list $x $y $z]
8393}
8394
Paul Mackerras106288c2005-08-19 23:11:39 +10008395proc showtag {tag isnew} {
Paul Mackerras62d3ea62006-09-11 10:36:53 +10008396 global ctext tagcontents tagids linknum tagobjid
Paul Mackerras106288c2005-08-19 23:11:39 +10008397
8398 if {$isnew} {
8399 addtohistory [list showtag $tag 0]
8400 }
8401 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10008402 clear_ctext
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10008403 settabs 0
Paul Mackerras106288c2005-08-19 23:11:39 +10008404 set linknum 0
Paul Mackerras62d3ea62006-09-11 10:36:53 +10008405 if {![info exists tagcontents($tag)]} {
8406 catch {
8407 set tagcontents($tag) [exec git cat-file tag $tagobjid($tag)]
8408 }
8409 }
Paul Mackerras106288c2005-08-19 23:11:39 +10008410 if {[info exists tagcontents($tag)]} {
8411 set text $tagcontents($tag)
8412 } else {
Christian Stimmingd990ced2007-11-07 18:42:55 +01008413 set text "[mc "Tag"]: $tag\n[mc "Id"]: $tagids($tag)"
Paul Mackerras106288c2005-08-19 23:11:39 +10008414 }
Sergey Vlasovf1b86292006-05-15 19:13:14 +04008415 appendwithlinks $text {}
Paul Mackerras106288c2005-08-19 23:11:39 +10008416 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10008417 init_flist {}
Paul Mackerras106288c2005-08-19 23:11:39 +10008418}
8419
Paul Mackerras1d10f362005-05-15 12:55:47 +00008420proc doquit {} {
8421 global stopped
8422 set stopped 100
Mark Levedahlb6047c52007-02-08 22:22:24 -05008423 savestuff .
Paul Mackerras1d10f362005-05-15 12:55:47 +00008424 destroy .
8425}
8426
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008427proc mkfontdisp {font top which} {
8428 global fontattr fontpref $font
8429
8430 set fontpref($font) [set $font]
8431 button $top.${font}but -text $which -font optionfont \
8432 -command [list choosefont $font $which]
8433 label $top.$font -relief flat -font $font \
8434 -text $fontattr($font,family) -justify left
8435 grid x $top.${font}but $top.$font -sticky w
8436}
8437
8438proc choosefont {font which} {
8439 global fontparam fontlist fonttop fontattr
8440
8441 set fontparam(which) $which
8442 set fontparam(font) $font
8443 set fontparam(family) [font actual $font -family]
8444 set fontparam(size) $fontattr($font,size)
8445 set fontparam(weight) $fontattr($font,weight)
8446 set fontparam(slant) $fontattr($font,slant)
8447 set top .gitkfont
8448 set fonttop $top
8449 if {![winfo exists $top]} {
8450 font create sample
8451 eval font config sample [font actual $font]
8452 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01008453 wm title $top [mc "Gitk font chooser"]
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008454 label $top.l -textvariable fontparam(which) -font uifont
8455 pack $top.l -side top
8456 set fontlist [lsort [font families]]
8457 frame $top.f
8458 listbox $top.f.fam -listvariable fontlist \
8459 -yscrollcommand [list $top.f.sb set]
8460 bind $top.f.fam <<ListboxSelect>> selfontfam
8461 scrollbar $top.f.sb -command [list $top.f.fam yview]
8462 pack $top.f.sb -side right -fill y
8463 pack $top.f.fam -side left -fill both -expand 1
8464 pack $top.f -side top -fill both -expand 1
8465 frame $top.g
8466 spinbox $top.g.size -from 4 -to 40 -width 4 \
8467 -textvariable fontparam(size) \
8468 -validatecommand {string is integer -strict %s}
8469 checkbutton $top.g.bold -padx 5 \
Christian Stimmingd990ced2007-11-07 18:42:55 +01008470 -font {{Times New Roman} 12 bold} -text [mc "B"] -indicatoron 0 \
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008471 -variable fontparam(weight) -onvalue bold -offvalue normal
8472 checkbutton $top.g.ital -padx 5 \
Christian Stimmingd990ced2007-11-07 18:42:55 +01008473 -font {{Times New Roman} 12 italic} -text [mc "I"] -indicatoron 0 \
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008474 -variable fontparam(slant) -onvalue italic -offvalue roman
8475 pack $top.g.size $top.g.bold $top.g.ital -side left
8476 pack $top.g -side top
8477 canvas $top.c -width 150 -height 50 -border 2 -relief sunk \
8478 -background white
8479 $top.c create text 100 25 -anchor center -text $which -font sample \
8480 -fill black -tags text
8481 bind $top.c <Configure> [list centertext $top.c]
8482 pack $top.c -side top -fill x
8483 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01008484 button $top.buts.ok -text [mc "OK"] -command fontok -default active \
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008485 -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01008486 button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal \
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008487 -font uifont
8488 grid $top.buts.ok $top.buts.can
8489 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8490 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8491 pack $top.buts -side bottom -fill x
8492 trace add variable fontparam write chg_fontparam
8493 } else {
8494 raise $top
8495 $top.c itemconf text -text $which
8496 }
8497 set i [lsearch -exact $fontlist $fontparam(family)]
8498 if {$i >= 0} {
8499 $top.f.fam selection set $i
8500 $top.f.fam see $i
8501 }
8502}
8503
8504proc centertext {w} {
8505 $w coords text [expr {[winfo width $w] / 2}] [expr {[winfo height $w] / 2}]
8506}
8507
8508proc fontok {} {
8509 global fontparam fontpref prefstop
8510
8511 set f $fontparam(font)
8512 set fontpref($f) [list $fontparam(family) $fontparam(size)]
8513 if {$fontparam(weight) eq "bold"} {
8514 lappend fontpref($f) "bold"
8515 }
8516 if {$fontparam(slant) eq "italic"} {
8517 lappend fontpref($f) "italic"
8518 }
8519 set w $prefstop.$f
8520 $w conf -text $fontparam(family) -font $fontpref($f)
8521
8522 fontcan
8523}
8524
8525proc fontcan {} {
8526 global fonttop fontparam
8527
8528 if {[info exists fonttop]} {
8529 catch {destroy $fonttop}
8530 catch {font delete sample}
8531 unset fonttop
8532 unset fontparam
8533 }
8534}
8535
8536proc selfontfam {} {
8537 global fonttop fontparam
8538
8539 set i [$fonttop.f.fam curselection]
8540 if {$i ne {}} {
8541 set fontparam(family) [$fonttop.f.fam get $i]
8542 }
8543}
8544
8545proc chg_fontparam {v sub op} {
8546 global fontparam
8547
8548 font config sample -$sub $fontparam($sub)
8549}
8550
Paul Mackerras712fcc02005-11-30 09:28:16 +11008551proc doprefs {} {
Paul Mackerras8d73b242007-10-06 20:22:00 +10008552 global maxwidth maxgraphpct
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008553 global oldprefs prefstop showneartags showlocalchanges
Mark Levedahl60378c02007-05-20 12:12:48 -04008554 global bgcolor fgcolor ctext diffcolors selectbgcolor
Paul Mackerras7a39a172007-10-23 10:15:11 +10008555 global uifont tabstop limitdiffs
Paul Mackerras232475d2005-11-15 10:34:03 +11008556
Paul Mackerras712fcc02005-11-30 09:28:16 +11008557 set top .gitkprefs
8558 set prefstop $top
8559 if {[winfo exists $top]} {
8560 raise $top
8561 return
Paul Mackerras757f17b2005-11-21 09:56:07 +11008562 }
Paul Mackerras3de07112007-10-23 22:40:50 +10008563 foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
Paul Mackerras94503912007-10-23 10:33:38 +10008564 limitdiffs tabstop} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11008565 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-15 10:34:03 +11008566 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11008567 toplevel $top
Christian Stimmingd990ced2007-11-07 18:42:55 +01008568 wm title $top [mc "Gitk preferences"]
8569 label $top.ldisp -text [mc "Commit list display options"]
Paul Mackerras9c311b32007-10-04 22:27:13 +10008570 $top.ldisp configure -font uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11008571 grid $top.ldisp - -sticky w -pady 10
8572 label $top.spacer -text " "
Christian Stimmingd990ced2007-11-07 18:42:55 +01008573 label $top.maxwidthl -text [mc "Maximum graph width (lines)"] \
Paul Mackerras712fcc02005-11-30 09:28:16 +11008574 -font optionfont
8575 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
8576 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
Christian Stimmingd990ced2007-11-07 18:42:55 +01008577 label $top.maxpctl -text [mc "Maximum graph width (% of pane)"] \
Paul Mackerras712fcc02005-11-30 09:28:16 +11008578 -font optionfont
8579 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
8580 grid x $top.maxpctl $top.maxpct -sticky w
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008581 frame $top.showlocal
Christian Stimmingd990ced2007-11-07 18:42:55 +01008582 label $top.showlocal.l -text [mc "Show local changes"] -font optionfont
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008583 checkbutton $top.showlocal.b -variable showlocalchanges
8584 pack $top.showlocal.b $top.showlocal.l -side left
8585 grid x $top.showlocal -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008586
Christian Stimmingd990ced2007-11-07 18:42:55 +01008587 label $top.ddisp -text [mc "Diff display options"]
Paul Mackerras9c311b32007-10-04 22:27:13 +10008588 $top.ddisp configure -font uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11008589 grid $top.ddisp - -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01008590 label $top.tabstopl -text [mc "Tab spacing"] -font optionfont
Paul Mackerras94503912007-10-23 10:33:38 +10008591 spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
8592 grid x $top.tabstopl $top.tabstop -sticky w
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10008593 frame $top.ntag
Christian Stimmingd990ced2007-11-07 18:42:55 +01008594 label $top.ntag.l -text [mc "Display nearby tags"] -font optionfont
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10008595 checkbutton $top.ntag.b -variable showneartags
8596 pack $top.ntag.b $top.ntag.l -side left
8597 grid x $top.ntag -sticky w
Paul Mackerras7a39a172007-10-23 10:15:11 +10008598 frame $top.ldiff
Christian Stimmingd990ced2007-11-07 18:42:55 +01008599 label $top.ldiff.l -text [mc "Limit diffs to listed paths"] -font optionfont
Paul Mackerras7a39a172007-10-23 10:15:11 +10008600 checkbutton $top.ldiff.b -variable limitdiffs
8601 pack $top.ldiff.b $top.ldiff.l -side left
8602 grid x $top.ldiff -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008603
Christian Stimmingd990ced2007-11-07 18:42:55 +01008604 label $top.cdisp -text [mc "Colors: press to choose"]
Paul Mackerras9c311b32007-10-04 22:27:13 +10008605 $top.cdisp configure -font uifont
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008606 grid $top.cdisp - -sticky w -pady 10
8607 label $top.bg -padx 40 -relief sunk -background $bgcolor
Christian Stimmingd990ced2007-11-07 18:42:55 +01008608 button $top.bgbut -text [mc "Background"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008609 -command [list choosecolor bgcolor 0 $top.bg background setbg]
8610 grid x $top.bgbut $top.bg -sticky w
8611 label $top.fg -padx 40 -relief sunk -background $fgcolor
Christian Stimmingd990ced2007-11-07 18:42:55 +01008612 button $top.fgbut -text [mc "Foreground"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008613 -command [list choosecolor fgcolor 0 $top.fg foreground setfg]
8614 grid x $top.fgbut $top.fg -sticky w
8615 label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
Christian Stimmingd990ced2007-11-07 18:42:55 +01008616 button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008617 -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
8618 [list $ctext tag conf d0 -foreground]]
8619 grid x $top.diffoldbut $top.diffold -sticky w
8620 label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
Christian Stimmingd990ced2007-11-07 18:42:55 +01008621 button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008622 -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
8623 [list $ctext tag conf d1 -foreground]]
8624 grid x $top.diffnewbut $top.diffnew -sticky w
8625 label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
Christian Stimmingd990ced2007-11-07 18:42:55 +01008626 button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008627 -command [list choosecolor diffcolors 2 $top.hunksep \
8628 "diff hunk header" \
8629 [list $ctext tag conf hunksep -foreground]]
8630 grid x $top.hunksepbut $top.hunksep -sticky w
Mark Levedahl60378c02007-05-20 12:12:48 -04008631 label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor
Christian Stimmingd990ced2007-11-07 18:42:55 +01008632 button $top.selbgbut -text [mc "Select bg"] -font optionfont \
Mark Levedahl281404c2007-06-26 21:51:34 -04008633 -command [list choosecolor selectbgcolor 0 $top.selbgsep background setselbg]
Mark Levedahl60378c02007-05-20 12:12:48 -04008634 grid x $top.selbgbut $top.selbgsep -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008635
Christian Stimmingd990ced2007-11-07 18:42:55 +01008636 label $top.cfont -text [mc "Fonts: press to choose"]
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008637 $top.cfont configure -font uifont
8638 grid $top.cfont - -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 18:42:55 +01008639 mkfontdisp mainfont $top [mc "Main font"]
8640 mkfontdisp textfont $top [mc "Diff display font"]
8641 mkfontdisp uifont $top [mc "User interface font"]
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008642
Paul Mackerras712fcc02005-11-30 09:28:16 +11008643 frame $top.buts
Christian Stimmingd990ced2007-11-07 18:42:55 +01008644 button $top.buts.ok -text [mc "OK"] -command prefsok -default active
Paul Mackerras9c311b32007-10-04 22:27:13 +10008645 $top.buts.ok configure -font uifont
Christian Stimmingd990ced2007-11-07 18:42:55 +01008646 button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal
Paul Mackerras9c311b32007-10-04 22:27:13 +10008647 $top.buts.can configure -font uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11008648 grid $top.buts.ok $top.buts.can
8649 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8650 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8651 grid $top.buts - - -pady 10 -sticky ew
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04008652 bind $top <Visibility> "focus $top.buts.ok"
Paul Mackerras712fcc02005-11-30 09:28:16 +11008653}
8654
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008655proc choosecolor {v vi w x cmd} {
8656 global $v
8657
8658 set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
Christian Stimmingd990ced2007-11-07 18:42:55 +01008659 -title [mc "Gitk: choose color for %s" $x]]
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008660 if {$c eq {}} return
8661 $w conf -background $c
8662 lset $v $vi $c
8663 eval $cmd $c
8664}
8665
Mark Levedahl60378c02007-05-20 12:12:48 -04008666proc setselbg {c} {
8667 global bglist cflist
8668 foreach w $bglist {
8669 $w configure -selectbackground $c
8670 }
8671 $cflist tag configure highlight \
8672 -background [$cflist cget -selectbackground]
8673 allcanvs itemconf secsel -fill $c
8674}
8675
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10008676proc setbg {c} {
8677 global bglist
8678
8679 foreach w $bglist {
8680 $w conf -background $c
8681 }
8682}
8683
8684proc setfg {c} {
8685 global fglist canv
8686
8687 foreach w $fglist {
8688 $w conf -foreground $c
8689 }
8690 allcanvs itemconf text -fill $c
8691 $canv itemconf circle -outline $c
8692}
8693
Paul Mackerras712fcc02005-11-30 09:28:16 +11008694proc prefscan {} {
Paul Mackerras94503912007-10-23 10:33:38 +10008695 global oldprefs prefstop
Paul Mackerras712fcc02005-11-30 09:28:16 +11008696
Paul Mackerras3de07112007-10-23 22:40:50 +10008697 foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
Paul Mackerras94503912007-10-23 10:33:38 +10008698 limitdiffs tabstop} {
8699 global $v
Paul Mackerras712fcc02005-11-30 09:28:16 +11008700 set $v $oldprefs($v)
8701 }
8702 catch {destroy $prefstop}
8703 unset prefstop
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008704 fontcan
Paul Mackerras712fcc02005-11-30 09:28:16 +11008705}
8706
8707proc prefsok {} {
8708 global maxwidth maxgraphpct
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008709 global oldprefs prefstop showneartags showlocalchanges
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008710 global fontpref mainfont textfont uifont
Paul Mackerras7b3b1512007-10-27 21:23:20 +10008711 global limitdiffs treediffs
Paul Mackerras712fcc02005-11-30 09:28:16 +11008712
8713 catch {destroy $prefstop}
8714 unset prefstop
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008715 fontcan
8716 set fontchanged 0
8717 if {$mainfont ne $fontpref(mainfont)} {
8718 set mainfont $fontpref(mainfont)
8719 parsefont mainfont $mainfont
8720 eval font configure mainfont [fontflags mainfont]
8721 eval font configure mainfontbold [fontflags mainfont 1]
8722 setcoords
8723 set fontchanged 1
8724 }
8725 if {$textfont ne $fontpref(textfont)} {
8726 set textfont $fontpref(textfont)
8727 parsefont textfont $textfont
8728 eval font configure textfont [fontflags textfont]
8729 eval font configure textfontbold [fontflags textfont 1]
8730 }
8731 if {$uifont ne $fontpref(uifont)} {
8732 set uifont $fontpref(uifont)
8733 parsefont uifont $uifont
8734 eval font configure uifont [fontflags uifont]
8735 }
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10008736 settabs
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008737 if {$showlocalchanges != $oldprefs(showlocalchanges)} {
8738 if {$showlocalchanges} {
8739 doshowlocalchanges
8740 } else {
8741 dohidelocalchanges
8742 }
8743 }
Paul Mackerras74a40c72007-10-24 10:16:56 +10008744 if {$limitdiffs != $oldprefs(limitdiffs)} {
8745 # treediffs elements are limited by path
8746 catch {unset treediffs}
8747 }
Paul Mackerras9a7558f2007-10-06 20:16:06 +10008748 if {$fontchanged || $maxwidth != $oldprefs(maxwidth)
Paul Mackerras712fcc02005-11-30 09:28:16 +11008749 || $maxgraphpct != $oldprefs(maxgraphpct)} {
8750 redisplay
Paul Mackerras7a39a172007-10-23 10:15:11 +10008751 } elseif {$showneartags != $oldprefs(showneartags) ||
8752 $limitdiffs != $oldprefs(limitdiffs)} {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10008753 reselectline
Paul Mackerras712fcc02005-11-30 09:28:16 +11008754 }
8755}
8756
8757proc formatdate {d} {
Arjen Laarhovene8b5f4b2007-08-14 22:02:04 +02008758 global datetimeformat
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008759 if {$d ne {}} {
Arjen Laarhovene8b5f4b2007-08-14 22:02:04 +02008760 set d [clock format $d -format $datetimeformat]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10008761 }
8762 return $d
Paul Mackerras232475d2005-11-15 10:34:03 +11008763}
8764
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11008765# This list of encoding names and aliases is distilled from
8766# http://www.iana.org/assignments/character-sets.
8767# Not all of them are supported by Tcl.
8768set encoding_aliases {
8769 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
8770 ISO646-US US-ASCII us IBM367 cp367 csASCII }
8771 { ISO-10646-UTF-1 csISO10646UTF1 }
8772 { ISO_646.basic:1983 ref csISO646basic1983 }
8773 { INVARIANT csINVARIANT }
8774 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
8775 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
8776 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
8777 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
8778 { NATS-DANO iso-ir-9-1 csNATSDANO }
8779 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
8780 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
8781 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
8782 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
8783 { ISO-2022-KR csISO2022KR }
8784 { EUC-KR csEUCKR }
8785 { ISO-2022-JP csISO2022JP }
8786 { ISO-2022-JP-2 csISO2022JP2 }
8787 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
8788 csISO13JISC6220jp }
8789 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
8790 { IT iso-ir-15 ISO646-IT csISO15Italian }
8791 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
8792 { ES iso-ir-17 ISO646-ES csISO17Spanish }
8793 { greek7-old iso-ir-18 csISO18Greek7Old }
8794 { latin-greek iso-ir-19 csISO19LatinGreek }
8795 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
8796 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
8797 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
8798 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
8799 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
8800 { BS_viewdata iso-ir-47 csISO47BSViewdata }
8801 { INIS iso-ir-49 csISO49INIS }
8802 { INIS-8 iso-ir-50 csISO50INIS8 }
8803 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
8804 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
8805 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
8806 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
8807 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
8808 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
8809 csISO60Norwegian1 }
8810 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
8811 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
8812 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
8813 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
8814 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
8815 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
8816 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
8817 { greek7 iso-ir-88 csISO88Greek7 }
8818 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
8819 { iso-ir-90 csISO90 }
8820 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
8821 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
8822 csISO92JISC62991984b }
8823 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
8824 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
8825 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
8826 csISO95JIS62291984handadd }
8827 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
8828 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
8829 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
8830 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
8831 CP819 csISOLatin1 }
8832 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
8833 { T.61-7bit iso-ir-102 csISO102T617bit }
8834 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
8835 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
8836 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
8837 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
8838 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
8839 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
8840 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
8841 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
8842 arabic csISOLatinArabic }
8843 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
8844 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
8845 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
8846 greek greek8 csISOLatinGreek }
8847 { T.101-G2 iso-ir-128 csISO128T101G2 }
8848 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
8849 csISOLatinHebrew }
8850 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
8851 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
8852 { CSN_369103 iso-ir-139 csISO139CSN369103 }
8853 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
8854 { ISO_6937-2-add iso-ir-142 csISOTextComm }
8855 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
8856 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
8857 csISOLatinCyrillic }
8858 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
8859 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
8860 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
8861 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
8862 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
8863 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
8864 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
8865 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
8866 { ISO_10367-box iso-ir-155 csISO10367Box }
8867 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
8868 { latin-lap lap iso-ir-158 csISO158Lap }
8869 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
8870 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
8871 { us-dk csUSDK }
8872 { dk-us csDKUS }
8873 { JIS_X0201 X0201 csHalfWidthKatakana }
8874 { KSC5636 ISO646-KR csKSC5636 }
8875 { ISO-10646-UCS-2 csUnicode }
8876 { ISO-10646-UCS-4 csUCS4 }
8877 { DEC-MCS dec csDECMCS }
8878 { hp-roman8 roman8 r8 csHPRoman8 }
8879 { macintosh mac csMacintosh }
8880 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
8881 csIBM037 }
8882 { IBM038 EBCDIC-INT cp038 csIBM038 }
8883 { IBM273 CP273 csIBM273 }
8884 { IBM274 EBCDIC-BE CP274 csIBM274 }
8885 { IBM275 EBCDIC-BR cp275 csIBM275 }
8886 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
8887 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
8888 { IBM280 CP280 ebcdic-cp-it csIBM280 }
8889 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
8890 { IBM284 CP284 ebcdic-cp-es csIBM284 }
8891 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
8892 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
8893 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
8894 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
8895 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
8896 { IBM424 cp424 ebcdic-cp-he csIBM424 }
8897 { IBM437 cp437 437 csPC8CodePage437 }
8898 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
8899 { IBM775 cp775 csPC775Baltic }
8900 { IBM850 cp850 850 csPC850Multilingual }
8901 { IBM851 cp851 851 csIBM851 }
8902 { IBM852 cp852 852 csPCp852 }
8903 { IBM855 cp855 855 csIBM855 }
8904 { IBM857 cp857 857 csIBM857 }
8905 { IBM860 cp860 860 csIBM860 }
8906 { IBM861 cp861 861 cp-is csIBM861 }
8907 { IBM862 cp862 862 csPC862LatinHebrew }
8908 { IBM863 cp863 863 csIBM863 }
8909 { IBM864 cp864 csIBM864 }
8910 { IBM865 cp865 865 csIBM865 }
8911 { IBM866 cp866 866 csIBM866 }
8912 { IBM868 CP868 cp-ar csIBM868 }
8913 { IBM869 cp869 869 cp-gr csIBM869 }
8914 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
8915 { IBM871 CP871 ebcdic-cp-is csIBM871 }
8916 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
8917 { IBM891 cp891 csIBM891 }
8918 { IBM903 cp903 csIBM903 }
8919 { IBM904 cp904 904 csIBBM904 }
8920 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
8921 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
8922 { IBM1026 CP1026 csIBM1026 }
8923 { EBCDIC-AT-DE csIBMEBCDICATDE }
8924 { EBCDIC-AT-DE-A csEBCDICATDEA }
8925 { EBCDIC-CA-FR csEBCDICCAFR }
8926 { EBCDIC-DK-NO csEBCDICDKNO }
8927 { EBCDIC-DK-NO-A csEBCDICDKNOA }
8928 { EBCDIC-FI-SE csEBCDICFISE }
8929 { EBCDIC-FI-SE-A csEBCDICFISEA }
8930 { EBCDIC-FR csEBCDICFR }
8931 { EBCDIC-IT csEBCDICIT }
8932 { EBCDIC-PT csEBCDICPT }
8933 { EBCDIC-ES csEBCDICES }
8934 { EBCDIC-ES-A csEBCDICESA }
8935 { EBCDIC-ES-S csEBCDICESS }
8936 { EBCDIC-UK csEBCDICUK }
8937 { EBCDIC-US csEBCDICUS }
8938 { UNKNOWN-8BIT csUnknown8BiT }
8939 { MNEMONIC csMnemonic }
8940 { MNEM csMnem }
8941 { VISCII csVISCII }
8942 { VIQR csVIQR }
8943 { KOI8-R csKOI8R }
8944 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
8945 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
8946 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
8947 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
8948 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
8949 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
8950 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
8951 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
8952 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
8953 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
8954 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
8955 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
8956 { IBM1047 IBM-1047 }
8957 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
8958 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
8959 { UNICODE-1-1 csUnicode11 }
8960 { CESU-8 csCESU-8 }
8961 { BOCU-1 csBOCU-1 }
8962 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
8963 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
8964 l8 }
8965 { ISO-8859-15 ISO_8859-15 Latin-9 }
8966 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
8967 { GBK CP936 MS936 windows-936 }
8968 { JIS_Encoding csJISEncoding }
8969 { Shift_JIS MS_Kanji csShiftJIS }
8970 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
8971 EUC-JP }
8972 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
8973 { ISO-10646-UCS-Basic csUnicodeASCII }
8974 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
8975 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
8976 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
8977 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
8978 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
8979 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
8980 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
8981 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
8982 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
8983 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
8984 { Adobe-Standard-Encoding csAdobeStandardEncoding }
8985 { Ventura-US csVenturaUS }
8986 { Ventura-International csVenturaInternational }
8987 { PC8-Danish-Norwegian csPC8DanishNorwegian }
8988 { PC8-Turkish csPC8Turkish }
8989 { IBM-Symbols csIBMSymbols }
8990 { IBM-Thai csIBMThai }
8991 { HP-Legal csHPLegal }
8992 { HP-Pi-font csHPPiFont }
8993 { HP-Math8 csHPMath8 }
8994 { Adobe-Symbol-Encoding csHPPSMath }
8995 { HP-DeskTop csHPDesktop }
8996 { Ventura-Math csVenturaMath }
8997 { Microsoft-Publishing csMicrosoftPublishing }
8998 { Windows-31J csWindows31J }
8999 { GB2312 csGB2312 }
9000 { Big5 csBig5 }
9001}
9002
9003proc tcl_encoding {enc} {
9004 global encoding_aliases
9005 set names [encoding names]
9006 set lcnames [string tolower $names]
9007 set enc [string tolower $enc]
9008 set i [lsearch -exact $lcnames $enc]
9009 if {$i < 0} {
9010 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
9011 if {[regsub {^iso[-_]} $enc iso encx]} {
9012 set i [lsearch -exact $lcnames $encx]
9013 }
9014 }
9015 if {$i < 0} {
9016 foreach l $encoding_aliases {
9017 set ll [string tolower $l]
9018 if {[lsearch -exact $ll $enc] < 0} continue
9019 # look through the aliases for one that tcl knows about
9020 foreach e $ll {
9021 set i [lsearch -exact $lcnames $e]
9022 if {$i < 0} {
9023 if {[regsub {^iso[-_]} $e iso ex]} {
9024 set i [lsearch -exact $lcnames $ex]
9025 }
9026 }
9027 if {$i >= 0} break
9028 }
9029 break
9030 }
9031 }
9032 if {$i >= 0} {
9033 return [lindex $names $i]
9034 }
9035 return {}
9036}
9037
Paul Mackerras5d7589d2007-10-20 21:21:03 +10009038# First check that Tcl/Tk is recent enough
9039if {[catch {package require Tk 8.4} err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009040 show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
9041 Gitk requires at least Tcl/Tk 8.4."]
Paul Mackerras5d7589d2007-10-20 21:21:03 +10009042 exit 1
9043}
9044
Paul Mackerras1d10f362005-05-15 12:55:47 +00009045# defaults...
9046set datemode 0
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03009047set wrcomcmd "git diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-27 16:12:51 -08009048
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11009049set gitencoding {}
Junio C Hamano671bc152005-11-27 16:12:51 -08009050catch {
Paul Mackerras27cb61c2007-02-15 08:54:34 +11009051 set gitencoding [exec git config --get i18n.commitencoding]
Junio C Hamano671bc152005-11-27 16:12:51 -08009052}
9053if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11009054 set gitencoding "utf-8"
9055}
9056set tclencoding [tcl_encoding $gitencoding]
9057if {$tclencoding == {}} {
9058 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-27 16:12:51 -08009059}
Paul Mackerras1d10f362005-05-15 12:55:47 +00009060
9061set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:47 +00009062set textfont {Courier 9}
Keith Packard4840be62006-04-04 00:19:45 -07009063set uifont {Helvetica 9 bold}
Mark Levedahl7e12f1a2007-05-20 11:45:50 -04009064set tabstop 8
Paul Mackerrasb74fd572005-07-16 07:46:13 -04009065set findmergefiles 0
Paul Mackerras8d858d12005-08-05 09:52:16 +10009066set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10009067set maxwidth 16
Paul Mackerras232475d2005-11-15 10:34:03 +11009068set revlistorder 0
Paul Mackerras757f17b2005-11-21 09:56:07 +11009069set fastdate 0
Paul Mackerras6e8c8702007-07-31 21:03:06 +10009070set uparrowlen 5
9071set downarrowlen 5
9072set mingaplen 100
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10009073set cmitmode "patch"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04009074set wrapcomment "none"
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10009075set showneartags 1
Paul Mackerras0a4dd8b2007-06-16 21:21:57 +10009076set maxrefs 20
Paul Mackerras322a8cc2006-10-15 18:03:46 +10009077set maxlinelen 200
Paul Mackerras219ea3a2006-09-07 10:21:39 +10009078set showlocalchanges 1
Paul Mackerras7a39a172007-10-23 10:15:11 +10009079set limitdiffs 1
Arjen Laarhovene8b5f4b2007-08-14 22:02:04 +02009080set datetimeformat "%Y-%m-%d %H:%M:%S"
Paul Mackerras1d10f362005-05-15 12:55:47 +00009081
9082set colors {green red blue magenta darkgrey brown orange}
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10009083set bgcolor white
9084set fgcolor black
9085set diffcolors {red "#00a000" blue}
Steffen Prohaska890fae72007-08-12 12:05:46 +02009086set diffcontext 3
Mark Levedahl60378c02007-05-20 12:12:48 -04009087set selectbgcolor gray85
Paul Mackerras1d10f362005-05-15 12:55:47 +00009088
Christian Stimming663c3aa2007-11-07 18:40:59 +01009089## For msgcat loading, first locate the installation location.
9090if { [info exists ::env(GITK_MSGSDIR)] } {
9091 ## Msgsdir was manually set in the environment.
9092 set gitk_msgsdir $::env(GITK_MSGSDIR)
9093} else {
9094 ## Let's guess the prefix from argv0.
9095 set gitk_prefix [file dirname [file dirname [file normalize $argv0]]]
9096 set gitk_libdir [file join $gitk_prefix share gitk lib]
9097 set gitk_msgsdir [file join $gitk_libdir msgs]
9098 unset gitk_prefix
9099}
9100
9101## Internationalization (i18n) through msgcat and gettext. See
9102## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
9103package require msgcat
9104namespace import ::msgcat::mc
9105## And eventually load the actual message catalog
9106::msgcat::mcload $gitk_msgsdir
9107
Paul Mackerras1d10f362005-05-15 12:55:47 +00009108catch {source ~/.gitk}
9109
Paul Mackerras712fcc02005-11-30 09:28:16 +11009110font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:00 +00009111
Paul Mackerras0ed1dd32007-10-06 18:27:37 +10009112parsefont mainfont $mainfont
9113eval font create mainfont [fontflags mainfont]
9114eval font create mainfontbold [fontflags mainfont 1]
9115
9116parsefont textfont $textfont
9117eval font create textfont [fontflags textfont]
9118eval font create textfontbold [fontflags textfont 1]
9119
9120parsefont uifont $uifont
9121eval font create uifont [fontflags uifont]
Paul Mackerras1db95b02005-05-09 04:08:39 +00009122
Paul Mackerrasaa81d972006-02-28 11:27:12 +11009123# check that we can find a .git directory somewhere...
Alex Riesen6c87d602007-07-29 22:29:45 +02009124if {[catch {set gitdir [gitdir]}]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009125 show_error {} . [mc "Cannot find a git repository here."]
Alex Riesen6c87d602007-07-29 22:29:45 +02009126 exit 1
9127}
Paul Mackerrasaa81d972006-02-28 11:27:12 +11009128if {![file isdirectory $gitdir]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009129 show_error {} . [mc "Cannot find the git directory \"%s\"." $gitdir]
Paul Mackerrasaa81d972006-02-28 11:27:12 +11009130 exit 1
9131}
9132
Paul Mackerras7a39a172007-10-23 10:15:11 +10009133set mergeonly 0
Paul Mackerrascdaee5d2007-07-12 22:29:49 +10009134set revtreeargs {}
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009135set cmdline_files {}
Paul Mackerrascdaee5d2007-07-12 22:29:49 +10009136set i 0
9137foreach arg $argv {
Paul Mackerras6ebedab2007-07-13 13:45:55 +10009138 switch -- $arg {
9139 "" { }
9140 "-d" { set datemode 1 }
Paul Mackerras7a39a172007-10-23 10:15:11 +10009141 "--merge" {
9142 set mergeonly 1
9143 lappend revtreeargs $arg
9144 }
Paul Mackerrascdaee5d2007-07-12 22:29:49 +10009145 "--" {
9146 set cmdline_files [lrange $argv [expr {$i + 1}] end]
9147 break
9148 }
9149 default {
9150 lappend revtreeargs $arg
9151 }
9152 }
9153 incr i
9154}
9155
9156if {$i >= [llength $argv] && $revtreeargs ne {}} {
9157 # no -- on command line, but some arguments (other than -d)
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009158 if {[catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03009159 set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009160 set cmdline_files [split $f "\n"]
9161 set n [llength $cmdline_files]
9162 set revtreeargs [lrange $revtreeargs 0 end-$n]
Paul Mackerrascdaee5d2007-07-12 22:29:49 +10009163 # Unfortunately git rev-parse doesn't produce an error when
9164 # something is both a revision and a filename. To be consistent
9165 # with git log and git rev-list, check revtreeargs for filenames.
9166 foreach arg $revtreeargs {
9167 if {[file exists $arg]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009168 show_error {} . [mc "Ambiguous argument '%s': both revision\
9169 and filename" $arg]
Paul Mackerrascdaee5d2007-07-12 22:29:49 +10009170 exit 1
9171 }
9172 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009173 } err]} {
9174 # unfortunately we get both stdout and stderr in $err,
9175 # so look for "fatal:".
9176 set i [string first "fatal:" $err]
9177 if {$i > 0} {
Junio C Hamanob5e09632006-05-26 00:07:15 -07009178 set err [string range $err [expr {$i + 6}] end]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009179 }
Christian Stimmingd990ced2007-11-07 18:42:55 +01009180 show_error {} . "[mc "Bad arguments to gitk:"]\n$err"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009181 exit 1
9182 }
9183}
9184
Paul Mackerras7a39a172007-10-23 10:15:11 +10009185if {$mergeonly} {
9186 # find the list of unmerged files
9187 set mlist {}
9188 set nr_unmerged 0
9189 if {[catch {
9190 set fd [open "| git ls-files -u" r]
9191 } err]} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009192 show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
Paul Mackerras7a39a172007-10-23 10:15:11 +10009193 exit 1
9194 }
9195 while {[gets $fd line] >= 0} {
9196 set i [string first "\t" $line]
9197 if {$i < 0} continue
9198 set fname [string range $line [expr {$i+1}] end]
9199 if {[lsearch -exact $mlist $fname] >= 0} continue
9200 incr nr_unmerged
9201 if {$cmdline_files eq {} || [path_filter $cmdline_files $fname]} {
9202 lappend mlist $fname
9203 }
9204 }
9205 catch {close $fd}
9206 if {$mlist eq {}} {
9207 if {$nr_unmerged == 0} {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009208 show_error {} . [mc "No files selected: --merge specified but\
9209 no files are unmerged."]
Paul Mackerras7a39a172007-10-23 10:15:11 +10009210 } else {
Christian Stimmingd990ced2007-11-07 18:42:55 +01009211 show_error {} . [mc "No files selected: --merge specified but\
9212 no unmerged files are within file limit."]
Paul Mackerras7a39a172007-10-23 10:15:11 +10009213 }
9214 exit 1
9215 }
9216 set cmdline_files $mlist
9217}
9218
Paul Mackerras219ea3a2006-09-07 10:21:39 +10009219set nullid "0000000000000000000000000000000000000000"
Paul Mackerras8f489362007-07-13 19:49:37 +10009220set nullid2 "0000000000000000000000000000000000000001"
9221
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10009222set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
Paul Mackerras219ea3a2006-09-07 10:21:39 +10009223
Paul Mackerras7eb3cb92007-06-17 14:45:00 +10009224set runq {}
Paul Mackerrasd6982062005-08-06 22:06:06 +10009225set history {}
9226set historyindex 0
Paul Mackerras908c3582006-05-20 09:38:11 +10009227set fh_serial 0
Paul Mackerras908c3582006-05-20 09:38:11 +10009228set nhl_names {}
Paul Mackerras63b79192006-05-20 21:31:52 +10009229set highlight_paths {}
Paul Mackerras687c8762007-09-22 12:49:33 +10009230set findpattern {}
Paul Mackerras1902c272006-05-25 21:25:13 +10009231set searchdirn -forwards
Paul Mackerras4e7d6772006-05-30 21:33:07 +10009232set boldrows {}
9233set boldnamerows {}
Paul Mackerrasa8d610a2007-04-19 11:39:12 +10009234set diffelide {0 0}
Paul Mackerras4fb0fa12007-07-04 19:43:51 +10009235set markingmatches 0
Paul Mackerras97645682007-08-23 22:24:38 +10009236set linkentercount 0
Paul Mackerras03800812007-08-29 21:45:21 +10009237set need_redisplay 0
9238set nrows_drawn 0
Paul Mackerras32f1b3e2007-09-28 21:27:39 +10009239set firsttabstop 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11009240
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009241set nextviewnum 1
9242set curview 0
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009243set selectedview 0
Christian Stimmingb007ee22007-11-07 18:44:35 +01009244set selectedhlview [mc "None"]
9245set highlight_related [mc "None"]
Paul Mackerras687c8762007-09-22 12:49:33 +10009246set highlight_files {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009247set viewfiles(0) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009248set viewperm(0) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009249set viewargs(0) {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009250
Paul Mackerras7fcc92b2007-12-03 10:33:01 +11009251set loginstance 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009252set cmdlineok 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00009253set stopped 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00009254set stuffsaved 0
Paul Mackerras74daedb2005-06-27 19:27:32 +10009255set patchnum 0
Paul Mackerras219ea3a2006-09-07 10:21:39 +10009256set lserial 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00009257setcoords
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10009258makewindow
Paul Mackerras0eafba12007-07-23 21:35:03 +10009259# wait for the window to become visible
9260tkwait visibility .
Doug Maxey6c283322006-12-10 14:31:46 -06009261wm title . "[file tail $argv0]: [file tail [pwd]]"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00009262readrefs
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10009263
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009264if {$cmdline_files ne {} || $revtreeargs ne {}} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009265 # create a view for the files/dirs specified on the command line
9266 set curview 1
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009267 set selectedview 1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009268 set nextviewnum 2
Christian Stimmingd990ced2007-11-07 18:42:55 +01009269 set viewname(1) [mc "Command line"]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009270 set viewfiles(1) $cmdline_files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009271 set viewargs(1) $revtreeargs
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009272 set viewperm(1) 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10009273 addviewmenu 1
Christian Stimmingd990ced2007-11-07 18:42:55 +01009274 .bar.view entryconf [mc "Edit view..."] -state normal
9275 .bar.view entryconf [mc "Delete view"] -state normal
Paul Mackerras50b44ec2006-04-04 10:16:22 +10009276}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009277
9278if {[info exists permviews]} {
9279 foreach v $permviews {
9280 set n $nextviewnum
9281 incr nextviewnum
9282 set viewname($n) [lindex $v 0]
9283 set viewfiles($n) [lindex $v 1]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10009284 set viewargs($n) [lindex $v 2]
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009285 set viewperm($n) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10009286 addviewmenu $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10009287 }
9288}
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10009289getcommits