blob: 9ddff3e7f7b011564c56fb619f57bed66d875f7e [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 Mackerrasda7c24d2006-05-02 11:15:29 +100019proc start_rev_list {view} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +100020 global startmsecs nextupdate
Paul Mackerras9f1afe02006-02-19 22:44:47 +110021 global commfd leftover tclencoding datemode
Paul Mackerras098dd8a2006-05-03 09:32:53 +100022 global viewargs viewfiles commitidx
Paul Mackerras38ad0912005-12-01 22:42:46 +110023
24 set startmsecs [clock clicks -milliseconds]
25 set nextupdate [expr {$startmsecs + 100}]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100026 set commitidx($view) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +100027 set args $viewargs($view)
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100028 if {$viewfiles($view) ne {}} {
29 set args [concat $args "--" $viewfiles($view)]
Paul Mackerrasa8aaf192006-04-23 22:45:55 +100030 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +110031 set order "--topo-order"
32 if {$datemode} {
33 set order "--date-order"
34 }
Paul Mackerras418c4c72006-02-07 09:10:18 +110035 if {[catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +030036 set fd [open [concat | git rev-list --header $order \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100037 --parents --boundary --default HEAD $args] r]
Paul Mackerras418c4c72006-02-07 09:10:18 +110038 } err]} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +030039 puts stderr "Error executing git rev-list: $err"
Paul Mackerras38ad0912005-12-01 22:42:46 +110040 exit 1
41 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100042 set commfd($view) $fd
43 set leftover($view) {}
44 fconfigure $fd -blocking 0 -translation lf
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +110045 if {$tclencoding != {}} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100046 fconfigure $fd -encoding $tclencoding
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +110047 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100048 fileevent $fd readable [list getcommitlines $fd $view]
49 nowbusy $view
Paul Mackerras38ad0912005-12-01 22:42:46 +110050}
51
Paul Mackerras22626ef2006-04-17 09:56:02 +100052proc stop_rev_list {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100053 global commfd curview
Paul Mackerras22626ef2006-04-17 09:56:02 +100054
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100055 if {![info exists commfd($curview)]} return
56 set fd $commfd($curview)
Paul Mackerras22626ef2006-04-17 09:56:02 +100057 catch {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100058 set pid [pid $fd]
Paul Mackerras22626ef2006-04-17 09:56:02 +100059 exec kill $pid
60 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100061 catch {close $fd}
62 unset commfd($curview)
Paul Mackerras22626ef2006-04-17 09:56:02 +100063}
64
Paul Mackerrasa8aaf192006-04-23 22:45:55 +100065proc getcommits {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100066 global phase canv mainfont curview
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010067
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010068 set phase getcommits
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100069 initlayout
70 start_rev_list $curview
Paul Mackerras098dd8a2006-05-03 09:32:53 +100071 show_status "Reading commits..."
Paul Mackerras1d10f362005-05-15 12:55:47 +000072}
73
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100074proc getcommitlines {fd view} {
Paul Mackerras8ed16482006-03-02 22:56:44 +110075 global commitlisted nextupdate
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100076 global leftover commfd
Paul Mackerras8ed16482006-03-02 22:56:44 +110077 global displayorder commitidx commitrow commitdata
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100078 global parentlist childlist children curview hlview
79 global vparentlist vchildlist vdisporder vcmitlisted
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +000080
Paul Mackerrasd1e46752006-08-16 20:02:32 +100081 set stuff [read $fd 500000]
Paul Mackerrasb490a992005-06-22 10:25:38 +100082 if {$stuff == {}} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100083 if {![eof $fd]} return
Paul Mackerras098dd8a2006-05-03 09:32:53 +100084 global viewname
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100085 unset commfd($view)
Paul Mackerras098dd8a2006-05-03 09:32:53 +100086 notbusy $view
Paul Mackerrasf0654862005-07-18 14:29:03 -040087 # set it blocking so we wait for the process to terminate
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100088 fconfigure $fd -blocking 1
Paul Mackerras098dd8a2006-05-03 09:32:53 +100089 if {[catch {close $fd} err]} {
90 set fv {}
91 if {$view != $curview} {
92 set fv " for the \"$viewname($view)\" view"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +100093 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +100094 if {[string range $err 0 4] == "usage"} {
95 set err "Gitk: error reading commits$fv:\
Timo Hirvonen8974c6f2006-05-24 10:57:40 +030096 bad arguments to git rev-list."
Paul Mackerras098dd8a2006-05-03 09:32:53 +100097 if {$viewname($view) eq "Command line"} {
98 append err \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +030099 " (Note: arguments to gitk are passed to git rev-list\
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000100 to allow selection of commits to be displayed.)"
101 }
102 } else {
103 set err "Error reading commits$fv: $err"
104 }
105 error_popup $err
Paul Mackerras1d10f362005-05-15 12:55:47 +0000106 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000107 if {$view == $curview} {
108 after idle finishcommits
Paul Mackerras9a40c502005-05-12 23:46:16 +0000109 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000110 return
Paul Mackerras9a40c502005-05-12 23:46:16 +0000111 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000112 set start 0
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100113 set gotsome 0
Paul Mackerrasb490a992005-06-22 10:25:38 +1000114 while 1 {
115 set i [string first "\0" $stuff $start]
116 if {$i < 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000117 append leftover($view) [string range $stuff $start end]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100118 break
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000119 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000120 if {$start == 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000121 set cmit $leftover($view)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100122 append cmit [string range $stuff 0 [expr {$i - 1}]]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000123 set leftover($view) {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100124 } else {
125 set cmit [string range $stuff $start [expr {$i - 1}]]
Paul Mackerrasb490a992005-06-22 10:25:38 +1000126 }
127 set start [expr {$i + 1}]
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000128 set j [string first "\n" $cmit]
129 set ok 0
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100130 set listed 1
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000131 if {$j >= 0} {
132 set ids [string range $cmit 0 [expr {$j - 1}]]
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100133 if {[string range $ids 0 0] == "-"} {
134 set listed 0
135 set ids [string range $ids 1 end]
136 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000137 set ok 1
138 foreach id $ids {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100139 if {[string length $id] != 40} {
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000140 set ok 0
141 break
142 }
143 }
144 }
145 if {!$ok} {
Paul Mackerras7e952e72005-06-27 20:04:26 +1000146 set shortcmit $cmit
147 if {[string length $shortcmit] > 80} {
148 set shortcmit "[string range $shortcmit 0 80]..."
149 }
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300150 error_popup "Can't parse git rev-list output: {$shortcmit}"
Paul Mackerrasb490a992005-06-22 10:25:38 +1000151 exit 1
152 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000153 set id [lindex $ids 0]
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100154 if {$listed} {
155 set olds [lrange $ids 1 end]
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000156 set i 0
Paul Mackerras79b2c752006-04-02 20:47:40 +1000157 foreach p $olds {
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000158 if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000159 lappend children($view,$p) $id
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000160 }
161 incr i
Paul Mackerras79b2c752006-04-02 20:47:40 +1000162 }
Paul Mackerras16c1ff92006-03-30 18:43:51 +1100163 } else {
164 set olds {}
165 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000166 if {![info exists children($view,$id)]} {
167 set children($view,$id) {}
Paul Mackerras79b2c752006-04-02 20:47:40 +1000168 }
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +1100169 set commitdata($id) [string range $cmit [expr {$j + 1}] end]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000170 set commitrow($view,$id) $commitidx($view)
171 incr commitidx($view)
172 if {$view == $curview} {
173 lappend parentlist $olds
174 lappend childlist $children($view,$id)
175 lappend displayorder $id
176 lappend commitlisted $listed
177 } else {
178 lappend vparentlist($view) $olds
179 lappend vchildlist($view) $children($view,$id)
180 lappend vdisporder($view) $id
181 lappend vcmitlisted($view) $listed
182 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100183 set gotsome 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100184 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100185 if {$gotsome} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000186 if {$view == $curview} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +1000187 while {[layoutmore $nextupdate]} doupdate
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000188 } elseif {[info exists hlview] && $view == $hlview} {
Paul Mackerras908c3582006-05-20 09:38:11 +1000189 vhighlightmore
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000190 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100191 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100192 if {[clock clicks -milliseconds] >= $nextupdate} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000193 doupdate
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000194 }
Paul Mackerrascfb45632005-05-31 12:14:42 +0000195}
196
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000197proc doupdate {} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +1000198 global commfd nextupdate numcommits
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000199
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000200 foreach v [array names commfd] {
201 fileevent $commfd($v) readable {}
Paul Mackerrasb6645502005-08-11 09:56:23 +1000202 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000203 update
Paul Mackerrasb6645502005-08-11 09:56:23 +1000204 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000205 foreach v [array names commfd] {
206 set fd $commfd($v)
207 fileevent $fd readable [list getcommitlines $fd $v]
Paul Mackerrasb6645502005-08-11 09:56:23 +1000208 }
Paul Mackerras1db95b02005-05-09 04:08:39 +0000209}
210
211proc readcommit {id} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300212 if {[catch {set contents [exec git cat-file commit $id]}]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100213 parsecommit $id $contents 0
Paul Mackerrasb490a992005-06-22 10:25:38 +1000214}
215
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000216proc updatecommits {} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000217 global viewdata curview phase displayorder
Paul Mackerras908c3582006-05-20 09:38:11 +1000218 global children commitrow selectedline thickerline
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000219
Paul Mackerras22626ef2006-04-17 09:56:02 +1000220 if {$phase ne {}} {
221 stop_rev_list
222 set phase {}
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100223 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +1000224 set n $curview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000225 foreach id $displayorder {
226 catch {unset children($n,$id)}
227 catch {unset commitrow($n,$id)}
228 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +1000229 set curview -1
Paul Mackerras908c3582006-05-20 09:38:11 +1000230 catch {unset selectedline}
231 catch {unset thickerline}
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +1000232 catch {unset viewdata($n)}
Paul Mackerras2d71bcc2006-06-07 09:19:45 +1000233 discardallcommits
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100234 readrefs
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +1000235 showview $n
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100236}
237
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100238proc parsecommit {id contents listed} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100239 global commitinfo cdate
240
241 set inhdr 1
242 set comment {}
243 set headline {}
244 set auname {}
245 set audate {}
246 set comname {}
247 set comdate {}
Paul Mackerras232475d2005-11-15 10:34:03 +1100248 set hdrend [string first "\n\n" $contents]
249 if {$hdrend < 0} {
250 # should never happen...
251 set hdrend [string length $contents]
252 }
253 set header [string range $contents 0 [expr {$hdrend - 1}]]
254 set comment [string range $contents [expr {$hdrend + 2}] end]
255 foreach line [split $header "\n"] {
256 set tag [lindex $line 0]
257 if {$tag == "author"} {
258 set audate [lindex $line end-1]
259 set auname [lrange $line 1 end-2]
260 } elseif {$tag == "committer"} {
261 set comdate [lindex $line end-1]
262 set comname [lrange $line 1 end-2]
Paul Mackerras1db95b02005-05-09 04:08:39 +0000263 }
264 }
Paul Mackerras232475d2005-11-15 10:34:03 +1100265 set headline {}
266 # take the first line of the comment as the headline
267 set i [string first "\n" $comment]
268 if {$i >= 0} {
269 set headline [string trim [string range $comment 0 $i]]
Paul Mackerrasf6e28692005-11-20 23:08:22 +1100270 } else {
271 set headline $comment
Paul Mackerras232475d2005-11-15 10:34:03 +1100272 }
273 if {!$listed} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300274 # git rev-list indents the comment by 4 spaces;
275 # if we got this via git cat-file, add the indentation
Paul Mackerras232475d2005-11-15 10:34:03 +1100276 set newcomment {}
277 foreach line [split $comment "\n"] {
278 append newcomment " "
279 append newcomment $line
Paul Mackerrasf6e28692005-11-20 23:08:22 +1100280 append newcomment "\n"
Paul Mackerras232475d2005-11-15 10:34:03 +1100281 }
282 set comment $newcomment
Paul Mackerras1db95b02005-05-09 04:08:39 +0000283 }
284 if {$comdate != {}} {
Paul Mackerrascfb45632005-05-31 12:14:42 +0000285 set cdate($id) $comdate
Paul Mackerras1db95b02005-05-09 04:08:39 +0000286 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000287 set commitinfo($id) [list $headline $auname $audate \
288 $comname $comdate $comment]
Paul Mackerras1db95b02005-05-09 04:08:39 +0000289}
290
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +1100291proc getcommit {id} {
Paul Mackerras79b2c752006-04-02 20:47:40 +1000292 global commitdata commitinfo
Paul Mackerras8ed16482006-03-02 22:56:44 +1100293
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +1100294 if {[info exists commitdata($id)]} {
295 parsecommit $id $commitdata($id) 1
Paul Mackerras8ed16482006-03-02 22:56:44 +1100296 } else {
297 readcommit $id
298 if {![info exists commitinfo($id)]} {
299 set commitinfo($id) {"No commit information available"}
Paul Mackerras8ed16482006-03-02 22:56:44 +1100300 }
301 }
302 return 1
303}
304
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000305proc readrefs {} {
Paul Mackerras106288c2005-08-19 23:11:39 +1000306 global tagids idtags headids idheads tagcontents
Paul Mackerras8a485712006-07-06 10:21:23 +1000307 global otherrefids idotherrefs mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000308
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100309 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
310 catch {unset $v}
311 }
Junio C Hamano0f57a312007-01-29 21:53:28 -0800312 set refd [open [list | git show-ref] r]
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800313 while {0 <= [set n [gets $refd line]]} {
Junio C Hamano0f57a312007-01-29 21:53:28 -0800314 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800315 match id path]} {
316 continue
317 }
Josef Weidendorfera970fcf2006-04-18 23:53:07 +0200318 if {[regexp {^remotes/.*/HEAD$} $path match]} {
319 continue
320 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800321 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
322 set type others
323 set name $path
324 }
Josef Weidendorfera970fcf2006-04-18 23:53:07 +0200325 if {[regexp {^remotes/} $path match]} {
326 set type heads
327 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800328 if {$type == "tags"} {
329 set tagids($name) $id
330 lappend idtags($id) $name
331 set obj {}
332 set type {}
333 set tag {}
334 catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +0300335 set commit [exec git rev-parse "$id^0"]
Paul Mackerrase1a7c812006-07-18 01:52:14 +1000336 if {$commit != $id} {
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800337 set tagids($name) $commit
338 lappend idtags($commit) $name
339 }
340 }
341 catch {
Paul Mackerrase1a7c812006-07-18 01:52:14 +1000342 set tagcontents($name) [exec git cat-file tag $id]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000343 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800344 } elseif { $type == "heads" } {
345 set headids($name) $id
346 lappend idheads($id) $name
347 } else {
348 set otherrefids($name) $id
349 lappend idotherrefs($id) $name
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000350 }
351 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800352 close $refd
Paul Mackerras8a485712006-07-06 10:21:23 +1000353 set mainhead {}
354 catch {
355 set thehead [exec git symbolic-ref HEAD]
356 if {[string match "refs/heads/*" $thehead]} {
357 set mainhead [string range $thehead 11 end]
358 }
359 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000360}
361
Paul Mackerrase54be9e2006-05-26 22:34:30 +1000362proc show_error {w top msg} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000363 message $w.m -text $msg -justify center -aspect 400
364 pack $w.m -side top -fill x -padx 20 -pady 20
Paul Mackerrase54be9e2006-05-26 22:34:30 +1000365 button $w.ok -text OK -command "destroy $top"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000366 pack $w.ok -side bottom -fill x
Paul Mackerrase54be9e2006-05-26 22:34:30 +1000367 bind $top <Visibility> "grab $top; focus $top"
368 bind $top <Key-Return> "destroy $top"
369 tkwait window $top
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000370}
371
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000372proc error_popup msg {
373 set w .error
374 toplevel $w
375 wm transient $w .
Paul Mackerrase54be9e2006-05-26 22:34:30 +1000376 show_error $w $w $msg
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000377}
378
Paul Mackerras10299152006-08-02 09:52:01 +1000379proc confirm_popup msg {
380 global confirm_ok
381 set confirm_ok 0
382 set w .confirm
383 toplevel $w
384 wm transient $w .
385 message $w.m -text $msg -justify center -aspect 400
386 pack $w.m -side top -fill x -padx 20 -pady 20
387 button $w.ok -text OK -command "set confirm_ok 1; destroy $w"
388 pack $w.ok -side left -fill x
389 button $w.cancel -text Cancel -command "destroy $w"
390 pack $w.cancel -side right -fill x
391 bind $w <Visibility> "grab $w; focus $w"
392 tkwait window $w
393 return $confirm_ok
394}
395
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +1000396proc makewindow {} {
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +1000397 global canv canv2 canv3 linespc charspc ctext cflist
398 global textfont mainfont uifont
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400399 global findtype findtypemenu findloc findstring fstring geometry
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000400 global entries sha1entry sha1string sha1but
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000401 global maincursor textcursor curtextcursor
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400402 global rowctxmenu mergemax wrapcomment
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000403 global highlight_files gdttype
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000404 global searchstring sstring
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000405 global bgcolor fgcolor bglist fglist diffcolors
Paul Mackerras10299152006-08-02 09:52:01 +1000406 global headctxmenu
Paul Mackerras9a40c502005-05-12 23:46:16 +0000407
408 menu .bar
409 .bar add cascade -label "File" -menu .bar.file
Keith Packard4840be62006-04-04 00:19:45 -0700410 .bar configure -font $uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +0000411 menu .bar.file
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000412 .bar.file add command -label "Update" -command updatecommits
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000413 .bar.file add command -label "Reread references" -command rereadrefs
Paul Mackerras1d10f362005-05-15 12:55:47 +0000414 .bar.file add command -label "Quit" -command doquit
Keith Packard4840be62006-04-04 00:19:45 -0700415 .bar.file configure -font $uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +1100416 menu .bar.edit
417 .bar add cascade -label "Edit" -menu .bar.edit
418 .bar.edit add command -label "Preferences" -command doprefs
Keith Packard4840be62006-04-04 00:19:45 -0700419 .bar.edit configure -font $uifont
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000420
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +1000421 menu .bar.view -font $uifont
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000422 .bar add cascade -label "View" -menu .bar.view
Paul Mackerrasda7c24d2006-05-02 11:15:29 +1000423 .bar.view add command -label "New view..." -command {newview 0}
424 .bar.view add command -label "Edit view..." -command editview \
425 -state disabled
Paul Mackerras50b44ec2006-04-04 10:16:22 +1000426 .bar.view add command -label "Delete view" -command delview -state disabled
427 .bar.view add separator
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000428 .bar.view add radiobutton -label "All files" -command {showview 0} \
429 -variable selectedview -value 0
Mark Levedahl32364b32007-02-01 08:44:46 -0500430
Paul Mackerras9a40c502005-05-12 23:46:16 +0000431 menu .bar.help
432 .bar add cascade -label "Help" -menu .bar.help
433 .bar.help add command -label "About gitk" -command about
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000434 .bar.help add command -label "Key bindings" -command keys
Keith Packard4840be62006-04-04 00:19:45 -0700435 .bar.help configure -font $uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +0000436 . configure -menu .bar
437
Mark Levedahl3468e712007-02-01 08:46:38 -0500438 # the gui has upper and lower half, parts of a paned window.
Paul Mackerras0327d272005-05-10 00:23:42 +0000439 panedwindow .ctop -orient vertical
Mark Levedahl3468e712007-02-01 08:46:38 -0500440
441 # possibly use assumed geometry
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500442 if {![info exists geometry(pwsash0)]} {
Mark Levedahl3468e712007-02-01 08:46:38 -0500443 set geometry(topheight) [expr {15 * $linespc}]
444 set geometry(topwidth) [expr {80 * $charspc}]
445 set geometry(botheight) [expr {15 * $linespc}]
446 set geometry(botwidth) [expr {50 * $charspc}]
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500447 set geometry(pwsash0) "[expr {40 * $charspc}] 2"
448 set geometry(pwsash1) "[expr {60 * $charspc}] 2"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000449 }
Mark Levedahl3468e712007-02-01 08:46:38 -0500450
451 # the upper half will have a paned window, a scroll bar to the right, and some stuff below
452 frame .tf -height $geometry(topheight) -width $geometry(topwidth)
453 frame .tf.histframe
454 panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
455
456 # create three canvases
457 set cscroll .tf.histframe.csb
458 set canv .tf.histframe.pwclist.canv
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500459 canvas $canv \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000460 -background $bgcolor -bd 0 \
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100461 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Mark Levedahl3468e712007-02-01 08:46:38 -0500462 .tf.histframe.pwclist add $canv
463 set canv2 .tf.histframe.pwclist.canv2
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500464 canvas $canv2 \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000465 -background $bgcolor -bd 0 -yscrollincr $linespc
Mark Levedahl3468e712007-02-01 08:46:38 -0500466 .tf.histframe.pwclist add $canv2
467 set canv3 .tf.histframe.pwclist.canv3
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500468 canvas $canv3 \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000469 -background $bgcolor -bd 0 -yscrollincr $linespc
Mark Levedahl3468e712007-02-01 08:46:38 -0500470 .tf.histframe.pwclist add $canv3
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500471 eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
472 eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
Paul Mackerras98f350e2005-05-15 05:56:51 +0000473
Mark Levedahl3468e712007-02-01 08:46:38 -0500474 # a scroll bar to rule them
475 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
476 pack $cscroll -side right -fill y
477 bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
478 lappend bglist $canv $canv2 $canv3
479 pack .tf.histframe.pwclist -fill both -expand 1 -side left
480
481 # we have two button bars at bottom of top frame. Bar 1
482 frame .tf.bar
483 frame .tf.lbar -height 15
484
485 set sha1entry .tf.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000486 set entries $sha1entry
Mark Levedahl3468e712007-02-01 08:46:38 -0500487 set sha1but .tf.bar.sha1label
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000488 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
Keith Packard4840be62006-04-04 00:19:45 -0700489 -command gotocommit -width 8 -font $uifont
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000490 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Mark Levedahl3468e712007-02-01 08:46:38 -0500491 pack .tf.bar.sha1label -side left
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000492 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
493 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51 +0000494 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 22:06:06 +1000495
496 image create bitmap bm-left -data {
497 #define left_width 16
498 #define left_height 16
499 static unsigned char left_bits[] = {
500 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
501 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
502 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
503 }
504 image create bitmap bm-right -data {
505 #define right_width 16
506 #define right_height 16
507 static unsigned char right_bits[] = {
508 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
509 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
510 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
511 }
Mark Levedahl3468e712007-02-01 08:46:38 -0500512 button .tf.bar.leftbut -image bm-left -command goback \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000513 -state disabled -width 26
Mark Levedahl3468e712007-02-01 08:46:38 -0500514 pack .tf.bar.leftbut -side left -fill y
515 button .tf.bar.rightbut -image bm-right -command goforw \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000516 -state disabled -width 26
Mark Levedahl3468e712007-02-01 08:46:38 -0500517 pack .tf.bar.rightbut -side left -fill y
Paul Mackerrasd6982062005-08-06 22:06:06 +1000518
Mark Levedahl3468e712007-02-01 08:46:38 -0500519 button .tf.bar.findbut -text "Find" -command dofind -font $uifont
520 pack .tf.bar.findbut -side left
Paul Mackerras98f350e2005-05-15 05:56:51 +0000521 set findstring {}
Mark Levedahl3468e712007-02-01 08:46:38 -0500522 set fstring .tf.bar.findstring
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000523 lappend entries $fstring
Paul Mackerras908c3582006-05-20 09:38:11 +1000524 entry $fstring -width 30 -font $textfont -textvariable findstring
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000525 trace add variable findstring write find_change
Mark Levedahl3468e712007-02-01 08:46:38 -0500526 pack $fstring -side left -expand 1 -fill x -in .tf.bar
Paul Mackerras98f350e2005-05-15 05:56:51 +0000527 set findtype Exact
Mark Levedahl3468e712007-02-01 08:46:38 -0500528 set findtypemenu [tk_optionMenu .tf.bar.findtype \
529 findtype Exact IgnCase Regexp]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000530 trace add variable findtype write find_change
Mark Levedahl3468e712007-02-01 08:46:38 -0500531 .tf.bar.findtype configure -font $uifont
532 .tf.bar.findtype.menu configure -font $uifont
Paul Mackerras98f350e2005-05-15 05:56:51 +0000533 set findloc "All fields"
Mark Levedahl3468e712007-02-01 08:46:38 -0500534 tk_optionMenu .tf.bar.findloc findloc "All fields" Headline \
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000535 Comments Author Committer
536 trace add variable findloc write find_change
Mark Levedahl3468e712007-02-01 08:46:38 -0500537 .tf.bar.findloc configure -font $uifont
538 .tf.bar.findloc.menu configure -font $uifont
539 pack .tf.bar.findloc -side right
540 pack .tf.bar.findtype -side right
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000541
Mark Levedahl3468e712007-02-01 08:46:38 -0500542 # build up the bottom bar of upper window
543 label .tf.lbar.flabel -text "Highlight: Commits " \
544 -font $uifont
545 pack .tf.lbar.flabel -side left -fill y
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000546 set gdttype "touching paths:"
Mark Levedahl3468e712007-02-01 08:46:38 -0500547 set gm [tk_optionMenu .tf.lbar.gdttype gdttype "touching paths:" \
548 "adding/removing string:"]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000549 trace add variable gdttype write hfiles_change
550 $gm conf -font $uifont
Mark Levedahl3468e712007-02-01 08:46:38 -0500551 .tf.lbar.gdttype conf -font $uifont
552 pack .tf.lbar.gdttype -side left -fill y
553 entry .tf.lbar.fent -width 25 -font $textfont \
Paul Mackerras908c3582006-05-20 09:38:11 +1000554 -textvariable highlight_files
555 trace add variable highlight_files write hfiles_change
Mark Levedahl3468e712007-02-01 08:46:38 -0500556 lappend entries .tf.lbar.fent
557 pack .tf.lbar.fent -side left -fill x -expand 1
558 label .tf.lbar.vlabel -text " OR in view" -font $uifont
559 pack .tf.lbar.vlabel -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000560 global viewhlmenu selectedhlview
Mark Levedahl3468e712007-02-01 08:46:38 -0500561 set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview None]
Paul Mackerras3cd204e2006-11-23 21:06:16 +1100562 $viewhlmenu entryconf None -command delvhighlight
Paul Mackerras63b79192006-05-20 21:31:52 +1000563 $viewhlmenu conf -font $uifont
Mark Levedahl3468e712007-02-01 08:46:38 -0500564 .tf.lbar.vhl conf -font $uifont
565 pack .tf.lbar.vhl -side left -fill y
566 label .tf.lbar.rlabel -text " OR " -font $uifont
567 pack .tf.lbar.rlabel -side left -fill y
Paul Mackerras164ff272006-05-29 19:50:02 +1000568 global highlight_related
Mark Levedahl3468e712007-02-01 08:46:38 -0500569 set m [tk_optionMenu .tf.lbar.relm highlight_related None \
570 "Descendent" "Not descendent" "Ancestor" "Not ancestor"]
Paul Mackerras164ff272006-05-29 19:50:02 +1000571 $m conf -font $uifont
Mark Levedahl3468e712007-02-01 08:46:38 -0500572 .tf.lbar.relm conf -font $uifont
Paul Mackerras164ff272006-05-29 19:50:02 +1000573 trace add variable highlight_related write vrel_change
Mark Levedahl3468e712007-02-01 08:46:38 -0500574 pack .tf.lbar.relm -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000575
Mark Levedahl3468e712007-02-01 08:46:38 -0500576 # Finish putting the upper half of the viewer together
577 pack .tf.lbar -in .tf -side bottom -fill x
578 pack .tf.bar -in .tf -side bottom -fill x
579 pack .tf.histframe -fill both -side top -expand 1
580 .ctop add .tf
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500581 .ctop paneconfigure .tf -height $geometry(topheight)
582 .ctop paneconfigure .tf -width $geometry(topwidth)
Mark Levedahl3468e712007-02-01 08:46:38 -0500583
584 # now build up the bottom
585 panedwindow .pwbottom -orient horizontal
586
587 # lower left, a text box over search bar, scroll bar to the right
588 # if we know window height, then that will set the lower text height, otherwise
589 # we set lower text height which will drive window height
590 if {[info exists geometry(main)]} {
591 frame .bleft -width $geometry(botwidth)
592 } else {
593 frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
594 }
595 frame .bleft.top
596
597 button .bleft.top.search -text "Search" -command dosearch \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000598 -font $uifont
Mark Levedahl3468e712007-02-01 08:46:38 -0500599 pack .bleft.top.search -side left -padx 5
600 set sstring .bleft.top.sstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000601 entry $sstring -width 20 -font $textfont -textvariable searchstring
602 lappend entries $sstring
603 trace add variable searchstring write incrsearch
604 pack $sstring -side left -expand 1 -fill x
Mark Levedahl3468e712007-02-01 08:46:38 -0500605 set ctext .bleft.ctext
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000606 text $ctext -background $bgcolor -foreground $fgcolor \
607 -state disabled -font $textfont \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000608 -yscrollcommand scrolltext -wrap none
Mark Levedahl3468e712007-02-01 08:46:38 -0500609 scrollbar .bleft.sb -command "$ctext yview"
610 pack .bleft.top -side top -fill x
611 pack .bleft.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000612 pack $ctext -side left -fill both -expand 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000613 lappend bglist $ctext
614 lappend fglist $ctext
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000615
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400616 $ctext tag conf comment -wrap $wrapcomment
Paul Mackerrasf0654862005-07-18 14:29:03 -0400617 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000618 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
619 $ctext tag conf d0 -fore [lindex $diffcolors 0]
620 $ctext tag conf d1 -fore [lindex $diffcolors 1]
Paul Mackerras712fcc02005-11-30 09:28:16 +1100621 $ctext tag conf m0 -fore red
622 $ctext tag conf m1 -fore blue
623 $ctext tag conf m2 -fore green
624 $ctext tag conf m3 -fore purple
625 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100626 $ctext tag conf m5 -fore "#009090"
627 $ctext tag conf m6 -fore magenta
628 $ctext tag conf m7 -fore "#808000"
629 $ctext tag conf m8 -fore "#009000"
630 $ctext tag conf m9 -fore "#ff0080"
631 $ctext tag conf m10 -fore cyan
632 $ctext tag conf m11 -fore "#b07070"
633 $ctext tag conf m12 -fore "#70b0f0"
634 $ctext tag conf m13 -fore "#70f0b0"
635 $ctext tag conf m14 -fore "#f0b070"
636 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-30 09:28:16 +1100637 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100638 set mergemax 16
Paul Mackerras712fcc02005-11-30 09:28:16 +1100639 $ctext tag conf mresult -font [concat $textfont bold]
640 $ctext tag conf msep -font [concat $textfont bold]
641 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000642
Mark Levedahl3468e712007-02-01 08:46:38 -0500643 .pwbottom add .bleft
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500644 .pwbottom paneconfigure .bleft -width $geometry(botwidth)
Mark Levedahl3468e712007-02-01 08:46:38 -0500645
646 # lower right
647 frame .bright
648 frame .bright.mode
649 radiobutton .bright.mode.patch -text "Patch" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000650 -command reselectline -variable cmitmode -value "patch"
Mark Levedahl3468e712007-02-01 08:46:38 -0500651 radiobutton .bright.mode.tree -text "Tree" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000652 -command reselectline -variable cmitmode -value "tree"
Mark Levedahl3468e712007-02-01 08:46:38 -0500653 grid .bright.mode.patch .bright.mode.tree -sticky ew
654 pack .bright.mode -side top -fill x
655 set cflist .bright.cfiles
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000656 set indent [font measure $mainfont "nn"]
Mark Levedahl3468e712007-02-01 08:46:38 -0500657 text $cflist \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000658 -background $bgcolor -foreground $fgcolor \
659 -font $mainfont \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000660 -tabs [list $indent [expr {2 * $indent}]] \
Mark Levedahl3468e712007-02-01 08:46:38 -0500661 -yscrollcommand ".bright.sb set" \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000662 -cursor [. cget -cursor] \
663 -spacing1 1 -spacing3 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000664 lappend bglist $cflist
665 lappend fglist $cflist
Mark Levedahl3468e712007-02-01 08:46:38 -0500666 scrollbar .bright.sb -command "$cflist yview"
667 pack .bright.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000668 pack $cflist -side left -fill both -expand 1
Paul Mackerras89b11d32006-05-02 19:55:31 +1000669 $cflist tag configure highlight \
670 -background [$cflist cget -selectbackground]
Paul Mackerras63b79192006-05-20 21:31:52 +1000671 $cflist tag configure bold -font [concat $mainfont bold]
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000672
Mark Levedahl3468e712007-02-01 08:46:38 -0500673 .pwbottom add .bright
674 .ctop add .pwbottom
Paul Mackerras1db95b02005-05-09 04:08:39 +0000675
Mark Levedahl3468e712007-02-01 08:46:38 -0500676 # restore window position if known
677 if {[info exists geometry(main)]} {
678 wm geometry . "$geometry(main)"
679 }
680
681 bind .pwbottom <Configure> {resizecdetpanes %W %w}
682 pack .ctop -fill both -expand 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000683 bindall <1> {selcanvline %W %x %y}
684 #bindall <B1-Motion> {selcanvline %W %x %y}
Paul Mackerrascfb45632005-05-31 12:14:42 +0000685 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
686 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100687 bindall <2> "canvscan mark %W %x %y"
688 bindall <B2-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000689 bindkey <Home> selfirstline
690 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:00 +0000691 bind . <Key-Up> "selnextline -1"
692 bind . <Key-Down> "selnextline 1"
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000693 bind . <Shift-Key-Up> "next_highlight -1"
694 bind . <Shift-Key-Down> "next_highlight 1"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000695 bindkey <Key-Right> "goforw"
696 bindkey <Key-Left> "goback"
697 bind . <Key-Prior> "selnextpage -1"
698 bind . <Key-Next> "selnextpage 1"
699 bind . <Control-Home> "allcanvs yview moveto 0.0"
700 bind . <Control-End> "allcanvs yview moveto 1.0"
701 bind . <Control-Key-Up> "allcanvs yview scroll -1 units"
702 bind . <Control-Key-Down> "allcanvs yview scroll 1 units"
703 bind . <Control-Key-Prior> "allcanvs yview scroll -1 pages"
704 bind . <Control-Key-Next> "allcanvs yview scroll 1 pages"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000705 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
706 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
707 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000708 bindkey p "selnextline -1"
709 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +1000710 bindkey z "goback"
711 bindkey x "goforw"
712 bindkey i "selnextline -1"
713 bindkey k "selnextline 1"
714 bindkey j "goback"
715 bindkey l "goforw"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000716 bindkey b "$ctext yview scroll -1 pages"
717 bindkey d "$ctext yview scroll 18 units"
718 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400719 bindkey / {findnext 1}
720 bindkey <Key-Return> {findnext 0}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000721 bindkey ? findprev
Paul Mackerras39ad8572005-05-19 12:35:53 +0000722 bindkey f nextfile
Paul Mackerras1d10f362005-05-15 12:55:47 +0000723 bind . <Control-q> doquit
Paul Mackerras98f350e2005-05-15 05:56:51 +0000724 bind . <Control-f> dofind
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400725 bind . <Control-g> {findnext 0}
Paul Mackerras1902c272006-05-25 21:25:13 +1000726 bind . <Control-r> dosearchback
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000727 bind . <Control-s> dosearch
Paul Mackerras1d10f362005-05-15 12:55:47 +0000728 bind . <Control-equal> {incrfont 1}
729 bind . <Control-KP_Add> {incrfont 1}
730 bind . <Control-minus> {incrfont -1}
731 bind . <Control-KP_Subtract> {incrfont -1}
Mark Levedahl602598f2007-02-08 22:22:24 -0500732 wm protocol . WM_DELETE_WINDOW doquit
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000733 bind . <Button-1> "click %W"
Paul Mackerras17386062005-05-18 22:51:00 +0000734 bind $fstring <Key-Return> dofind
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000735 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 16:37:13 +1000736 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000737 bind $cflist <1> {sel_flist %W %x %y; break}
738 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000739 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
Paul Mackerrasea13cba2005-06-16 10:54:04 +0000740
741 set maincursor [. cget -cursor]
742 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000743 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26 +0000744
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000745 set rowctxmenu .rowctxmenu
746 menu $rowctxmenu -tearoff 0
747 $rowctxmenu add command -label "Diff this -> selected" \
748 -command {diffvssel 0}
749 $rowctxmenu add command -label "Diff selected -> this" \
750 -command {diffvssel 1}
Paul Mackerras74daedb2005-06-27 19:27:32 +1000751 $rowctxmenu add command -label "Make patch" -command mkpatch
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +1000752 $rowctxmenu add command -label "Create tag" -command mktag
Paul Mackerras4a2139f2005-06-29 09:47:48 +1000753 $rowctxmenu add command -label "Write commit to file" -command writecommit
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +1000754 $rowctxmenu add command -label "Create new branch" -command mkbranch
Paul Mackerrasca6d8f52006-08-06 21:08:05 +1000755 $rowctxmenu add command -label "Cherry-pick this commit" \
756 -command cherrypick
Paul Mackerras10299152006-08-02 09:52:01 +1000757
758 set headctxmenu .headctxmenu
759 menu $headctxmenu -tearoff 0
760 $headctxmenu add command -label "Check out this branch" \
761 -command cobranch
762 $headctxmenu add command -label "Remove this branch" \
763 -command rmbranch
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000764}
765
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100766# mouse-2 makes all windows scan vertically, but only the one
767# the cursor is in scans horizontally
768proc canvscan {op w x y} {
769 global canv canv2 canv3
770 foreach c [list $canv $canv2 $canv3] {
771 if {$c == $w} {
772 $c scan $op $x $y
773 } else {
774 $c scan $op 0 $y
775 }
776 }
777}
778
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100779proc scrollcanv {cscroll f0 f1} {
780 $cscroll set $f0 $f1
781 drawfrac $f0 $f1
Paul Mackerras908c3582006-05-20 09:38:11 +1000782 flushhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100783}
784
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000785# when we make a key binding for the toplevel, make sure
786# it doesn't get triggered when that key is pressed in the
787# find string entry widget.
788proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000789 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000790 bind . $ev $script
791 set escript [bind Entry $ev]
792 if {$escript == {}} {
793 set escript [bind Entry <Key>]
794 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000795 foreach e $entries {
796 bind $e $ev "$escript; break"
797 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000798}
799
800# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000801# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000802proc click {w} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000803 global entries
804 foreach e $entries {
805 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000806 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000807 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000808}
809
810proc savestuff {w} {
Keith Packard4840be62006-04-04 00:19:45 -0700811 global canv canv2 canv3 ctext cflist mainfont textfont uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +1100812 global stuffsaved findmergefiles maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000813 global maxwidth showneartags
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000814 global viewname viewfiles viewargs viewperm nextviewnum
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400815 global cmitmode wrapcomment
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000816 global colors bgcolor fgcolor diffcolors
Paul Mackerras4ef17532005-07-27 22:16:51 -0500817
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000818 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000819 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000820 catch {
821 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400822 puts $f [list set mainfont $mainfont]
823 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 00:19:45 -0700824 puts $f [list set uifont $uifont]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400825 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-05 09:52:16 +1000826 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 10:22:24 +1000827 puts $f [list set maxwidth $maxwidth]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000828 puts $f [list set cmitmode $cmitmode]
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400829 puts $f [list set wrapcomment $wrapcomment]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000830 puts $f [list set showneartags $showneartags]
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000831 puts $f [list set bgcolor $bgcolor]
832 puts $f [list set fgcolor $fgcolor]
833 puts $f [list set colors $colors]
834 puts $f [list set diffcolors $diffcolors]
Mark Levedahl3468e712007-02-01 08:46:38 -0500835
Mark Levedahl602598f2007-02-08 22:22:24 -0500836 puts $f "set geometry(main) [wm geometry .]"
Mark Levedahl3468e712007-02-01 08:46:38 -0500837 puts $f "set geometry(topwidth) [winfo width .tf]"
838 puts $f "set geometry(topheight) [winfo height .tf]"
Mark Levedahl2055f3b2007-02-12 19:19:34 -0500839 puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
840 puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
Mark Levedahl3468e712007-02-01 08:46:38 -0500841 puts $f "set geometry(botwidth) [winfo width .bleft]"
842 puts $f "set geometry(botheight) [winfo height .bleft]"
843
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000844 puts -nonewline $f "set permviews {"
845 for {set v 0} {$v < $nextviewnum} {incr v} {
846 if {$viewperm($v)} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000847 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000848 }
849 }
850 puts $f "}"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000851 close $f
852 file rename -force "~/.gitk-new" "~/.gitk"
853 }
854 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:39 +0000855}
856
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000857proc resizeclistpanes {win w} {
858 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100859 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000860 set s0 [$win sash coord 0]
861 set s1 [$win sash coord 1]
862 if {$w < 60} {
863 set sash0 [expr {int($w/2 - 2)}]
864 set sash1 [expr {int($w*5/6 - 2)}]
865 } else {
866 set factor [expr {1.0 * $w / $oldwidth($win)}]
867 set sash0 [expr {int($factor * [lindex $s0 0])}]
868 set sash1 [expr {int($factor * [lindex $s1 0])}]
869 if {$sash0 < 30} {
870 set sash0 30
871 }
872 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800873 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000874 }
875 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800876 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000877 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800878 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000879 }
880 }
881 }
882 $win sash place 0 $sash0 [lindex $s0 1]
883 $win sash place 1 $sash1 [lindex $s1 1]
884 }
885 set oldwidth($win) $w
886}
887
888proc resizecdetpanes {win w} {
889 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100890 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000891 set s0 [$win sash coord 0]
892 if {$w < 60} {
893 set sash0 [expr {int($w*3/4 - 2)}]
894 } else {
895 set factor [expr {1.0 * $w / $oldwidth($win)}]
896 set sash0 [expr {int($factor * [lindex $s0 0])}]
897 if {$sash0 < 45} {
898 set sash0 45
899 }
900 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800901 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000902 }
903 }
904 $win sash place 0 $sash0 [lindex $s0 1]
905 }
906 set oldwidth($win) $w
907}
908
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000909proc allcanvs args {
910 global canv canv2 canv3
911 eval $canv $args
912 eval $canv2 $args
913 eval $canv3 $args
914}
915
916proc bindall {event action} {
917 global canv canv2 canv3
918 bind $canv $event $action
919 bind $canv2 $event $action
920 bind $canv3 $event $action
921}
922
Paul Mackerras9a40c502005-05-12 23:46:16 +0000923proc about {} {
924 set w .about
925 if {[winfo exists $w]} {
926 raise $w
927 return
928 }
929 toplevel $w
930 wm title $w "About gitk"
931 message $w.m -text {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100932Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16 +0000933
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100934Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16 +0000935
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000936Use and redistribute under the terms of the GNU General Public License} \
Paul Mackerras9a40c502005-05-12 23:46:16 +0000937 -justify center -aspect 400
938 pack $w.m -side top -fill x -padx 20 -pady 20
939 button $w.ok -text Close -command "destroy $w"
940 pack $w.ok -side bottom
941}
942
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000943proc keys {} {
944 set w .keys
945 if {[winfo exists $w]} {
946 raise $w
947 return
948 }
949 toplevel $w
950 wm title $w "Gitk key bindings"
951 message $w.m -text {
952Gitk key bindings:
953
954<Ctrl-Q> Quit
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000955<Home> Move to first commit
956<End> Move to last commit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000957<Up>, p, i Move up one commit
958<Down>, n, k Move down one commit
959<Left>, z, j Go back in history list
960<Right>, x, l Go forward in history list
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000961<PageUp> Move up one page in commit list
962<PageDown> Move down one page in commit list
963<Ctrl-Home> Scroll to top of commit list
964<Ctrl-End> Scroll to bottom of commit list
965<Ctrl-Up> Scroll commit list up one line
966<Ctrl-Down> Scroll commit list down one line
967<Ctrl-PageUp> Scroll commit list up one page
968<Ctrl-PageDown> Scroll commit list down one page
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000969<Shift-Up> Move to previous highlighted line
970<Shift-Down> Move to next highlighted line
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000971<Delete>, b Scroll diff view up one page
972<Backspace> Scroll diff view up one page
973<Space> Scroll diff view down one page
974u Scroll diff view up 18 lines
975d Scroll diff view down 18 lines
976<Ctrl-F> Find
977<Ctrl-G> Move to next find hit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000978<Return> Move to next find hit
979/ Move to next find hit, or redo find
980? Move to previous find hit
981f Scroll diff view to next file
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000982<Ctrl-S> Search for next hit in diff view
983<Ctrl-R> Search for previous hit in diff view
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000984<Ctrl-KP+> Increase font size
985<Ctrl-plus> Increase font size
986<Ctrl-KP-> Decrease font size
987<Ctrl-minus> Decrease font size
988} \
989 -justify left -bg white -border 2 -relief sunken
990 pack $w.m -side top -fill both
991 button $w.ok -text Close -command "destroy $w"
992 pack $w.ok -side bottom
993}
994
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000995# Procedures for manipulating the file list window at the
996# bottom right of the overall window.
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000997
998proc treeview {w l openlevs} {
999 global treecontents treediropen treeheight treeparent treeindex
1000
1001 set ix 0
1002 set treeindex() 0
1003 set lev 0
1004 set prefix {}
1005 set prefixend -1
1006 set prefendstack {}
1007 set htstack {}
1008 set ht 0
1009 set treecontents() {}
1010 $w conf -state normal
1011 foreach f $l {
1012 while {[string range $f 0 $prefixend] ne $prefix} {
1013 if {$lev <= $openlevs} {
1014 $w mark set e:$treeindex($prefix) "end -1c"
1015 $w mark gravity e:$treeindex($prefix) left
1016 }
1017 set treeheight($prefix) $ht
1018 incr ht [lindex $htstack end]
1019 set htstack [lreplace $htstack end end]
1020 set prefixend [lindex $prefendstack end]
1021 set prefendstack [lreplace $prefendstack end end]
1022 set prefix [string range $prefix 0 $prefixend]
1023 incr lev -1
1024 }
1025 set tail [string range $f [expr {$prefixend+1}] end]
1026 while {[set slash [string first "/" $tail]] >= 0} {
1027 lappend htstack $ht
1028 set ht 0
1029 lappend prefendstack $prefixend
1030 incr prefixend [expr {$slash + 1}]
1031 set d [string range $tail 0 $slash]
1032 lappend treecontents($prefix) $d
1033 set oldprefix $prefix
1034 append prefix $d
1035 set treecontents($prefix) {}
1036 set treeindex($prefix) [incr ix]
1037 set treeparent($prefix) $oldprefix
1038 set tail [string range $tail [expr {$slash+1}] end]
1039 if {$lev <= $openlevs} {
1040 set ht 1
1041 set treediropen($prefix) [expr {$lev < $openlevs}]
1042 set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
1043 $w mark set d:$ix "end -1c"
1044 $w mark gravity d:$ix left
1045 set str "\n"
1046 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1047 $w insert end $str
1048 $w image create end -align center -image $bm -padx 1 \
1049 -name a:$ix
Paul Mackerras45a9d502006-05-20 22:56:27 +10001050 $w insert end $d [highlight_tag $prefix]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001051 $w mark set s:$ix "end -1c"
1052 $w mark gravity s:$ix left
1053 }
1054 incr lev
1055 }
1056 if {$tail ne {}} {
1057 if {$lev <= $openlevs} {
1058 incr ht
1059 set str "\n"
1060 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1061 $w insert end $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001062 $w insert end $tail [highlight_tag $f]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001063 }
1064 lappend treecontents($prefix) $tail
1065 }
1066 }
1067 while {$htstack ne {}} {
1068 set treeheight($prefix) $ht
1069 incr ht [lindex $htstack end]
1070 set htstack [lreplace $htstack end end]
1071 }
1072 $w conf -state disabled
1073}
1074
1075proc linetoelt {l} {
1076 global treeheight treecontents
1077
1078 set y 2
1079 set prefix {}
1080 while {1} {
1081 foreach e $treecontents($prefix) {
1082 if {$y == $l} {
1083 return "$prefix$e"
1084 }
1085 set n 1
1086 if {[string index $e end] eq "/"} {
1087 set n $treeheight($prefix$e)
1088 if {$y + $n > $l} {
1089 append prefix $e
1090 incr y
1091 break
1092 }
1093 }
1094 incr y $n
1095 }
1096 }
1097}
1098
Paul Mackerras45a9d502006-05-20 22:56:27 +10001099proc highlight_tree {y prefix} {
1100 global treeheight treecontents cflist
1101
1102 foreach e $treecontents($prefix) {
1103 set path $prefix$e
1104 if {[highlight_tag $path] ne {}} {
1105 $cflist tag add bold $y.0 "$y.0 lineend"
1106 }
1107 incr y
1108 if {[string index $e end] eq "/" && $treeheight($path) > 1} {
1109 set y [highlight_tree $y $path]
1110 }
1111 }
1112 return $y
1113}
1114
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001115proc treeclosedir {w dir} {
1116 global treediropen treeheight treeparent treeindex
1117
1118 set ix $treeindex($dir)
1119 $w conf -state normal
1120 $w delete s:$ix e:$ix
1121 set treediropen($dir) 0
1122 $w image configure a:$ix -image tri-rt
1123 $w conf -state disabled
1124 set n [expr {1 - $treeheight($dir)}]
1125 while {$dir ne {}} {
1126 incr treeheight($dir) $n
1127 set dir $treeparent($dir)
1128 }
1129}
1130
1131proc treeopendir {w dir} {
1132 global treediropen treeheight treeparent treecontents treeindex
1133
1134 set ix $treeindex($dir)
1135 $w conf -state normal
1136 $w image configure a:$ix -image tri-dn
1137 $w mark set e:$ix s:$ix
1138 $w mark gravity e:$ix right
1139 set lev 0
1140 set str "\n"
1141 set n [llength $treecontents($dir)]
1142 for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
1143 incr lev
1144 append str "\t"
1145 incr treeheight($x) $n
1146 }
1147 foreach e $treecontents($dir) {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001148 set de $dir$e
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001149 if {[string index $e end] eq "/"} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001150 set iy $treeindex($de)
1151 $w mark set d:$iy e:$ix
1152 $w mark gravity d:$iy left
1153 $w insert e:$ix $str
1154 set treediropen($de) 0
1155 $w image create e:$ix -align center -image tri-rt -padx 1 \
1156 -name a:$iy
Paul Mackerras45a9d502006-05-20 22:56:27 +10001157 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001158 $w mark set s:$iy e:$ix
1159 $w mark gravity s:$iy left
1160 set treeheight($de) 1
1161 } else {
1162 $w insert e:$ix $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001163 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001164 }
1165 }
1166 $w mark gravity e:$ix left
1167 $w conf -state disabled
1168 set treediropen($dir) 1
1169 set top [lindex [split [$w index @0,0] .] 0]
1170 set ht [$w cget -height]
1171 set l [lindex [split [$w index s:$ix] .] 0]
1172 if {$l < $top} {
1173 $w yview $l.0
1174 } elseif {$l + $n + 1 > $top + $ht} {
1175 set top [expr {$l + $n + 2 - $ht}]
1176 if {$l < $top} {
1177 set top $l
1178 }
1179 $w yview $top.0
1180 }
1181}
1182
1183proc treeclick {w x y} {
1184 global treediropen cmitmode ctext cflist cflist_top
1185
1186 if {$cmitmode ne "tree"} return
1187 if {![info exists cflist_top]} return
1188 set l [lindex [split [$w index "@$x,$y"] "."] 0]
1189 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1190 $cflist tag add highlight $l.0 "$l.0 lineend"
1191 set cflist_top $l
1192 if {$l == 1} {
1193 $ctext yview 1.0
1194 return
1195 }
1196 set e [linetoelt $l]
1197 if {[string index $e end] ne "/"} {
1198 showfile $e
1199 } elseif {$treediropen($e)} {
1200 treeclosedir $w $e
1201 } else {
1202 treeopendir $w $e
1203 }
1204}
1205
1206proc setfilelist {id} {
1207 global treefilelist cflist
1208
1209 treeview $cflist $treefilelist($id) 0
1210}
1211
1212image create bitmap tri-rt -background black -foreground blue -data {
1213 #define tri-rt_width 13
1214 #define tri-rt_height 13
1215 static unsigned char tri-rt_bits[] = {
1216 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x70, 0x00, 0xf0, 0x00,
1217 0xf0, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00,
1218 0x00, 0x00};
1219} -maskdata {
1220 #define tri-rt-mask_width 13
1221 #define tri-rt-mask_height 13
1222 static unsigned char tri-rt-mask_bits[] = {
1223 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
1224 0xf8, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00,
1225 0x08, 0x00};
1226}
1227image create bitmap tri-dn -background black -foreground blue -data {
1228 #define tri-dn_width 13
1229 #define tri-dn_height 13
1230 static unsigned char tri-dn_bits[] = {
1231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf8, 0x03,
1232 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1233 0x00, 0x00};
1234} -maskdata {
1235 #define tri-dn-mask_width 13
1236 #define tri-dn-mask_height 13
1237 static unsigned char tri-dn-mask_bits[] = {
1238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07,
1239 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
1240 0x00, 0x00};
1241}
1242
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001243proc init_flist {first} {
Paul Mackerras89b11d32006-05-02 19:55:31 +10001244 global cflist cflist_top selectedline difffilestart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001245
1246 $cflist conf -state normal
1247 $cflist delete 0.0 end
1248 if {$first ne {}} {
1249 $cflist insert end $first
1250 set cflist_top 1
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001251 $cflist tag add highlight 1.0 "1.0 lineend"
1252 } else {
1253 catch {unset cflist_top}
1254 }
1255 $cflist conf -state disabled
1256 set difffilestart {}
1257}
1258
Paul Mackerras63b79192006-05-20 21:31:52 +10001259proc highlight_tag {f} {
1260 global highlight_paths
1261
1262 foreach p $highlight_paths {
1263 if {[string match $p $f]} {
1264 return "bold"
1265 }
1266 }
1267 return {}
1268}
1269
1270proc highlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001271 global cmitmode cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001272
Paul Mackerras45a9d502006-05-20 22:56:27 +10001273 $cflist conf -state normal
1274 if {$cmitmode ne "tree"} {
Paul Mackerras63b79192006-05-20 21:31:52 +10001275 set end [lindex [split [$cflist index end] .] 0]
1276 for {set l 2} {$l < $end} {incr l} {
1277 set line [$cflist get $l.0 "$l.0 lineend"]
1278 if {[highlight_tag $line] ne {}} {
1279 $cflist tag add bold $l.0 "$l.0 lineend"
1280 }
1281 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001282 } else {
1283 highlight_tree 2 {}
Paul Mackerras63b79192006-05-20 21:31:52 +10001284 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001285 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001286}
1287
1288proc unhighlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001289 global cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001290
Paul Mackerras45a9d502006-05-20 22:56:27 +10001291 $cflist conf -state normal
1292 $cflist tag remove bold 1.0 end
1293 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001294}
1295
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001296proc add_flist {fl} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001297 global cflist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001298
Paul Mackerras45a9d502006-05-20 22:56:27 +10001299 $cflist conf -state normal
1300 foreach f $fl {
1301 $cflist insert end "\n"
1302 $cflist insert end $f [highlight_tag $f]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001303 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001304 $cflist conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001305}
1306
1307proc sel_flist {w x y} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001308 global ctext difffilestart cflist cflist_top cmitmode
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001309
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001310 if {$cmitmode eq "tree"} return
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001311 if {![info exists cflist_top]} return
1312 set l [lindex [split [$w index "@$x,$y"] "."] 0]
Paul Mackerras89b11d32006-05-02 19:55:31 +10001313 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1314 $cflist tag add highlight $l.0 "$l.0 lineend"
1315 set cflist_top $l
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001316 if {$l == 1} {
1317 $ctext yview 1.0
1318 } else {
1319 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001320 }
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001321}
1322
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001323# Functions for adding and removing shell-type quoting
1324
1325proc shellquote {str} {
1326 if {![string match "*\['\"\\ \t]*" $str]} {
1327 return $str
1328 }
1329 if {![string match "*\['\"\\]*" $str]} {
1330 return "\"$str\""
1331 }
1332 if {![string match "*'*" $str]} {
1333 return "'$str'"
1334 }
1335 return "\"[string map {\" \\\" \\ \\\\} $str]\""
1336}
1337
1338proc shellarglist {l} {
1339 set str {}
1340 foreach a $l {
1341 if {$str ne {}} {
1342 append str " "
1343 }
1344 append str [shellquote $a]
1345 }
1346 return $str
1347}
1348
1349proc shelldequote {str} {
1350 set ret {}
1351 set used -1
1352 while {1} {
1353 incr used
1354 if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
1355 append ret [string range $str $used end]
1356 set used [string length $str]
1357 break
1358 }
1359 set first [lindex $first 0]
1360 set ch [string index $str $first]
1361 if {$first > $used} {
1362 append ret [string range $str $used [expr {$first - 1}]]
1363 set used $first
1364 }
1365 if {$ch eq " " || $ch eq "\t"} break
1366 incr used
1367 if {$ch eq "'"} {
1368 set first [string first "'" $str $used]
1369 if {$first < 0} {
1370 error "unmatched single-quote"
1371 }
1372 append ret [string range $str $used [expr {$first - 1}]]
1373 set used $first
1374 continue
1375 }
1376 if {$ch eq "\\"} {
1377 if {$used >= [string length $str]} {
1378 error "trailing backslash"
1379 }
1380 append ret [string index $str $used]
1381 continue
1382 }
1383 # here ch == "\""
1384 while {1} {
1385 if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
1386 error "unmatched double-quote"
1387 }
1388 set first [lindex $first 0]
1389 set ch [string index $str $first]
1390 if {$first > $used} {
1391 append ret [string range $str $used [expr {$first - 1}]]
1392 set used $first
1393 }
1394 if {$ch eq "\""} break
1395 incr used
1396 append ret [string index $str $used]
1397 incr used
1398 }
1399 }
1400 return [list $used $ret]
1401}
1402
1403proc shellsplit {str} {
1404 set l {}
1405 while {1} {
1406 set str [string trimleft $str]
1407 if {$str eq {}} break
1408 set dq [shelldequote $str]
1409 set n [lindex $dq 0]
1410 set word [lindex $dq 1]
1411 set str [string range $str $n end]
1412 lappend l $word
1413 }
1414 return $l
1415}
1416
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001417# Code to implement multiple views
1418
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001419proc newview {ishighlight} {
1420 global nextviewnum newviewname newviewperm uifont newishighlight
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001421 global newviewargs revtreeargs
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001422
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001423 set newishighlight $ishighlight
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001424 set top .gitkview
1425 if {[winfo exists $top]} {
1426 raise $top
1427 return
1428 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001429 set newviewname($nextviewnum) "View $nextviewnum"
1430 set newviewperm($nextviewnum) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001431 set newviewargs($nextviewnum) [shellarglist $revtreeargs]
Mark Levedahl32364b32007-02-01 08:44:46 -05001432 vieweditor $top $nextviewnum "Gitk view definition"
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001433}
1434
1435proc editview {} {
1436 global curview
1437 global viewname viewperm newviewname newviewperm
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001438 global viewargs newviewargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001439
1440 set top .gitkvedit-$curview
1441 if {[winfo exists $top]} {
1442 raise $top
1443 return
1444 }
1445 set newviewname($curview) $viewname($curview)
1446 set newviewperm($curview) $viewperm($curview)
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001447 set newviewargs($curview) [shellarglist $viewargs($curview)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001448 vieweditor $top $curview "Gitk: edit view $viewname($curview)"
1449}
1450
1451proc vieweditor {top n title} {
1452 global newviewname newviewperm viewfiles
1453 global uifont
1454
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001455 toplevel $top
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001456 wm title $top $title
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001457 label $top.nl -text "Name" -font $uifont
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001458 entry $top.name -width 20 -textvariable newviewname($n)
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001459 grid $top.nl $top.name -sticky w -pady 5
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001460 checkbutton $top.perm -text "Remember this view" -variable newviewperm($n)
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001461 grid $top.perm - -pady 5 -sticky w
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001462 message $top.al -aspect 1000 -font $uifont \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03001463 -text "Commits to include (arguments to git rev-list):"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001464 grid $top.al - -sticky w -pady 5
1465 entry $top.args -width 50 -textvariable newviewargs($n) \
1466 -background white
1467 grid $top.args - -sticky ew -padx 5
1468 message $top.l -aspect 1000 -font $uifont \
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001469 -text "Enter files and directories to include, one per line:"
1470 grid $top.l - -sticky w
1471 text $top.t -width 40 -height 10 -background white
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001472 if {[info exists viewfiles($n)]} {
1473 foreach f $viewfiles($n) {
1474 $top.t insert end $f
1475 $top.t insert end "\n"
1476 }
1477 $top.t delete {end - 1c} end
1478 $top.t mark set insert 0.0
1479 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001480 grid $top.t - -sticky ew -padx 5
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001481 frame $top.buts
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001482 button $top.buts.ok -text "OK" -command [list newviewok $top $n]
1483 button $top.buts.can -text "Cancel" -command [list destroy $top]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001484 grid $top.buts.ok $top.buts.can
1485 grid columnconfigure $top.buts 0 -weight 1 -uniform a
1486 grid columnconfigure $top.buts 1 -weight 1 -uniform a
1487 grid $top.buts - -pady 10 -sticky ew
1488 focus $top.t
1489}
1490
Paul Mackerras908c3582006-05-20 09:38:11 +10001491proc doviewmenu {m first cmd op argv} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001492 set nmenu [$m index end]
1493 for {set i $first} {$i <= $nmenu} {incr i} {
1494 if {[$m entrycget $i -command] eq $cmd} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001495 eval $m $op $i $argv
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001496 break
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001497 }
1498 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001499}
1500
1501proc allviewmenus {n op args} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001502 global viewhlmenu
1503
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001504 doviewmenu .bar.view 5 [list showview $n] $op $args
Paul Mackerras908c3582006-05-20 09:38:11 +10001505 doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001506}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001507
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001508proc newviewok {top n} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001509 global nextviewnum newviewperm newviewname newishighlight
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001510 global viewname viewfiles viewperm selectedview curview
Paul Mackerras908c3582006-05-20 09:38:11 +10001511 global viewargs newviewargs viewhlmenu
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001512
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001513 if {[catch {
1514 set newargs [shellsplit $newviewargs($n)]
1515 } err]} {
1516 error_popup "Error in commit selection arguments: $err"
1517 wm raise $top
1518 focus $top
1519 return
1520 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001521 set files {}
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001522 foreach f [split [$top.t get 0.0 end] "\n"] {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001523 set ft [string trim $f]
1524 if {$ft ne {}} {
1525 lappend files $ft
1526 }
1527 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001528 if {![info exists viewfiles($n)]} {
1529 # creating a new view
1530 incr nextviewnum
1531 set viewname($n) $newviewname($n)
1532 set viewperm($n) $newviewperm($n)
1533 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001534 set viewargs($n) $newargs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001535 addviewmenu $n
1536 if {!$newishighlight} {
1537 after idle showview $n
1538 } else {
Paul Mackerras908c3582006-05-20 09:38:11 +10001539 after idle addvhighlight $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001540 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001541 } else {
1542 # editing an existing view
1543 set viewperm($n) $newviewperm($n)
1544 if {$newviewname($n) ne $viewname($n)} {
1545 set viewname($n) $newviewname($n)
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001546 doviewmenu .bar.view 5 [list showview $n] \
Paul Mackerras908c3582006-05-20 09:38:11 +10001547 entryconf [list -label $viewname($n)]
1548 doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
1549 entryconf [list -label $viewname($n) -value $viewname($n)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001550 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001551 if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001552 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001553 set viewargs($n) $newargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001554 if {$curview == $n} {
1555 after idle updatecommits
1556 }
1557 }
1558 }
1559 catch {destroy $top}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001560}
1561
1562proc delview {} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001563 global curview viewdata viewperm hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001564
1565 if {$curview == 0} return
Paul Mackerras908c3582006-05-20 09:38:11 +10001566 if {[info exists hlview] && $hlview == $curview} {
1567 set selectedhlview None
1568 unset hlview
1569 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001570 allviewmenus $curview delete
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001571 set viewdata($curview) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001572 set viewperm($curview) 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001573 showview 0
1574}
1575
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001576proc addviewmenu {n} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001577 global viewname viewhlmenu
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001578
1579 .bar.view add radiobutton -label $viewname($n) \
1580 -command [list showview $n] -variable selectedview -value $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001581 $viewhlmenu add radiobutton -label $viewname($n) \
1582 -command [list addvhighlight $n] -variable selectedhlview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001583}
1584
Paul Mackerras22626ef2006-04-17 09:56:02 +10001585proc flatten {var} {
1586 global $var
1587
1588 set ret {}
1589 foreach i [array names $var] {
1590 lappend ret $i [set $var\($i\)]
1591 }
1592 return $ret
1593}
1594
1595proc unflatten {var l} {
1596 global $var
1597
1598 catch {unset $var}
1599 foreach {i v} $l {
1600 set $var\($i\) $v
1601 }
1602}
1603
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001604proc showview {n} {
1605 global curview viewdata viewfiles
1606 global displayorder parentlist childlist rowidlist rowoffsets
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001607 global colormap rowtextx commitrow nextcolor canvxmax
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001608 global numcommits rowrangelist commitlisted idrowranges
1609 global selectedline currentid canv canvy0
1610 global matchinglines treediffs
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001611 global pending_select phase
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001612 global commitidx rowlaidout rowoptim linesegends
Paul Mackerras22626ef2006-04-17 09:56:02 +10001613 global commfd nextupdate
Paul Mackerras908c3582006-05-20 09:38:11 +10001614 global selectedview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001615 global vparentlist vchildlist vdisporder vcmitlisted
Paul Mackerras908c3582006-05-20 09:38:11 +10001616 global hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001617
1618 if {$n == $curview} return
1619 set selid {}
1620 if {[info exists selectedline]} {
1621 set selid $currentid
1622 set y [yc $selectedline]
1623 set ymax [lindex [$canv cget -scrollregion] 3]
1624 set span [$canv yview]
1625 set ytop [expr {[lindex $span 0] * $ymax}]
1626 set ybot [expr {[lindex $span 1] * $ymax}]
1627 if {$ytop < $y && $y < $ybot} {
1628 set yscreen [expr {$y - $ytop}]
1629 } else {
1630 set yscreen [expr {($ybot - $ytop) / 2}]
1631 }
1632 }
1633 unselectline
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10001634 normalline
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001635 stopfindproc
Paul Mackerras22626ef2006-04-17 09:56:02 +10001636 if {$curview >= 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001637 set vparentlist($curview) $parentlist
1638 set vchildlist($curview) $childlist
1639 set vdisporder($curview) $displayorder
1640 set vcmitlisted($curview) $commitlisted
Paul Mackerras22626ef2006-04-17 09:56:02 +10001641 if {$phase ne {}} {
1642 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001643 [list $phase $rowidlist $rowoffsets $rowrangelist \
1644 [flatten idrowranges] [flatten idinlist] \
1645 $rowlaidout $rowoptim $numcommits $linesegends]
Paul Mackerras2516dae2006-04-21 10:35:31 +10001646 } elseif {![info exists viewdata($curview)]
1647 || [lindex $viewdata($curview) 0] ne {}} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10001648 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001649 [list {} $rowidlist $rowoffsets $rowrangelist]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001650 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001651 }
1652 catch {unset matchinglines}
1653 catch {unset treediffs}
1654 clear_display
Paul Mackerras908c3582006-05-20 09:38:11 +10001655 if {[info exists hlview] && $hlview == $n} {
1656 unset hlview
1657 set selectedhlview None
1658 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001659
1660 set curview $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001661 set selectedview $n
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001662 .bar.view entryconf Edit* -state [expr {$n == 0? "disabled": "normal"}]
1663 .bar.view entryconf Delete* -state [expr {$n == 0? "disabled": "normal"}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001664
1665 if {![info exists viewdata($n)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001666 set pending_select $selid
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10001667 getcommits
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001668 return
1669 }
1670
Paul Mackerras22626ef2006-04-17 09:56:02 +10001671 set v $viewdata($n)
1672 set phase [lindex $v 0]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001673 set displayorder $vdisporder($n)
1674 set parentlist $vparentlist($n)
1675 set childlist $vchildlist($n)
1676 set commitlisted $vcmitlisted($n)
1677 set rowidlist [lindex $v 1]
1678 set rowoffsets [lindex $v 2]
1679 set rowrangelist [lindex $v 3]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001680 if {$phase eq {}} {
1681 set numcommits [llength $displayorder]
1682 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10001683 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001684 unflatten idrowranges [lindex $v 4]
1685 unflatten idinlist [lindex $v 5]
1686 set rowlaidout [lindex $v 6]
1687 set rowoptim [lindex $v 7]
1688 set numcommits [lindex $v 8]
1689 set linesegends [lindex $v 9]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001690 }
1691
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001692 catch {unset colormap}
1693 catch {unset rowtextx}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001694 set nextcolor 0
1695 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001696 set curview $n
1697 set row 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001698 setcanvscroll
1699 set yf 0
1700 set row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001701 if {$selid ne {} && [info exists commitrow($n,$selid)]} {
1702 set row $commitrow($n,$selid)
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001703 # try to get the selected row in the same position on the screen
1704 set ymax [lindex [$canv cget -scrollregion] 3]
1705 set ytop [expr {[yc $row] - $yscreen}]
1706 if {$ytop < 0} {
1707 set ytop 0
1708 }
1709 set yf [expr {$ytop * 1.0 / $ymax}]
1710 }
1711 allcanvs yview moveto $yf
1712 drawvisible
1713 selectline $row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001714 if {$phase ne {}} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001715 if {$phase eq "getcommits"} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001716 show_status "Reading commits..."
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001717 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001718 if {[info exists commfd($n)]} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +10001719 layoutmore {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001720 } else {
1721 finishcommits
1722 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001723 } elseif {$numcommits == 0} {
1724 show_status "No commits selected"
Paul Mackerras2516dae2006-04-21 10:35:31 +10001725 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001726}
1727
Paul Mackerras908c3582006-05-20 09:38:11 +10001728# Stuff relating to the highlighting facility
1729
1730proc ishighlighted {row} {
Paul Mackerras164ff272006-05-29 19:50:02 +10001731 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10001732
1733 if {[info exists nhighlights($row)] && $nhighlights($row) > 0} {
1734 return $nhighlights($row)
1735 }
1736 if {[info exists vhighlights($row)] && $vhighlights($row) > 0} {
1737 return $vhighlights($row)
1738 }
1739 if {[info exists fhighlights($row)] && $fhighlights($row) > 0} {
1740 return $fhighlights($row)
1741 }
Paul Mackerras164ff272006-05-29 19:50:02 +10001742 if {[info exists rhighlights($row)] && $rhighlights($row) > 0} {
1743 return $rhighlights($row)
1744 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001745 return 0
1746}
1747
1748proc bolden {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001749 global canv linehtag selectedline boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001750
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001751 lappend boldrows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001752 $canv itemconf $linehtag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001753 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001754 $canv delete secsel
1755 set t [eval $canv create rect [$canv bbox $linehtag($row)] \
1756 -outline {{}} -tags secsel \
1757 -fill [$canv cget -selectbackground]]
1758 $canv lower $t
1759 }
1760}
1761
1762proc bolden_name {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001763 global canv2 linentag selectedline boldnamerows
Paul Mackerras908c3582006-05-20 09:38:11 +10001764
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001765 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001766 $canv2 itemconf $linentag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001767 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001768 $canv2 delete secsel
1769 set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
1770 -outline {{}} -tags secsel \
1771 -fill [$canv2 cget -selectbackground]]
1772 $canv2 lower $t
1773 }
1774}
1775
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001776proc unbolden {} {
1777 global mainfont boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001778
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001779 set stillbold {}
1780 foreach row $boldrows {
Paul Mackerras908c3582006-05-20 09:38:11 +10001781 if {![ishighlighted $row]} {
1782 bolden $row $mainfont
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001783 } else {
1784 lappend stillbold $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001785 }
1786 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001787 set boldrows $stillbold
Paul Mackerras908c3582006-05-20 09:38:11 +10001788}
1789
1790proc addvhighlight {n} {
1791 global hlview curview viewdata vhl_done vhighlights commitidx
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001792
1793 if {[info exists hlview]} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001794 delvhighlight
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001795 }
1796 set hlview $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001797 if {$n != $curview && ![info exists viewdata($n)]} {
1798 set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}]
1799 set vparentlist($n) {}
1800 set vchildlist($n) {}
1801 set vdisporder($n) {}
1802 set vcmitlisted($n) {}
1803 start_rev_list $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001804 }
1805 set vhl_done $commitidx($hlview)
1806 if {$vhl_done > 0} {
1807 drawvisible
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001808 }
1809}
1810
Paul Mackerras908c3582006-05-20 09:38:11 +10001811proc delvhighlight {} {
1812 global hlview vhighlights
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001813
1814 if {![info exists hlview]} return
1815 unset hlview
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001816 catch {unset vhighlights}
1817 unbolden
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001818}
1819
Paul Mackerras908c3582006-05-20 09:38:11 +10001820proc vhighlightmore {} {
1821 global hlview vhl_done commitidx vhighlights
1822 global displayorder vdisporder curview mainfont
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001823
1824 set font [concat $mainfont bold]
1825 set max $commitidx($hlview)
1826 if {$hlview == $curview} {
1827 set disp $displayorder
1828 } else {
1829 set disp $vdisporder($hlview)
1830 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001831 set vr [visiblerows]
1832 set r0 [lindex $vr 0]
1833 set r1 [lindex $vr 1]
1834 for {set i $vhl_done} {$i < $max} {incr i} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001835 set id [lindex $disp $i]
1836 if {[info exists commitrow($curview,$id)]} {
1837 set row $commitrow($curview,$id)
Paul Mackerras908c3582006-05-20 09:38:11 +10001838 if {$r0 <= $row && $row <= $r1} {
1839 if {![highlighted $row]} {
1840 bolden $row $font
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001841 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001842 set vhighlights($row) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001843 }
1844 }
1845 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001846 set vhl_done $max
1847}
1848
1849proc askvhighlight {row id} {
1850 global hlview vhighlights commitrow iddrawn mainfont
1851
1852 if {[info exists commitrow($hlview,$id)]} {
1853 if {[info exists iddrawn($id)] && ![ishighlighted $row]} {
1854 bolden $row [concat $mainfont bold]
1855 }
1856 set vhighlights($row) 1
1857 } else {
1858 set vhighlights($row) 0
1859 }
1860}
1861
1862proc hfiles_change {name ix op} {
1863 global highlight_files filehighlight fhighlights fh_serial
Paul Mackerras63b79192006-05-20 21:31:52 +10001864 global mainfont highlight_paths
Paul Mackerras908c3582006-05-20 09:38:11 +10001865
1866 if {[info exists filehighlight]} {
1867 # delete previous highlights
1868 catch {close $filehighlight}
1869 unset filehighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001870 catch {unset fhighlights}
1871 unbolden
Paul Mackerras63b79192006-05-20 21:31:52 +10001872 unhighlight_filelist
Paul Mackerras908c3582006-05-20 09:38:11 +10001873 }
Paul Mackerras63b79192006-05-20 21:31:52 +10001874 set highlight_paths {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001875 after cancel do_file_hl $fh_serial
1876 incr fh_serial
1877 if {$highlight_files ne {}} {
1878 after 300 do_file_hl $fh_serial
1879 }
1880}
1881
Paul Mackerras63b79192006-05-20 21:31:52 +10001882proc makepatterns {l} {
1883 set ret {}
1884 foreach e $l {
1885 set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
1886 if {[string index $ee end] eq "/"} {
1887 lappend ret "$ee*"
1888 } else {
1889 lappend ret $ee
1890 lappend ret "$ee/*"
1891 }
1892 }
1893 return $ret
1894}
1895
Paul Mackerras908c3582006-05-20 09:38:11 +10001896proc do_file_hl {serial} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001897 global highlight_files filehighlight highlight_paths gdttype fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001898
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001899 if {$gdttype eq "touching paths:"} {
1900 if {[catch {set paths [shellsplit $highlight_files]}]} return
1901 set highlight_paths [makepatterns $paths]
1902 highlight_filelist
1903 set gdtargs [concat -- $paths]
1904 } else {
1905 set gdtargs [list "-S$highlight_files"]
1906 }
1907 set cmd [concat | git-diff-tree -r -s --stdin $gdtargs]
Paul Mackerras908c3582006-05-20 09:38:11 +10001908 set filehighlight [open $cmd r+]
1909 fconfigure $filehighlight -blocking 0
1910 fileevent $filehighlight readable readfhighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001911 set fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001912 drawvisible
1913 flushhighlights
1914}
1915
1916proc flushhighlights {} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001917 global filehighlight fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001918
1919 if {[info exists filehighlight]} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001920 lappend fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001921 puts $filehighlight ""
1922 flush $filehighlight
1923 }
1924}
1925
1926proc askfilehighlight {row id} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001927 global filehighlight fhighlights fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001928
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001929 lappend fhl_list $id
1930 set fhighlights($row) -1
Paul Mackerras908c3582006-05-20 09:38:11 +10001931 puts $filehighlight $id
1932}
1933
1934proc readfhighlight {} {
1935 global filehighlight fhighlights commitrow curview mainfont iddrawn
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001936 global fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001937
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001938 while {[gets $filehighlight line] >= 0} {
1939 set line [string trim $line]
1940 set i [lsearch -exact $fhl_list $line]
1941 if {$i < 0} continue
1942 for {set j 0} {$j < $i} {incr j} {
1943 set id [lindex $fhl_list $j]
1944 if {[info exists commitrow($curview,$id)]} {
1945 set fhighlights($commitrow($curview,$id)) 0
1946 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001947 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001948 set fhl_list [lrange $fhl_list [expr {$i+1}] end]
1949 if {$line eq {}} continue
1950 if {![info exists commitrow($curview,$line)]} continue
1951 set row $commitrow($curview,$line)
1952 if {[info exists iddrawn($line)] && ![ishighlighted $row]} {
1953 bolden $row [concat $mainfont bold]
1954 }
1955 set fhighlights($row) 1
Paul Mackerras908c3582006-05-20 09:38:11 +10001956 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001957 if {[eof $filehighlight]} {
1958 # strange...
1959 puts "oops, git-diff-tree died"
1960 catch {close $filehighlight}
1961 unset filehighlight
Paul Mackerras908c3582006-05-20 09:38:11 +10001962 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001963 next_hlcont
Paul Mackerras908c3582006-05-20 09:38:11 +10001964}
1965
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001966proc find_change {name ix op} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001967 global nhighlights mainfont boldnamerows
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001968 global findstring findpattern findtype
Paul Mackerras908c3582006-05-20 09:38:11 +10001969
1970 # delete previous highlights, if any
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001971 foreach row $boldnamerows {
1972 bolden_name $row $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10001973 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001974 set boldnamerows {}
1975 catch {unset nhighlights}
1976 unbolden
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001977 if {$findtype ne "Regexp"} {
1978 set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
1979 $findstring]
1980 set findpattern "*$e*"
Paul Mackerras908c3582006-05-20 09:38:11 +10001981 }
1982 drawvisible
1983}
1984
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001985proc askfindhighlight {row id} {
1986 global nhighlights commitinfo iddrawn mainfont
1987 global findstring findtype findloc findpattern
Paul Mackerras908c3582006-05-20 09:38:11 +10001988
1989 if {![info exists commitinfo($id)]} {
1990 getcommit $id
1991 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001992 set info $commitinfo($id)
Paul Mackerras908c3582006-05-20 09:38:11 +10001993 set isbold 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001994 set fldtypes {Headline Author Date Committer CDate Comments}
1995 foreach f $info ty $fldtypes {
1996 if {$findloc ne "All fields" && $findloc ne $ty} {
1997 continue
Paul Mackerras908c3582006-05-20 09:38:11 +10001998 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001999 if {$findtype eq "Regexp"} {
2000 set doesmatch [regexp $findstring $f]
2001 } elseif {$findtype eq "IgnCase"} {
2002 set doesmatch [string match -nocase $findpattern $f]
2003 } else {
2004 set doesmatch [string match $findpattern $f]
2005 }
2006 if {$doesmatch} {
2007 if {$ty eq "Author"} {
2008 set isbold 2
2009 } else {
2010 set isbold 1
2011 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002012 }
2013 }
2014 if {[info exists iddrawn($id)]} {
2015 if {$isbold && ![ishighlighted $row]} {
2016 bolden $row [concat $mainfont bold]
2017 }
2018 if {$isbold >= 2} {
2019 bolden_name $row [concat $mainfont bold]
2020 }
2021 }
2022 set nhighlights($row) $isbold
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002023}
2024
Paul Mackerras164ff272006-05-29 19:50:02 +10002025proc vrel_change {name ix op} {
2026 global highlight_related
2027
2028 rhighlight_none
2029 if {$highlight_related ne "None"} {
2030 after idle drawvisible
2031 }
2032}
2033
2034# prepare for testing whether commits are descendents or ancestors of a
2035proc rhighlight_sel {a} {
2036 global descendent desc_todo ancestor anc_todo
2037 global highlight_related rhighlights
2038
2039 catch {unset descendent}
2040 set desc_todo [list $a]
2041 catch {unset ancestor}
2042 set anc_todo [list $a]
2043 if {$highlight_related ne "None"} {
2044 rhighlight_none
2045 after idle drawvisible
2046 }
2047}
2048
2049proc rhighlight_none {} {
2050 global rhighlights
2051
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002052 catch {unset rhighlights}
2053 unbolden
Paul Mackerras164ff272006-05-29 19:50:02 +10002054}
2055
2056proc is_descendent {a} {
2057 global curview children commitrow descendent desc_todo
2058
2059 set v $curview
2060 set la $commitrow($v,$a)
2061 set todo $desc_todo
2062 set leftover {}
2063 set done 0
2064 for {set i 0} {$i < [llength $todo]} {incr i} {
2065 set do [lindex $todo $i]
2066 if {$commitrow($v,$do) < $la} {
2067 lappend leftover $do
2068 continue
2069 }
2070 foreach nk $children($v,$do) {
2071 if {![info exists descendent($nk)]} {
2072 set descendent($nk) 1
2073 lappend todo $nk
2074 if {$nk eq $a} {
2075 set done 1
2076 }
2077 }
2078 }
2079 if {$done} {
2080 set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2081 return
2082 }
2083 }
2084 set descendent($a) 0
2085 set desc_todo $leftover
2086}
2087
2088proc is_ancestor {a} {
2089 global curview parentlist commitrow ancestor anc_todo
2090
2091 set v $curview
2092 set la $commitrow($v,$a)
2093 set todo $anc_todo
2094 set leftover {}
2095 set done 0
2096 for {set i 0} {$i < [llength $todo]} {incr i} {
2097 set do [lindex $todo $i]
2098 if {![info exists commitrow($v,$do)] || $commitrow($v,$do) > $la} {
2099 lappend leftover $do
2100 continue
2101 }
2102 foreach np [lindex $parentlist $commitrow($v,$do)] {
2103 if {![info exists ancestor($np)]} {
2104 set ancestor($np) 1
2105 lappend todo $np
2106 if {$np eq $a} {
2107 set done 1
2108 }
2109 }
2110 }
2111 if {$done} {
2112 set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2113 return
2114 }
2115 }
2116 set ancestor($a) 0
2117 set anc_todo $leftover
2118}
2119
2120proc askrelhighlight {row id} {
2121 global descendent highlight_related iddrawn mainfont rhighlights
2122 global selectedline ancestor
2123
2124 if {![info exists selectedline]} return
2125 set isbold 0
2126 if {$highlight_related eq "Descendent" ||
2127 $highlight_related eq "Not descendent"} {
2128 if {![info exists descendent($id)]} {
2129 is_descendent $id
2130 }
2131 if {$descendent($id) == ($highlight_related eq "Descendent")} {
2132 set isbold 1
2133 }
2134 } elseif {$highlight_related eq "Ancestor" ||
2135 $highlight_related eq "Not ancestor"} {
2136 if {![info exists ancestor($id)]} {
2137 is_ancestor $id
2138 }
2139 if {$ancestor($id) == ($highlight_related eq "Ancestor")} {
2140 set isbold 1
2141 }
2142 }
2143 if {[info exists iddrawn($id)]} {
2144 if {$isbold && ![ishighlighted $row]} {
2145 bolden $row [concat $mainfont bold]
2146 }
2147 }
2148 set rhighlights($row) $isbold
2149}
2150
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002151proc next_hlcont {} {
2152 global fhl_row fhl_dirn displayorder numcommits
2153 global vhighlights fhighlights nhighlights rhighlights
2154 global hlview filehighlight findstring highlight_related
2155
2156 if {![info exists fhl_dirn] || $fhl_dirn == 0} return
2157 set row $fhl_row
2158 while {1} {
2159 if {$row < 0 || $row >= $numcommits} {
2160 bell
2161 set fhl_dirn 0
2162 return
2163 }
2164 set id [lindex $displayorder $row]
2165 if {[info exists hlview]} {
2166 if {![info exists vhighlights($row)]} {
2167 askvhighlight $row $id
2168 }
2169 if {$vhighlights($row) > 0} break
2170 }
2171 if {$findstring ne {}} {
2172 if {![info exists nhighlights($row)]} {
2173 askfindhighlight $row $id
2174 }
2175 if {$nhighlights($row) > 0} break
2176 }
2177 if {$highlight_related ne "None"} {
2178 if {![info exists rhighlights($row)]} {
2179 askrelhighlight $row $id
2180 }
2181 if {$rhighlights($row) > 0} break
2182 }
2183 if {[info exists filehighlight]} {
2184 if {![info exists fhighlights($row)]} {
2185 # ask for a few more while we're at it...
2186 set r $row
2187 for {set n 0} {$n < 100} {incr n} {
2188 if {![info exists fhighlights($r)]} {
2189 askfilehighlight $r [lindex $displayorder $r]
2190 }
2191 incr r $fhl_dirn
2192 if {$r < 0 || $r >= $numcommits} break
2193 }
2194 flushhighlights
2195 }
2196 if {$fhighlights($row) < 0} {
2197 set fhl_row $row
2198 return
2199 }
2200 if {$fhighlights($row) > 0} break
2201 }
2202 incr row $fhl_dirn
2203 }
2204 set fhl_dirn 0
2205 selectline $row 1
2206}
2207
2208proc next_highlight {dirn} {
2209 global selectedline fhl_row fhl_dirn
2210 global hlview filehighlight findstring highlight_related
2211
2212 if {![info exists selectedline]} return
2213 if {!([info exists hlview] || $findstring ne {} ||
2214 $highlight_related ne "None" || [info exists filehighlight])} return
2215 set fhl_row [expr {$selectedline + $dirn}]
2216 set fhl_dirn $dirn
2217 next_hlcont
2218}
2219
2220proc cancel_next_highlight {} {
2221 global fhl_dirn
2222
2223 set fhl_dirn 0
2224}
2225
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002226# Graph layout functions
2227
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002228proc shortids {ids} {
2229 set res {}
2230 foreach id $ids {
2231 if {[llength $id] > 1} {
2232 lappend res [shortids $id]
2233 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
2234 lappend res [string range $id 0 7]
2235 } else {
2236 lappend res $id
2237 }
2238 }
2239 return $res
2240}
2241
2242proc incrange {l x o} {
2243 set n [llength $l]
2244 while {$x < $n} {
2245 set e [lindex $l $x]
2246 if {$e ne {}} {
2247 lset l $x [expr {$e + $o}]
2248 }
2249 incr x
2250 }
2251 return $l
2252}
2253
2254proc ntimes {n o} {
2255 set ret {}
2256 for {} {$n > 0} {incr n -1} {
2257 lappend ret $o
2258 }
2259 return $ret
2260}
2261
2262proc usedinrange {id l1 l2} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002263 global children commitrow childlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002264
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002265 if {[info exists commitrow($curview,$id)]} {
2266 set r $commitrow($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002267 if {$l1 <= $r && $r <= $l2} {
2268 return [expr {$r - $l1 + 1}]
2269 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002270 set kids [lindex $childlist $r]
2271 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002272 set kids $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002273 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002274 foreach c $kids {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002275 set r $commitrow($curview,$c)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002276 if {$l1 <= $r && $r <= $l2} {
2277 return [expr {$r - $l1 + 1}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002278 }
2279 }
2280 return 0
2281}
2282
2283proc sanity {row {full 0}} {
2284 global rowidlist rowoffsets
2285
2286 set col -1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002287 set ids [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002288 foreach id $ids {
2289 incr col
2290 if {$id eq {}} continue
2291 if {$col < [llength $ids] - 1 &&
2292 [lsearch -exact -start [expr {$col+1}] $ids $id] >= 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002293 puts "oops: [shortids $id] repeated in row $row col $col: {[shortids [lindex $rowidlist $row]]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002294 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002295 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002296 set y $row
2297 set x $col
2298 while {$o ne {}} {
2299 incr y -1
2300 incr x $o
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002301 if {[lindex $rowidlist $y $x] != $id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002302 puts "oops: rowoffsets wrong at row [expr {$y+1}] col [expr {$x-$o}]"
2303 puts " id=[shortids $id] check started at row $row"
2304 for {set i $row} {$i >= $y} {incr i -1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002305 puts " row $i ids={[shortids [lindex $rowidlist $i]]} offs={[lindex $rowoffsets $i]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002306 }
2307 break
2308 }
2309 if {!$full} break
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002310 set o [lindex $rowoffsets $y $x]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002311 }
2312 }
2313}
2314
2315proc makeuparrow {oid x y z} {
2316 global rowidlist rowoffsets uparrowlen idrowranges
2317
2318 for {set i 1} {$i < $uparrowlen && $y > 1} {incr i} {
2319 incr y -1
2320 incr x $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002321 set off0 [lindex $rowoffsets $y]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002322 for {set x0 $x} {1} {incr x0} {
2323 if {$x0 >= [llength $off0]} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002324 set x0 [llength [lindex $rowoffsets [expr {$y-1}]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002325 break
2326 }
2327 set z [lindex $off0 $x0]
2328 if {$z ne {}} {
2329 incr x0 $z
2330 break
2331 }
2332 }
2333 set z [expr {$x0 - $x}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002334 lset rowidlist $y [linsert [lindex $rowidlist $y] $x $oid]
2335 lset rowoffsets $y [linsert [lindex $rowoffsets $y] $x $z]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002336 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002337 set tmp [lreplace [lindex $rowoffsets $y] $x $x {}]
2338 lset rowoffsets $y [incrange $tmp [expr {$x+1}] -1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002339 lappend idrowranges($oid) $y
2340}
2341
2342proc initlayout {} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002343 global rowidlist rowoffsets displayorder commitlisted
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002344 global rowlaidout rowoptim
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002345 global idinlist rowchk rowrangelist idrowranges
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002346 global numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002347 global nextcolor
Paul Mackerras79b2c752006-04-02 20:47:40 +10002348 global parentlist childlist children
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002349 global colormap rowtextx
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002350 global linesegends
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002351
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002352 set numcommits 0
2353 set displayorder {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002354 set commitlisted {}
2355 set parentlist {}
2356 set childlist {}
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002357 set rowrangelist {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002358 set nextcolor 0
2359 set rowidlist {{}}
2360 set rowoffsets {{}}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002361 catch {unset idinlist}
2362 catch {unset rowchk}
2363 set rowlaidout 0
2364 set rowoptim 0
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002365 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002366 catch {unset colormap}
2367 catch {unset rowtextx}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002368 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002369 set linesegends {}
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002370}
2371
2372proc setcanvscroll {} {
2373 global canv canv2 canv3 numcommits linespc canvxmax canvy0
2374
2375 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
2376 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
2377 $canv2 conf -scrollregion [list 0 0 0 $ymax]
2378 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002379}
2380
2381proc visiblerows {} {
2382 global canv numcommits linespc
2383
2384 set ymax [lindex [$canv cget -scrollregion] 3]
2385 if {$ymax eq {} || $ymax == 0} return
2386 set f [$canv yview]
2387 set y0 [expr {int([lindex $f 0] * $ymax)}]
2388 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
2389 if {$r0 < 0} {
2390 set r0 0
2391 }
2392 set y1 [expr {int([lindex $f 1] * $ymax)}]
2393 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
2394 if {$r1 >= $numcommits} {
2395 set r1 [expr {$numcommits - 1}]
2396 }
2397 return [list $r0 $r1]
2398}
2399
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002400proc layoutmore {tmax} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002401 global rowlaidout rowoptim commitidx numcommits optim_delay
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002402 global uparrowlen curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002403
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002404 while {1} {
2405 if {$rowoptim - $optim_delay > $numcommits} {
2406 showstuff [expr {$rowoptim - $optim_delay}]
2407 } elseif {$rowlaidout - $uparrowlen - 1 > $rowoptim} {
2408 set nr [expr {$rowlaidout - $uparrowlen - 1 - $rowoptim}]
2409 if {$nr > 100} {
2410 set nr 100
2411 }
2412 optimize_rows $rowoptim 0 [expr {$rowoptim + $nr}]
2413 incr rowoptim $nr
2414 } elseif {$commitidx($curview) > $rowlaidout} {
2415 set nr [expr {$commitidx($curview) - $rowlaidout}]
2416 # may need to increase this threshold if uparrowlen or
2417 # mingaplen are increased...
2418 if {$nr > 150} {
2419 set nr 150
2420 }
2421 set row $rowlaidout
2422 set rowlaidout [layoutrows $row [expr {$row + $nr}] 0]
2423 if {$rowlaidout == $row} {
2424 return 0
2425 }
2426 } else {
2427 return 0
2428 }
2429 if {$tmax ne {} && [clock clicks -milliseconds] >= $tmax} {
2430 return 1
2431 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002432 }
2433}
2434
2435proc showstuff {canshow} {
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002436 global numcommits commitrow pending_select selectedline
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002437 global linesegends idrowranges idrangedrawn curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002438
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002439 if {$numcommits == 0} {
2440 global phase
2441 set phase "incrdraw"
2442 allcanvs delete all
2443 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002444 set row $numcommits
2445 set numcommits $canshow
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002446 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002447 set rows [visiblerows]
2448 set r0 [lindex $rows 0]
2449 set r1 [lindex $rows 1]
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002450 set selrow -1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002451 for {set r $row} {$r < $canshow} {incr r} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10002452 foreach id [lindex $linesegends [expr {$r+1}]] {
2453 set i -1
2454 foreach {s e} [rowranges $id] {
2455 incr i
2456 if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
2457 && ![info exists idrangedrawn($id,$i)]} {
2458 drawlineseg $id $i
2459 set idrangedrawn($id,$i) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002460 }
2461 }
2462 }
2463 }
2464 if {$canshow > $r1} {
2465 set canshow $r1
2466 }
2467 while {$row < $canshow} {
2468 drawcmitrow $row
2469 incr row
2470 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002471 if {[info exists pending_select] &&
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002472 [info exists commitrow($curview,$pending_select)] &&
2473 $commitrow($curview,$pending_select) < $numcommits} {
2474 selectline $commitrow($curview,$pending_select) 1
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002475 }
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002476 if {![info exists selectedline] && ![info exists pending_select]} {
2477 selectline 0 1
2478 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002479}
2480
2481proc layoutrows {row endrow last} {
2482 global rowidlist rowoffsets displayorder
2483 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras79b2c752006-04-02 20:47:40 +10002484 global childlist parentlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002485 global idrowranges linesegends
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002486 global commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002487 global idinlist rowchk rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002488
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002489 set idlist [lindex $rowidlist $row]
2490 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002491 while {$row < $endrow} {
2492 set id [lindex $displayorder $row]
2493 set oldolds {}
2494 set newolds {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002495 foreach p [lindex $parentlist $row] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002496 if {![info exists idinlist($p)]} {
2497 lappend newolds $p
2498 } elseif {!$idinlist($p)} {
2499 lappend oldolds $p
2500 }
2501 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002502 set lse {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002503 set nev [expr {[llength $idlist] + [llength $newolds]
2504 + [llength $oldolds] - $maxwidth + 1}]
2505 if {$nev > 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002506 if {!$last &&
2507 $row + $uparrowlen + $mingaplen >= $commitidx($curview)} break
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002508 for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
2509 set i [lindex $idlist $x]
2510 if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
2511 set r [usedinrange $i [expr {$row - $downarrowlen}] \
2512 [expr {$row + $uparrowlen + $mingaplen}]]
2513 if {$r == 0} {
2514 set idlist [lreplace $idlist $x $x]
2515 set offs [lreplace $offs $x $x]
2516 set offs [incrange $offs $x 1]
2517 set idinlist($i) 0
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002518 set rm1 [expr {$row - 1}]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002519 lappend lse $i
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002520 lappend idrowranges($i) $rm1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002521 if {[incr nev -1] <= 0} break
2522 continue
2523 }
2524 set rowchk($id) [expr {$row + $r}]
2525 }
2526 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002527 lset rowidlist $row $idlist
2528 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002529 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002530 lappend linesegends $lse
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002531 set col [lsearch -exact $idlist $id]
2532 if {$col < 0} {
2533 set col [llength $idlist]
2534 lappend idlist $id
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002535 lset rowidlist $row $idlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002536 set z {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002537 if {[lindex $childlist $row] ne {}} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002538 set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002539 unset idinlist($id)
2540 }
2541 lappend offs $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002542 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002543 if {$z ne {}} {
2544 makeuparrow $id $col $row $z
2545 }
2546 } else {
2547 unset idinlist($id)
2548 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002549 set ranges {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002550 if {[info exists idrowranges($id)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002551 set ranges $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002552 lappend ranges $row
2553 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002554 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002555 lappend rowrangelist $ranges
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002556 incr row
2557 set offs [ntimes [llength $idlist] 0]
2558 set l [llength $newolds]
2559 set idlist [eval lreplace \$idlist $col $col $newolds]
2560 set o 0
2561 if {$l != 1} {
2562 set offs [lrange $offs 0 [expr {$col - 1}]]
2563 foreach x $newolds {
2564 lappend offs {}
2565 incr o -1
2566 }
2567 incr o
2568 set tmp [expr {[llength $idlist] - [llength $offs]}]
2569 if {$tmp > 0} {
2570 set offs [concat $offs [ntimes $tmp $o]]
2571 }
2572 } else {
2573 lset offs $col {}
2574 }
2575 foreach i $newolds {
2576 set idinlist($i) 1
2577 set idrowranges($i) $row
2578 }
2579 incr col $l
2580 foreach oid $oldolds {
2581 set idinlist($oid) 1
2582 set idlist [linsert $idlist $col $oid]
2583 set offs [linsert $offs $col $o]
2584 makeuparrow $oid $col $row $o
2585 incr col
2586 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002587 lappend rowidlist $idlist
2588 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002589 }
2590 return $row
2591}
2592
2593proc addextraid {id row} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002594 global displayorder commitrow commitinfo
Paul Mackerrase7da3472006-04-17 10:27:59 +10002595 global commitidx commitlisted
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002596 global parentlist childlist children curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002597
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002598 incr commitidx($curview)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002599 lappend displayorder $id
Paul Mackerrase7da3472006-04-17 10:27:59 +10002600 lappend commitlisted 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10002601 lappend parentlist {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002602 set commitrow($curview,$id) $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002603 readcommit $id
2604 if {![info exists commitinfo($id)]} {
2605 set commitinfo($id) {"No commit information available"}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002606 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002607 if {![info exists children($curview,$id)]} {
2608 set children($curview,$id) {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002609 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002610 lappend childlist $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002611}
2612
2613proc layouttail {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002614 global rowidlist rowoffsets idinlist commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002615 global idrowranges rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002616
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002617 set row $commitidx($curview)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002618 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002619 while {$idlist ne {}} {
2620 set col [expr {[llength $idlist] - 1}]
2621 set id [lindex $idlist $col]
2622 addextraid $id $row
2623 unset idinlist($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002624 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002625 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002626 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002627 incr row
2628 set offs [ntimes $col 0]
2629 set idlist [lreplace $idlist $col $col]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002630 lappend rowidlist $idlist
2631 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002632 }
2633
2634 foreach id [array names idinlist] {
2635 addextraid $id $row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002636 lset rowidlist $row [list $id]
2637 lset rowoffsets $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002638 makeuparrow $id 0 $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002639 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002640 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002641 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002642 incr row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002643 lappend rowidlist {}
2644 lappend rowoffsets {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002645 }
2646}
2647
2648proc insert_pad {row col npad} {
2649 global rowidlist rowoffsets
2650
2651 set pad [ntimes $npad {}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002652 lset rowidlist $row [eval linsert [list [lindex $rowidlist $row]] $col $pad]
2653 set tmp [eval linsert [list [lindex $rowoffsets $row]] $col $pad]
2654 lset rowoffsets $row [incrange $tmp [expr {$col + $npad}] [expr {-$npad}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002655}
2656
2657proc optimize_rows {row col endrow} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002658 global rowidlist rowoffsets idrowranges displayorder
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002659
2660 for {} {$row < $endrow} {incr row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002661 set idlist [lindex $rowidlist $row]
2662 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002663 set haspad 0
2664 for {} {$col < [llength $offs]} {incr col} {
2665 if {[lindex $idlist $col] eq {}} {
2666 set haspad 1
2667 continue
2668 }
2669 set z [lindex $offs $col]
2670 if {$z eq {}} continue
2671 set isarrow 0
2672 set x0 [expr {$col + $z}]
2673 set y0 [expr {$row - 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002674 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002675 if {$z0 eq {}} {
2676 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002677 set ranges [rowranges $id]
2678 if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002679 set isarrow 1
2680 }
2681 }
2682 if {$z < -1 || ($z < 0 && $isarrow)} {
2683 set npad [expr {-1 - $z + $isarrow}]
2684 set offs [incrange $offs $col $npad]
2685 insert_pad $y0 $x0 $npad
2686 if {$y0 > 0} {
2687 optimize_rows $y0 $x0 $row
2688 }
2689 set z [lindex $offs $col]
2690 set x0 [expr {$col + $z}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002691 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002692 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
2693 set npad [expr {$z - 1 + $isarrow}]
2694 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002695 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002696 set x1 -1
2697 foreach z $offs2 {
2698 incr x1
2699 if {$z eq {} || $x1 + $z < $col} continue
2700 if {$x1 + $z > $col} {
2701 incr npad
2702 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002703 lset rowoffsets $y1 [incrange $offs2 $x1 $npad]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002704 break
2705 }
2706 set pad [ntimes $npad {}]
2707 set idlist [eval linsert \$idlist $col $pad]
2708 set tmp [eval linsert \$offs $col $pad]
2709 incr col $npad
2710 set offs [incrange $tmp $col [expr {-$npad}]]
2711 set z [lindex $offs $col]
2712 set haspad 1
2713 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002714 if {$z0 eq {} && !$isarrow} {
2715 # this line links to its first child on row $row-2
2716 set rm2 [expr {$row - 2}]
2717 set id [lindex $displayorder $rm2]
2718 set xc [lsearch -exact [lindex $rowidlist $rm2] $id]
2719 if {$xc >= 0} {
2720 set z0 [expr {$xc - $x0}]
2721 }
2722 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002723 if {$z0 ne {} && $z < 0 && $z0 > 0} {
2724 insert_pad $y0 $x0 1
2725 set offs [incrange $offs $col 1]
2726 optimize_rows $y0 [expr {$x0 + 1}] $row
2727 }
2728 }
2729 if {!$haspad} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002730 set o {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002731 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
2732 set o [lindex $offs $col]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002733 if {$o eq {}} {
2734 # check if this is the link to the first child
2735 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002736 set ranges [rowranges $id]
2737 if {$ranges ne {} && $row == [lindex $ranges 0]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002738 # it is, work out offset to child
2739 set y0 [expr {$row - 1}]
2740 set id [lindex $displayorder $y0]
2741 set x0 [lsearch -exact [lindex $rowidlist $y0] $id]
2742 if {$x0 >= 0} {
2743 set o [expr {$x0 - $col}]
2744 }
2745 }
2746 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002747 if {$o eq {} || $o <= 0} break
2748 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002749 if {$o ne {} && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002750 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002751 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002752 set x1 -1
2753 foreach z $offs2 {
2754 incr x1
2755 if {$z eq {} || $x1 + $z < $col} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002756 lset rowoffsets $y1 [incrange $offs2 $x1 1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002757 break
2758 }
2759 set idlist [linsert $idlist $col {}]
2760 set tmp [linsert $offs $col {}]
2761 incr col
2762 set offs [incrange $tmp $col -1]
2763 }
2764 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002765 lset rowidlist $row $idlist
2766 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002767 set col 0
2768 }
2769}
2770
2771proc xc {row col} {
2772 global canvx0 linespc
2773 return [expr {$canvx0 + $col * $linespc}]
2774}
2775
2776proc yc {row} {
2777 global canvy0 linespc
2778 return [expr {$canvy0 + $row * $linespc}]
2779}
2780
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002781proc linewidth {id} {
2782 global thickerline lthickness
2783
2784 set wid $lthickness
2785 if {[info exists thickerline] && $id eq $thickerline} {
2786 set wid [expr {2 * $lthickness}]
2787 }
2788 return $wid
2789}
2790
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002791proc rowranges {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002792 global phase idrowranges commitrow rowlaidout rowrangelist curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002793
2794 set ranges {}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002795 if {$phase eq {} ||
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002796 ([info exists commitrow($curview,$id)]
2797 && $commitrow($curview,$id) < $rowlaidout)} {
2798 set ranges [lindex $rowrangelist $commitrow($curview,$id)]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002799 } elseif {[info exists idrowranges($id)]} {
2800 set ranges $idrowranges($id)
2801 }
2802 return $ranges
2803}
2804
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002805proc drawlineseg {id i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002806 global rowoffsets rowidlist
Paul Mackerraseb447a12006-03-18 23:11:37 +11002807 global displayorder
Paul Mackerras879e8b12006-03-31 10:45:14 +11002808 global canv colormap linespc
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002809 global numcommits commitrow curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002810
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002811 set ranges [rowranges $id]
2812 set downarrow 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002813 if {[info exists commitrow($curview,$id)]
2814 && $commitrow($curview,$id) < $numcommits} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002815 set downarrow [expr {$i < [llength $ranges] / 2 - 1}]
2816 } else {
2817 set downarrow 1
2818 }
2819 set startrow [lindex $ranges [expr {2 * $i}]]
2820 set row [lindex $ranges [expr {2 * $i + 1}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002821 if {$startrow == $row} return
2822 assigncolor $id
2823 set coords {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002824 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002825 if {$col < 0} {
2826 puts "oops: drawline: id $id not on row $row"
2827 return
2828 }
2829 set lasto {}
2830 set ns 0
2831 while {1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002832 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002833 if {$o eq {}} break
2834 if {$o ne $lasto} {
2835 # changing direction
2836 set x [xc $row $col]
2837 set y [yc $row]
2838 lappend coords $x $y
2839 set lasto $o
2840 }
2841 incr col $o
2842 incr row -1
2843 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002844 set x [xc $row $col]
2845 set y [yc $row]
2846 lappend coords $x $y
Paul Mackerraseb447a12006-03-18 23:11:37 +11002847 if {$i == 0} {
2848 # draw the link to the first child as part of this line
2849 incr row -1
2850 set child [lindex $displayorder $row]
2851 set ccol [lsearch -exact [lindex $rowidlist $row] $child]
2852 if {$ccol >= 0} {
2853 set x [xc $row $ccol]
2854 set y [yc $row]
2855 if {$ccol < $col - 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002856 lappend coords [xc $row [expr {$col - 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002857 } elseif {$ccol > $col + 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002858 lappend coords [xc $row [expr {$col + 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002859 }
2860 lappend coords $x $y
2861 }
2862 }
2863 if {[llength $coords] < 4} return
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002864 if {$downarrow} {
Paul Mackerras879e8b12006-03-31 10:45:14 +11002865 # This line has an arrow at the lower end: check if the arrow is
2866 # on a diagonal segment, and if so, work around the Tk 8.4
2867 # refusal to draw arrows on diagonal lines.
2868 set x0 [lindex $coords 0]
2869 set x1 [lindex $coords 2]
2870 if {$x0 != $x1} {
2871 set y0 [lindex $coords 1]
2872 set y1 [lindex $coords 3]
2873 if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
2874 # we have a nearby vertical segment, just trim off the diag bit
2875 set coords [lrange $coords 2 end]
2876 } else {
2877 set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
2878 set xi [expr {$x0 - $slope * $linespc / 2}]
2879 set yi [expr {$y0 - $linespc / 2}]
2880 set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
2881 }
2882 }
2883 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002884 set arrow [expr {2 * ($i > 0) + $downarrow}]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002885 set arrow [lindex {none first last both} $arrow]
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002886 set t [$canv create line $coords -width [linewidth $id] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002887 -fill $colormap($id) -tags lines.$id -arrow $arrow]
2888 $canv lower $t
2889 bindline $t $id
2890}
2891
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002892proc drawparentlinks {id row col olds} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002893 global rowidlist canv colormap
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002894
2895 set row2 [expr {$row + 1}]
2896 set x [xc $row $col]
2897 set y [yc $row]
2898 set y2 [yc $row2]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002899 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002900 # rmx = right-most X coord used
2901 set rmx 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002902 foreach p $olds {
Paul Mackerrasf3408442006-03-31 09:54:24 +11002903 set i [lsearch -exact $ids $p]
2904 if {$i < 0} {
2905 puts "oops, parent $p of $id not in list"
2906 continue
2907 }
2908 set x2 [xc $row2 $i]
2909 if {$x2 > $rmx} {
2910 set rmx $x2
2911 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002912 set ranges [rowranges $p]
2913 if {$ranges ne {} && $row2 == [lindex $ranges 0]
2914 && $row2 < [lindex $ranges 1]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002915 # drawlineseg will do this one for us
2916 continue
2917 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002918 assigncolor $p
2919 # should handle duplicated parents here...
2920 set coords [list $x $y]
2921 if {$i < $col - 1} {
2922 lappend coords [xc $row [expr {$i + 1}]] $y
2923 } elseif {$i > $col + 1} {
2924 lappend coords [xc $row [expr {$i - 1}]] $y
2925 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002926 lappend coords $x2 $y2
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002927 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002928 -fill $colormap($p) -tags lines.$p]
2929 $canv lower $t
2930 bindline $t $p
2931 }
2932 return $rmx
2933}
2934
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002935proc drawlines {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002936 global colormap canv
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002937 global idrangedrawn
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002938 global children iddrawn commitrow rowidlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002939
2940 $canv delete lines.$id
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002941 set nr [expr {[llength [rowranges $id]] / 2}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002942 for {set i 0} {$i < $nr} {incr i} {
2943 if {[info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002944 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002945 }
2946 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002947 foreach child $children($curview,$id) {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002948 if {[info exists iddrawn($child)]} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002949 set row $commitrow($curview,$child)
Paul Mackerras79b2c752006-04-02 20:47:40 +10002950 set col [lsearch -exact [lindex $rowidlist $row] $child]
2951 if {$col >= 0} {
2952 drawparentlinks $child $row $col [list $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002953 }
2954 }
2955 }
2956}
2957
2958proc drawcmittext {id row col rmx} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002959 global linespc canv canv2 canv3 canvy0 fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002960 global commitlisted commitinfo rowidlist
2961 global rowtextx idpos idtags idheads idotherrefs
2962 global linehtag linentag linedtag
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002963 global mainfont canvxmax boldrows boldnamerows fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002964
Paul Mackerras79b2c752006-04-02 20:47:40 +10002965 set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002966 set x [xc $row $col]
2967 set y [yc $row]
2968 set orad [expr {$linespc / 3}]
2969 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
2970 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002971 -fill $ofill -outline $fgcolor -width 1 -tags circle]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002972 $canv raise $t
2973 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002974 set xt [xc $row [llength [lindex $rowidlist $row]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002975 if {$xt < $rmx} {
2976 set xt $rmx
2977 }
2978 set rowtextx($row) $xt
2979 set idpos($id) [list $x $xt $y]
2980 if {[info exists idtags($id)] || [info exists idheads($id)]
2981 || [info exists idotherrefs($id)]} {
2982 set xt [drawtags $id $x $xt $y]
2983 }
2984 set headline [lindex $commitinfo($id) 0]
2985 set name [lindex $commitinfo($id) 1]
2986 set date [lindex $commitinfo($id) 2]
2987 set date [formatdate $date]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002988 set font $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10002989 set nfont $mainfont
2990 set isbold [ishighlighted $row]
2991 if {$isbold > 0} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002992 lappend boldrows $row
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002993 lappend font bold
Paul Mackerras908c3582006-05-20 09:38:11 +10002994 if {$isbold > 1} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002995 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10002996 lappend nfont bold
2997 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002998 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002999 set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
3000 -text $headline -font $font -tags text]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003001 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003002 set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
3003 -text $name -font $nfont -tags text]
3004 set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
3005 -text $date -font $mainfont -tags text]
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11003006 set xr [expr {$xt + [font measure $mainfont $headline]}]
3007 if {$xr > $canvxmax} {
3008 set canvxmax $xr
3009 setcanvscroll
3010 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003011}
3012
3013proc drawcmitrow {row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003014 global displayorder rowidlist
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003015 global idrangedrawn iddrawn
Paul Mackerrase7da3472006-04-17 10:27:59 +10003016 global commitinfo parentlist numcommits
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003017 global filehighlight fhighlights findstring nhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10003018 global hlview vhighlights
Paul Mackerras164ff272006-05-29 19:50:02 +10003019 global highlight_related rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003020
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003021 if {$row >= $numcommits} return
3022 foreach id [lindex $rowidlist $row] {
Paul Mackerras22626ef2006-04-17 09:56:02 +10003023 if {$id eq {}} continue
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003024 set i -1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003025 foreach {s e} [rowranges $id] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003026 incr i
3027 if {$row < $s} continue
3028 if {$e eq {}} break
3029 if {$row <= $e} {
3030 if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11003031 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003032 set idrangedrawn($id,$i) 1
3033 }
3034 break
3035 }
3036 }
3037 }
3038
3039 set id [lindex $displayorder $row]
Paul Mackerras908c3582006-05-20 09:38:11 +10003040 if {[info exists hlview] && ![info exists vhighlights($row)]} {
3041 askvhighlight $row $id
3042 }
3043 if {[info exists filehighlight] && ![info exists fhighlights($row)]} {
3044 askfilehighlight $row $id
3045 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003046 if {$findstring ne {} && ![info exists nhighlights($row)]} {
3047 askfindhighlight $row $id
Paul Mackerras908c3582006-05-20 09:38:11 +10003048 }
Paul Mackerras164ff272006-05-29 19:50:02 +10003049 if {$highlight_related ne "None" && ![info exists rhighlights($row)]} {
3050 askrelhighlight $row $id
3051 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003052 if {[info exists iddrawn($id)]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003053 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003054 if {$col < 0} {
3055 puts "oops, row $row id $id not in list"
3056 return
3057 }
3058 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003059 getcommit $id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003060 }
3061 assigncolor $id
Paul Mackerras79b2c752006-04-02 20:47:40 +10003062 set olds [lindex $parentlist $row]
3063 if {$olds ne {}} {
3064 set rmx [drawparentlinks $id $row $col $olds]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003065 } else {
3066 set rmx 0
3067 }
3068 drawcmittext $id $row $col $rmx
3069 set iddrawn($id) 1
3070}
3071
3072proc drawfrac {f0 f1} {
3073 global numcommits canv
3074 global linespc
3075
3076 set ymax [lindex [$canv cget -scrollregion] 3]
3077 if {$ymax eq {} || $ymax == 0} return
3078 set y0 [expr {int($f0 * $ymax)}]
3079 set row [expr {int(($y0 - 3) / $linespc) - 1}]
3080 if {$row < 0} {
3081 set row 0
3082 }
3083 set y1 [expr {int($f1 * $ymax)}]
3084 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
3085 if {$endrow >= $numcommits} {
3086 set endrow [expr {$numcommits - 1}]
3087 }
3088 for {} {$row <= $endrow} {incr row} {
3089 drawcmitrow $row
3090 }
3091}
3092
3093proc drawvisible {} {
3094 global canv
3095 eval drawfrac [$canv yview]
3096}
3097
3098proc clear_display {} {
3099 global iddrawn idrangedrawn
Paul Mackerras164ff272006-05-29 19:50:02 +10003100 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003101
3102 allcanvs delete all
3103 catch {unset iddrawn}
3104 catch {unset idrangedrawn}
Paul Mackerras908c3582006-05-20 09:38:11 +10003105 catch {unset vhighlights}
3106 catch {unset fhighlights}
3107 catch {unset nhighlights}
Paul Mackerras164ff272006-05-29 19:50:02 +10003108 catch {unset rhighlights}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003109}
3110
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003111proc findcrossings {id} {
3112 global rowidlist parentlist numcommits rowoffsets displayorder
3113
3114 set cross {}
3115 set ccross {}
3116 foreach {s e} [rowranges $id] {
3117 if {$e >= $numcommits} {
3118 set e [expr {$numcommits - 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003119 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003120 if {$e <= $s} continue
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003121 set x [lsearch -exact [lindex $rowidlist $e] $id]
3122 if {$x < 0} {
3123 puts "findcrossings: oops, no [shortids $id] in row $e"
3124 continue
3125 }
3126 for {set row $e} {[incr row -1] >= $s} {} {
3127 set olds [lindex $parentlist $row]
3128 set kid [lindex $displayorder $row]
3129 set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
3130 if {$kidx < 0} continue
3131 set nextrow [lindex $rowidlist [expr {$row + 1}]]
3132 foreach p $olds {
3133 set px [lsearch -exact $nextrow $p]
3134 if {$px < 0} continue
3135 if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
3136 if {[lsearch -exact $ccross $p] >= 0} continue
3137 if {$x == $px + ($kidx < $px? -1: 1)} {
3138 lappend ccross $p
3139 } elseif {[lsearch -exact $cross $p] < 0} {
3140 lappend cross $p
3141 }
3142 }
3143 }
3144 set inc [lindex $rowoffsets $row $x]
3145 if {$inc eq {}} break
3146 incr x $inc
3147 }
3148 }
3149 return [concat $ccross {{}} $cross]
3150}
3151
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003152proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +11003153 global colormap colors nextcolor
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003154 global commitrow parentlist children children curview
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003155
Paul Mackerras418c4c72006-02-07 09:10:18 +11003156 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003157 set ncolors [llength $colors]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003158 if {[info exists children($curview,$id)]} {
3159 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10003160 } else {
3161 set kids {}
3162 }
3163 if {[llength $kids] == 1} {
3164 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003165 if {[info exists colormap($child)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003166 && [llength [lindex $parentlist $commitrow($curview,$child)]] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003167 set colormap($id) $colormap($child)
3168 return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003169 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003170 }
3171 set badcolors {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003172 set origbad {}
3173 foreach x [findcrossings $id] {
3174 if {$x eq {}} {
3175 # delimiter between corner crossings and other crossings
3176 if {[llength $badcolors] >= $ncolors - 1} break
3177 set origbad $badcolors
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003178 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003179 if {[info exists colormap($x)]
3180 && [lsearch -exact $badcolors $colormap($x)] < 0} {
3181 lappend badcolors $colormap($x)
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003182 }
3183 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003184 if {[llength $badcolors] >= $ncolors} {
3185 set badcolors $origbad
3186 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003187 set origbad $badcolors
3188 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003189 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003190 if {[info exists colormap($child)]
3191 && [lsearch -exact $badcolors $colormap($child)] < 0} {
3192 lappend badcolors $colormap($child)
3193 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003194 foreach p [lindex $parentlist $commitrow($curview,$child)] {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003195 if {[info exists colormap($p)]
3196 && [lsearch -exact $badcolors $colormap($p)] < 0} {
3197 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003198 }
3199 }
3200 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003201 if {[llength $badcolors] >= $ncolors} {
3202 set badcolors $origbad
3203 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003204 }
3205 for {set i 0} {$i <= $ncolors} {incr i} {
3206 set c [lindex $colors $nextcolor]
3207 if {[incr nextcolor] >= $ncolors} {
3208 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003209 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003210 if {[lsearch -exact $badcolors $c]} break
3211 }
3212 set colormap($id) $c
3213}
3214
Paul Mackerrasa823a912005-06-21 10:01:38 +10003215proc bindline {t id} {
3216 global canv
3217
Paul Mackerrasa823a912005-06-21 10:01:38 +10003218 $canv bind $t <Enter> "lineenter %x %y $id"
3219 $canv bind $t <Motion> "linemotion %x %y $id"
3220 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003221 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 10:01:38 +10003222}
3223
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003224proc drawtags {id x xt y1} {
Paul Mackerras8a485712006-07-06 10:21:23 +10003225 global idtags idheads idotherrefs mainhead
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003226 global linespc lthickness
Paul Mackerras8a485712006-07-06 10:21:23 +10003227 global canv mainfont commitrow rowtextx curview fgcolor bgcolor
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003228
3229 set marks {}
3230 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003231 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003232 if {[info exists idtags($id)]} {
3233 set marks $idtags($id)
3234 set ntags [llength $marks]
3235 }
3236 if {[info exists idheads($id)]} {
3237 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003238 set nheads [llength $idheads($id)]
3239 }
3240 if {[info exists idotherrefs($id)]} {
3241 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003242 }
3243 if {$marks eq {}} {
3244 return $xt
3245 }
3246
3247 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003248 set yt [expr {$y1 - 0.5 * $linespc}]
3249 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003250 set xvals {}
3251 set wvals {}
Paul Mackerras8a485712006-07-06 10:21:23 +10003252 set i -1
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003253 foreach tag $marks {
Paul Mackerras8a485712006-07-06 10:21:23 +10003254 incr i
3255 if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
3256 set wid [font measure [concat $mainfont bold] $tag]
3257 } else {
3258 set wid [font measure $mainfont $tag]
3259 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003260 lappend xvals $xt
3261 lappend wvals $wid
3262 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
3263 }
3264 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
3265 -width $lthickness -fill black -tags tag.$id]
3266 $canv lower $t
3267 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003268 set xl [expr {$x + $delta}]
3269 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerras8a485712006-07-06 10:21:23 +10003270 set font $mainfont
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003271 if {[incr ntags -1] >= 0} {
3272 # draw a tag
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003273 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
3274 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 23:11:39 +10003275 -width 1 -outline black -fill yellow -tags tag.$id]
3276 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003277 set rowtextx($commitrow($curview,$id)) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003278 } else {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003279 # draw a head or other ref
3280 if {[incr nheads -1] >= 0} {
3281 set col green
Paul Mackerras8a485712006-07-06 10:21:23 +10003282 if {$tag eq $mainhead} {
3283 lappend font bold
3284 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003285 } else {
3286 set col "#ddddff"
3287 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003288 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003289 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003290 -width 1 -outline black -fill $col -tags tag.$id
Josef Weidendorfera970fcf2006-04-18 23:53:07 +02003291 if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
3292 set rwid [font measure $mainfont $remoteprefix]
3293 set xi [expr {$x + 1}]
3294 set yti [expr {$yt + 1}]
3295 set xri [expr {$x + $rwid}]
3296 $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
3297 -width 0 -fill "#ffddaa" -tags tag.$id
3298 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003299 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003300 set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
Paul Mackerras8a485712006-07-06 10:21:23 +10003301 -font $font -tags [list tag.$id text]]
Paul Mackerras106288c2005-08-19 23:11:39 +10003302 if {$ntags >= 0} {
3303 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras10299152006-08-02 09:52:01 +10003304 } elseif {$nheads >= 0} {
3305 $canv bind $t <Button-3> [list headmenu %X %Y $id $tag]
Paul Mackerras106288c2005-08-19 23:11:39 +10003306 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003307 }
3308 return $xt
3309}
3310
Paul Mackerras8d858d12005-08-05 09:52:16 +10003311proc xcoord {i level ln} {
3312 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003313
Paul Mackerras8d858d12005-08-05 09:52:16 +10003314 set x [expr {$canvx0 + $i * $xspc1($ln)}]
3315 if {$i > 0 && $i == $level} {
3316 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
3317 } elseif {$i > $level} {
3318 set x [expr {$x + $xspc2 - $xspc1($ln)}]
3319 }
3320 return $x
3321}
3322
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003323proc show_status {msg} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003324 global canv mainfont fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003325
3326 clear_display
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003327 $canv create text 3 3 -anchor nw -text $msg -font $mainfont \
3328 -tags text -fill $fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003329}
3330
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003331proc finishcommits {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003332 global commitidx phase curview
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003333 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003334
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003335 if {$commitidx($curview) > 0} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003336 drawrest
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003337 } else {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003338 show_status "No commits selected"
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003339 }
Paul Mackerras8ed16482006-03-02 22:56:44 +11003340 set phase {}
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003341 catch {unset pending_select}
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003342}
3343
Paul Mackerras561d0382006-08-28 22:41:09 +10003344# Insert a new commit as the child of the commit on row $row.
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003345# The new commit will be displayed on row $row and the commits
3346# on that row and below will move down one row.
3347proc insertrow {row newcmit} {
3348 global displayorder parentlist childlist commitlisted
3349 global commitrow curview rowidlist rowoffsets numcommits
3350 global rowrangelist idrowranges rowlaidout rowoptim numcommits
Paul Mackerras561d0382006-08-28 22:41:09 +10003351 global linesegends selectedline
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003352
3353 if {$row >= $numcommits} {
3354 puts "oops, inserting new row $row but only have $numcommits rows"
3355 return
3356 }
3357 set p [lindex $displayorder $row]
3358 set displayorder [linsert $displayorder $row $newcmit]
3359 set parentlist [linsert $parentlist $row $p]
3360 set kids [lindex $childlist $row]
3361 lappend kids $newcmit
3362 lset childlist $row $kids
3363 set childlist [linsert $childlist $row {}]
Paul Mackerras561d0382006-08-28 22:41:09 +10003364 set commitlisted [linsert $commitlisted $row 1]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003365 set l [llength $displayorder]
3366 for {set r $row} {$r < $l} {incr r} {
3367 set id [lindex $displayorder $r]
3368 set commitrow($curview,$id) $r
3369 }
3370
3371 set idlist [lindex $rowidlist $row]
3372 set offs [lindex $rowoffsets $row]
3373 set newoffs {}
3374 foreach x $idlist {
3375 if {$x eq {} || ($x eq $p && [llength $kids] == 1)} {
3376 lappend newoffs {}
3377 } else {
3378 lappend newoffs 0
3379 }
3380 }
3381 if {[llength $kids] == 1} {
3382 set col [lsearch -exact $idlist $p]
3383 lset idlist $col $newcmit
3384 } else {
3385 set col [llength $idlist]
3386 lappend idlist $newcmit
3387 lappend offs {}
3388 lset rowoffsets $row $offs
3389 }
3390 set rowidlist [linsert $rowidlist $row $idlist]
3391 set rowoffsets [linsert $rowoffsets [expr {$row+1}] $newoffs]
3392
3393 set rowrangelist [linsert $rowrangelist $row {}]
3394 set l [llength $rowrangelist]
3395 for {set r 0} {$r < $l} {incr r} {
3396 set ranges [lindex $rowrangelist $r]
3397 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3398 set newranges {}
3399 foreach x $ranges {
3400 if {$x >= $row} {
3401 lappend newranges [expr {$x + 1}]
3402 } else {
3403 lappend newranges $x
3404 }
3405 }
3406 lset rowrangelist $r $newranges
3407 }
3408 }
3409 if {[llength $kids] > 1} {
3410 set rp1 [expr {$row + 1}]
3411 set ranges [lindex $rowrangelist $rp1]
3412 if {$ranges eq {}} {
3413 set ranges [list $row $rp1]
3414 } elseif {[lindex $ranges end-1] == $rp1} {
3415 lset ranges end-1 $row
3416 }
3417 lset rowrangelist $rp1 $ranges
3418 }
3419 foreach id [array names idrowranges] {
3420 set ranges $idrowranges($id)
3421 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3422 set newranges {}
3423 foreach x $ranges {
3424 if {$x >= $row} {
3425 lappend newranges [expr {$x + 1}]
3426 } else {
3427 lappend newranges $x
3428 }
3429 }
3430 set idrowranges($id) $newranges
3431 }
3432 }
3433
3434 set linesegends [linsert $linesegends $row {}]
3435
3436 incr rowlaidout
3437 incr rowoptim
3438 incr numcommits
3439
Paul Mackerras561d0382006-08-28 22:41:09 +10003440 if {[info exists selectedline] && $selectedline >= $row} {
3441 incr selectedline
3442 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003443 redisplay
3444}
3445
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003446# Don't change the text pane cursor if it is currently the hand cursor,
3447# showing that we are over a sha1 ID link.
3448proc settextcursor {c} {
3449 global ctext curtextcursor
3450
3451 if {[$ctext cget -cursor] == $curtextcursor} {
3452 $ctext config -cursor $c
3453 }
3454 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003455}
3456
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003457proc nowbusy {what} {
3458 global isbusy
3459
3460 if {[array names isbusy] eq {}} {
3461 . config -cursor watch
3462 settextcursor watch
3463 }
3464 set isbusy($what) 1
3465}
3466
3467proc notbusy {what} {
3468 global isbusy maincursor textcursor
3469
3470 catch {unset isbusy($what)}
3471 if {[array names isbusy] eq {}} {
3472 . config -cursor $maincursor
3473 settextcursor $textcursor
3474 }
3475}
3476
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10003477proc drawrest {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003478 global startmsecs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003479 global rowlaidout commitidx curview
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003480 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003481
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003482 set row $rowlaidout
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003483 layoutrows $rowlaidout $commitidx($curview) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003484 layouttail
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003485 optimize_rows $row 0 $commitidx($curview)
3486 showstuff $commitidx($curview)
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003487 if {[info exists pending_select]} {
3488 selectline 0 1
3489 }
Paul Mackerras4dd5d0d2005-12-06 09:46:23 +11003490
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003491 set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003492 #global numcommits
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10003493 #puts "overall $drawmsecs ms for $numcommits commits"
Paul Mackerras1db95b02005-05-09 04:08:39 +00003494}
3495
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003496proc findmatches {f} {
3497 global findtype foundstring foundstrlen
3498 if {$findtype == "Regexp"} {
3499 set matches [regexp -indices -all -inline $foundstring $f]
3500 } else {
3501 if {$findtype == "IgnCase"} {
3502 set str [string tolower $f]
3503 } else {
3504 set str $f
3505 }
3506 set matches {}
3507 set i 0
3508 while {[set j [string first $foundstring $str $i]] >= 0} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003509 lappend matches [list $j [expr {$j+$foundstrlen-1}]]
3510 set i [expr {$j + $foundstrlen}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003511 }
3512 }
3513 return $matches
3514}
3515
Paul Mackerras98f350e2005-05-15 05:56:51 +00003516proc dofind {} {
3517 global findtype findloc findstring markedmatches commitinfo
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003518 global numcommits displayorder linehtag linentag linedtag
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003519 global mainfont canv canv2 canv3 selectedline
Paul Mackerras8ed16482006-03-02 22:56:44 +11003520 global matchinglines foundstring foundstrlen matchstring
3521 global commitdata
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003522
3523 stopfindproc
Paul Mackerras98f350e2005-05-15 05:56:51 +00003524 unmarkmatches
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003525 cancel_next_highlight
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003526 focus .
Paul Mackerras98f350e2005-05-15 05:56:51 +00003527 set matchinglines {}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003528 if {$findtype == "IgnCase"} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003529 set foundstring [string tolower $findstring]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003530 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003531 set foundstring $findstring
Paul Mackerras98f350e2005-05-15 05:56:51 +00003532 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003533 set foundstrlen [string length $findstring]
3534 if {$foundstrlen == 0} return
Paul Mackerras8ed16482006-03-02 22:56:44 +11003535 regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
3536 set matchstring "*$matchstring*"
Paul Mackerras98f350e2005-05-15 05:56:51 +00003537 if {![info exists selectedline]} {
3538 set oldsel -1
3539 } else {
3540 set oldsel $selectedline
3541 }
3542 set didsel 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003543 set fldtypes {Headline Author Date Committer CDate Comments}
Paul Mackerras8ed16482006-03-02 22:56:44 +11003544 set l -1
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003545 foreach id $displayorder {
3546 set d $commitdata($id)
Paul Mackerras8ed16482006-03-02 22:56:44 +11003547 incr l
3548 if {$findtype == "Regexp"} {
3549 set doesmatch [regexp $foundstring $d]
3550 } elseif {$findtype == "IgnCase"} {
3551 set doesmatch [string match -nocase $matchstring $d]
3552 } else {
3553 set doesmatch [string match $matchstring $d]
3554 }
3555 if {!$doesmatch} continue
Paul Mackerras8ed16482006-03-02 22:56:44 +11003556 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003557 getcommit $id
Paul Mackerras8ed16482006-03-02 22:56:44 +11003558 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003559 set info $commitinfo($id)
3560 set doesmatch 0
3561 foreach f $info ty $fldtypes {
3562 if {$findloc != "All fields" && $findloc != $ty} {
3563 continue
3564 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003565 set matches [findmatches $f]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003566 if {$matches == {}} continue
3567 set doesmatch 1
3568 if {$ty == "Headline"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003569 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003570 markmatches $canv $l $f $linehtag($l) $matches $mainfont
3571 } elseif {$ty == "Author"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003572 drawcmitrow $l
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003573 markmatches $canv2 $l $f $linentag($l) $matches $mainfont
Paul Mackerras98f350e2005-05-15 05:56:51 +00003574 } elseif {$ty == "Date"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003575 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003576 markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
3577 }
3578 }
3579 if {$doesmatch} {
3580 lappend matchinglines $l
3581 if {!$didsel && $l > $oldsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003582 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003583 set didsel 1
3584 }
3585 }
3586 }
3587 if {$matchinglines == {}} {
3588 bell
3589 } elseif {!$didsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003590 findselectline [lindex $matchinglines 0]
3591 }
3592}
3593
3594proc findselectline {l} {
3595 global findloc commentend ctext
Paul Mackerrasd6982062005-08-06 22:06:06 +10003596 selectline $l 1
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003597 if {$findloc == "All fields" || $findloc == "Comments"} {
3598 # highlight the matches in the comments
3599 set f [$ctext get 1.0 $commentend]
3600 set matches [findmatches $f]
3601 foreach match $matches {
3602 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003603 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003604 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
3605 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003606 }
3607}
3608
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003609proc findnext {restart} {
Paul Mackerras98f350e2005-05-15 05:56:51 +00003610 global matchinglines selectedline
3611 if {![info exists matchinglines]} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003612 if {$restart} {
3613 dofind
3614 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003615 return
3616 }
3617 if {![info exists selectedline]} return
3618 foreach l $matchinglines {
3619 if {$l > $selectedline} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003620 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003621 return
3622 }
3623 }
3624 bell
3625}
3626
3627proc findprev {} {
3628 global matchinglines selectedline
3629 if {![info exists matchinglines]} {
3630 dofind
3631 return
3632 }
3633 if {![info exists selectedline]} return
3634 set prev {}
3635 foreach l $matchinglines {
3636 if {$l >= $selectedline} break
3637 set prev $l
3638 }
3639 if {$prev != {}} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003640 findselectline $prev
Paul Mackerras98f350e2005-05-15 05:56:51 +00003641 } else {
3642 bell
3643 }
3644}
3645
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003646proc stopfindproc {{done 0}} {
3647 global findprocpid findprocfile findids
3648 global ctext findoldcursor phase maincursor textcursor
3649 global findinprogress
3650
3651 catch {unset findids}
3652 if {[info exists findprocpid]} {
3653 if {!$done} {
3654 catch {exec kill $findprocpid}
3655 }
3656 catch {close $findprocfile}
3657 unset findprocpid
3658 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003659 catch {unset findinprogress}
3660 notbusy find
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003661}
3662
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003663# mark a commit as matching by putting a yellow background
3664# behind the headline
3665proc markheadline {l id} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11003666 global canv mainfont linehtag
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003667
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003668 drawcmitrow $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003669 set bbox [$canv bbox $linehtag($l)]
3670 set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
3671 $canv lower $t
3672}
3673
3674# mark the bits of a headline, author or date that match a find string
Paul Mackerras98f350e2005-05-15 05:56:51 +00003675proc markmatches {canv l str tag matches font} {
3676 set bbox [$canv bbox $tag]
3677 set x0 [lindex $bbox 0]
3678 set y0 [lindex $bbox 1]
3679 set y1 [lindex $bbox 3]
3680 foreach match $matches {
3681 set start [lindex $match 0]
3682 set end [lindex $match 1]
3683 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003684 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
3685 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
3686 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
3687 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras98f350e2005-05-15 05:56:51 +00003688 -outline {} -tags matches -fill yellow]
3689 $canv lower $t
3690 }
3691}
3692
3693proc unmarkmatches {} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003694 global matchinglines findids
Paul Mackerras98f350e2005-05-15 05:56:51 +00003695 allcanvs delete matches
3696 catch {unset matchinglines}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003697 catch {unset findids}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003698}
3699
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003700proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003701 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003702 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:39 +00003703 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:42 +00003704 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:39 +00003705 set yfrac [lindex [$canv yview] 0]
3706 set y [expr {$y + $yfrac * $ymax}]
3707 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
3708 if {$l < 0} {
3709 set l 0
3710 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003711 if {$w eq $canv} {
3712 if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
3713 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003714 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10003715 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003716}
3717
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003718proc commit_descriptor {p} {
3719 global commitinfo
Paul Mackerrasb0934482006-05-15 09:56:08 +10003720 if {![info exists commitinfo($p)]} {
3721 getcommit $p
3722 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003723 set l "..."
Paul Mackerrasb0934482006-05-15 09:56:08 +10003724 if {[llength $commitinfo($p)] > 1} {
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003725 set l [lindex $commitinfo($p) 0]
3726 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003727 return "$p ($l)\n"
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003728}
3729
Paul Mackerras106288c2005-08-19 23:11:39 +10003730# append some text to the ctext widget, and make any SHA1 ID
3731# that we know about be a clickable link.
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003732proc appendwithlinks {text tags} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003733 global ctext commitrow linknum curview
Paul Mackerras106288c2005-08-19 23:11:39 +10003734
3735 set start [$ctext index "end - 1c"]
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003736 $ctext insert end $text $tags
Paul Mackerras106288c2005-08-19 23:11:39 +10003737 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
3738 foreach l $links {
3739 set s [lindex $l 0]
3740 set e [lindex $l 1]
3741 set linkid [string range $text $s $e]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003742 if {![info exists commitrow($curview,$linkid)]} continue
Paul Mackerras106288c2005-08-19 23:11:39 +10003743 incr e
3744 $ctext tag add link "$start + $s c" "$start + $e c"
3745 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003746 $ctext tag bind link$linknum <1> \
3747 [list selectline $commitrow($curview,$linkid) 1]
Paul Mackerras106288c2005-08-19 23:11:39 +10003748 incr linknum
3749 }
3750 $ctext tag conf link -foreground blue -underline 1
3751 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3752 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3753}
3754
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10003755proc viewnextline {dir} {
3756 global canv linespc
3757
3758 $canv delete hover
3759 set ymax [lindex [$canv cget -scrollregion] 3]
3760 set wnow [$canv yview]
3761 set wtop [expr {[lindex $wnow 0] * $ymax}]
3762 set newtop [expr {$wtop + $dir * $linespc}]
3763 if {$newtop < 0} {
3764 set newtop 0
3765 } elseif {$newtop > $ymax} {
3766 set newtop $ymax
3767 }
3768 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
3769}
3770
Paul Mackerrasef030b82006-06-04 11:50:38 +10003771# add a list of tag or branch names at position pos
3772# returns the number of names inserted
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003773proc appendrefs {pos tags var} {
3774 global ctext commitrow linknum curview $var
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003775
Paul Mackerrasef030b82006-06-04 11:50:38 +10003776 if {[catch {$ctext index $pos}]} {
3777 return 0
3778 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003779 set tags [lsort $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003780 set sep {}
3781 foreach tag $tags {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003782 set id [set $var\($tag\)]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003783 set lk link$linknum
3784 incr linknum
3785 $ctext insert $pos $sep
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003786 $ctext insert $pos $tag $lk
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003787 $ctext tag conf $lk -foreground blue
3788 if {[info exists commitrow($curview,$id)]} {
3789 $ctext tag bind $lk <1> \
3790 [list selectline $commitrow($curview,$id) 1]
3791 $ctext tag conf $lk -underline 1
3792 $ctext tag bind $lk <Enter> { %W configure -cursor hand2 }
3793 $ctext tag bind $lk <Leave> { %W configure -cursor $curtextcursor }
3794 }
3795 set sep ", "
3796 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003797 return [llength $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003798}
3799
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003800proc taglist {ids} {
3801 global idtags
3802
3803 set tags {}
3804 foreach id $ids {
3805 foreach tag $idtags($id) {
3806 lappend tags $tag
3807 }
3808 }
3809 return $tags
3810}
3811
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003812# called when we have finished computing the nearby tags
3813proc dispneartags {} {
3814 global selectedline currentid ctext anc_tags desc_tags showneartags
Paul Mackerrasef030b82006-06-04 11:50:38 +10003815 global desc_heads
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003816
3817 if {![info exists selectedline] || !$showneartags} return
3818 set id $currentid
3819 $ctext conf -state normal
Paul Mackerrasef030b82006-06-04 11:50:38 +10003820 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003821 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003822 $ctext insert "branch -2c" "es"
3823 }
3824 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003825 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003826 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003827 }
3828 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003829 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003830 }
3831 $ctext conf -state disabled
3832}
3833
Paul Mackerrasd6982062005-08-06 22:06:06 +10003834proc selectline {l isnew} {
Paul Mackerrasd2610d12005-05-11 00:45:38 +00003835 global canv canv2 canv3 ctext commitinfo selectedline
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003836 global displayorder linehtag linentag linedtag
Paul Mackerras79b2c752006-04-02 20:47:40 +10003837 global canvy0 linespc parentlist childlist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10003838 global currentid sha1entry
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003839 global commentend idtags linknum
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003840 global mergemax numcommits pending_select
Paul Mackerrasef030b82006-06-04 11:50:38 +10003841 global cmitmode desc_tags anc_tags showneartags allcommits desc_heads
Paul Mackerrasd6982062005-08-06 22:06:06 +10003842
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003843 catch {unset pending_select}
Paul Mackerras84ba7342005-06-17 00:12:26 +00003844 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10003845 normalline
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003846 cancel_next_highlight
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003847 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003848 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:00 +00003849 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:42 +00003850 set ytop [expr {$y - $linespc - 1}]
3851 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003852 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003853 set wtop [expr {[lindex $wnow 0] * $ymax}]
3854 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:42 +00003855 set wh [expr {$wbot - $wtop}]
3856 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:00 +00003857 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:42 +00003858 if {$ybot < $wtop} {
3859 set newtop [expr {$y - $wh / 2.0}]
3860 } else {
3861 set newtop $ytop
3862 if {$newtop > $wtop - $linespc} {
3863 set newtop [expr {$wtop - $linespc}]
3864 }
Paul Mackerras17386062005-05-18 22:51:00 +00003865 }
Paul Mackerras58422152005-05-19 10:56:42 +00003866 } elseif {$ybot > $wbot} {
3867 if {$ytop > $wbot} {
3868 set newtop [expr {$y - $wh / 2.0}]
3869 } else {
3870 set newtop [expr {$ybot - $wh}]
3871 if {$newtop < $wtop + $linespc} {
3872 set newtop [expr {$wtop + $linespc}]
3873 }
Paul Mackerras17386062005-05-18 22:51:00 +00003874 }
Paul Mackerras58422152005-05-19 10:56:42 +00003875 }
3876 if {$newtop != $wtop} {
3877 if {$newtop < 0} {
3878 set newtop 0
3879 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003880 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003881 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003882 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003883
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003884 if {![info exists linehtag($l)]} return
3885 $canv delete secsel
3886 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
3887 -tags secsel -fill [$canv cget -selectbackground]]
3888 $canv lower $t
3889 $canv2 delete secsel
3890 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
3891 -tags secsel -fill [$canv2 cget -selectbackground]]
3892 $canv2 lower $t
3893 $canv3 delete secsel
3894 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
3895 -tags secsel -fill [$canv3 cget -selectbackground]]
3896 $canv3 lower $t
3897
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003898 if {$isnew} {
3899 addtohistory [list selectline $l 0]
Paul Mackerrasd6982062005-08-06 22:06:06 +10003900 }
3901
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003902 set selectedline $l
3903
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003904 set id [lindex $displayorder $l]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003905 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003906 $sha1entry delete 0 end
3907 $sha1entry insert 0 $id
3908 $sha1entry selection from 0
3909 $sha1entry selection to end
Paul Mackerras164ff272006-05-29 19:50:02 +10003910 rhighlight_sel $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003911
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003912 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10003913 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10003914 set linknum 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00003915 set info $commitinfo($id)
Paul Mackerras232475d2005-11-15 10:34:03 +11003916 set date [formatdate [lindex $info 2]]
3917 $ctext insert end "Author: [lindex $info 1] $date\n"
3918 set date [formatdate [lindex $info 4]]
3919 $ctext insert end "Committer: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003920 if {[info exists idtags($id)]} {
3921 $ctext insert end "Tags:"
3922 foreach tag $idtags($id) {
3923 $ctext insert end " $tag"
3924 }
3925 $ctext insert end "\n"
3926 }
Mark Levedahl32364b32007-02-01 08:44:46 -05003927
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003928 set headers {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10003929 set olds [lindex $parentlist $l]
3930 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003931 set np 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10003932 foreach p $olds {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003933 if {$np >= $mergemax} {
3934 set tag mmax
3935 } else {
3936 set tag m$np
3937 }
3938 $ctext insert end "Parent: " $tag
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003939 appendwithlinks [commit_descriptor $p] {}
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003940 incr np
3941 }
3942 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003943 foreach p $olds {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003944 append headers "Parent: [commit_descriptor $p]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003945 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003946 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003947
Paul Mackerras79b2c752006-04-02 20:47:40 +10003948 foreach c [lindex $childlist $l] {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003949 append headers "Child: [commit_descriptor $c]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003950 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003951
3952 # make anything that looks like a SHA1 ID be a clickable link
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003953 appendwithlinks $headers {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003954 if {$showneartags} {
3955 if {![info exists allcommits]} {
3956 getallcommits
3957 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003958 $ctext insert end "Branch: "
3959 $ctext mark set branch "end -1c"
3960 $ctext mark gravity branch left
3961 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003962 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003963 # turn "Branch" into "Branches"
3964 $ctext insert "branch -2c" "es"
3965 }
3966 }
3967 $ctext insert end "\nFollows: "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003968 $ctext mark set follows "end -1c"
3969 $ctext mark gravity follows left
3970 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003971 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003972 }
3973 $ctext insert end "\nPrecedes: "
3974 $ctext mark set precedes "end -1c"
3975 $ctext mark gravity precedes left
3976 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003977 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003978 }
3979 $ctext insert end "\n"
3980 }
3981 $ctext insert end "\n"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003982 appendwithlinks [lindex $info 5] {comment}
Paul Mackerrasd6982062005-08-06 22:06:06 +10003983
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003984 $ctext tag delete Comments
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003985 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003986 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003987 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003988
Paul Mackerras7fcceed2006-04-27 19:21:49 +10003989 init_flist "Comments"
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10003990 if {$cmitmode eq "tree"} {
3991 gettree $id
3992 } elseif {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 20:41:56 +11003993 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 20:50:40 +11003994 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003995 mergediff $id $l
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003996 }
3997}
3998
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10003999proc selfirstline {} {
4000 unmarkmatches
4001 selectline 0 1
4002}
4003
4004proc sellastline {} {
4005 global numcommits
4006 unmarkmatches
4007 set l [expr {$numcommits - 1}]
4008 selectline $l 1
4009}
4010
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004011proc selnextline {dir} {
4012 global selectedline
4013 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004014 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:51 +00004015 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10004016 selectline $l 1
4017}
4018
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004019proc selnextpage {dir} {
4020 global canv linespc selectedline numcommits
4021
4022 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
4023 if {$lpp < 1} {
4024 set lpp 1
4025 }
4026 allcanvs yview scroll [expr {$dir * $lpp}] units
Paul Mackerrase72ee5e2006-05-20 09:58:49 +10004027 drawvisible
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004028 if {![info exists selectedline]} return
4029 set l [expr {$selectedline + $dir * $lpp}]
4030 if {$l < 0} {
4031 set l 0
4032 } elseif {$l >= $numcommits} {
4033 set l [expr $numcommits - 1]
4034 }
4035 unmarkmatches
Mark Levedahl32364b32007-02-01 08:44:46 -05004036 selectline $l 1
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004037}
4038
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004039proc unselectline {} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004040 global selectedline currentid
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004041
4042 catch {unset selectedline}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004043 catch {unset currentid}
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004044 allcanvs delete secsel
Paul Mackerras164ff272006-05-29 19:50:02 +10004045 rhighlight_none
Paul Mackerras4e7d6772006-05-30 21:33:07 +10004046 cancel_next_highlight
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004047}
4048
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004049proc reselectline {} {
4050 global selectedline
4051
4052 if {[info exists selectedline]} {
4053 selectline $selectedline 0
4054 }
4055}
4056
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004057proc addtohistory {cmd} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004058 global history historyindex curview
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004059
Paul Mackerras2516dae2006-04-21 10:35:31 +10004060 set elt [list $curview $cmd]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004061 if {$historyindex > 0
Paul Mackerras2516dae2006-04-21 10:35:31 +10004062 && [lindex $history [expr {$historyindex - 1}]] == $elt} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004063 return
4064 }
4065
4066 if {$historyindex < [llength $history]} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004067 set history [lreplace $history $historyindex end $elt]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004068 } else {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004069 lappend history $elt
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004070 }
4071 incr historyindex
4072 if {$historyindex > 1} {
Mark Levedahl3468e712007-02-01 08:46:38 -05004073 .tf.bar.leftbut conf -state normal
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004074 } else {
Mark Levedahl3468e712007-02-01 08:46:38 -05004075 .tf.bar.leftbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004076 }
Mark Levedahl3468e712007-02-01 08:46:38 -05004077 .tf.bar.rightbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004078}
4079
Paul Mackerras2516dae2006-04-21 10:35:31 +10004080proc godo {elt} {
4081 global curview
4082
4083 set view [lindex $elt 0]
4084 set cmd [lindex $elt 1]
4085 if {$curview != $view} {
4086 showview $view
4087 }
4088 eval $cmd
4089}
4090
Paul Mackerrasd6982062005-08-06 22:06:06 +10004091proc goback {} {
4092 global history historyindex
4093
4094 if {$historyindex > 1} {
4095 incr historyindex -1
Paul Mackerras2516dae2006-04-21 10:35:31 +10004096 godo [lindex $history [expr {$historyindex - 1}]]
Mark Levedahl3468e712007-02-01 08:46:38 -05004097 .tf.bar.rightbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004098 }
4099 if {$historyindex <= 1} {
Mark Levedahl3468e712007-02-01 08:46:38 -05004100 .tf.bar.leftbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004101 }
4102}
4103
4104proc goforw {} {
4105 global history historyindex
4106
4107 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004108 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 22:06:06 +10004109 incr historyindex
Paul Mackerras2516dae2006-04-21 10:35:31 +10004110 godo $cmd
Mark Levedahl3468e712007-02-01 08:46:38 -05004111 .tf.bar.leftbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004112 }
4113 if {$historyindex >= [llength $history]} {
Mark Levedahl3468e712007-02-01 08:46:38 -05004114 .tf.bar.rightbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004115 }
Paul Mackerras5ad588d2005-05-10 01:02:55 +00004116}
4117
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004118proc gettree {id} {
4119 global treefilelist treeidlist diffids diffmergeid treepending
4120
4121 set diffids $id
4122 catch {unset diffmergeid}
4123 if {![info exists treefilelist($id)]} {
4124 if {![info exists treepending]} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004125 if {[catch {set gtf [open [concat | git ls-tree -r $id] r]}]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004126 return
4127 }
4128 set treepending $id
4129 set treefilelist($id) {}
4130 set treeidlist($id) {}
4131 fconfigure $gtf -blocking 0
4132 fileevent $gtf readable [list gettreeline $gtf $id]
4133 }
4134 } else {
4135 setfilelist $id
4136 }
4137}
4138
4139proc gettreeline {gtf id} {
4140 global treefilelist treeidlist treepending cmitmode diffids
4141
4142 while {[gets $gtf line] >= 0} {
4143 if {[lindex $line 1] ne "blob"} continue
4144 set sha1 [lindex $line 2]
4145 set fname [lindex $line 3]
4146 lappend treefilelist($id) $fname
4147 lappend treeidlist($id) $sha1
4148 }
4149 if {![eof $gtf]} return
4150 close $gtf
4151 unset treepending
4152 if {$cmitmode ne "tree"} {
4153 if {![info exists diffmergeid]} {
4154 gettreediffs $diffids
4155 }
4156 } elseif {$id ne $diffids} {
4157 gettree $diffids
4158 } else {
4159 setfilelist $id
4160 }
4161}
4162
4163proc showfile {f} {
4164 global treefilelist treeidlist diffids
4165 global ctext commentend
4166
4167 set i [lsearch -exact $treefilelist($diffids) $f]
4168 if {$i < 0} {
4169 puts "oops, $f not in list for id $diffids"
4170 return
4171 }
4172 set blob [lindex $treeidlist($diffids) $i]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004173 if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004174 puts "oops, error reading blob $blob: $err"
4175 return
4176 }
4177 fconfigure $bf -blocking 0
4178 fileevent $bf readable [list getblobline $bf $diffids]
4179 $ctext config -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004180 clear_ctext $commentend
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004181 $ctext insert end "\n"
4182 $ctext insert end "$f\n" filesep
4183 $ctext config -state disabled
4184 $ctext yview $commentend
4185}
4186
4187proc getblobline {bf id} {
4188 global diffids cmitmode ctext
4189
4190 if {$id ne $diffids || $cmitmode ne "tree"} {
4191 catch {close $bf}
4192 return
4193 }
4194 $ctext config -state normal
4195 while {[gets $bf line] >= 0} {
4196 $ctext insert end "$line\n"
4197 }
4198 if {[eof $bf]} {
4199 # delete last newline
4200 $ctext delete "end - 2c" "end - 1c"
4201 close $bf
4202 }
4203 $ctext config -state disabled
4204}
4205
Paul Mackerras79b2c752006-04-02 20:47:40 +10004206proc mergediff {id l} {
4207 global diffmergeid diffopts mdifffd
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004208 global diffids
Paul Mackerras79b2c752006-04-02 20:47:40 +10004209 global parentlist
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004210
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004211 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004212 set diffids $id
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004213 # this doesn't seem to actually affect anything...
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004214 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004215 set cmd [concat | git diff-tree --no-commit-id --cc $id]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004216 if {[catch {set mdf [open $cmd r]} err]} {
4217 error_popup "Error getting merge diffs: $err"
4218 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004219 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004220 fconfigure $mdf -blocking 0
4221 set mdifffd($id) $mdf
Paul Mackerras79b2c752006-04-02 20:47:40 +10004222 set np [llength [lindex $parentlist $l]]
4223 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004224 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004225}
4226
Paul Mackerras79b2c752006-04-02 20:47:40 +10004227proc getmergediffline {mdf id np} {
4228 global diffmergeid ctext cflist nextupdate mergemax
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004229 global difffilestart mdifffd
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004230
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004231 set n [gets $mdf line]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004232 if {$n < 0} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004233 if {[eof $mdf]} {
4234 close $mdf
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004235 }
4236 return
4237 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004238 if {![info exists diffmergeid] || $id != $diffmergeid
4239 || $mdf != $mdifffd($id)} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004240 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004241 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004242 $ctext conf -state normal
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004243 if {[regexp {^diff --cc (.*)} $line match fname]} {
4244 # start of a new file
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004245 $ctext insert end "\n"
4246 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004247 lappend difffilestart $here
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004248 add_flist [list $fname]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004249 set l [expr {(78 - [string length $fname]) / 2}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004250 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004251 $ctext insert end "$pad $fname $pad\n" filesep
4252 } elseif {[regexp {^@@} $line]} {
4253 $ctext insert end "$line\n" hunksep
4254 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
4255 # do nothing
4256 } else {
4257 # parse the prefix - one ' ', '-' or '+' for each parent
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004258 set spaces {}
4259 set minuses {}
4260 set pluses {}
4261 set isbad 0
4262 for {set j 0} {$j < $np} {incr j} {
4263 set c [string range $line $j $j]
4264 if {$c == " "} {
4265 lappend spaces $j
4266 } elseif {$c == "-"} {
4267 lappend minuses $j
4268 } elseif {$c == "+"} {
4269 lappend pluses $j
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004270 } else {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004271 set isbad 1
4272 break
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004273 }
4274 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004275 set tags {}
4276 set num {}
4277 if {!$isbad && $minuses ne {} && $pluses eq {}} {
4278 # line doesn't appear in result, parents in $minuses have the line
4279 set num [lindex $minuses 0]
4280 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
4281 # line appears in result, parents in $pluses don't have the line
4282 lappend tags mresult
4283 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004284 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004285 if {$num ne {}} {
4286 if {$num >= $mergemax} {
4287 set num "max"
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004288 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004289 lappend tags m$num
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004290 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004291 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004292 }
4293 $ctext conf -state disabled
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004294 if {[clock clicks -milliseconds] >= $nextupdate} {
4295 incr nextupdate 100
4296 fileevent $mdf readable {}
4297 update
Paul Mackerrasc5a4c4d2006-04-06 10:20:03 +10004298 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004299 }
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004300}
4301
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004302proc startdiff {ids} {
4303 global treediffs diffids treepending diffmergeid
4304
4305 set diffids $ids
4306 catch {unset diffmergeid}
4307 if {![info exists treediffs($ids)]} {
4308 if {![info exists treepending]} {
4309 gettreediffs $ids
4310 }
4311 } else {
4312 addtocflist $ids
4313 }
4314}
4315
4316proc addtocflist {ids} {
4317 global treediffs cflist
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004318 add_flist $treediffs($ids)
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004319 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004320}
4321
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004322proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004323 global treediff treepending
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004324 set treepending $ids
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004325 set treediff {}
Paul Mackerras418c4c72006-02-07 09:10:18 +11004326 if {[catch \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004327 {set gdtf [open [concat | git diff-tree --no-commit-id -r $ids] r]} \
Paul Mackerras418c4c72006-02-07 09:10:18 +11004328 ]} return
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004329 fconfigure $gdtf -blocking 0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004330 fileevent $gdtf readable [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004331}
4332
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004333proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004334 global treediff treediffs treepending diffids diffmergeid
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004335 global cmitmode
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004336
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004337 set n [gets $gdtf line]
4338 if {$n < 0} {
4339 if {![eof $gdtf]} return
4340 close $gdtf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004341 set treediffs($ids) $treediff
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004342 unset treepending
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004343 if {$cmitmode eq "tree"} {
4344 gettree $diffids
4345 } elseif {$ids != $diffids} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004346 if {![info exists diffmergeid]} {
4347 gettreediffs $diffids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004348 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004349 } else {
4350 addtocflist $ids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004351 }
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004352 return
4353 }
Paul Mackerrasd4e95cb2005-06-01 00:02:13 +00004354 set file [lindex $line 5]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004355 lappend treediff $file
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004356}
4357
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004358proc getblobdiffs {ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004359 global diffopts blobdifffd diffids env curdifftag curtagstart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004360 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004361
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004362 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004363 set cmd [concat | git diff-tree --no-commit-id -r -p -C $ids]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004364 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004365 puts "error getting diffs: $err"
4366 return
4367 }
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004368 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004369 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004370 set blobdifffd($ids) $bdf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004371 set curdifftag Comments
4372 set curtagstart 0.0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004373 fileevent $bdf readable [list getblobdiffline $bdf $diffids]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004374 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004375}
4376
Paul Mackerras89b11d32006-05-02 19:55:31 +10004377proc setinlist {var i val} {
4378 global $var
4379
4380 while {[llength [set $var]] < $i} {
4381 lappend $var {}
4382 }
4383 if {[llength [set $var]] == $i} {
4384 lappend $var $val
4385 } else {
4386 lset $var $i $val
4387 }
4388}
4389
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004390proc getblobdiffline {bdf ids} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004391 global diffids blobdifffd ctext curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04004392 global diffnexthead diffnextnote difffilestart
4393 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004394
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004395 set n [gets $bdf line]
4396 if {$n < 0} {
4397 if {[eof $bdf]} {
4398 close $bdf
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004399 if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004400 $ctext tag add $curdifftag $curtagstart end
4401 }
4402 }
4403 return
4404 }
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004405 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004406 return
4407 }
4408 $ctext conf -state normal
Paul Mackerras7eab2932005-07-20 12:25:54 -04004409 if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004410 # start of a new file
4411 $ctext insert end "\n"
4412 $ctext tag add $curdifftag $curtagstart end
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004413 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004414 set curtagstart $here
4415 set header $newname
Paul Mackerras89b11d32006-05-02 19:55:31 +10004416 set i [lsearch -exact $treediffs($ids) $fname]
4417 if {$i >= 0} {
4418 setinlist difffilestart $i $here
4419 }
4420 if {$newname ne $fname} {
4421 set i [lsearch -exact $treediffs($ids) $newname]
4422 if {$i >= 0} {
4423 setinlist difffilestart $i $here
4424 }
Paul Mackerras7eab2932005-07-20 12:25:54 -04004425 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004426 set curdifftag "f:$fname"
4427 $ctext tag delete $curdifftag
Paul Mackerras58422152005-05-19 10:56:42 +00004428 set l [expr {(78 - [string length $header]) / 2}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004429 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerras58422152005-05-19 10:56:42 +00004430 $ctext insert end "$pad $header $pad\n" filesep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004431 set diffinhdr 1
Paul Mackerrasb06bc2a2006-03-08 09:15:32 +11004432 } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
4433 # do nothing
4434 } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004435 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004436 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
4437 $line match f1l f1c f2l f2c rest]} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11004438 $ctext insert end "$line\n" hunksep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004439 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004440 } else {
4441 set x [string range $line 0 0]
4442 if {$x == "-" || $x == "+"} {
4443 set tag [expr {$x == "+"}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004444 $ctext insert end "$line\n" d$tag
4445 } elseif {$x == " "} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004446 $ctext insert end "$line\n"
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004447 } elseif {$diffinhdr || $x == "\\"} {
Paul Mackerras58422152005-05-19 10:56:42 +00004448 # e.g. "\ No newline at end of file"
4449 $ctext insert end "$line\n" filesep
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004450 } else {
4451 # Something else we don't recognize
4452 if {$curdifftag != "Comments"} {
4453 $ctext insert end "\n"
4454 $ctext tag add $curdifftag $curtagstart end
4455 set curtagstart [$ctext index "end - 1c"]
4456 set curdifftag Comments
4457 }
4458 $ctext insert end "$line\n" filesep
4459 }
4460 }
4461 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004462 if {[clock clicks -milliseconds] >= $nextupdate} {
4463 incr nextupdate 100
4464 fileevent $bdf readable {}
4465 update
4466 fileevent $bdf readable "getblobdiffline $bdf {$ids}"
4467 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004468}
4469
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004470proc prevfile {} {
4471 global difffilestart ctext
4472 set prev [lindex $difffilestart 0]
4473 set here [$ctext index @0,0]
4474 foreach loc $difffilestart {
4475 if {[$ctext compare $loc >= $here]} {
4476 $ctext yview $prev
4477 return
4478 }
4479 set prev $loc
4480 }
4481 $ctext yview $prev
4482}
4483
Paul Mackerras39ad8572005-05-19 12:35:53 +00004484proc nextfile {} {
4485 global difffilestart ctext
4486 set here [$ctext index @0,0]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004487 foreach loc $difffilestart {
4488 if {[$ctext compare $loc > $here]} {
4489 $ctext yview $loc
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004490 return
Paul Mackerras39ad8572005-05-19 12:35:53 +00004491 }
4492 }
Paul Mackerras1db95b02005-05-09 04:08:39 +00004493}
4494
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004495proc clear_ctext {{first 1.0}} {
4496 global ctext smarktop smarkbot
4497
Paul Mackerras1902c272006-05-25 21:25:13 +10004498 set l [lindex [split $first .] 0]
4499 if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
4500 set smarktop $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004501 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004502 if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
4503 set smarkbot $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004504 }
4505 $ctext delete $first end
4506}
4507
4508proc incrsearch {name ix op} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004509 global ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004510
4511 $ctext tag remove found 1.0 end
Paul Mackerras1902c272006-05-25 21:25:13 +10004512 if {[catch {$ctext index anchor}]} {
4513 # no anchor set, use start of selection, or of visible area
4514 set sel [$ctext tag ranges sel]
4515 if {$sel ne {}} {
4516 $ctext mark set anchor [lindex $sel 0]
4517 } elseif {$searchdirn eq "-forwards"} {
4518 $ctext mark set anchor @0,0
4519 } else {
4520 $ctext mark set anchor @0,[winfo height $ctext]
4521 }
4522 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004523 if {$searchstring ne {}} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004524 set here [$ctext search $searchdirn -- $searchstring anchor]
4525 if {$here ne {}} {
4526 $ctext see $here
4527 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004528 searchmarkvisible 1
4529 }
4530}
4531
4532proc dosearch {} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004533 global sstring ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004534
4535 focus $sstring
4536 $sstring icursor end
Paul Mackerras1902c272006-05-25 21:25:13 +10004537 set searchdirn -forwards
4538 if {$searchstring ne {}} {
4539 set sel [$ctext tag ranges sel]
4540 if {$sel ne {}} {
4541 set start "[lindex $sel 0] + 1c"
4542 } elseif {[catch {set start [$ctext index anchor]}]} {
4543 set start "@0,0"
4544 }
4545 set match [$ctext search -count mlen -- $searchstring $start]
4546 $ctext tag remove sel 1.0 end
4547 if {$match eq {}} {
4548 bell
4549 return
4550 }
4551 $ctext see $match
4552 set mend "$match + $mlen c"
4553 $ctext tag add sel $match $mend
4554 $ctext mark unset anchor
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004555 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004556}
4557
4558proc dosearchback {} {
4559 global sstring ctext searchstring searchdirn
4560
4561 focus $sstring
4562 $sstring icursor end
4563 set searchdirn -backwards
4564 if {$searchstring ne {}} {
4565 set sel [$ctext tag ranges sel]
4566 if {$sel ne {}} {
4567 set start [lindex $sel 0]
4568 } elseif {[catch {set start [$ctext index anchor]}]} {
4569 set start @0,[winfo height $ctext]
4570 }
4571 set match [$ctext search -backwards -count ml -- $searchstring $start]
4572 $ctext tag remove sel 1.0 end
4573 if {$match eq {}} {
4574 bell
4575 return
4576 }
4577 $ctext see $match
4578 set mend "$match + $ml c"
4579 $ctext tag add sel $match $mend
4580 $ctext mark unset anchor
4581 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004582}
4583
4584proc searchmark {first last} {
4585 global ctext searchstring
4586
4587 set mend $first.0
4588 while {1} {
4589 set match [$ctext search -count mlen -- $searchstring $mend $last.end]
4590 if {$match eq {}} break
4591 set mend "$match + $mlen c"
4592 $ctext tag add found $match $mend
4593 }
4594}
4595
4596proc searchmarkvisible {doall} {
4597 global ctext smarktop smarkbot
4598
4599 set topline [lindex [split [$ctext index @0,0] .] 0]
4600 set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
4601 if {$doall || $botline < $smarktop || $topline > $smarkbot} {
4602 # no overlap with previous
4603 searchmark $topline $botline
4604 set smarktop $topline
4605 set smarkbot $botline
4606 } else {
4607 if {$topline < $smarktop} {
4608 searchmark $topline [expr {$smarktop-1}]
4609 set smarktop $topline
4610 }
4611 if {$botline > $smarkbot} {
4612 searchmark [expr {$smarkbot+1}] $botline
4613 set smarkbot $botline
4614 }
4615 }
4616}
4617
4618proc scrolltext {f0 f1} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004619 global searchstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004620
Mark Levedahl3468e712007-02-01 08:46:38 -05004621 .bleft.sb set $f0 $f1
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004622 if {$searchstring ne {}} {
4623 searchmarkvisible 0
4624 }
4625}
4626
Paul Mackerras1d10f362005-05-15 12:55:47 +00004627proc setcoords {} {
4628 global linespc charspc canvx0 canvy0 mainfont
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004629 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-05 09:52:16 +10004630
Paul Mackerras1d10f362005-05-15 12:55:47 +00004631 set linespc [font metrics $mainfont -linespace]
4632 set charspc [font measure $mainfont "m"]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004633 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
4634 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004635 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-05 09:52:16 +10004636 set xspc1(0) $linespc
4637 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:16 +00004638}
Paul Mackerras1db95b02005-05-09 04:08:39 +00004639
Paul Mackerras1d10f362005-05-15 12:55:47 +00004640proc redisplay {} {
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004641 global canv
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004642 global selectedline
4643
4644 set ymax [lindex [$canv cget -scrollregion] 3]
4645 if {$ymax eq {} || $ymax == 0} return
4646 set span [$canv yview]
4647 clear_display
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004648 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004649 allcanvs yview moveto [lindex $span 0]
4650 drawvisible
4651 if {[info exists selectedline]} {
4652 selectline $selectedline 0
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10004653 allcanvs yview moveto [lindex $span 0]
Paul Mackerras1db95b02005-05-09 04:08:39 +00004654 }
4655}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004656
4657proc incrfont {inc} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004658 global mainfont textfont ctext canv phase
Paul Mackerrascfb45632005-05-31 12:14:42 +00004659 global stopped entries
Paul Mackerras1d10f362005-05-15 12:55:47 +00004660 unmarkmatches
4661 set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
Paul Mackerras1d10f362005-05-15 12:55:47 +00004662 set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
4663 setcoords
4664 $ctext conf -font $textfont
4665 $ctext tag conf filesep -font [concat $textfont bold]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004666 foreach e $entries {
4667 $e conf -font $mainfont
4668 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10004669 if {$phase eq "getcommits"} {
Paul Mackerras1d10f362005-05-15 12:55:47 +00004670 $canv itemconf textitems -font $mainfont
4671 }
4672 redisplay
Paul Mackerras1db95b02005-05-09 04:08:39 +00004673}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004674
Paul Mackerrasee3dc722005-06-25 16:37:13 +10004675proc clearsha1 {} {
4676 global sha1entry sha1string
4677 if {[string length $sha1string] == 40} {
4678 $sha1entry delete 0 end
4679 }
4680}
4681
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004682proc sha1change {n1 n2 op} {
4683 global sha1string currentid sha1but
4684 if {$sha1string == {}
4685 || ([info exists currentid] && $sha1string == $currentid)} {
4686 set state disabled
4687 } else {
4688 set state normal
4689 }
4690 if {[$sha1but cget -state] == $state} return
4691 if {$state == "normal"} {
4692 $sha1but conf -state normal -relief raised -text "Goto: "
4693 } else {
4694 $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
4695 }
4696}
4697
4698proc gotocommit {} {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004699 global sha1string currentid commitrow tagids headids
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004700 global displayorder numcommits curview
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004701
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004702 if {$sha1string == {}
4703 || ([info exists currentid] && $sha1string == $currentid)} return
4704 if {[info exists tagids($sha1string)]} {
4705 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 16:13:12 +11004706 } elseif {[info exists headids($sha1string)]} {
4707 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004708 } else {
4709 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004710 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
4711 set matches {}
Paul Mackerras8ed16482006-03-02 22:56:44 +11004712 foreach i $displayorder {
4713 if {[string match $id* $i]} {
4714 lappend matches $i
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004715 }
4716 }
4717 if {$matches ne {}} {
4718 if {[llength $matches] > 1} {
4719 error_popup "Short SHA1 id $id is ambiguous"
4720 return
4721 }
4722 set id [lindex $matches 0]
4723 }
4724 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004725 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004726 if {[info exists commitrow($curview,$id)]} {
4727 selectline $commitrow($curview,$id) 1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004728 return
4729 }
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004730 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004731 set type "SHA1 id"
4732 } else {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004733 set type "Tag/Head"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004734 }
4735 error_popup "$type $sha1string is not known"
4736}
4737
Paul Mackerras84ba7342005-06-17 00:12:26 +00004738proc lineenter {x y id} {
4739 global hoverx hovery hoverid hovertimer
4740 global commitinfo canv
4741
Paul Mackerras8ed16482006-03-02 22:56:44 +11004742 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:26 +00004743 set hoverx $x
4744 set hovery $y
4745 set hoverid $id
4746 if {[info exists hovertimer]} {
4747 after cancel $hovertimer
4748 }
4749 set hovertimer [after 500 linehover]
4750 $canv delete hover
4751}
4752
4753proc linemotion {x y id} {
4754 global hoverx hovery hoverid hovertimer
4755
4756 if {[info exists hoverid] && $id == $hoverid} {
4757 set hoverx $x
4758 set hovery $y
4759 if {[info exists hovertimer]} {
4760 after cancel $hovertimer
4761 }
4762 set hovertimer [after 500 linehover]
4763 }
4764}
4765
4766proc lineleave {id} {
4767 global hoverid hovertimer canv
4768
4769 if {[info exists hoverid] && $id == $hoverid} {
4770 $canv delete hover
4771 if {[info exists hovertimer]} {
4772 after cancel $hovertimer
4773 unset hovertimer
4774 }
4775 unset hoverid
4776 }
4777}
4778
4779proc linehover {} {
4780 global hoverx hovery hoverid hovertimer
4781 global canv linespc lthickness
4782 global commitinfo mainfont
4783
4784 set text [lindex $commitinfo($hoverid) 0]
4785 set ymax [lindex [$canv cget -scrollregion] 3]
4786 if {$ymax == {}} return
4787 set yfrac [lindex [$canv yview] 0]
4788 set x [expr {$hoverx + 2 * $linespc}]
4789 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
4790 set x0 [expr {$x - 2 * $lthickness}]
4791 set y0 [expr {$y - 2 * $lthickness}]
4792 set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
4793 set y1 [expr {$y + $linespc + 2 * $lthickness}]
4794 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
4795 -fill \#ffff80 -outline black -width 1 -tags hover]
4796 $canv raise $t
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004797 set t [$canv create text $x $y -anchor nw -text $text -tags hover \
4798 -font $mainfont]
Paul Mackerras84ba7342005-06-17 00:12:26 +00004799 $canv raise $t
4800}
4801
Paul Mackerras9843c302005-08-30 10:57:11 +10004802proc clickisonarrow {id y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004803 global lthickness
Paul Mackerras9843c302005-08-30 10:57:11 +10004804
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004805 set ranges [rowranges $id]
Paul Mackerras9843c302005-08-30 10:57:11 +10004806 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004807 set n [expr {[llength $ranges] - 1}]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004808 for {set i 1} {$i < $n} {incr i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004809 set row [lindex $ranges $i]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004810 if {abs([yc $row] - $y) < $thresh} {
4811 return $i
Paul Mackerras9843c302005-08-30 10:57:11 +10004812 }
4813 }
4814 return {}
4815}
4816
Paul Mackerrasf6342482006-02-28 10:02:03 +11004817proc arrowjump {id n y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004818 global canv
Paul Mackerras9843c302005-08-30 10:57:11 +10004819
Paul Mackerrasf6342482006-02-28 10:02:03 +11004820 # 1 <-> 2, 3 <-> 4, etc...
4821 set n [expr {(($n - 1) ^ 1) + 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004822 set row [lindex [rowranges $id] $n]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004823 set yt [yc $row]
Paul Mackerras9843c302005-08-30 10:57:11 +10004824 set ymax [lindex [$canv cget -scrollregion] 3]
4825 if {$ymax eq {} || $ymax <= 0} return
4826 set view [$canv yview]
4827 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
4828 set yfrac [expr {$yt / $ymax - $yspan / 2}]
4829 if {$yfrac < 0} {
4830 set yfrac 0
4831 }
Paul Mackerrasf6342482006-02-28 10:02:03 +11004832 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 10:57:11 +10004833}
4834
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004835proc lineclick {x y id isnew} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004836 global ctext commitinfo children canv thickerline curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004837
Paul Mackerras8ed16482006-03-02 22:56:44 +11004838 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004839 unmarkmatches
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004840 unselectline
Paul Mackerras9843c302005-08-30 10:57:11 +10004841 normalline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004842 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10004843 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 10:57:11 +10004844 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004845 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004846 if {$isnew} {
4847 set ymax [lindex [$canv cget -scrollregion] 3]
4848 if {$ymax eq {}} return
4849 set yfrac [lindex [$canv yview] 0]
4850 set y [expr {$y + $yfrac * $ymax}]
4851 }
4852 set dirn [clickisonarrow $id $y]
4853 if {$dirn ne {}} {
4854 arrowjump $id $dirn $y
4855 return
4856 }
4857
4858 if {$isnew} {
4859 addtohistory [list lineclick $x $y $id 0]
4860 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004861 # fill the details pane with info about this line
4862 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004863 clear_ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004864 $ctext tag conf link -foreground blue -underline 1
4865 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4866 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4867 $ctext insert end "Parent:\t"
4868 $ctext insert end $id [list link link0]
4869 $ctext tag bind link0 <1> [list selbyid $id]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004870 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004871 $ctext insert end "\n\t[lindex $info 0]\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004872 $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11004873 set date [formatdate [lindex $info 2]]
4874 $ctext insert end "\tDate:\t$date\n"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004875 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10004876 if {$kids ne {}} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004877 $ctext insert end "\nChildren:"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004878 set i 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10004879 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004880 incr i
Paul Mackerras8ed16482006-03-02 22:56:44 +11004881 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004882 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004883 $ctext insert end "\n\t"
4884 $ctext insert end $child [list link link$i]
4885 $ctext tag bind link$i <1> [list selbyid $child]
4886 $ctext insert end "\n\t[lindex $info 0]"
4887 $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-15 10:34:03 +11004888 set date [formatdate [lindex $info 2]]
4889 $ctext insert end "\n\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004890 }
4891 }
4892 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004893 init_flist {}
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004894}
4895
Paul Mackerras9843c302005-08-30 10:57:11 +10004896proc normalline {} {
4897 global thickerline
4898 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004899 set id $thickerline
Paul Mackerras9843c302005-08-30 10:57:11 +10004900 unset thickerline
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004901 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004902 }
4903}
4904
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004905proc selbyid {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004906 global commitrow curview
4907 if {[info exists commitrow($curview,$id)]} {
4908 selectline $commitrow($curview,$id) 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004909 }
4910}
4911
4912proc mstime {} {
4913 global startmstime
4914 if {![info exists startmstime]} {
4915 set startmstime [clock clicks -milliseconds]
4916 }
4917 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
4918}
4919
4920proc rowmenu {x y id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004921 global rowctxmenu commitrow selectedline rowmenuid curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004922
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004923 if {![info exists selectedline]
4924 || $commitrow($curview,$id) eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004925 set state disabled
4926 } else {
4927 set state normal
4928 }
Paul Mackerras3cd204e2006-11-23 21:06:16 +11004929 $rowctxmenu entryconfigure "Diff this*" -state $state
4930 $rowctxmenu entryconfigure "Diff selected*" -state $state
4931 $rowctxmenu entryconfigure "Make patch" -state $state
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004932 set rowmenuid $id
4933 tk_popup $rowctxmenu $x $y
4934}
4935
4936proc diffvssel {dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004937 global rowmenuid selectedline displayorder
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004938
4939 if {![info exists selectedline]} return
4940 if {$dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004941 set oldid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004942 set newid $rowmenuid
4943 } else {
4944 set oldid $rowmenuid
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004945 set newid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004946 }
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004947 addtohistory [list doseldiff $oldid $newid]
4948 doseldiff $oldid $newid
4949}
4950
4951proc doseldiff {oldid newid} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004952 global ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004953 global commitinfo
4954
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004955 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004956 clear_ctext
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004957 init_flist "Top"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004958 $ctext insert end "From "
4959 $ctext tag conf link -foreground blue -underline 1
4960 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4961 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4962 $ctext tag bind link0 <1> [list selbyid $oldid]
4963 $ctext insert end $oldid [list link link0]
4964 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004965 $ctext insert end [lindex $commitinfo($oldid) 0]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004966 $ctext insert end "\n\nTo "
4967 $ctext tag bind link1 <1> [list selbyid $newid]
4968 $ctext insert end $newid [list link link1]
4969 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004970 $ctext insert end [lindex $commitinfo($newid) 0]
4971 $ctext insert end "\n"
4972 $ctext conf -state disabled
4973 $ctext tag delete Comments
4974 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 20:41:56 +11004975 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004976}
4977
Paul Mackerras74daedb2005-06-27 19:27:32 +10004978proc mkpatch {} {
4979 global rowmenuid currentid commitinfo patchtop patchnum
4980
4981 if {![info exists currentid]} return
4982 set oldid $currentid
4983 set oldhead [lindex $commitinfo($oldid) 0]
4984 set newid $rowmenuid
4985 set newhead [lindex $commitinfo($newid) 0]
4986 set top .patch
4987 set patchtop $top
4988 catch {destroy $top}
4989 toplevel $top
4990 label $top.title -text "Generate patch"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004991 grid $top.title - -pady 10
Paul Mackerras74daedb2005-06-27 19:27:32 +10004992 label $top.from -text "From:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004993 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10004994 $top.fromsha1 insert 0 $oldid
4995 $top.fromsha1 conf -state readonly
4996 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004997 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10004998 $top.fromhead insert 0 $oldhead
4999 $top.fromhead conf -state readonly
5000 grid x $top.fromhead -sticky w
5001 label $top.to -text "To:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005002 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005003 $top.tosha1 insert 0 $newid
5004 $top.tosha1 conf -state readonly
5005 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005006 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005007 $top.tohead insert 0 $newhead
5008 $top.tohead conf -state readonly
5009 grid x $top.tohead -sticky w
5010 button $top.rev -text "Reverse" -command mkpatchrev -padx 5
5011 grid $top.rev x -pady 10
5012 label $top.flab -text "Output file:"
5013 entry $top.fname -width 60
5014 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
5015 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005016 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 19:27:32 +10005017 frame $top.buts
5018 button $top.buts.gen -text "Generate" -command mkpatchgo
5019 button $top.buts.can -text "Cancel" -command mkpatchcan
5020 grid $top.buts.gen $top.buts.can
5021 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5022 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5023 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005024 focus $top.fname
Paul Mackerras74daedb2005-06-27 19:27:32 +10005025}
5026
5027proc mkpatchrev {} {
5028 global patchtop
5029
5030 set oldid [$patchtop.fromsha1 get]
5031 set oldhead [$patchtop.fromhead get]
5032 set newid [$patchtop.tosha1 get]
5033 set newhead [$patchtop.tohead get]
5034 foreach e [list fromsha1 fromhead tosha1 tohead] \
5035 v [list $newid $newhead $oldid $oldhead] {
5036 $patchtop.$e conf -state normal
5037 $patchtop.$e delete 0 end
5038 $patchtop.$e insert 0 $v
5039 $patchtop.$e conf -state readonly
5040 }
5041}
5042
5043proc mkpatchgo {} {
5044 global patchtop
5045
5046 set oldid [$patchtop.fromsha1 get]
5047 set newid [$patchtop.tosha1 get]
5048 set fname [$patchtop.fname get]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03005049 if {[catch {exec git diff-tree -p $oldid $newid >$fname &} err]} {
Paul Mackerras74daedb2005-06-27 19:27:32 +10005050 error_popup "Error creating patch: $err"
5051 }
5052 catch {destroy $patchtop}
5053 unset patchtop
5054}
5055
5056proc mkpatchcan {} {
5057 global patchtop
5058
5059 catch {destroy $patchtop}
5060 unset patchtop
5061}
5062
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005063proc mktag {} {
5064 global rowmenuid mktagtop commitinfo
5065
5066 set top .maketag
5067 set mktagtop $top
5068 catch {destroy $top}
5069 toplevel $top
5070 label $top.title -text "Create tag"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005071 grid $top.title - -pady 10
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005072 label $top.id -text "ID:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005073 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005074 $top.sha1 insert 0 $rowmenuid
5075 $top.sha1 conf -state readonly
5076 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005077 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005078 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5079 $top.head conf -state readonly
5080 grid x $top.head -sticky w
5081 label $top.tlab -text "Tag name:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005082 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005083 grid $top.tlab $top.tag -sticky w
5084 frame $top.buts
5085 button $top.buts.gen -text "Create" -command mktaggo
5086 button $top.buts.can -text "Cancel" -command mktagcan
5087 grid $top.buts.gen $top.buts.can
5088 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5089 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5090 grid $top.buts - -pady 10 -sticky ew
5091 focus $top.tag
5092}
5093
5094proc domktag {} {
5095 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005096
5097 set id [$mktagtop.sha1 get]
5098 set tag [$mktagtop.tag get]
5099 if {$tag == {}} {
5100 error_popup "No tag name specified"
5101 return
5102 }
5103 if {[info exists tagids($tag)]} {
5104 error_popup "Tag \"$tag\" already exists"
5105 return
5106 }
5107 if {[catch {
Junio C Hamano73b6a6c2005-07-28 00:28:44 -07005108 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005109 set fname [file join $dir "refs/tags" $tag]
5110 set f [open $fname w]
5111 puts $f $id
5112 close $f
5113 } err]} {
5114 error_popup "Error creating tag: $err"
5115 return
5116 }
5117
5118 set tagids($tag) $id
5119 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005120 redrawtags $id
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005121 addedtag $id
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005122}
5123
5124proc redrawtags {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005125 global canv linehtag commitrow idpos selectedline curview
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005126 global mainfont canvxmax
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005127
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005128 if {![info exists commitrow($curview,$id)]} return
5129 drawcmitrow $commitrow($curview,$id)
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005130 $canv delete tag.$id
5131 set xt [eval drawtags $id $idpos($id)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005132 $canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005133 set text [$canv itemcget $linehtag($commitrow($curview,$id)) -text]
5134 set xr [expr {$xt + [font measure $mainfont $text]}]
5135 if {$xr > $canvxmax} {
5136 set canvxmax $xr
5137 setcanvscroll
5138 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005139 if {[info exists selectedline]
5140 && $selectedline == $commitrow($curview,$id)} {
Paul Mackerrasd6982062005-08-06 22:06:06 +10005141 selectline $selectedline 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005142 }
5143}
5144
5145proc mktagcan {} {
5146 global mktagtop
5147
5148 catch {destroy $mktagtop}
5149 unset mktagtop
5150}
5151
5152proc mktaggo {} {
5153 domktag
5154 mktagcan
5155}
5156
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005157proc writecommit {} {
5158 global rowmenuid wrcomtop commitinfo wrcomcmd
5159
5160 set top .writecommit
5161 set wrcomtop $top
5162 catch {destroy $top}
5163 toplevel $top
5164 label $top.title -text "Write commit to file"
5165 grid $top.title - -pady 10
5166 label $top.id -text "ID:"
5167 entry $top.sha1 -width 40 -relief flat
5168 $top.sha1 insert 0 $rowmenuid
5169 $top.sha1 conf -state readonly
5170 grid $top.id $top.sha1 -sticky w
5171 entry $top.head -width 60 -relief flat
5172 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5173 $top.head conf -state readonly
5174 grid x $top.head -sticky w
5175 label $top.clab -text "Command:"
5176 entry $top.cmd -width 60 -textvariable wrcomcmd
5177 grid $top.clab $top.cmd -sticky w -pady 10
5178 label $top.flab -text "Output file:"
5179 entry $top.fname -width 60
5180 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
5181 grid $top.flab $top.fname -sticky w
5182 frame $top.buts
5183 button $top.buts.gen -text "Write" -command wrcomgo
5184 button $top.buts.can -text "Cancel" -command wrcomcan
5185 grid $top.buts.gen $top.buts.can
5186 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5187 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5188 grid $top.buts - -pady 10 -sticky ew
5189 focus $top.fname
5190}
5191
5192proc wrcomgo {} {
5193 global wrcomtop
5194
5195 set id [$wrcomtop.sha1 get]
5196 set cmd "echo $id | [$wrcomtop.cmd get]"
5197 set fname [$wrcomtop.fname get]
5198 if {[catch {exec sh -c $cmd >$fname &} err]} {
5199 error_popup "Error writing commit: $err"
5200 }
5201 catch {destroy $wrcomtop}
5202 unset wrcomtop
5203}
5204
5205proc wrcomcan {} {
5206 global wrcomtop
5207
5208 catch {destroy $wrcomtop}
5209 unset wrcomtop
5210}
5211
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005212proc mkbranch {} {
5213 global rowmenuid mkbrtop
5214
5215 set top .makebranch
5216 catch {destroy $top}
5217 toplevel $top
5218 label $top.title -text "Create new branch"
5219 grid $top.title - -pady 10
5220 label $top.id -text "ID:"
5221 entry $top.sha1 -width 40 -relief flat
5222 $top.sha1 insert 0 $rowmenuid
5223 $top.sha1 conf -state readonly
5224 grid $top.id $top.sha1 -sticky w
5225 label $top.nlab -text "Name:"
5226 entry $top.name -width 40
5227 grid $top.nlab $top.name -sticky w
5228 frame $top.buts
5229 button $top.buts.go -text "Create" -command [list mkbrgo $top]
5230 button $top.buts.can -text "Cancel" -command "catch {destroy $top}"
5231 grid $top.buts.go $top.buts.can
5232 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5233 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5234 grid $top.buts - -pady 10 -sticky ew
5235 focus $top.name
5236}
5237
5238proc mkbrgo {top} {
5239 global headids idheads
5240
5241 set name [$top.name get]
5242 set id [$top.sha1 get]
5243 if {$name eq {}} {
5244 error_popup "Please specify a name for the new branch"
5245 return
5246 }
5247 catch {destroy $top}
5248 nowbusy newbranch
5249 update
5250 if {[catch {
5251 exec git branch $name $id
5252 } err]} {
5253 notbusy newbranch
5254 error_popup $err
5255 } else {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005256 addedhead $id $name
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005257 # XXX should update list of heads displayed for selected commit
5258 notbusy newbranch
5259 redrawtags $id
5260 }
5261}
5262
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005263proc cherrypick {} {
5264 global rowmenuid curview commitrow
5265 global mainhead desc_heads anc_tags desc_tags allparents allchildren
5266
5267 if {[info exists desc_heads($rowmenuid)]
5268 && [lsearch -exact $desc_heads($rowmenuid) $mainhead] >= 0} {
5269 set ok [confirm_popup "Commit [string range $rowmenuid 0 7] is already\
5270 included in branch $mainhead -- really re-apply it?"]
5271 if {!$ok} return
5272 }
5273 nowbusy cherrypick
5274 update
5275 set oldhead [exec git rev-parse HEAD]
5276 # Unfortunately git-cherry-pick writes stuff to stderr even when
5277 # no error occurs, and exec takes that as an indication of error...
5278 if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
5279 notbusy cherrypick
5280 error_popup $err
5281 return
5282 }
5283 set newhead [exec git rev-parse HEAD]
5284 if {$newhead eq $oldhead} {
5285 notbusy cherrypick
5286 error_popup "No changes committed"
5287 return
5288 }
5289 set allparents($newhead) $oldhead
5290 lappend allchildren($oldhead) $newhead
5291 set desc_heads($newhead) $mainhead
5292 if {[info exists anc_tags($oldhead)]} {
5293 set anc_tags($newhead) $anc_tags($oldhead)
5294 }
5295 set desc_tags($newhead) {}
5296 if {[info exists commitrow($curview,$oldhead)]} {
5297 insertrow $commitrow($curview,$oldhead) $newhead
5298 if {$mainhead ne {}} {
5299 movedhead $newhead $mainhead
5300 }
5301 redrawtags $oldhead
5302 redrawtags $newhead
5303 }
5304 notbusy cherrypick
5305}
5306
Paul Mackerras10299152006-08-02 09:52:01 +10005307# context menu for a head
5308proc headmenu {x y id head} {
5309 global headmenuid headmenuhead headctxmenu
5310
5311 set headmenuid $id
5312 set headmenuhead $head
5313 tk_popup $headctxmenu $x $y
5314}
5315
5316proc cobranch {} {
5317 global headmenuid headmenuhead mainhead headids
5318
5319 # check the tree is clean first??
5320 set oldmainhead $mainhead
5321 nowbusy checkout
5322 update
5323 if {[catch {
5324 exec git checkout $headmenuhead
5325 } err]} {
5326 notbusy checkout
5327 error_popup $err
5328 } else {
5329 notbusy checkout
Paul Mackerras53cda8d2006-08-02 19:43:34 +10005330 set mainhead $headmenuhead
Paul Mackerras10299152006-08-02 09:52:01 +10005331 if {[info exists headids($oldmainhead)]} {
5332 redrawtags $headids($oldmainhead)
5333 }
5334 redrawtags $headmenuid
5335 }
5336}
5337
5338proc rmbranch {} {
5339 global desc_heads headmenuid headmenuhead mainhead
5340 global headids idheads
5341
5342 set head $headmenuhead
5343 set id $headmenuid
5344 if {$head eq $mainhead} {
5345 error_popup "Cannot delete the currently checked-out branch"
5346 return
5347 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005348 if {$desc_heads($id) eq $head} {
Paul Mackerras10299152006-08-02 09:52:01 +10005349 # the stuff on this branch isn't on any other branch
5350 if {![confirm_popup "The commits on branch $head aren't on any other\
5351 branch.\nReally delete branch $head?"]} return
5352 }
5353 nowbusy rmbranch
5354 update
5355 if {[catch {exec git branch -D $head} err]} {
5356 notbusy rmbranch
5357 error_popup $err
5358 return
5359 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005360 removedhead $id $head
Paul Mackerras10299152006-08-02 09:52:01 +10005361 redrawtags $id
5362 notbusy rmbranch
5363}
5364
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005365# Stuff for finding nearby tags
5366proc getallcommits {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005367 global allcstart allcommits allcfd allids
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005368
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005369 set allids {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005370 set fd [open [concat | git rev-list --all --topo-order --parents] r]
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005371 set allcfd $fd
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005372 fconfigure $fd -blocking 0
5373 set allcommits "reading"
5374 nowbusy allcommits
5375 restartgetall $fd
5376}
5377
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005378proc discardallcommits {} {
5379 global allparents allchildren allcommits allcfd
5380 global desc_tags anc_tags alldtags tagisdesc allids desc_heads
5381
5382 if {![info exists allcommits]} return
5383 if {$allcommits eq "reading"} {
5384 catch {close $allcfd}
5385 }
5386 foreach v {allcommits allchildren allparents allids desc_tags anc_tags
5387 alldtags tagisdesc desc_heads} {
5388 catch {unset $v}
5389 }
5390}
5391
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005392proc restartgetall {fd} {
5393 global allcstart
5394
5395 fileevent $fd readable [list getallclines $fd]
5396 set allcstart [clock clicks -milliseconds]
5397}
5398
5399proc combine_dtags {l1 l2} {
5400 global tagisdesc notfirstd
5401
5402 set res [lsort -unique [concat $l1 $l2]]
5403 for {set i 0} {$i < [llength $res]} {incr i} {
5404 set x [lindex $res $i]
5405 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5406 set y [lindex $res $j]
5407 if {[info exists tagisdesc($x,$y)]} {
5408 if {$tagisdesc($x,$y) > 0} {
5409 # x is a descendent of y, exclude x
5410 set res [lreplace $res $i $i]
5411 incr i -1
5412 break
5413 } else {
5414 # y is a descendent of x, exclude y
5415 set res [lreplace $res $j $j]
5416 }
5417 } else {
5418 # no relation, keep going
5419 incr j
5420 }
5421 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005422 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005423 return $res
5424}
5425
5426proc combine_atags {l1 l2} {
5427 global tagisdesc
5428
5429 set res [lsort -unique [concat $l1 $l2]]
5430 for {set i 0} {$i < [llength $res]} {incr i} {
5431 set x [lindex $res $i]
5432 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5433 set y [lindex $res $j]
5434 if {[info exists tagisdesc($x,$y)]} {
5435 if {$tagisdesc($x,$y) < 0} {
5436 # x is an ancestor of y, exclude x
5437 set res [lreplace $res $i $i]
5438 incr i -1
5439 break
5440 } else {
5441 # y is an ancestor of x, exclude y
5442 set res [lreplace $res $j $j]
5443 }
5444 } else {
5445 # no relation, keep going
5446 incr j
5447 }
5448 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005449 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005450 return $res
5451}
5452
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005453proc forward_pass {id children} {
5454 global idtags desc_tags idheads desc_heads alldtags tagisdesc
5455
5456 set dtags {}
5457 set dheads {}
5458 foreach child $children {
5459 if {[info exists idtags($child)]} {
5460 set ctags [list $child]
5461 } else {
5462 set ctags $desc_tags($child)
5463 }
5464 if {$dtags eq {}} {
5465 set dtags $ctags
5466 } elseif {$ctags ne $dtags} {
5467 set dtags [combine_dtags $dtags $ctags]
5468 }
5469 set cheads $desc_heads($child)
5470 if {$dheads eq {}} {
5471 set dheads $cheads
5472 } elseif {$cheads ne $dheads} {
5473 set dheads [lsort -unique [concat $dheads $cheads]]
5474 }
5475 }
5476 set desc_tags($id) $dtags
5477 if {[info exists idtags($id)]} {
5478 set adt $dtags
5479 foreach tag $dtags {
5480 set adt [concat $adt $alldtags($tag)]
5481 }
5482 set adt [lsort -unique $adt]
5483 set alldtags($id) $adt
5484 foreach tag $adt {
5485 set tagisdesc($id,$tag) -1
5486 set tagisdesc($tag,$id) 1
5487 }
5488 }
5489 if {[info exists idheads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005490 set dheads [concat $dheads $idheads($id)]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005491 }
5492 set desc_heads($id) $dheads
5493}
5494
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005495proc getallclines {fd} {
5496 global allparents allchildren allcommits allcstart
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005497 global desc_tags anc_tags idtags tagisdesc allids
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005498 global idheads travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005499
5500 while {[gets $fd line] >= 0} {
5501 set id [lindex $line 0]
5502 lappend allids $id
5503 set olds [lrange $line 1 end]
5504 set allparents($id) $olds
5505 if {![info exists allchildren($id)]} {
5506 set allchildren($id) {}
5507 }
5508 foreach p $olds {
5509 lappend allchildren($p) $id
5510 }
5511 # compute nearest tagged descendents as we go
Paul Mackerrasef030b82006-06-04 11:50:38 +10005512 # also compute descendent heads
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005513 forward_pass $id $allchildren($id)
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005514 if {[clock clicks -milliseconds] - $allcstart >= 50} {
5515 fileevent $fd readable {}
5516 after idle restartgetall $fd
5517 return
5518 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005519 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005520 if {[eof $fd]} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005521 set travindex [llength $allids]
5522 set allcommits "traversing"
5523 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005524 if {[catch {close $fd} err]} {
5525 error_popup "Error reading full commit graph: $err.\n\
5526 Results may be incomplete."
5527 }
5528 }
5529}
5530
5531# walk backward through the tree and compute nearest tagged ancestors
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005532proc restartatags {} {
5533 global allids allparents idtags anc_tags travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005534
5535 set t0 [clock clicks -milliseconds]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005536 set i $travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005537 while {[incr i -1] >= 0} {
5538 set id [lindex $allids $i]
5539 set atags {}
5540 foreach p $allparents($id) {
5541 if {[info exists idtags($p)]} {
5542 set ptags [list $p]
5543 } else {
5544 set ptags $anc_tags($p)
5545 }
5546 if {$atags eq {}} {
5547 set atags $ptags
5548 } elseif {$ptags ne $atags} {
5549 set atags [combine_atags $atags $ptags]
5550 }
5551 }
5552 set anc_tags($id) $atags
5553 if {[clock clicks -milliseconds] - $t0 >= 50} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005554 set travindex $i
5555 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005556 return
5557 }
5558 }
5559 set allcommits "done"
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005560 set travindex 0
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005561 notbusy allcommits
5562 dispneartags
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005563}
5564
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005565# update the desc_tags and anc_tags arrays for a new tag just added
5566proc addedtag {id} {
5567 global desc_tags anc_tags allparents allchildren allcommits
5568 global idtags tagisdesc alldtags
5569
5570 if {![info exists desc_tags($id)]} return
5571 set adt $desc_tags($id)
5572 foreach t $desc_tags($id) {
5573 set adt [concat $adt $alldtags($t)]
5574 }
5575 set adt [lsort -unique $adt]
5576 set alldtags($id) $adt
5577 foreach t $adt {
5578 set tagisdesc($id,$t) -1
5579 set tagisdesc($t,$id) 1
5580 }
5581 if {[info exists anc_tags($id)]} {
5582 set todo $anc_tags($id)
5583 while {$todo ne {}} {
5584 set do [lindex $todo 0]
5585 set todo [lrange $todo 1 end]
5586 if {[info exists tagisdesc($id,$do)]} continue
5587 set tagisdesc($do,$id) -1
5588 set tagisdesc($id,$do) 1
5589 if {[info exists anc_tags($do)]} {
5590 set todo [concat $todo $anc_tags($do)]
5591 }
5592 }
5593 }
5594
5595 set lastold $desc_tags($id)
5596 set lastnew [list $id]
5597 set nup 0
5598 set nch 0
5599 set todo $allparents($id)
5600 while {$todo ne {}} {
5601 set do [lindex $todo 0]
5602 set todo [lrange $todo 1 end]
5603 if {![info exists desc_tags($do)]} continue
5604 if {$desc_tags($do) ne $lastold} {
5605 set lastold $desc_tags($do)
5606 set lastnew [combine_dtags $lastold [list $id]]
5607 incr nch
5608 }
5609 if {$lastold eq $lastnew} continue
5610 set desc_tags($do) $lastnew
5611 incr nup
5612 if {![info exists idtags($do)]} {
5613 set todo [concat $todo $allparents($do)]
5614 }
5615 }
5616
5617 if {![info exists anc_tags($id)]} return
5618 set lastold $anc_tags($id)
5619 set lastnew [list $id]
5620 set nup 0
5621 set nch 0
5622 set todo $allchildren($id)
5623 while {$todo ne {}} {
5624 set do [lindex $todo 0]
5625 set todo [lrange $todo 1 end]
5626 if {![info exists anc_tags($do)]} continue
5627 if {$anc_tags($do) ne $lastold} {
5628 set lastold $anc_tags($do)
5629 set lastnew [combine_atags $lastold [list $id]]
5630 incr nch
5631 }
5632 if {$lastold eq $lastnew} continue
5633 set anc_tags($do) $lastnew
5634 incr nup
5635 if {![info exists idtags($do)]} {
5636 set todo [concat $todo $allchildren($do)]
5637 }
5638 }
5639}
5640
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005641# update the desc_heads array for a new head just added
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005642proc addedhead {hid head} {
5643 global desc_heads allparents headids idheads
5644
5645 set headids($head) $hid
5646 lappend idheads($hid) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005647
5648 set todo [list $hid]
5649 while {$todo ne {}} {
5650 set do [lindex $todo 0]
5651 set todo [lrange $todo 1 end]
5652 if {![info exists desc_heads($do)] ||
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005653 [lsearch -exact $desc_heads($do) $head] >= 0} continue
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005654 set oldheads $desc_heads($do)
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005655 lappend desc_heads($do) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005656 set heads $desc_heads($do)
5657 while {1} {
5658 set p $allparents($do)
5659 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5660 $desc_heads($p) ne $oldheads} break
5661 set do $p
5662 set desc_heads($do) $heads
5663 }
5664 set todo [concat $todo $p]
5665 }
5666}
5667
Paul Mackerras10299152006-08-02 09:52:01 +10005668# update the desc_heads array for a head just removed
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005669proc removedhead {hid head} {
5670 global desc_heads allparents headids idheads
5671
5672 unset headids($head)
5673 if {$idheads($hid) eq $head} {
5674 unset idheads($hid)
5675 } else {
5676 set i [lsearch -exact $idheads($hid) $head]
5677 if {$i >= 0} {
5678 set idheads($hid) [lreplace $idheads($hid) $i $i]
5679 }
5680 }
Paul Mackerras10299152006-08-02 09:52:01 +10005681
5682 set todo [list $hid]
5683 while {$todo ne {}} {
5684 set do [lindex $todo 0]
5685 set todo [lrange $todo 1 end]
5686 if {![info exists desc_heads($do)]} continue
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005687 set i [lsearch -exact $desc_heads($do) $head]
Paul Mackerras10299152006-08-02 09:52:01 +10005688 if {$i < 0} continue
5689 set oldheads $desc_heads($do)
5690 set heads [lreplace $desc_heads($do) $i $i]
5691 while {1} {
5692 set desc_heads($do) $heads
5693 set p $allparents($do)
5694 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5695 $desc_heads($p) ne $oldheads} break
5696 set do $p
5697 }
5698 set todo [concat $todo $p]
5699 }
5700}
5701
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005702# update things for a head moved to a child of its previous location
5703proc movedhead {id name} {
5704 global headids idheads
5705
5706 set oldid $headids($name)
5707 set headids($name) $id
5708 if {$idheads($oldid) eq $name} {
5709 unset idheads($oldid)
5710 } else {
5711 set i [lsearch -exact $idheads($oldid) $name]
5712 if {$i >= 0} {
5713 set idheads($oldid) [lreplace $idheads($oldid) $i $i]
5714 }
5715 }
5716 lappend idheads($id) $name
5717}
5718
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005719proc changedrefs {} {
5720 global desc_heads desc_tags anc_tags allcommits allids
5721 global allchildren allparents idtags travindex
5722
5723 if {![info exists allcommits]} return
5724 catch {unset desc_heads}
5725 catch {unset desc_tags}
5726 catch {unset anc_tags}
5727 catch {unset alldtags}
5728 catch {unset tagisdesc}
5729 foreach id $allids {
5730 forward_pass $id $allchildren($id)
5731 }
5732 if {$allcommits ne "reading"} {
5733 set travindex [llength $allids]
5734 if {$allcommits ne "traversing"} {
5735 set allcommits "traversing"
5736 after idle restartatags
5737 }
5738 }
5739}
5740
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005741proc rereadrefs {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005742 global idtags idheads idotherrefs mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005743
5744 set refids [concat [array names idtags] \
5745 [array names idheads] [array names idotherrefs]]
5746 foreach id $refids {
5747 if {![info exists ref($id)]} {
5748 set ref($id) [listrefs $id]
5749 }
5750 }
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005751 set oldmainhead $mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005752 readrefs
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005753 changedrefs
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005754 set refids [lsort -unique [concat $refids [array names idtags] \
5755 [array names idheads] [array names idotherrefs]]]
5756 foreach id $refids {
5757 set v [listrefs $id]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005758 if {![info exists ref($id)] || $ref($id) != $v ||
5759 ($id eq $oldmainhead && $id ne $mainhead) ||
5760 ($id eq $mainhead && $id ne $oldmainhead)} {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005761 redrawtags $id
5762 }
5763 }
5764}
5765
Junio C Hamano2e1ded42006-06-11 09:50:47 -07005766proc listrefs {id} {
5767 global idtags idheads idotherrefs
5768
5769 set x {}
5770 if {[info exists idtags($id)]} {
5771 set x $idtags($id)
5772 }
5773 set y {}
5774 if {[info exists idheads($id)]} {
5775 set y $idheads($id)
5776 }
5777 set z {}
5778 if {[info exists idotherrefs($id)]} {
5779 set z $idotherrefs($id)
5780 }
5781 return [list $x $y $z]
5782}
5783
Paul Mackerras106288c2005-08-19 23:11:39 +10005784proc showtag {tag isnew} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005785 global ctext tagcontents tagids linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10005786
5787 if {$isnew} {
5788 addtohistory [list showtag $tag 0]
5789 }
5790 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10005791 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10005792 set linknum 0
5793 if {[info exists tagcontents($tag)]} {
5794 set text $tagcontents($tag)
5795 } else {
5796 set text "Tag: $tag\nId: $tagids($tag)"
5797 }
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005798 appendwithlinks $text {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005799 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005800 init_flist {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005801}
5802
Paul Mackerras1d10f362005-05-15 12:55:47 +00005803proc doquit {} {
5804 global stopped
5805 set stopped 100
Mark Levedahl602598f2007-02-08 22:22:24 -05005806 savestuff .
Paul Mackerras1d10f362005-05-15 12:55:47 +00005807 destroy .
5808}
5809
Paul Mackerras712fcc02005-11-30 09:28:16 +11005810proc doprefs {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005811 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005812 global oldprefs prefstop showneartags
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005813 global bgcolor fgcolor ctext diffcolors
Paul Mackerras232475d2005-11-15 10:34:03 +11005814
Paul Mackerras712fcc02005-11-30 09:28:16 +11005815 set top .gitkprefs
5816 set prefstop $top
5817 if {[winfo exists $top]} {
5818 raise $top
5819 return
Paul Mackerras757f17b2005-11-21 09:56:07 +11005820 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005821 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005822 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-15 10:34:03 +11005823 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11005824 toplevel $top
5825 wm title $top "Gitk preferences"
5826 label $top.ldisp -text "Commit list display options"
5827 grid $top.ldisp - -sticky w -pady 10
5828 label $top.spacer -text " "
5829 label $top.maxwidthl -text "Maximum graph width (lines)" \
5830 -font optionfont
5831 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
5832 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
5833 label $top.maxpctl -text "Maximum graph width (% of pane)" \
5834 -font optionfont
5835 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
5836 grid x $top.maxpctl $top.maxpct -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005837
Paul Mackerras712fcc02005-11-30 09:28:16 +11005838 label $top.ddisp -text "Diff display options"
5839 grid $top.ddisp - -sticky w -pady 10
5840 label $top.diffoptl -text "Options for diff program" \
5841 -font optionfont
5842 entry $top.diffopt -width 20 -textvariable diffopts
5843 grid x $top.diffoptl $top.diffopt -sticky w
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005844 frame $top.ntag
5845 label $top.ntag.l -text "Display nearby tags" -font optionfont
5846 checkbutton $top.ntag.b -variable showneartags
5847 pack $top.ntag.b $top.ntag.l -side left
5848 grid x $top.ntag -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005849
5850 label $top.cdisp -text "Colors: press to choose"
5851 grid $top.cdisp - -sticky w -pady 10
5852 label $top.bg -padx 40 -relief sunk -background $bgcolor
5853 button $top.bgbut -text "Background" -font optionfont \
5854 -command [list choosecolor bgcolor 0 $top.bg background setbg]
5855 grid x $top.bgbut $top.bg -sticky w
5856 label $top.fg -padx 40 -relief sunk -background $fgcolor
5857 button $top.fgbut -text "Foreground" -font optionfont \
5858 -command [list choosecolor fgcolor 0 $top.fg foreground setfg]
5859 grid x $top.fgbut $top.fg -sticky w
5860 label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
5861 button $top.diffoldbut -text "Diff: old lines" -font optionfont \
5862 -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
5863 [list $ctext tag conf d0 -foreground]]
5864 grid x $top.diffoldbut $top.diffold -sticky w
5865 label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
5866 button $top.diffnewbut -text "Diff: new lines" -font optionfont \
5867 -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
5868 [list $ctext tag conf d1 -foreground]]
5869 grid x $top.diffnewbut $top.diffnew -sticky w
5870 label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
5871 button $top.hunksepbut -text "Diff: hunk header" -font optionfont \
5872 -command [list choosecolor diffcolors 2 $top.hunksep \
5873 "diff hunk header" \
5874 [list $ctext tag conf hunksep -foreground]]
5875 grid x $top.hunksepbut $top.hunksep -sticky w
5876
Paul Mackerras712fcc02005-11-30 09:28:16 +11005877 frame $top.buts
5878 button $top.buts.ok -text "OK" -command prefsok
5879 button $top.buts.can -text "Cancel" -command prefscan
5880 grid $top.buts.ok $top.buts.can
5881 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5882 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5883 grid $top.buts - - -pady 10 -sticky ew
5884}
5885
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005886proc choosecolor {v vi w x cmd} {
5887 global $v
5888
5889 set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
5890 -title "Gitk: choose color for $x"]
5891 if {$c eq {}} return
5892 $w conf -background $c
5893 lset $v $vi $c
5894 eval $cmd $c
5895}
5896
5897proc setbg {c} {
5898 global bglist
5899
5900 foreach w $bglist {
5901 $w conf -background $c
5902 }
5903}
5904
5905proc setfg {c} {
5906 global fglist canv
5907
5908 foreach w $fglist {
5909 $w conf -foreground $c
5910 }
5911 allcanvs itemconf text -fill $c
5912 $canv itemconf circle -outline $c
5913}
5914
Paul Mackerras712fcc02005-11-30 09:28:16 +11005915proc prefscan {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005916 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005917 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005918
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005919 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005920 set $v $oldprefs($v)
5921 }
5922 catch {destroy $prefstop}
5923 unset prefstop
5924}
5925
5926proc prefsok {} {
5927 global maxwidth maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005928 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005929
5930 catch {destroy $prefstop}
5931 unset prefstop
5932 if {$maxwidth != $oldprefs(maxwidth)
5933 || $maxgraphpct != $oldprefs(maxgraphpct)} {
5934 redisplay
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005935 } elseif {$showneartags != $oldprefs(showneartags)} {
5936 reselectline
Paul Mackerras712fcc02005-11-30 09:28:16 +11005937 }
5938}
5939
5940proc formatdate {d} {
5941 return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
Paul Mackerras232475d2005-11-15 10:34:03 +11005942}
5943
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11005944# This list of encoding names and aliases is distilled from
5945# http://www.iana.org/assignments/character-sets.
5946# Not all of them are supported by Tcl.
5947set encoding_aliases {
5948 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
5949 ISO646-US US-ASCII us IBM367 cp367 csASCII }
5950 { ISO-10646-UTF-1 csISO10646UTF1 }
5951 { ISO_646.basic:1983 ref csISO646basic1983 }
5952 { INVARIANT csINVARIANT }
5953 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
5954 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
5955 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
5956 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
5957 { NATS-DANO iso-ir-9-1 csNATSDANO }
5958 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
5959 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
5960 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
5961 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
5962 { ISO-2022-KR csISO2022KR }
5963 { EUC-KR csEUCKR }
5964 { ISO-2022-JP csISO2022JP }
5965 { ISO-2022-JP-2 csISO2022JP2 }
5966 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
5967 csISO13JISC6220jp }
5968 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
5969 { IT iso-ir-15 ISO646-IT csISO15Italian }
5970 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
5971 { ES iso-ir-17 ISO646-ES csISO17Spanish }
5972 { greek7-old iso-ir-18 csISO18Greek7Old }
5973 { latin-greek iso-ir-19 csISO19LatinGreek }
5974 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
5975 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
5976 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
5977 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
5978 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
5979 { BS_viewdata iso-ir-47 csISO47BSViewdata }
5980 { INIS iso-ir-49 csISO49INIS }
5981 { INIS-8 iso-ir-50 csISO50INIS8 }
5982 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
5983 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
5984 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
5985 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
5986 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
5987 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
5988 csISO60Norwegian1 }
5989 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
5990 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
5991 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
5992 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
5993 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
5994 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
5995 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
5996 { greek7 iso-ir-88 csISO88Greek7 }
5997 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
5998 { iso-ir-90 csISO90 }
5999 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
6000 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
6001 csISO92JISC62991984b }
6002 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
6003 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
6004 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
6005 csISO95JIS62291984handadd }
6006 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
6007 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
6008 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
6009 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
6010 CP819 csISOLatin1 }
6011 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
6012 { T.61-7bit iso-ir-102 csISO102T617bit }
6013 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
6014 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
6015 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
6016 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
6017 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
6018 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
6019 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
6020 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
6021 arabic csISOLatinArabic }
6022 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
6023 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
6024 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
6025 greek greek8 csISOLatinGreek }
6026 { T.101-G2 iso-ir-128 csISO128T101G2 }
6027 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
6028 csISOLatinHebrew }
6029 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
6030 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
6031 { CSN_369103 iso-ir-139 csISO139CSN369103 }
6032 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
6033 { ISO_6937-2-add iso-ir-142 csISOTextComm }
6034 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
6035 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
6036 csISOLatinCyrillic }
6037 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
6038 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
6039 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
6040 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
6041 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
6042 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
6043 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
6044 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
6045 { ISO_10367-box iso-ir-155 csISO10367Box }
6046 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
6047 { latin-lap lap iso-ir-158 csISO158Lap }
6048 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
6049 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
6050 { us-dk csUSDK }
6051 { dk-us csDKUS }
6052 { JIS_X0201 X0201 csHalfWidthKatakana }
6053 { KSC5636 ISO646-KR csKSC5636 }
6054 { ISO-10646-UCS-2 csUnicode }
6055 { ISO-10646-UCS-4 csUCS4 }
6056 { DEC-MCS dec csDECMCS }
6057 { hp-roman8 roman8 r8 csHPRoman8 }
6058 { macintosh mac csMacintosh }
6059 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
6060 csIBM037 }
6061 { IBM038 EBCDIC-INT cp038 csIBM038 }
6062 { IBM273 CP273 csIBM273 }
6063 { IBM274 EBCDIC-BE CP274 csIBM274 }
6064 { IBM275 EBCDIC-BR cp275 csIBM275 }
6065 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
6066 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
6067 { IBM280 CP280 ebcdic-cp-it csIBM280 }
6068 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
6069 { IBM284 CP284 ebcdic-cp-es csIBM284 }
6070 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
6071 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
6072 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
6073 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
6074 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
6075 { IBM424 cp424 ebcdic-cp-he csIBM424 }
6076 { IBM437 cp437 437 csPC8CodePage437 }
6077 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
6078 { IBM775 cp775 csPC775Baltic }
6079 { IBM850 cp850 850 csPC850Multilingual }
6080 { IBM851 cp851 851 csIBM851 }
6081 { IBM852 cp852 852 csPCp852 }
6082 { IBM855 cp855 855 csIBM855 }
6083 { IBM857 cp857 857 csIBM857 }
6084 { IBM860 cp860 860 csIBM860 }
6085 { IBM861 cp861 861 cp-is csIBM861 }
6086 { IBM862 cp862 862 csPC862LatinHebrew }
6087 { IBM863 cp863 863 csIBM863 }
6088 { IBM864 cp864 csIBM864 }
6089 { IBM865 cp865 865 csIBM865 }
6090 { IBM866 cp866 866 csIBM866 }
6091 { IBM868 CP868 cp-ar csIBM868 }
6092 { IBM869 cp869 869 cp-gr csIBM869 }
6093 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
6094 { IBM871 CP871 ebcdic-cp-is csIBM871 }
6095 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
6096 { IBM891 cp891 csIBM891 }
6097 { IBM903 cp903 csIBM903 }
6098 { IBM904 cp904 904 csIBBM904 }
6099 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
6100 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
6101 { IBM1026 CP1026 csIBM1026 }
6102 { EBCDIC-AT-DE csIBMEBCDICATDE }
6103 { EBCDIC-AT-DE-A csEBCDICATDEA }
6104 { EBCDIC-CA-FR csEBCDICCAFR }
6105 { EBCDIC-DK-NO csEBCDICDKNO }
6106 { EBCDIC-DK-NO-A csEBCDICDKNOA }
6107 { EBCDIC-FI-SE csEBCDICFISE }
6108 { EBCDIC-FI-SE-A csEBCDICFISEA }
6109 { EBCDIC-FR csEBCDICFR }
6110 { EBCDIC-IT csEBCDICIT }
6111 { EBCDIC-PT csEBCDICPT }
6112 { EBCDIC-ES csEBCDICES }
6113 { EBCDIC-ES-A csEBCDICESA }
6114 { EBCDIC-ES-S csEBCDICESS }
6115 { EBCDIC-UK csEBCDICUK }
6116 { EBCDIC-US csEBCDICUS }
6117 { UNKNOWN-8BIT csUnknown8BiT }
6118 { MNEMONIC csMnemonic }
6119 { MNEM csMnem }
6120 { VISCII csVISCII }
6121 { VIQR csVIQR }
6122 { KOI8-R csKOI8R }
6123 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
6124 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
6125 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
6126 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
6127 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
6128 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
6129 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
6130 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
6131 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
6132 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
6133 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
6134 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
6135 { IBM1047 IBM-1047 }
6136 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
6137 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
6138 { UNICODE-1-1 csUnicode11 }
6139 { CESU-8 csCESU-8 }
6140 { BOCU-1 csBOCU-1 }
6141 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
6142 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
6143 l8 }
6144 { ISO-8859-15 ISO_8859-15 Latin-9 }
6145 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
6146 { GBK CP936 MS936 windows-936 }
6147 { JIS_Encoding csJISEncoding }
6148 { Shift_JIS MS_Kanji csShiftJIS }
6149 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
6150 EUC-JP }
6151 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
6152 { ISO-10646-UCS-Basic csUnicodeASCII }
6153 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
6154 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
6155 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
6156 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
6157 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
6158 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
6159 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
6160 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
6161 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
6162 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
6163 { Adobe-Standard-Encoding csAdobeStandardEncoding }
6164 { Ventura-US csVenturaUS }
6165 { Ventura-International csVenturaInternational }
6166 { PC8-Danish-Norwegian csPC8DanishNorwegian }
6167 { PC8-Turkish csPC8Turkish }
6168 { IBM-Symbols csIBMSymbols }
6169 { IBM-Thai csIBMThai }
6170 { HP-Legal csHPLegal }
6171 { HP-Pi-font csHPPiFont }
6172 { HP-Math8 csHPMath8 }
6173 { Adobe-Symbol-Encoding csHPPSMath }
6174 { HP-DeskTop csHPDesktop }
6175 { Ventura-Math csVenturaMath }
6176 { Microsoft-Publishing csMicrosoftPublishing }
6177 { Windows-31J csWindows31J }
6178 { GB2312 csGB2312 }
6179 { Big5 csBig5 }
6180}
6181
6182proc tcl_encoding {enc} {
6183 global encoding_aliases
6184 set names [encoding names]
6185 set lcnames [string tolower $names]
6186 set enc [string tolower $enc]
6187 set i [lsearch -exact $lcnames $enc]
6188 if {$i < 0} {
6189 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
6190 if {[regsub {^iso[-_]} $enc iso encx]} {
6191 set i [lsearch -exact $lcnames $encx]
6192 }
6193 }
6194 if {$i < 0} {
6195 foreach l $encoding_aliases {
6196 set ll [string tolower $l]
6197 if {[lsearch -exact $ll $enc] < 0} continue
6198 # look through the aliases for one that tcl knows about
6199 foreach e $ll {
6200 set i [lsearch -exact $lcnames $e]
6201 if {$i < 0} {
6202 if {[regsub {^iso[-_]} $e iso ex]} {
6203 set i [lsearch -exact $lcnames $ex]
6204 }
6205 }
6206 if {$i >= 0} break
6207 }
6208 break
6209 }
6210 }
6211 if {$i >= 0} {
6212 return [lindex $names $i]
6213 }
6214 return {}
6215}
6216
Paul Mackerras1d10f362005-05-15 12:55:47 +00006217# defaults...
6218set datemode 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006219set diffopts "-U 5 -p"
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006220set wrcomcmd "git diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-27 16:12:51 -08006221
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006222set gitencoding {}
Junio C Hamano671bc152005-11-27 16:12:51 -08006223catch {
Tom Princee0d10e12007-01-28 16:16:53 -08006224 set gitencoding [exec git config --get i18n.commitencoding]
Junio C Hamano671bc152005-11-27 16:12:51 -08006225}
6226if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006227 set gitencoding "utf-8"
6228}
6229set tclencoding [tcl_encoding $gitencoding]
6230if {$tclencoding == {}} {
6231 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-27 16:12:51 -08006232}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006233
6234set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006235set textfont {Courier 9}
Keith Packard4840be62006-04-04 00:19:45 -07006236set uifont {Helvetica 9 bold}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04006237set findmergefiles 0
Paul Mackerras8d858d12005-08-05 09:52:16 +10006238set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10006239set maxwidth 16
Paul Mackerras232475d2005-11-15 10:34:03 +11006240set revlistorder 0
Paul Mackerras757f17b2005-11-21 09:56:07 +11006241set fastdate 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006242set uparrowlen 7
6243set downarrowlen 7
6244set mingaplen 30
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10006245set cmitmode "patch"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04006246set wrapcomment "none"
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10006247set showneartags 1
Paul Mackerras1d10f362005-05-15 12:55:47 +00006248
6249set colors {green red blue magenta darkgrey brown orange}
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10006250set bgcolor white
6251set fgcolor black
6252set diffcolors {red "#00a000" blue}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006253
6254catch {source ~/.gitk}
6255
Paul Mackerras712fcc02005-11-30 09:28:16 +11006256font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:00 +00006257
Paul Mackerras1d10f362005-05-15 12:55:47 +00006258set revtreeargs {}
6259foreach arg $argv {
6260 switch -regexp -- $arg {
6261 "^$" { }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006262 "^-d" { set datemode 1 }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006263 default {
6264 lappend revtreeargs $arg
6265 }
6266 }
6267}
6268
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006269# check that we can find a .git directory somewhere...
6270set gitdir [gitdir]
6271if {![file isdirectory $gitdir]} {
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006272 show_error {} . "Cannot find the git directory \"$gitdir\"."
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006273 exit 1
6274}
6275
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006276set cmdline_files {}
6277set i [lsearch -exact $revtreeargs "--"]
6278if {$i >= 0} {
6279 set cmdline_files [lrange $revtreeargs [expr {$i + 1}] end]
6280 set revtreeargs [lrange $revtreeargs 0 [expr {$i - 1}]]
6281} elseif {$revtreeargs ne {}} {
6282 if {[catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006283 set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006284 set cmdline_files [split $f "\n"]
6285 set n [llength $cmdline_files]
6286 set revtreeargs [lrange $revtreeargs 0 end-$n]
6287 } err]} {
6288 # unfortunately we get both stdout and stderr in $err,
6289 # so look for "fatal:".
6290 set i [string first "fatal:" $err]
6291 if {$i > 0} {
Junio C Hamanob5e09632006-05-26 00:07:15 -07006292 set err [string range $err [expr {$i + 6}] end]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006293 }
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006294 show_error {} . "Bad arguments to gitk:\n$err"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006295 exit 1
6296 }
6297}
6298
Paul Mackerrasd6982062005-08-06 22:06:06 +10006299set history {}
6300set historyindex 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006301set fh_serial 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006302set nhl_names {}
Paul Mackerras63b79192006-05-20 21:31:52 +10006303set highlight_paths {}
Paul Mackerras1902c272006-05-25 21:25:13 +10006304set searchdirn -forwards
Paul Mackerras4e7d6772006-05-30 21:33:07 +10006305set boldrows {}
6306set boldnamerows {}
Paul Mackerrasd6982062005-08-06 22:06:06 +10006307
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006308set optim_delay 16
6309
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006310set nextviewnum 1
6311set curview 0
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006312set selectedview 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006313set selectedhlview None
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006314set viewfiles(0) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006315set viewperm(0) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006316set viewargs(0) {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006317
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006318set cmdlineok 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006319set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:58 +00006320set stuffsaved 0
Paul Mackerras74daedb2005-06-27 19:27:32 +10006321set patchnum 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006322setcoords
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10006323makewindow
Doug Maxey6c283322006-12-10 14:31:46 -06006324wm title . "[file tail $argv0]: [file tail [pwd]]"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006325readrefs
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006326
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006327if {$cmdline_files ne {} || $revtreeargs ne {}} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006328 # create a view for the files/dirs specified on the command line
6329 set curview 1
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006330 set selectedview 1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006331 set nextviewnum 2
6332 set viewname(1) "Command line"
6333 set viewfiles(1) $cmdline_files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006334 set viewargs(1) $revtreeargs
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006335 set viewperm(1) 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006336 addviewmenu 1
Paul Mackerras3cd204e2006-11-23 21:06:16 +11006337 .bar.view entryconf Edit* -state normal
6338 .bar.view entryconf Delete* -state normal
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006339}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006340
6341if {[info exists permviews]} {
6342 foreach v $permviews {
6343 set n $nextviewnum
6344 incr nextviewnum
6345 set viewname($n) [lindex $v 0]
6346 set viewfiles($n) [lindex $v 1]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006347 set viewargs($n) [lindex $v 2]
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006348 set viewperm($n) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006349 addviewmenu $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006350 }
6351}
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006352getcommits